src/hg/makeDb/mdbUpdate/mdbUpdate.c 1.1
1.1 2010/04/13 19:59:16 tdreszer
Renamed metaTbl to 'mdb' and eliminated objType.
Index: src/hg/makeDb/mdbUpdate/mdbUpdate.c
===================================================================
RCS file: src/hg/makeDb/mdbUpdate/mdbUpdate.c
diff -N src/hg/makeDb/mdbUpdate/mdbUpdate.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/hg/makeDb/mdbUpdate/mdbUpdate.c 13 Apr 2010 19:59:16 -0000 1.1
@@ -0,0 +1,291 @@
+/* mdbUpdate - Adds, updates or removes metadata objects and variables from the 'mdb' metadata table. */
+#include "common.h"
+#include "linefile.h"
+#include "options.h"
+#include "mdb.h"
+#include "hash.h"
+
+static char const rcsid[] = "$Id$";
+
+#define OBJTYPE_DEFAULT "table"
+
+void usage()
+/* Explain usage and exit. */
+{
+errAbort(
+ "mdbUpdate - Adds, updates or removes metadata objects and variables from the 'mdb' metadata table.\n"
+ "usage:\n"
+ " mdbUpdate {db} [-table= [-force]] [-recreate] [-test [-verbose=2]]\n"
+ " [-obj= [-type=] [-delete] [-var=] [-binary] [-val=]]\n"
+ " [-vars=\"var1=val1 var2=val2... [-delete] [-var=] [-binary] [-val=]]\n"
+ " [{fileName}] [-replace]\n"
+ "Options:\n"
+ " {db} Database to update metadata in. This argument is required.\n"
+ " -table Table to update metadata to. Default is the sandbox version of\n"
+ " '" MDB_DEFAULT_NAME "'.\n"
+ " -recreate Creates or empties the table. No further arguemts are needed.\n"
+ " -force Overrides restrictions placed on shared '" MDB_DEFAULT_NAME "'.\n"
+ " -test Does not update but only reports results. Use with -verbose=2 to see SQL.\n"
+ " if {fileName} argument not provided, then -obj or -vars must be provided\n"
+ " -obj={objName} Update this single object from the command lineas :\n"
+ " -vars={var=val...} Apply update to group of objects matching these restrictions.\n"
+ " It is recommended you test the selection criteria with mdbPrint\n"
+ " to verify which objects meet your selection criteria first.\n"
+ " Use of 'var!=val', 'var=v%%' and 'var=?' are supported.\n"
+ " These options work on objects selected with -obj or -vars:\n"
+ " -delete Remove a specific var or entire obj (if -var not provided).\n"
+ " -var={varName} Provide variable name (if no -var then must be -delete)\n"
+ " -binary NOT YET IMPLEMENTED. This var has a binary val and -val={file}\n"
+ " -val={value} (Enclosed in \"quotes if necessary\".) Not required to delete var\n"
+ " -setVars={var=val...} Allows setting multiple var=val pairs.\n"
+ " [{fileName}] File containing formatted metadata lines. (Ignored if -obj or -vars used).\n"
+ " -replace Means remove all old variables for each object before adding new variables\n\n"
+ "There are two ways to call mdbUpdate. The object (or objects matching vars) and var to update "
+ "can be declared on the command line, or a file of formatted metadata lines can be provided. "
+ "The file can be the formatted output from mdbPrint or the following special formats:\n"
+ " metadata objName var1=val1 var2=\"val2 with spaces\" var3=...\n"
+ " Adds or updates the specific object and variables\n"
+ " metadata objName delete\n"
+ " delete all metadata for objName\n"
+ " metadata objName delete var=val var2=val2\n"
+ " deletes specifically named variables for objName. (Must provide val but value is ignored).\n"
+ " Special ENCODE format as produced by the doEncodeValidate.pl\n"
+ "NOTE: Updates to the shared '" MDB_DEFAULT_NAME "' can only be done by a file written\n"
+ " directly from mdbPrint. Update sandbox first, then move updates to shared table.\n"
+ "HINT: Use '%%' in any command line obj, var or val as a wildcard for selection.\n\n"
+ "Examples:\n"
+ " mdbUpdate hg19 -vars=\"grant=Snyder cell=GM12878 antibody=CTCF\" -var=expId -val=1427\n"
+ " Update all objects matcing Snyder/GM12878/CTCF and set the expId=1472.\n"
+ " mdbUpdate hg19 -obj=fredsTable -var=description val=\"Ethyl's husband's clutter\"\n"
+ " Updates fredsTable with a description.\n"
+ " mdbUpdate mm9 -table=mdb_braney -recreate\n"
+ " Creates or empties the named metadata table.\n"
+ " mdbUpdate hg18 -test vars=\"composite=wgEncodeDukeDNase\" -delete\n"
+ " Tests the delete of all objects that have the named composite defined.\n"
+ " mdbUpdate hg18 -table=mdb encBroadHistone.mdb.ra -replace\n"
+ " Replaces all metadata for objects found in the provided file.\n"
+ " File must have been printed with mdbPrint.\n"
+ );
+}
+
+static struct optionSpec optionSpecs[] = {
+ {"table", OPTION_STRING}, // default "mdb"
+ {"obj", OPTION_STRING}, // objName or objId
+ {"vars", OPTION_STRING}, // Select set of object by vars
+ {"var", OPTION_STRING}, // variable
+ {"val", OPTION_STRING}, // value
+ {"setVars", OPTION_STRING}, // Allows setting multiple var=val pairs
+ {"delete", OPTION_BOOLEAN},// delete one obj or obj/var
+ {"binary", OPTION_BOOLEAN},// val is binary (NOT YET IMPLEMENTED) implies -val={file}
+ {"replace", OPTION_BOOLEAN},// replace entire obj when loading from file
+ {"recreate",OPTION_BOOLEAN},// creates or recreates the table
+ {"force", OPTION_BOOLEAN},// override restrictions on shared table
+ {"test", OPTION_BOOLEAN},// give it a test, will ya?
+ {NULL, 0}
+};
+
+int main(int argc, char *argv[])
+// Process command line.
+{
+if(argc == 1)
+ usage();
+
+struct mdbObj * mdbObjs = NULL;
+
+optionInit(&argc, argv, optionSpecs);
+
+if(argc < 2)
+ {
+ verbose(1, "REQUIRED 'DB' argument not found:\n");
+ usage();
+ }
+
+char *db = argv[1];
+char *table = optionVal("table",NULL);
+boolean deleteIt = optionExists("delete");
+boolean testIt = optionExists("test");
+boolean recreate = optionExists("recreate");
+boolean force = optionExists("force");
+boolean replace = FALSE;
+char *var = optionVal("var",NULL);
+char *val = optionVal("val",NULL);
+char *setVars = optionVal("setVars",NULL);
+
+struct sqlConnection *conn = sqlConnect(db);
+
+// Find the table if necessary
+if(table == NULL)
+ {
+ table = mdbTableName((recreate?NULL:conn),TRUE); // Look for sandBox name first
+ if(table == NULL)
+ {
+ table = mdbTableName((recreate?NULL:conn),FALSE); // Okay, default then
+ if(table == NULL) // Now you are just getting me angry!
+ {
+ sqlDisconnect(&conn);
+ if(!recreate) // assertable
+ errAbort("No '%s.%s' found. Consider using -recreate flag.\n",db,MDB_DEFAULT_NAME);
+ else
+ errAbort("No '%s.%s' found.\n",db,MDB_DEFAULT_NAME);
+ }
+ }
+ verbose(1, "Using table named '%s.%s'.\n",db,table);
+ }
+
+boolean sharedTbl = sameWord(table,MDB_DEFAULT_NAME); // Special restrictions apply
+
+// Recreate the table
+if(recreate)
+ {
+ if(sharedTbl && ! force)
+ {
+ sqlDisconnect(&conn);
+ verbose(1, "NOT SUPPORTED for shared table '%s'.\n",MDB_DEFAULT_NAME);
+ }
+ boolean recreated = sqlTableExists(conn,table);
+ mdbReCreate(conn,table,testIt);
+ if(testIt)
+ {
+ verbose(1, "Would %screate table named '%s'.\n",
+ (recreated?"re":""),table);
+ if(!recreated)
+ {
+ sqlDisconnect(&conn);
+ if(optionExists("obj") || optionExists("vars") || argc > 2)
+ verbose(1, "Can't test further commands. Consider '-db= [-table=] -recreate' as the only arguments.\n");
+ return 0; // Don't test any update if we haven't actually created the table!
+ }
+ }
+ else
+ verbose(1, "%s table named '%s'.\n",(recreated?"Recreated":"Created"),table);
+ }
+
+if(argc > 2 && (deleteIt || var != NULL || val != NULL || setVars != NULL))
+ {
+ verbose(1, "INCONSISTENT REQUEST: can't combine supplied file with -delete, -var, -val or -setVars.\n");
+ usage();
+ }
+if(deleteIt && var != NULL && val != NULL)
+ {
+ verbose(1, "INCONSISTENT REQUEST: can't combine -delete with -var and -val.\n");
+ usage();
+ }
+if (argc != 3 && !deleteIt)
+ {
+ if(setVars == NULL && (var == NULL || val == NULL))
+ {
+ if(recreate) // no problem
+ return 0;
+ verbose(1, "INCONSISTENT REQUEST: need both -var and -val.\n");
+ usage();
+ }
+ else if (setVars != NULL && (var != NULL || val != NULL))
+ {
+ if(recreate) // no problem
+ return 0;
+ verbose(1, "INCONSISTENT REQUEST: can't combin -var or -val with -setVars.\n");
+ usage();
+ }
+ }
+
+// Now get the object list
+if(optionExists("obj"))
+ {
+ if(sharedTbl && !force)
+ {
+ sqlDisconnect(&conn);
+ verbose(1, "NOT SUPPORTED for shared table '%s'.\n",MDB_DEFAULT_NAME);
+ usage(); // Must not have submitted formatted file also
+ }
+ if(argc > 2 || optionExists("vars"))
+ {
+ sqlDisconnect(&conn);
+ verbose(1, "INCONSISTENT REQUEST: can't combine -obj with -vars or a supplied file.\n");
+ usage(); // Must not have submitted formatted file also
+ }
+
+ mdbObjs = mdbObjCreate(optionVal("obj", NULL),var,
+ (optionExists("binary") ? "binary" : "txt"), // FIXME: don't know how to deal with binary yet
+ val);
+ mdbObjs->deleteThis = deleteIt;
+
+ if(setVars != NULL)
+ mdbObjSwapVars(mdbObjs,setVars,deleteIt);
+
+ verbose(2, "metadata %s %s%s%s%s\n",
+ mdbObjs->obj,(mdbObjs->deleteThis ? "delete ":""),
+ (mdbObjs->vars && mdbObjs->vars->var!=NULL?mdbObjs->vars->var:""),
+ (mdbObjs->vars && mdbObjs->vars->val!=NULL?"=":""),
+ (mdbObjs->vars && mdbObjs->vars->val!=NULL?mdbObjs->vars->val:""));
+ }
+else if(optionExists("vars"))
+ {
+ if(sharedTbl && !force)
+ {
+ sqlDisconnect(&conn);
+ verbose(1, "NOT SUPPORTED for shared table '%s'.\n",MDB_DEFAULT_NAME);
+ usage(); // Must not have submitted formatted file also
+ }
+ if(argc > 2)
+ {
+ sqlDisconnect(&conn);
+ verbose(1, "INCONSISTENT REQUEST: can't combine -vars with a supplied file.\n");
+ usage(); // Must not have submitted formatted file also
+ }
+ struct mdbByVar * mdbByVars = mdbByVarsLineParse(optionVal("vars", NULL));
+ mdbObjs = mdbObjsQueryByVars(conn,table,mdbByVars);
+
+ // replace all found vars but update request
+ if(setVars != NULL)
+ mdbObjSwapVars(mdbObjs,setVars,deleteIt);
+ else
+ mdbObjTransformToUpdate(mdbObjs,var,
+ (optionExists("binary") ? "binary" : "txt"), // FIXME: don't know how to deal with binary yet
+ val,deleteIt);
+ }
+else // Must be submitting formatted file
+ {
+ if(argc != 3)
+ {
+ sqlDisconnect(&conn);
+ if(recreate) // no problem
+ return 0;
+ verbose(1, "REQUIRED: must declare -obj, -vars or supply a file.\n");
+ usage(); // Must not have submitted formatted file also
+ }
+
+ replace = optionExists("replace");
+ boolean validated = FALSE;
+ mdbObjs = mdbObjsLoadFromFormattedFile(argv[2],&validated);
+ if(sharedTbl && !force && !validated)
+ {
+ sqlDisconnect(&conn);
+ errAbort("Update to shared table '%s' requires file directly written by mdbPrint from sandbox file.\n", table);
+ }
+ if(mdbObjs != NULL)
+ verbose(1, "Read %d metadata objects from %s\n", slCount(mdbObjs),argv[1]);
+ }
+
+int count = 0;
+
+if(mdbObjs != NULL)
+ {
+ if(testIt && verboseLevel() > 2)
+ mdbObjPrint(mdbObjs,FALSE);
+
+ count = mdbObjsSetToDb(conn,table,mdbObjs,replace,testIt);
+ }
+if(testIt)
+ verbose(1, "Command would affected %d row(s) in %s.%s\n", count,db,table);
+else
+ verbose(1, "Affected %d row(s) in %s.%s\n", count,db,table);
+
+sqlDisconnect(&conn);
+mdbObjsFree(&mdbObjs);
+return 0;
+
+// TODO:
+// 1) Case insensitive hashs?
+// 2) -ra by default (-1 line)?
+// 3) expId table? -exp=start requests generating unique ids for selected vars, then updating them. -expTbl generates expTable as id,"var=val var=val var=val"
+}