00001
00002
00003
00004
00005
00006
00007 #include "jsoc_main.h"
00008 #include "drms.h"
00009 #include "drms_names.h"
00010 #include "drms_cmdparams.h"
00131 ModuleArgs_t module_args[] =
00132 {
00133 {ARG_STRING, "ds", "Not Specified", "Series name with optional record spec"},
00134 {ARG_FLAG, "h", "0", "Print usage message and quit"},
00135 {ARG_FLAG, "c", "0", "Create a new record from command line keywords"},
00136 {ARG_FLAG, "C", "0", "Force cloning of needed records to be DRMS_COPY_SEGMENT mode"},
00137 {ARG_FLAG, "i", NULL, "Ignore the default behavior of ingesting the FITS-file header"},
00138 {ARG_FLAG, "k", "0", "Create new records as specified from stdin"},
00139 {ARG_FLAG, "m", "0", "allow multiple records to be updated"},
00140 {ARG_FLAG, "t", "0", "create any needed records as DRMS_TRANSIENT, default is DRMS_PERMANENT"},
00141 {ARG_FLAG, "v", "0", "verbose flag"},
00142 {ARG_END}
00143 };
00144
00145 char *module_name = "set_info";
00146
00147 int verbose = 0;
00148
00149 int nice_intro(int help)
00150 {
00151 int usage = cmdparams_get_int(&cmdparams, "h", NULL) != 0;
00152 verbose = cmdparams_get_int(&cmdparams, "v", NULL) != 0;
00153 if (usage || help)
00154 {
00155 printf("set_info (({-c}|{-k})|{-m}) {-C} {-i} {-t} {-h} {-v} "
00156 "ds=<recordset query> {keyword=value} ... \n"
00157 " -h: print this message\n"
00158 " -c: create - create new record\n"
00159 " -i: ignore - ignore the FITS-file header\n"
00160 " -k: create_many - create a set of new records\n"
00161 " -m: multiple - allow multiple records to be updated\n"
00162 " -C: Force cloning of needed records to be DRMS_COPY_SEGMENT mode\n"
00163 " -t: create any needed records as DRMS_TRANSIENT, default is DRMS_PERMANENT\n"
00164 " -v: verbose\n"
00165 "ds=<recordset query> as <series>{[record specifier]} - required\n"
00166 "keyword=value pairs as needed\n"
00167 "segment=filename pairs \n");
00168 return(1);
00169 }
00170 return(0);
00171 }
00172
00173 #define DIE(msg) {fprintf(stderr,"$$$$ set_info error: %s\n",msg); return 1;}
00174
00175 DRMS_Type_Value_t cmdparams_get_type(CmdParams_t *cmdparams, char *keyname, DRMS_Type_t keytype, int *status);
00176
00177
00178
00179 static int FitsImport(DRMS_Record_t *rec, DRMS_Segment_t *seg, const char *file, HContainer_t **keys, HContainer_t *keylist)
00180 {
00181 int err = 0;
00182 int drmsstat = DRMS_SUCCESS;
00183 DRMS_Array_t *data = NULL;
00184 HContainer_t *keysint = NULL;
00185 HIterator_t hit;
00186 const char *intstr = NULL;
00187 DRMS_Keyword_t *akey = NULL;
00188 HContainer_t *keysintFiltered = NULL;
00189 DRMS_Keyword_t *drmskey = NULL;
00190
00191
00192
00193
00194
00195
00196 data = drms_fitsrw_read(drms_env, file, 1, &keysint, &drmsstat);
00197 if (data && drmsstat == DRMS_SUCCESS)
00198 {
00199 drmsstat = drms_segment_write(seg, data, 0);
00200 if (drmsstat != DRMS_SUCCESS)
00201 {
00202 err = 1;
00203 }
00204 else
00205 {
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 keysintFiltered = hcon_create(sizeof(DRMS_Keyword_t),
00219 DRMS_MAXKEYNAMELEN,
00220 (void (*)(const void *))drms_free_template_keyword_struct,
00221 NULL,
00222 NULL,
00223 NULL,
00224 0);
00225
00226 hiter_new_sort(&hit, keysint, drms_keyword_ranksort);
00227 while ((akey = hiter_extgetnext(&hit, &intstr)) != NULL)
00228 {
00229
00230
00231
00232 drmskey = drms_keyword_lookup(rec, akey->info->name, 0);
00233
00234 if (drmskey && !drms_keyword_isconstant(drmskey))
00235 {
00236
00237
00238 hcon_insert(keysintFiltered, intstr, akey);
00239
00240 if (!hcon_member(keylist, intstr))
00241 {
00242 hcon_insert(keylist, intstr, (const void *)&akey->info->rank);
00243 }
00244
00245
00246
00247 akey->info = NULL;
00248 }
00249
00250 }
00251
00252 hiter_free(&hit);
00253
00254 keys[seg->info->segnum] = keysintFiltered;
00255 hcon_destroy(&keysint);
00256 }
00257 }
00258 else
00259 {
00260 err = 1;
00261 }
00262
00263 if (data)
00264 {
00265 drms_free_array(data);
00266 data = NULL;
00267 }
00268
00269 return err;
00270 }
00271
00272 static inline int KeySort(const void *he1, const void *he2)
00273 {
00274 int *r1 = (int *)hcon_getval(*((HContainerElement_t **)he1));
00275 int *r2 = (int *)hcon_getval(*((HContainerElement_t **)he2));
00276
00277 XASSERT(r1 && r2);
00278
00279 return (*r1 < *r2) ? -1 : (*r1 > *r2 ? 1 : 0);
00280 }
00281
00282
00283
00284
00285 static int WriteKeyValues(DRMS_Record_t *rec, int nsegments, HContainer_t *keylist, HContainer_t **segfilekeys)
00286 {
00287 int conflict;
00288 int skipkey;
00289 HIterator_t keyhit;
00290 const char *kbuf = NULL;
00291 char persegkey[DRMS_MAXKEYNAMELEN];
00292 DRMS_Type_Value_t *val;
00293 DRMS_Type_t *valtype;
00294 int persegexists = 0;
00295 DRMS_Keyword_t *segfilekey = NULL;
00296 HContainer_t *segfilekeyhash = NULL;
00297 int isegment;
00298 char query[DRMS_MAXQUERYLEN];
00299 DB_Text_Result_t *qres = NULL;
00300 char *ns = NULL;
00301 int skret;
00302 int err = 1;
00303
00304 get_namespace(rec->seriesinfo->seriesname, &ns, NULL);
00305 if (ns)
00306 {
00307 if (hcon_size(keylist) > 0)
00308 {
00309 hiter_new_sort(&keyhit, keylist, KeySort);
00310 while (hiter_extgetnext(&keyhit, &kbuf))
00311 {
00312 conflict = 0;
00313 skipkey = 0;
00314 val = NULL;
00315 valtype = NULL;
00316
00317
00318 for (isegment = 0; isegment < nsegments; isegment++)
00319 {
00320 segfilekeyhash = segfilekeys[isegment];
00321
00322 if (segfilekeyhash)
00323 {
00324
00325 segfilekey = (DRMS_Keyword_t *)hcon_lookup(segfilekeyhash, kbuf);
00326
00327 if (segfilekey)
00328 {
00329
00330 if (val)
00331 {
00332 if (*valtype != segfilekey->info->type)
00333 {
00334
00335
00336 fprintf(stderr, "Conflicting data types for keyword '%s'; no value for this keyword will be written to this record.\n", segfilekey->info->name);
00337 skipkey = 1;
00338 break;
00339 }
00340 else if (!drms_equal(*valtype, val, &segfilekey->value))
00341 {
00342 conflict = 1;
00343 break;
00344 }
00345 }
00346 else
00347 {
00348 val = &segfilekey->value;
00349 valtype = &segfilekey->info->type;
00350 }
00351 }
00352 else
00353 {
00354
00355 fprintf(stderr, "Keyword '%s' is not present in all segment files; no value for this keyword will be written to this record.\n", kbuf);
00356 skipkey = 1;
00357 break;
00358 }
00359 }
00360 }
00361
00362
00363 if (!skipkey)
00364 {
00365 char *lckeyname = strdup(kbuf);
00366
00367 strtolower(lckeyname);
00368
00369
00370 snprintf(query, sizeof(query), "SELECT * FROM %s.drms_keyword WHERE lower(seriesname) = '%s' AND lower(keywordname) = '%s' AND persegment & 1 = 1", ns, rec->seriesinfo->seriesname, lckeyname);
00371 free(lckeyname);
00372
00373 if (rec->env->verbose)
00374 {
00375 fprintf(stdout , "Per-segment Keyword-Check Query: %s\n", query);
00376 }
00377
00378 if ((qres = drms_query_txt(rec->env->session, query)) != NULL && qres->num_rows != 0)
00379 {
00380 persegexists = 1;
00381 }
00382 else
00383 {
00384 persegexists = 0;
00385 }
00386
00387 if (qres)
00388 {
00389 db_free_text_result(qres);
00390 qres = NULL;
00391 }
00392
00393 if (conflict || persegexists)
00394 {
00395 if (persegexists)
00396 {
00397
00398 for (isegment = 0; isegment < nsegments; isegment++)
00399 {
00400 segfilekeyhash = segfilekeys[isegment];
00401
00402 if (segfilekeyhash)
00403 {
00404 segfilekey = hcon_lookup(segfilekeyhash, kbuf);
00405 snprintf(persegkey, sizeof(persegkey), "%s[%d]", kbuf, isegment);
00406
00407 if (!drms_keyword_lookup(rec, persegkey, 0))
00408 {
00409 fprintf(stderr, "The output series '%s' does not contain keyword '%s', skipping and continuing.\n", rec->seriesinfo->seriesname, kbuf);
00410 }
00411 else
00412 {
00413 if ((skret = drms_setkey(rec, persegkey, segfilekey->info->type, &segfilekey->value)) == DRMS_ERROR_KEYWORDREADONLY)
00414 {
00415 fprintf(stderr, "Unable to write value for read-only keyword '%s'.\n", kbuf);
00416 }
00417 else if (skret != DRMS_SUCCESS)
00418 {
00419 fprintf(stderr, "Error writing value for keyword '%s'; continuing.\n", kbuf);
00420 }
00421 else
00422 {
00423 err = 0;
00424 }
00425 }
00426 }
00427 }
00428 }
00429 else
00430 {
00431 fprintf(stderr, "Conflicting keyword values for keyword '%s' and no per-segment keyword exists; no value for this keyword will be written to this record.\n", kbuf);
00432 }
00433 }
00434 else
00435 {
00436
00437
00438
00439 if (!drms_keyword_lookup(rec, kbuf, 0))
00440 {
00441 fprintf(stderr, "The output series '%s' does not contain keyword '%s', skipping and continuing.\n", rec->seriesinfo->seriesname, kbuf);
00442 }
00443 else
00444 {
00445
00446 if ((skret = drms_setkey(rec, kbuf, *valtype, val)) == DRMS_ERROR_KEYWORDREADONLY)
00447 {
00448 fprintf(stderr, "Unable to write value for read-only keyword '%s'.\n", kbuf);
00449 }
00450 else if (skret != DRMS_SUCCESS)
00451 {
00452 fprintf(stderr, "Error writing value for keyword '%s'; continuing.\n", kbuf);
00453 }
00454 else
00455 {
00456 err = 0;
00457 }
00458 }
00459 }
00460 }
00461 }
00462
00463 hiter_free(&keyhit);
00464 }
00465 else
00466 {
00467
00468 err = 0;
00469 }
00470
00471 free(ns);
00472 }
00473
00474 return err;
00475 }
00476
00477 static int IngestingAFile(DRMS_Record_t * rec)
00478 {
00479 int rv = 0;
00480 DRMS_Segment_t *seg = NULL;
00481 HIterator_t *hit = NULL;
00482
00483
00484 while ((seg = drms_record_nextseg(rec, &hit, 0)) != NULL)
00485 {
00486 if (!seg->info->islink)
00487 {
00488
00489
00490 if (seg->info->protocol == DRMS_GENERIC || seg->info->protocol == DRMS_FITS)
00491 {
00492 const char *segname = NULL;
00493 const char *filename = NULL;
00494 segname = seg->info->name;
00495 filename = cmdparams_get_str(&cmdparams, segname, NULL);
00496 if (filename && *filename)
00497 {
00498 rv = 1;
00499 break;
00500
00501
00502
00503 }
00504 }
00505 }
00506 }
00507
00508 if (hit)
00509 {
00510 hiter_destroy(&hit);
00511 }
00512
00513 return rv;
00514 }
00515
00516 static int CreateLinks(DRMS_Record_t *srec, HContainer_t *links)
00517 {
00518 HIterator_t *lhit = NULL;
00519 DRMS_Link_t *lnk = NULL;
00520 int status;
00521 int rv = 0;
00522
00523 lhit = hiter_create(links);
00524
00525 if (lhit)
00526 {
00527 const char *lname = NULL;
00528 const char *lval = NULL;
00529 DRMS_RecordSet_t *rs = NULL;
00530 DRMS_Record_t *rec = NULL;
00531
00532 while ((lnk = (DRMS_Link_t *)hiter_getnext(lhit)) != NULL)
00533 {
00534 lname = lnk->info->name;
00535
00536 if (cmdparams_exists(&cmdparams, (char*)lname))
00537 {
00538 lval = cmdparams_get_str(&cmdparams, lname, NULL);
00539
00540
00541 rs = drms_open_records(drms_env, lval, &status);
00542 if (!rs || status != DRMS_SUCCESS)
00543 {
00544 fprintf(stderr, "Invalid record-set specification '%s'.\n", lval);
00545 rv = 1;
00546 break;
00547 }
00548
00549 if (rs->n != 1)
00550 {
00551 fprintf(stderr, "Record-set specification '%s' does not identify a single record.\n", lval);
00552 rv = 1;
00553 break;
00554 }
00555
00556 rec = drms_recordset_fetchnext(drms_env, rs, &status, NULL, NULL);
00557
00558 if (!rec || status != DRMS_SUCCESS)
00559 {
00560 fprintf(stderr, "Unable to fetch records.\n");
00561 rv = 1;
00562 break;
00563 }
00564
00565 if (drms_link_set(lname, srec, rec) != DRMS_SUCCESS)
00566 {
00567 fprintf(stderr, "Failure creating %s link.\n", lname);
00568 rv = 1;
00569 break;
00570 }
00571 }
00572 }
00573
00574 if (rs)
00575 {
00576 drms_close_records(rs, DRMS_FREE_RECORD);
00577 }
00578
00579 hiter_destroy(&lhit);
00580 }
00581 else
00582 {
00583 fprintf(stderr, "Unable to create iterator.\n");
00584 rv = 1;
00585 }
00586
00587 return rv;
00588 }
00589
00590 int found_from_stdin = 0;
00591
00592
00593 int get_params_from_stdin()
00594 {
00595 char buf[4096];
00596 while (fgets(buf, 4096, stdin))
00597 {
00598 char *eq;
00599 char *p = buf;
00600 while (*p && isblank(*p))
00601 p++;
00602 if (*p == '\n')
00603 {
00604 if (found_from_stdin)
00605 {
00606 fprintf(stderr,"found_from_stdin=%d\n",found_from_stdin);
00607 return(1);
00608 }
00609 else
00610 {
00611 fprintf(stderr,"found blank line, skip\n");
00612 continue;
00613 }
00614 }
00615 if (*p == '#')
00616 continue;
00617 eq = index(p, '=');
00618 if (!eq)
00619 continue;
00620 *eq++ = '\0';
00621 while (*eq && isblank(*eq))
00622 eq++;
00623 found_from_stdin++;
00624 if (*eq == '"')
00625 {
00626 eq++;
00627 char *rquote = rindex(eq, '"');
00628 if (rquote)
00629 *rquote = '\0';
00630 else
00631 fprintf(stderr, "Keyword %s has leading but not trailing quote\n", p);
00632 }
00633 char *nl = rindex(eq, '\n');
00634 if (nl)
00635 *nl = '\0';
00636
00637 cmdparams_set(&cmdparams, p, eq);
00638 if (verbose)
00639 fprintf(stderr,"added %s = %s\n",p,eq);
00640 }
00641 return(0);
00642 }
00643
00644
00645 int DoIt(void)
00646 {
00647 int status = 0;
00648 int multiple = 0;
00649 int create = 0;
00650 int create_from_stdin = 0;
00651 int nrecs, irec;
00652 int force_transient;
00653 int force_copyseg;
00654 int ignoreHeader = 0;
00655 const char *keyname;
00656 char prime_names[100][32];
00657 char **pkeys;
00658 char *query;
00659 char *p;
00660 DRMS_Type_t keytype;
00661 DRMS_Type_Value_t key_anyval;
00662 DRMS_Record_t *rec;
00663 DRMS_RecordSet_t *rs;
00664 DRMS_Keyword_t *key;
00665 DRMS_Segment_t *seg;
00666 int nprime, iprime;
00667 int isegment;
00668 int is_new_seg = 0;
00669
00670 if (nice_intro(0))
00671 return(0);
00672
00673
00674 query = strdup(cmdparams_get_str(&cmdparams, "ds", NULL));
00675
00676 force_copyseg = cmdparams_get_int(&cmdparams, "C", NULL) != 0;
00677 ignoreHeader = cmdparams_isflagset(&cmdparams, "i");
00678 force_transient = cmdparams_get_int(&cmdparams, "t", NULL) != 0;
00679
00680 multiple = cmdparams_get_int(&cmdparams, "m", NULL) != 0;
00681 create = cmdparams_get_int(&cmdparams, "c", NULL) != 0;
00682 create_from_stdin = cmdparams_get_int(&cmdparams, "k", NULL) != 0;
00683 if (multiple && (create || create_from_stdin))
00684 {
00685 if (query) { free(query); query = NULL; }
00686 DIE("-c or -k with -m not compatible");
00687 }
00688 p = index(query,'[');
00689 if (!p && !(create || create_from_stdin))
00690 {
00691 if (query) { free(query); query = NULL; }
00692 DIE ("must be in create mode if no record spec given");
00693 }
00694 if (p && (create || create_from_stdin))
00695 {
00696 if (query) { free(query); query = NULL; }
00697 DIE("can only create new record, record set spec not allowed");
00698 }
00699
00700
00701 if (verbose)
00702 {
00703
00704 fprintf(stderr, "set_info() %s, query is %s.\n", (create || create_from_stdin) ? "creating record(s)" : "updating record", query);
00705 }
00706
00707 if (create || create_from_stdin)
00708 {
00709 if (verbose)fprintf(stderr, "Make new record\n");
00710 rs = drms_create_records(drms_env, 1, query, (force_transient ? DRMS_TRANSIENT : DRMS_PERMANENT), &status);
00711 if (status)
00712 {
00713 char msgbuf[128];
00714 snprintf(msgbuf, sizeof(msgbuf), "cant create records in series %s, status %d", query, status);
00715 if (query) { free(query); query = NULL; }
00716 DIE(msgbuf);
00717 }
00718 nrecs = 1;
00719 rec = rs->records[0];
00720 if (verbose) fprintf(stderr, "recnum=%lld\n", rec->recnum);
00721
00722 pkeys = drms_series_createpkeyarray(drms_env,
00723 rec->seriesinfo->seriesname,
00724 &nprime,
00725 &status);
00726 if (status)
00727 {
00728 if (query) { free(query); query = NULL; }
00729 DIE("series bad, prime key missing");
00730 }
00731
00732 for (iprime = 0; iprime < nprime; iprime++)
00733 {
00734 keyname = pkeys[iprime];
00735 strcpy(prime_names[iprime], keyname);
00736 key = drms_keyword_lookup(rec, keyname, 1);
00737 if (key->info->islink || key->info->recscope == kRecScopeType_Constant)
00738 DIE("Prime keys may not be linked or constant");
00739 }
00740
00741
00742 }
00743 else
00744 {
00745
00746 DRMS_RecordSet_t *ors;
00747 if (verbose)fprintf(stderr, "Clone record for update\n");
00748 ors = drms_open_records(drms_env, query, &status);
00749 if (status)
00750 {
00751 if (query) { free(query); query = NULL; }
00752 DIE("cant open recordset query");
00753 }
00754 nrecs = ors->n;
00755 if (nrecs > 1 && !multiple)
00756 {
00757 if (query) { free(query); query = NULL; }
00758 DIE("multiple records not expected");
00759 }
00760 if (nrecs == 0)
00761 {
00762 printf("No records found for %s\n", query);
00763 return 0;
00764 }
00765 rec = ors->records[0];
00766
00767 pkeys = drms_series_createpkeyarray(drms_env,
00768 rec->seriesinfo->seriesname,
00769 &nprime,
00770 &status);
00771
00772 for (iprime = 0; iprime < nprime; iprime++)
00773 {
00774 keyname = pkeys[iprime];
00775 strcpy(prime_names[iprime], keyname);
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785 is_new_seg = IngestingAFile(rec);
00786
00787 if (is_new_seg || force_copyseg)
00788 {
00789 rs = drms_clone_records(ors, (force_transient ? DRMS_TRANSIENT : DRMS_PERMANENT), DRMS_COPY_SEGMENTS , &status);
00790 }
00791 else
00792 {
00793 rs = drms_clone_records_nosums(ors, (force_transient ? DRMS_TRANSIENT : DRMS_PERMANENT), DRMS_SHARE_SEGMENTS, &status);
00794 }
00795
00796
00797 drms_close_records(ors, DRMS_FREE_RECORD);
00798
00799 if (rs->n != nrecs || status)
00800 {
00801 if (query) { free(query); query = NULL; }
00802 DIE("failed to clone records from query");
00803 }
00804 }
00805
00806
00807
00808 HContainer_t **segfilekeys = NULL;
00809 HContainer_t *keylist = NULL;
00810 int noutsegs = 0;
00811 int nonlnksegs = 0;
00812 HIterator_t *seghit = NULL;
00813
00814 for (irec = 0; irec<nrecs; irec++)
00815 {
00816 if (create_from_stdin)
00817 {
00818 if (get_params_from_stdin() && found_from_stdin == 0)
00819 {
00820 drms_free_records(rs);
00821 rs = NULL;
00822 continue;
00823 }
00824 }
00825 char recordpath[DRMS_MAXPATHLEN];
00826 rec = rs->records[irec];
00827 noutsegs = hcon_size(&rec->segments);
00828
00829 if (noutsegs > 0)
00830 {
00831 segfilekeys = malloc(sizeof(HContainer_t *) * noutsegs);
00832 memset(segfilekeys, 0, sizeof(HContainer_t *) * noutsegs);
00833 keylist = hcon_create(sizeof(int), sizeof(DRMS_MAXKEYNAMELEN), NULL, NULL, NULL, NULL, 0);
00834 }
00835
00836
00837
00838
00839
00840 if (is_new_seg || force_copyseg)
00841 {
00842 drms_record_directory(rec, recordpath, 1);
00843 }
00844
00845
00846 while ((seg = drms_record_nextseg(rec, &seghit, 0)) != NULL)
00847 {
00848 if (!seg->info->islink)
00849 {
00850 const char *filename = NULL;
00851 const char *segname = seg->info->name;
00852
00853 nonlnksegs++;
00854 segfilekeys[seg->info->segnum] = NULL;
00855
00856 filename = cmdparams_get_str(&cmdparams, segname, NULL);
00857
00858 if (filename && *filename)
00859 {
00860
00861 if (seg->info->protocol == DRMS_GENERIC)
00862 {
00863
00864 char *afile = NULL;
00865 char *pch = NULL;
00866 char *tmp = strdup(filename);
00867
00868 if (tmp)
00869 {
00870 afile = tmp;
00871 while ((pch = strchr(afile, ',')) != NULL)
00872 {
00873 *pch = '\0';
00874
00875
00876 if ((status = drms_segment_write_from_file(seg, afile)))
00877 {
00878 if (query) { free(query); query = NULL; }
00879 free(tmp);
00880 tmp = NULL;
00881 DIE("segment name matches cmdline arg but file copy failed.\n");
00882 }
00883
00884 afile = pch + 1;
00885 }
00886
00887
00888 if ((status = drms_segment_write_from_file(seg, afile)))
00889 {
00890 if (query) { free(query); query = NULL; }
00891 free(tmp);
00892 tmp = NULL;
00893 DIE("segment name matches cmdline arg but file copy failed.\n");
00894 }
00895
00896 free(tmp);
00897 tmp = NULL;
00898 }
00899 }
00900 else if (seg->info->protocol == DRMS_FITS)
00901 {
00902 if (!ignoreHeader)
00903 {
00904 if (FitsImport(rec, seg, filename, segfilekeys, keylist) != 0)
00905 {
00906 char diebuf[256];
00907
00908 snprintf(diebuf, sizeof(diebuf),
00909 "File '%s' does not contain data compatible with segment '%s'.\n",
00910 filename, seg->info->name);
00911 if (query) { free(query); query = NULL; }
00912 DIE(diebuf);
00913 }
00914 }
00915 }
00916 else
00917 {
00918 fprintf(stderr, "Unsupported file protocol '%s'.\n", drms_prot2str(seg->info->protocol));
00919 }
00920 }
00921 }
00922 }
00923
00924 if (seghit)
00925 {
00926 hiter_destroy(&seghit);
00927 }
00928
00929
00930 if (nonlnksegs > 0)
00931 {
00932 WriteKeyValues(rec, noutsegs, keylist, segfilekeys);
00933 }
00934
00935
00936 if (segfilekeys)
00937 {
00938 for (isegment = 0; isegment < noutsegs; isegment++)
00939 {
00940 if (segfilekeys[isegment])
00941 {
00942 hcon_destroy(&segfilekeys[isegment]);
00943 }
00944 }
00945
00946 free(segfilekeys);
00947 }
00948
00949 if (keylist)
00950 {
00951 hcon_destroy(&keylist);
00952 }
00953
00954
00955
00956 HIterator_t *last = NULL;
00957 const char *argname = NULL;
00958 DRMS_Value_t *keyval = NULL;
00959 CmdParams_Arg_t *arg = NULL;
00960
00961 while ((arg = drms_cmdparams_getnext(&cmdparams, &last, &status)) != NULL)
00962 {
00963 if (status)
00964 {
00965 DIE("Problem examining cmd-line arguments.");
00966 }
00967
00968 argname = cmdparams_get_argname(arg);
00969
00970 if (argname)
00971 {
00972 key = drms_keyword_lookup(rec, argname, 0);
00973 }
00974 else
00975 {
00976
00977 continue;
00978 }
00979
00980 if (key)
00981 {
00982 keyname = argname;
00983
00984 keytype = drms_keyword_gettype(key);
00985
00986
00987 if (drms_keyword_isprime(key))
00988 {
00989
00990 if (!create && !create_from_stdin)
00991 {
00992 if (query) { free(query); query = NULL; }
00993 DIE("Attempt to change prime key - not allowed");
00994 }
00995 else
00996 {
00997 keyval = drms_cmdparams_get(&cmdparams, keyname, keytype, &status);
00998
00999 if (status != DRMS_SUCCESS)
01000 {
01001 char msg[128];
01002 snprintf(msg, sizeof(msg), "Cannot get cmd-line argument %s.", keyname);
01003 DIE(msg);
01004 }
01005
01006 key_anyval = keyval->value;
01007 status = drms_setkey(rec, keyname, keytype, &key_anyval);
01008
01009 if (keytype == DRMS_TYPE_STRING)
01010 {
01011 free(key_anyval.string_val);
01012 key_anyval.string_val = NULL;
01013 }
01014 }
01015 }
01016 else if (drms_keyword_getrecscope(key) == kRecScopeType_Constant)
01017 {
01018 ;
01019 }
01020 else
01021 {
01022 keyval = drms_cmdparams_get(&cmdparams, keyname, keytype, &status);
01023
01024 if (status != DRMS_SUCCESS)
01025 {
01026 char msg[128];
01027 snprintf(msg, sizeof(msg), "Cannot get cmd-line argument %s.", keyname);
01028 DIE(msg);
01029 }
01030
01031 if (!keyname || !keytype || !keyval)
01032 {
01033 char buffer[DRMS_MAXKEYNAMELEN];
01034
01035 snprintf(buffer, sizeof(buffer), "Unable to get cmd-line value for keyword %s.", keyname);
01036 status = DRMS_ERROR_INVALIDDATA;
01037 DIE(buffer);
01038 }
01039
01040 key_anyval = keyval->value;
01041
01042
01043 if (strcasecmp("history", keyname) == 0)
01044 {
01045 if (keytype == DRMS_TYPE_STRING)
01046 {
01047 if (drms_appendhistory(rec, key_anyval.string_val, 1))
01048 {
01049 DIE("Unable to append to HISTORY keyword.");
01050 }
01051 }
01052 else
01053 {
01054 DIE("Unable to append to HISTORY keyword - unexpected keyword type.");
01055 }
01056 }
01057 else if (strcasecmp("comment", keyname) == 0)
01058 {
01059 if (keytype == DRMS_TYPE_STRING)
01060 {
01061 if (drms_appendcomment(rec, key_anyval.string_val, 1))
01062 {
01063 DIE("Unable to append to COMMENT keyword.");
01064 }
01065 }
01066 else
01067 {
01068 DIE("Unable to append to COMMENT keyword - unexpected keyword type.");
01069 }
01070 }
01071 else
01072 {
01073 status = drms_setkey(rec, keyname, keytype, &key_anyval);
01074 }
01075
01076 if (keytype == DRMS_TYPE_STRING)
01077 {
01078 free(key_anyval.string_val);
01079 key_anyval.string_val = NULL;
01080 }
01081
01082 free(keyval);
01083 keyval = NULL;
01084
01085 if (status)
01086 {
01087 if (query) { free(query); query = NULL; }
01088 DIE("keyval bad, cant set key val with keyname");
01089 }
01090 }
01091 }
01092 }
01093
01094 if (last)
01095 {
01096 hiter_destroy(&last);
01097 }
01098
01099
01100 if (create || create_from_stdin)
01101 {
01102 keyval = malloc(sizeof(DRMS_Value_t));
01103
01104 if (!keyval)
01105 {
01106 free(keyval);
01107 DIE("Out of memory.");
01108 }
01109
01110 for (iprime = 0; iprime < nprime; iprime++)
01111 {
01112 *keyval = drms_getkey_p(rec, prime_names[iprime], &status);
01113
01114 if (status != DRMS_SUCCESS)
01115 {
01116 free(keyval);
01117 DIE("Problem getting keyword value.");
01118 }
01119
01120 if (drms_ismissing(keyval))
01121 {
01122 free(keyval);
01123 DIE("some prime key not specified on command line");
01124 }
01125 }
01126
01127 free(keyval);
01128 }
01129
01130
01131 if (CreateLinks(rec, &rec->links))
01132 {
01133 DIE("Unable to create link.");
01134 }
01135
01136 if (create_from_stdin && found_from_stdin)
01137 {
01138 fprintf(stderr,"closing record\n");
01139 status = drms_close_records(rs, DRMS_INSERT_RECORD);
01140 if (status)
01141 {
01142 fprintf(stderr, "XXX close error from stdin record, rs=%p, nrecs=%d",rs,(rs ? rs->n : -1));
01143 DIE("close failure");
01144 }
01145 rs = drms_create_records(drms_env, 1, query, (force_transient ? DRMS_TRANSIENT : DRMS_PERMANENT), &status);
01146 irec = -1;
01147 found_from_stdin = 0;
01148 }
01149 }
01150
01151 if (pkeys)
01152 {
01153 drms_series_destroypkeyarray(&pkeys, nprime);
01154 }
01155
01156 if (rs)
01157 status = drms_close_records(rs, DRMS_INSERT_RECORD);
01158 if (status)
01159 {
01160 if (query) { free(query); query = NULL; }
01161 DIE("close failure");
01162 }
01163
01164 if (query)
01165 {
01166 free(query);
01167 query = NULL;
01168 }
01169
01170 return 0;
01171 }
01172
01173
01174
01175 DRMS_Type_Value_t cmdparams_get_type(CmdParams_t *cmdparams, char *keyname, DRMS_Type_t keytype, int *status)
01176 {
01177 DRMS_Type_Value_t value;
01178 switch (keytype)
01179 {
01180 case DRMS_TYPE_CHAR:
01181 value.char_val = cmdparams_get_int8(cmdparams, keyname, status);
01182 break;
01183 case DRMS_TYPE_SHORT:
01184 value.short_val = cmdparams_get_int16(cmdparams, keyname, status);
01185 break;
01186 case DRMS_TYPE_INT:
01187 value.int_val = cmdparams_get_int32(cmdparams, keyname, status);
01188 break;
01189 case DRMS_TYPE_LONGLONG:
01190 value.longlong_val = cmdparams_get_int64(cmdparams, keyname, status);
01191 break;
01192 case DRMS_TYPE_FLOAT:
01193 value.float_val = cmdparams_get_float(cmdparams, keyname, status);
01194 break;
01195 case DRMS_TYPE_DOUBLE:
01196 value.double_val = cmdparams_get_double(cmdparams, keyname, status);
01197 break;
01198 case DRMS_TYPE_TIME:
01199 value.time_val = cmdparams_get_time(cmdparams, keyname, status);
01200 break;
01201 case DRMS_TYPE_STRING:
01202 value.string_val = strdup(cmdparams_get_str(cmdparams, keyname, status));
01203 break;
01204 default:
01205 *status=1;
01206 break;
01207 }
01208 return value;
01209 }
01210