00001
00002
00003 #include "jsoc_main.h"
00004 #include "drms.h"
00005 #include "drms_names.h"
00106 ModuleArgs_t module_args[] =
00107 {
00108 {ARG_STRING, "ds", "Not Specified", "Series name with optional record spec"},
00109 {ARG_FLAG, "h", "0", "Print usage message and quit"},
00110 {ARG_FLAG, "c", "0", "Create new record(s) if needed"},
00111 {ARG_FLAG, "C", "0", "Force cloning of needed records to be DRMS_COPY_SEGMENT mode"},
00112 {ARG_FLAG, "m", "0", "allow multiple records to be updated"},
00113 {ARG_FLAG, "t", "0", "create any needed records as DRMS_TRANSIENT, default is DRMS_PERMANENT"},
00114 {ARG_FLAG, "l", NULL, "keyword names on cmd-line specified in all lower case (and may not match the case of the keyword names stored in DRMS)"},
00115 {ARG_FLAG, "v", "0", "verbose flag"},
00116 {ARG_END}
00117 };
00118
00119 char *module_name = "set_keys";
00120
00121 int verbose = 0;
00122
00123 int nice_intro(int help)
00124 {
00125 int usage = cmdparams_get_int(&cmdparams, "h", NULL) != 0;
00126 verbose = cmdparams_get_int(&cmdparams, "v", NULL) != 0;
00127 if (usage || help)
00128 {
00129 printf("set_keys {-c}|{-m} {-C} {-t} {-h} {-v} "
00130 "ds=<recordset query> {keyword=value} ... \n"
00131 " -h: print this message\n"
00132 " -c: create - allow creation of new record\n"
00133 " -m: multiple - allow multiple records to be updated\n"
00134 " -C: Force cloning of needed records to be DRMS_COPY_SEGMENT mode\n"
00135 " -t: create any needed records as DRMS_TRANSIENT, default is DRMS_PERMANENT\n"
00136 " -v: verbose\n"
00137 "ds=<recordset query> as <series>{[record specifier]} - required\n"
00138 "keyword=value pairs as needed\n"
00139 "segment=filename pairs \n");
00140 return(1);
00141 }
00142 return(0);
00143 }
00144
00145 #define DIE(msg) {fprintf(stderr,"$$$$ set_keys error: %s\n",msg); return 1;}
00146
00147 DRMS_Type_Value_t cmdparams_get_type(CmdParams_t *cmdparams, char *keyname, DRMS_Type_t keytype, int *status);
00148
00149
00150 int DoIt(void)
00151 {
00152 int status = 0;
00153 int multiple = 0;
00154 int create = 0;
00155 int lckeys = 0;
00156 int nrecs, irec;
00157 int force_transient;
00158 int force_copyseg;
00159 char *keyname;
00160 char *lckeyname = NULL;
00161 char prime_names[100][32];
00162 char **pkeys;
00163 char *query;
00164 char *p;
00165 DRMS_Type_t keytype;
00166 DRMS_Type_Value_t key_anyval;
00167 DRMS_Record_t *rec;
00168 DRMS_RecordSet_t *rs;
00169 DRMS_Keyword_t *key;
00170 DRMS_Segment_t *seg;
00171 HIterator_t key_hit;
00172 int nprime, iprime;
00173 int nsegments, isegment;
00174 int is_new_seg = 0;
00175
00176 if (nice_intro(0))
00177 return(0);
00178
00179
00180 query = strdup(cmdparams_get_str(&cmdparams, "ds", NULL));
00181
00182 force_copyseg = cmdparams_get_int(&cmdparams, "C", NULL) != 0;
00183 force_transient = cmdparams_get_int(&cmdparams, "t", NULL) != 0;
00184
00185 multiple = cmdparams_get_int(&cmdparams, "m", NULL) != 0;
00186 create = cmdparams_get_int(&cmdparams, "c", NULL) != 0;
00187 lckeys = cmdparams_isflagset(&cmdparams, "l");
00188 if (multiple && create)
00189 DIE("-c and -m not compatible");
00190 p = index(query,'[');
00191 if (!p && !create)
00192 DIE ("must be in create mode if no record spec given");
00193 if (p && create)
00194 DIE("can only create new record, record set not allowed");
00195
00196
00197 if (verbose)
00198 {
00199
00200 printf("set_keys() %s, query is %s.\n", create ? "creating record" : "updating record", query);
00201 }
00202
00203 if (create)
00204 {
00205 if (verbose)printf("Make new record\n");
00206 rs = drms_create_records(drms_env, 1, query, (force_transient ? DRMS_TRANSIENT : DRMS_PERMANENT), &status);
00207 if (status)
00208 DIE("cant create records from in given series");
00209 nrecs = 1;
00210 rec = rs->records[0];
00211 pkeys = drms_series_createpkeyarray(drms_env,
00212 rec->seriesinfo->seriesname,
00213 &nprime,
00214 &status);
00215
00216 for (iprime = 0; iprime < nprime; iprime++)
00217 {
00218 keyname = pkeys[iprime];
00219 strcpy(prime_names[iprime], keyname);
00220 key = drms_keyword_lookup(rec, keyname, 1);
00221 keytype = key->info->type;
00222 if (status)
00223 DIE("series bad, prime key missing");
00224
00225 if (lckeys)
00226 {
00227 lckeyname = strdup(keyname);
00228 strtolower(lckeyname);
00229 keyname = lckeyname;
00230 }
00231
00232 if (!cmdparams_exists(&cmdparams, keyname))
00233 DIE("some prime key not specified on command line");
00234 key_anyval = cmdparams_get_type(&cmdparams, keyname, keytype, &status);
00235 status = drms_setkey(rec, keyname, keytype, &key_anyval);
00236 if (status)
00237 DIE("keyval bad, cant set prime key val with keyname");
00238
00239 if (lckeys && lckeyname)
00240 {
00241 free(lckeyname);
00242 lckeyname = NULL;
00243 }
00244 }
00245
00246
00247 }
00248 else
00249 {
00250 DRMS_RecordSet_t *ors;
00251 if (verbose)printf("Clone record for update\n");
00252 ors = drms_open_records(drms_env, query, &status);
00253 if (status)
00254 DIE("cant open recordset query");
00255 nrecs = ors->n;
00256 if (nrecs > 1 && !multiple)
00257 DIE("multiple records not expected");
00258 if (nrecs == 0)
00259 {
00260 printf("No records found for %s\n", query);
00261 return 0;
00262 }
00263 rec = ors->records[0];
00264
00265 pkeys = drms_series_createpkeyarray(drms_env,
00266 rec->seriesinfo->seriesname,
00267 &nprime,
00268 &status);
00269
00270 for (iprime = 0; iprime < nprime; iprime++)
00271 {
00272 keyname = pkeys[iprime];
00273 strcpy(prime_names[iprime], keyname);
00274 }
00275
00276
00277
00278
00279
00280
00281 is_new_seg = 0;
00282 nsegments = hcon_size(&rec->segments);
00283 for (isegment=0; isegment<nsegments; isegment++)
00284 {
00285 seg = drms_segment_lookupnum(rec, isegment);
00286
00287 if (seg->info->protocol == DRMS_GENERIC)
00288 {
00289 const char *segname, *filename;
00290 segname = seg->info->name;
00291 filename = cmdparams_get_str(&cmdparams, segname, NULL);
00292 if (filename && *filename)
00293 {
00294 is_new_seg = 1;
00295 break;
00296 }
00297 }
00298 }
00299 rs = drms_clone_records(ors, (force_transient ? DRMS_TRANSIENT : DRMS_PERMANENT),
00300 ((is_new_seg||force_copyseg) ? DRMS_COPY_SEGMENTS : DRMS_SHARE_SEGMENTS), &status);
00301 if (rs->n != nrecs || status)
00302 DIE("failed to clone records from query");
00303 }
00304
00305
00306 for (irec = 0; irec<nrecs; irec++)
00307 {
00308 char recordpath[DRMS_MAXPATHLEN];
00309 rec = rs->records[irec];
00310
00311
00312 drms_record_directory(rec, recordpath, is_new_seg||force_copyseg);
00313
00314 nsegments = hcon_size(&rec->segments);
00315 for (isegment=0; isegment<nsegments; isegment++)
00316 {
00317 seg = drms_segment_lookupnum(rec, isegment);
00318 const char *filename = NULL;
00319 char *segname = seg->info->name;
00320 filename = cmdparams_get_str(&cmdparams, segname, NULL);
00321
00322 if (filename && *filename)
00323 {
00324
00325 if (seg->info->protocol == DRMS_GENERIC)
00326 {
00327 if ((status = drms_segment_write_from_file(seg, filename)))
00328 DIE("segment name matches cmdline arg but file copy failed.\n");
00329 }
00330 }
00331 }
00332
00333 hiter_new(&key_hit, &rec->keywords);
00334 while( (key = (DRMS_Keyword_t *)hiter_getnext(&key_hit)) )
00335 {
00336 int is_prime = 0;
00337 keyname = key->info->name;
00338 keytype = key->info->type;
00339
00340 if (lckeys)
00341 {
00342 lckeyname = strdup(keyname);
00343 strtolower(lckeyname);
00344 keyname = lckeyname;
00345 }
00346
00347
00348 if (cmdparams_exists(&cmdparams, keyname))
00349 {
00350
00351 for (is_prime=0, iprime = 0; iprime < nprime; iprime++)
00352 if (strcasecmp(keyname, prime_names[iprime]) == 0)
00353 is_prime = 1;
00354 if (is_prime)
00355 {
00356 if (!create)
00357 DIE("Attempt to change prime key - not allowed");
00358 }
00359 else
00360 {
00361 key_anyval = cmdparams_get_type(&cmdparams, keyname, keytype, &status);
00362 status = drms_setkey(rec, keyname, keytype, &key_anyval);
00363 if (status)
00364 DIE("keyval bad, cant set key val with keyname");
00365 }
00366 }
00367
00368 if (lckeys && lckeyname)
00369 {
00370 free(lckeyname);
00371 lckeyname = NULL;
00372 }
00373 }
00374 }
00375
00376 if (pkeys)
00377 {
00378 drms_series_destroypkeyarray(&pkeys, nprime);
00379 }
00380
00381 status = drms_close_records(rs, DRMS_INSERT_RECORD);
00382 if (status)
00383 DIE("close failure");
00384 return 0;
00385 }
00386
00387
00388
00389 DRMS_Type_Value_t cmdparams_get_type(CmdParams_t *cmdparams, char *keyname, DRMS_Type_t keytype, int *status)
00390 {
00391 DRMS_Type_Value_t value;
00392 switch (keytype)
00393 {
00394 case DRMS_TYPE_CHAR:
00395 value.char_val = cmdparams_get_int8(cmdparams, keyname, status);
00396 break;
00397 case DRMS_TYPE_SHORT:
00398 value.short_val = cmdparams_get_int16(cmdparams, keyname, status);
00399 break;
00400 case DRMS_TYPE_INT:
00401 value.int_val = cmdparams_get_int32(cmdparams, keyname, status);
00402 break;
00403 case DRMS_TYPE_LONGLONG:
00404 value.longlong_val = cmdparams_get_int64(cmdparams, keyname, status);
00405 break;
00406 case DRMS_TYPE_FLOAT:
00407 value.float_val = cmdparams_get_float(cmdparams, keyname, status);
00408 break;
00409 case DRMS_TYPE_DOUBLE:
00410 value.double_val = cmdparams_get_double(cmdparams, keyname, status);
00411 break;
00412 case DRMS_TYPE_TIME:
00413 value.time_val = cmdparams_get_time(cmdparams, keyname, status);
00414 break;
00415 case DRMS_TYPE_STRING:
00416 value.string_val = strdup(cmdparams_get_str(cmdparams, keyname, status));
00417 break;
00418 default:
00419 *status=1;
00420 break;
00421 }
00422 return value;
00423 }
00424