Changeset 10681 for trunk/ippdb/src/ippdb.c
- Timestamp:
- Dec 12, 2006, 5:52:50 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/ippdb/src/ippdb.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ippdb/src/ippdb.c
r10449 r10681 63 63 #define DETRESIDEXP_TABLE_NAME "detResidExp" 64 64 #define DETRUNSUMMARY_TABLE_NAME "detRunSummary" 65 #define P4RUN_TABLE_NAME "p4Run" 66 #define P4INPUTIMFILE_TABLE_NAME "p4InputImfile" 67 #define P4PWARPEDIMFILE_TABLE_NAME "p4PWarpedImfile" 68 #define P4PSTACKEDIMFILE_TABLE_NAME "p4PStackedImfile" 69 #define P4PDIFFIMFILE_TABLE_NAME "p4PDiffImfile" 70 #define P4PMAGICMASKIMFILE_TABLE_NAME "p4PMagicMaskImfile" 65 71 #define MAX_STRING_LENGTH 1024 66 72 … … 13164 13170 return true; 13165 13171 } 13172 static void p4RunRowFree(p4RunRow *object); 13173 13174 p4RunRow *p4RunRowAlloc(psS32 p4_id, const char *survey_mode, const char *state, const char *filter, const char *skycell_id, const char *tess_id, psF64 ra, psF64 decl, const char *input_ss, const char *output_ss) 13175 { 13176 p4RunRow *_object; 13177 13178 _object = psAlloc(sizeof(p4RunRow)); 13179 psMemSetDeallocator(_object, (psFreeFunc)p4RunRowFree); 13180 13181 _object->p4_id = p4_id; 13182 _object->survey_mode = psStringCopy(survey_mode); 13183 _object->state = psStringCopy(state); 13184 _object->filter = psStringCopy(filter); 13185 _object->skycell_id = psStringCopy(skycell_id); 13186 _object->tess_id = psStringCopy(tess_id); 13187 _object->ra = ra; 13188 _object->decl = decl; 13189 _object->input_ss = psStringCopy(input_ss); 13190 _object->output_ss = psStringCopy(output_ss); 13191 13192 return _object; 13193 } 13194 13195 static void p4RunRowFree(p4RunRow *object) 13196 { 13197 psFree(object->survey_mode); 13198 psFree(object->state); 13199 psFree(object->filter); 13200 psFree(object->skycell_id); 13201 psFree(object->tess_id); 13202 psFree(object->input_ss); 13203 psFree(object->output_ss); 13204 } 13205 13206 bool p4RunCreateTable(psDB *dbh) 13207 { 13208 psMetadata *md = psMetadataAlloc(); 13209 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key AUTO_INCREMENT", 0)) { 13210 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 13211 psFree(md); 13212 return false; 13213 } 13214 if (!psMetadataAdd(md, PS_LIST_TAIL, "survey_mode", PS_DATA_STRING, "Key", "64")) { 13215 psError(PS_ERR_UNKNOWN, false, "failed to add item survey_mode"); 13216 psFree(md); 13217 return false; 13218 } 13219 if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, "Key", "64")) { 13220 psError(PS_ERR_UNKNOWN, false, "failed to add item state"); 13221 psFree(md); 13222 return false; 13223 } 13224 if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, "64")) { 13225 psError(PS_ERR_UNKNOWN, false, "failed to add item filter"); 13226 psFree(md); 13227 return false; 13228 } 13229 if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, "64")) { 13230 psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id"); 13231 psFree(md); 13232 return false; 13233 } 13234 if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, "64")) { 13235 psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id"); 13236 psFree(md); 13237 return false; 13238 } 13239 if (!psMetadataAdd(md, PS_LIST_TAIL, "ra", PS_DATA_F64, NULL, 0.0)) { 13240 psError(PS_ERR_UNKNOWN, false, "failed to add item ra"); 13241 psFree(md); 13242 return false; 13243 } 13244 if (!psMetadataAdd(md, PS_LIST_TAIL, "decl", PS_DATA_F64, NULL, 0.0)) { 13245 psError(PS_ERR_UNKNOWN, false, "failed to add item decl"); 13246 psFree(md); 13247 return false; 13248 } 13249 if (!psMetadataAdd(md, PS_LIST_TAIL, "input_ss", PS_DATA_STRING, NULL, "64")) { 13250 psError(PS_ERR_UNKNOWN, false, "failed to add item input_ss"); 13251 psFree(md); 13252 return false; 13253 } 13254 if (!psMetadataAdd(md, PS_LIST_TAIL, "output_ss", PS_DATA_STRING, NULL, "64")) { 13255 psError(PS_ERR_UNKNOWN, false, "failed to add item output_ss"); 13256 psFree(md); 13257 return false; 13258 } 13259 13260 bool status = psDBCreateTable(dbh, P4RUN_TABLE_NAME, md); 13261 13262 psFree(md); 13263 13264 return status; 13265 } 13266 13267 bool p4RunDropTable(psDB *dbh) 13268 { 13269 return psDBDropTable(dbh, P4RUN_TABLE_NAME); 13270 } 13271 13272 bool p4RunInsert(psDB * dbh, psS32 p4_id, const char *survey_mode, const char *state, const char *filter, const char *skycell_id, const char *tess_id, psF64 ra, psF64 decl, const char *input_ss, const char *output_ss) 13273 { 13274 psMetadata *md = psMetadataAlloc(); 13275 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) { 13276 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 13277 psFree(md); 13278 return false; 13279 } 13280 if (!psMetadataAdd(md, PS_LIST_TAIL, "survey_mode", PS_DATA_STRING, NULL, survey_mode)) { 13281 psError(PS_ERR_UNKNOWN, false, "failed to add item survey_mode"); 13282 psFree(md); 13283 return false; 13284 } 13285 if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) { 13286 psError(PS_ERR_UNKNOWN, false, "failed to add item state"); 13287 psFree(md); 13288 return false; 13289 } 13290 if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, filter)) { 13291 psError(PS_ERR_UNKNOWN, false, "failed to add item filter"); 13292 psFree(md); 13293 return false; 13294 } 13295 if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) { 13296 psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id"); 13297 psFree(md); 13298 return false; 13299 } 13300 if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) { 13301 psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id"); 13302 psFree(md); 13303 return false; 13304 } 13305 if (!psMetadataAdd(md, PS_LIST_TAIL, "ra", PS_DATA_F64, NULL, ra)) { 13306 psError(PS_ERR_UNKNOWN, false, "failed to add item ra"); 13307 psFree(md); 13308 return false; 13309 } 13310 if (!psMetadataAdd(md, PS_LIST_TAIL, "decl", PS_DATA_F64, NULL, decl)) { 13311 psError(PS_ERR_UNKNOWN, false, "failed to add item decl"); 13312 psFree(md); 13313 return false; 13314 } 13315 if (!psMetadataAdd(md, PS_LIST_TAIL, "input_ss", PS_DATA_STRING, NULL, input_ss)) { 13316 psError(PS_ERR_UNKNOWN, false, "failed to add item input_ss"); 13317 psFree(md); 13318 return false; 13319 } 13320 if (!psMetadataAdd(md, PS_LIST_TAIL, "output_ss", PS_DATA_STRING, NULL, output_ss)) { 13321 psError(PS_ERR_UNKNOWN, false, "failed to add item output_ss"); 13322 psFree(md); 13323 return false; 13324 } 13325 13326 bool status = psDBInsertOneRow(dbh, P4RUN_TABLE_NAME, md); 13327 psFree(md); 13328 13329 return status; 13330 } 13331 13332 long long p4RunDelete(psDB *dbh, const psMetadata *where, unsigned long long limit) 13333 { 13334 long long deleted = 0; 13335 13336 long long count = psDBDeleteRows(dbh, P4RUN_TABLE_NAME, where, limit); 13337 if (count < 0) { 13338 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4Run"); 13339 return count; 13340 13341 deleted += count; 13342 } 13343 13344 return deleted; 13345 } 13346 bool p4RunInsertObject(psDB *dbh, p4RunRow *object) 13347 { 13348 return p4RunInsert(dbh, object->p4_id, object->survey_mode, object->state, object->filter, object->skycell_id, object->tess_id, object->ra, object->decl, object->input_ss, object->output_ss); 13349 } 13350 13351 bool p4RunInsertObjects(psDB *dbh, psArray *objects) 13352 { 13353 for (long i = 0; i < psArrayLength(objects); i++) { 13354 if (!p4RunInsertObject(dbh, objects->data[i])) { 13355 return false; 13356 } 13357 } 13358 13359 return true; 13360 } 13361 13362 bool p4RunInsertFits(psDB *dbh, const psFits *fits) 13363 { 13364 psArray *rowSet; 13365 13366 // move to (the first?) extension named P4RUN_TABLE_NAME 13367 if (!psFitsMoveExtName(fits, P4RUN_TABLE_NAME)) { 13368 psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4RUN_TABLE_NAME); 13369 return false; 13370 } 13371 13372 // check HDU type 13373 if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE) { 13374 psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE"); 13375 return false; 13376 } 13377 13378 // read fits table 13379 rowSet = psFitsReadTable(fits); 13380 if (!rowSet) { 13381 psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty"); 13382 psFree(rowSet); 13383 return false; 13384 } 13385 13386 if (!psDBInsertRows(dbh, P4RUN_TABLE_NAME, rowSet)) { 13387 psError(PS_ERR_UNKNOWN, false, "databse insert failed"); 13388 psFree(rowSet); 13389 return false; 13390 } 13391 13392 psFree(rowSet); 13393 13394 return true; 13395 } 13396 13397 bool p4RunSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit) 13398 { 13399 psArray *rowSet; 13400 13401 rowSet = psDBSelectRows(dbh, P4RUN_TABLE_NAME, where, limit); 13402 if (!rowSet) { 13403 return false; 13404 } 13405 13406 // output to fits 13407 if (!psFitsWriteTable(fits, NULL, rowSet, P4RUN_TABLE_NAME)) { 13408 psError(PS_ERR_UNKNOWN, false, "FITS table write failed"); 13409 psFree(rowSet); 13410 return false; 13411 } 13412 13413 psFree(rowSet); 13414 13415 return true; 13416 } 13417 13418 psMetadata *p4RunMetadataFromObject(const p4RunRow *object) 13419 { 13420 psMetadata *md = psMetadataAlloc(); 13421 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) { 13422 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 13423 psFree(md); 13424 return false; 13425 } 13426 if (!psMetadataAdd(md, PS_LIST_TAIL, "survey_mode", PS_DATA_STRING, NULL, object->survey_mode)) { 13427 psError(PS_ERR_UNKNOWN, false, "failed to add item survey_mode"); 13428 psFree(md); 13429 return false; 13430 } 13431 if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) { 13432 psError(PS_ERR_UNKNOWN, false, "failed to add item state"); 13433 psFree(md); 13434 return false; 13435 } 13436 if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, object->filter)) { 13437 psError(PS_ERR_UNKNOWN, false, "failed to add item filter"); 13438 psFree(md); 13439 return false; 13440 } 13441 if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) { 13442 psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id"); 13443 psFree(md); 13444 return false; 13445 } 13446 if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) { 13447 psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id"); 13448 psFree(md); 13449 return false; 13450 } 13451 if (!psMetadataAdd(md, PS_LIST_TAIL, "ra", PS_DATA_F64, NULL, object->ra)) { 13452 psError(PS_ERR_UNKNOWN, false, "failed to add item ra"); 13453 psFree(md); 13454 return false; 13455 } 13456 if (!psMetadataAdd(md, PS_LIST_TAIL, "decl", PS_DATA_F64, NULL, object->decl)) { 13457 psError(PS_ERR_UNKNOWN, false, "failed to add item decl"); 13458 psFree(md); 13459 return false; 13460 } 13461 if (!psMetadataAdd(md, PS_LIST_TAIL, "input_ss", PS_DATA_STRING, NULL, object->input_ss)) { 13462 psError(PS_ERR_UNKNOWN, false, "failed to add item input_ss"); 13463 psFree(md); 13464 return false; 13465 } 13466 if (!psMetadataAdd(md, PS_LIST_TAIL, "output_ss", PS_DATA_STRING, NULL, object->output_ss)) { 13467 psError(PS_ERR_UNKNOWN, false, "failed to add item output_ss"); 13468 psFree(md); 13469 return false; 13470 } 13471 13472 13473 return md; 13474 } 13475 13476 p4RunRow *p4RunObjectFromMetadata(psMetadata *md) 13477 { 13478 13479 bool status = false; 13480 psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id"); 13481 if (!status) { 13482 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id"); 13483 return false; 13484 } 13485 char* survey_mode = psMetadataLookupPtr(&status, md, "survey_mode"); 13486 if (!status) { 13487 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item survey_mode"); 13488 return false; 13489 } 13490 char* state = psMetadataLookupPtr(&status, md, "state"); 13491 if (!status) { 13492 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state"); 13493 return false; 13494 } 13495 char* filter = psMetadataLookupPtr(&status, md, "filter"); 13496 if (!status) { 13497 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item filter"); 13498 return false; 13499 } 13500 char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id"); 13501 if (!status) { 13502 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id"); 13503 return false; 13504 } 13505 char* tess_id = psMetadataLookupPtr(&status, md, "tess_id"); 13506 if (!status) { 13507 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id"); 13508 return false; 13509 } 13510 psF64 ra = psMetadataLookupF64(&status, md, "ra"); 13511 if (!status) { 13512 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra"); 13513 return false; 13514 } 13515 psF64 decl = psMetadataLookupF64(&status, md, "decl"); 13516 if (!status) { 13517 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl"); 13518 return false; 13519 } 13520 char* input_ss = psMetadataLookupPtr(&status, md, "input_ss"); 13521 if (!status) { 13522 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item input_ss"); 13523 return false; 13524 } 13525 char* output_ss = psMetadataLookupPtr(&status, md, "output_ss"); 13526 if (!status) { 13527 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item output_ss"); 13528 return false; 13529 } 13530 13531 return p4RunRowAlloc(p4_id, survey_mode, state, filter, skycell_id, tess_id, ra, decl, input_ss, output_ss); 13532 } 13533 psArray *p4RunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit) 13534 { 13535 psArray *rowSet; 13536 psArray *returnSet; 13537 psU64 i; 13538 13539 rowSet = psDBSelectRows(dbh, P4RUN_TABLE_NAME, where, limit); 13540 if (!rowSet) { 13541 return NULL; 13542 } 13543 13544 // convert psMetadata rows to row objects 13545 13546 returnSet = psArrayAllocEmpty(rowSet->n); 13547 13548 for (i = 0; i < rowSet->n; i++) { 13549 p4RunRow *object = p4RunObjectFromMetadata(rowSet->data[i]); 13550 psArrayAdd(returnSet, 0, object); 13551 psFree(object); 13552 } 13553 13554 psFree(rowSet); 13555 13556 return returnSet; 13557 } 13558 bool p4RunDeleteObject(psDB *dbh, const p4RunRow *object) 13559 { 13560 psMetadata *where = p4RunMetadataFromObject(object); 13561 long long count = psDBDeleteRows(dbh, P4RUN_TABLE_NAME, where, 0); 13562 psFree(where) 13563 if (count < 0) { 13564 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4Run"); 13565 return false; 13566 } 13567 if (count > 1) { 13568 // XXX should this be a psAbort() instead? It is possible that 13569 // having an object match multiple rows was by design. 13570 psError(PS_ERR_UNKNOWN, true, "p4RunRow object matched more then one row. Check your database schema"); 13571 return false; 13572 } 13573 13574 return true; 13575 } 13576 long long p4RunDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit) 13577 { 13578 long long deleted = 0; 13579 13580 for (long long i = 0; i < objects->n; i++) { 13581 p4RunRow *object = objects->data[i]; 13582 psMetadata *where = p4RunMetadataFromObject(object); 13583 long long count = psDBDeleteRows(dbh, P4RUN_TABLE_NAME, where, limit); 13584 psFree(where) 13585 if (count < 0) { 13586 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4Run"); 13587 return count; 13588 } 13589 13590 deleted += count; 13591 } 13592 13593 return deleted; 13594 } 13595 bool p4RunPrintObjects(FILE *stream, psArray *objects, bool mdcf) 13596 { 13597 PS_ASSERT_PTR_NON_NULL(objects, false); 13598 13599 psMetadata *output = psMetadataAlloc(); 13600 for (long i = 0; i < psArrayLength(objects); i++) { 13601 psMetadata *md = p4RunMetadataFromObject(objects->data[i]); 13602 if (!psMetadataAddMetadata( 13603 output, 13604 PS_LIST_TAIL, 13605 P4RUN_TABLE_NAME, 13606 PS_META_DUPLICATE_OK, 13607 NULL, 13608 md 13609 )) { 13610 psError(PS_ERR_UNKNOWN, false, "failed to add metadata"); 13611 psFree(md); 13612 psFree(output); 13613 return false; 13614 } 13615 psFree(md); 13616 } 13617 13618 if (!ippdbPrintMetadataRaw(stream, output, mdcf)) { 13619 psError(PS_ERR_UNKNOWN, false, "failed to print metadata"); 13620 psFree(output); 13621 } 13622 psFree(output); 13623 13624 return true; 13625 } 13626 static void p4InputImfileRowFree(p4InputImfileRow *object); 13627 13628 p4InputImfileRow *p4InputImfileRowAlloc(psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id) 13629 { 13630 p4InputImfileRow *_object; 13631 13632 _object = psAlloc(sizeof(p4InputImfileRow)); 13633 psMemSetDeallocator(_object, (psFreeFunc)p4InputImfileRowFree); 13634 13635 _object->p4_id = p4_id; 13636 _object->exp_tag = psStringCopy(exp_tag); 13637 _object->p3_version = p3_version; 13638 _object->class_id = psStringCopy(class_id); 13639 13640 return _object; 13641 } 13642 13643 static void p4InputImfileRowFree(p4InputImfileRow *object) 13644 { 13645 psFree(object->exp_tag); 13646 psFree(object->class_id); 13647 } 13648 13649 bool p4InputImfileCreateTable(psDB *dbh) 13650 { 13651 psMetadata *md = psMetadataAlloc(); 13652 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) { 13653 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 13654 psFree(md); 13655 return false; 13656 } 13657 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) { 13658 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 13659 psFree(md); 13660 return false; 13661 } 13662 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) { 13663 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 13664 psFree(md); 13665 return false; 13666 } 13667 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) { 13668 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 13669 psFree(md); 13670 return false; 13671 } 13672 13673 bool status = psDBCreateTable(dbh, P4INPUTIMFILE_TABLE_NAME, md); 13674 13675 psFree(md); 13676 13677 return status; 13678 } 13679 13680 bool p4InputImfileDropTable(psDB *dbh) 13681 { 13682 return psDBDropTable(dbh, P4INPUTIMFILE_TABLE_NAME); 13683 } 13684 13685 bool p4InputImfileInsert(psDB * dbh, psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id) 13686 { 13687 psMetadata *md = psMetadataAlloc(); 13688 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) { 13689 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 13690 psFree(md); 13691 return false; 13692 } 13693 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) { 13694 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 13695 psFree(md); 13696 return false; 13697 } 13698 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) { 13699 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 13700 psFree(md); 13701 return false; 13702 } 13703 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) { 13704 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 13705 psFree(md); 13706 return false; 13707 } 13708 13709 bool status = psDBInsertOneRow(dbh, P4INPUTIMFILE_TABLE_NAME, md); 13710 psFree(md); 13711 13712 return status; 13713 } 13714 13715 long long p4InputImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit) 13716 { 13717 long long deleted = 0; 13718 13719 long long count = psDBDeleteRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, limit); 13720 if (count < 0) { 13721 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4InputImfile"); 13722 return count; 13723 13724 deleted += count; 13725 } 13726 13727 return deleted; 13728 } 13729 bool p4InputImfileInsertObject(psDB *dbh, p4InputImfileRow *object) 13730 { 13731 return p4InputImfileInsert(dbh, object->p4_id, object->exp_tag, object->p3_version, object->class_id); 13732 } 13733 13734 bool p4InputImfileInsertObjects(psDB *dbh, psArray *objects) 13735 { 13736 for (long i = 0; i < psArrayLength(objects); i++) { 13737 if (!p4InputImfileInsertObject(dbh, objects->data[i])) { 13738 return false; 13739 } 13740 } 13741 13742 return true; 13743 } 13744 13745 bool p4InputImfileInsertFits(psDB *dbh, const psFits *fits) 13746 { 13747 psArray *rowSet; 13748 13749 // move to (the first?) extension named P4INPUTIMFILE_TABLE_NAME 13750 if (!psFitsMoveExtName(fits, P4INPUTIMFILE_TABLE_NAME)) { 13751 psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4INPUTIMFILE_TABLE_NAME); 13752 return false; 13753 } 13754 13755 // check HDU type 13756 if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE) { 13757 psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE"); 13758 return false; 13759 } 13760 13761 // read fits table 13762 rowSet = psFitsReadTable(fits); 13763 if (!rowSet) { 13764 psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty"); 13765 psFree(rowSet); 13766 return false; 13767 } 13768 13769 if (!psDBInsertRows(dbh, P4INPUTIMFILE_TABLE_NAME, rowSet)) { 13770 psError(PS_ERR_UNKNOWN, false, "databse insert failed"); 13771 psFree(rowSet); 13772 return false; 13773 } 13774 13775 psFree(rowSet); 13776 13777 return true; 13778 } 13779 13780 bool p4InputImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit) 13781 { 13782 psArray *rowSet; 13783 13784 rowSet = psDBSelectRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, limit); 13785 if (!rowSet) { 13786 return false; 13787 } 13788 13789 // output to fits 13790 if (!psFitsWriteTable(fits, NULL, rowSet, P4INPUTIMFILE_TABLE_NAME)) { 13791 psError(PS_ERR_UNKNOWN, false, "FITS table write failed"); 13792 psFree(rowSet); 13793 return false; 13794 } 13795 13796 psFree(rowSet); 13797 13798 return true; 13799 } 13800 13801 psMetadata *p4InputImfileMetadataFromObject(const p4InputImfileRow *object) 13802 { 13803 psMetadata *md = psMetadataAlloc(); 13804 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) { 13805 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 13806 psFree(md); 13807 return false; 13808 } 13809 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) { 13810 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 13811 psFree(md); 13812 return false; 13813 } 13814 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) { 13815 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 13816 psFree(md); 13817 return false; 13818 } 13819 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) { 13820 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 13821 psFree(md); 13822 return false; 13823 } 13824 13825 13826 return md; 13827 } 13828 13829 p4InputImfileRow *p4InputImfileObjectFromMetadata(psMetadata *md) 13830 { 13831 13832 bool status = false; 13833 psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id"); 13834 if (!status) { 13835 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id"); 13836 return false; 13837 } 13838 char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag"); 13839 if (!status) { 13840 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag"); 13841 return false; 13842 } 13843 psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version"); 13844 if (!status) { 13845 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version"); 13846 return false; 13847 } 13848 char* class_id = psMetadataLookupPtr(&status, md, "class_id"); 13849 if (!status) { 13850 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id"); 13851 return false; 13852 } 13853 13854 return p4InputImfileRowAlloc(p4_id, exp_tag, p3_version, class_id); 13855 } 13856 psArray *p4InputImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit) 13857 { 13858 psArray *rowSet; 13859 psArray *returnSet; 13860 psU64 i; 13861 13862 rowSet = psDBSelectRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, limit); 13863 if (!rowSet) { 13864 return NULL; 13865 } 13866 13867 // convert psMetadata rows to row objects 13868 13869 returnSet = psArrayAllocEmpty(rowSet->n); 13870 13871 for (i = 0; i < rowSet->n; i++) { 13872 p4InputImfileRow *object = p4InputImfileObjectFromMetadata(rowSet->data[i]); 13873 psArrayAdd(returnSet, 0, object); 13874 psFree(object); 13875 } 13876 13877 psFree(rowSet); 13878 13879 return returnSet; 13880 } 13881 bool p4InputImfileDeleteObject(psDB *dbh, const p4InputImfileRow *object) 13882 { 13883 psMetadata *where = p4InputImfileMetadataFromObject(object); 13884 long long count = psDBDeleteRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, 0); 13885 psFree(where) 13886 if (count < 0) { 13887 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4InputImfile"); 13888 return false; 13889 } 13890 if (count > 1) { 13891 // XXX should this be a psAbort() instead? It is possible that 13892 // having an object match multiple rows was by design. 13893 psError(PS_ERR_UNKNOWN, true, "p4InputImfileRow object matched more then one row. Check your database schema"); 13894 return false; 13895 } 13896 13897 return true; 13898 } 13899 long long p4InputImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit) 13900 { 13901 long long deleted = 0; 13902 13903 for (long long i = 0; i < objects->n; i++) { 13904 p4InputImfileRow *object = objects->data[i]; 13905 psMetadata *where = p4InputImfileMetadataFromObject(object); 13906 long long count = psDBDeleteRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, limit); 13907 psFree(where) 13908 if (count < 0) { 13909 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4InputImfile"); 13910 return count; 13911 } 13912 13913 deleted += count; 13914 } 13915 13916 return deleted; 13917 } 13918 bool p4InputImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf) 13919 { 13920 PS_ASSERT_PTR_NON_NULL(objects, false); 13921 13922 psMetadata *output = psMetadataAlloc(); 13923 for (long i = 0; i < psArrayLength(objects); i++) { 13924 psMetadata *md = p4InputImfileMetadataFromObject(objects->data[i]); 13925 if (!psMetadataAddMetadata( 13926 output, 13927 PS_LIST_TAIL, 13928 P4INPUTIMFILE_TABLE_NAME, 13929 PS_META_DUPLICATE_OK, 13930 NULL, 13931 md 13932 )) { 13933 psError(PS_ERR_UNKNOWN, false, "failed to add metadata"); 13934 psFree(md); 13935 psFree(output); 13936 return false; 13937 } 13938 psFree(md); 13939 } 13940 13941 if (!ippdbPrintMetadataRaw(stream, output, mdcf)) { 13942 psError(PS_ERR_UNKNOWN, false, "failed to print metadata"); 13943 psFree(output); 13944 } 13945 psFree(output); 13946 13947 return true; 13948 } 13949 static void p4PWarpedImfileRowFree(p4PWarpedImfileRow *object); 13950 13951 p4PWarpedImfileRow *p4PWarpedImfileRowAlloc(psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri) 13952 { 13953 p4PWarpedImfileRow *_object; 13954 13955 _object = psAlloc(sizeof(p4PWarpedImfileRow)); 13956 psMemSetDeallocator(_object, (psFreeFunc)p4PWarpedImfileRowFree); 13957 13958 _object->p4_id = p4_id; 13959 _object->exp_tag = psStringCopy(exp_tag); 13960 _object->p3_version = p3_version; 13961 _object->class_id = psStringCopy(class_id); 13962 _object->uri = psStringCopy(uri); 13963 _object->b1_uri = psStringCopy(b1_uri); 13964 _object->b2_uri = psStringCopy(b2_uri); 13965 13966 return _object; 13967 } 13968 13969 static void p4PWarpedImfileRowFree(p4PWarpedImfileRow *object) 13970 { 13971 psFree(object->exp_tag); 13972 psFree(object->class_id); 13973 psFree(object->uri); 13974 psFree(object->b1_uri); 13975 psFree(object->b2_uri); 13976 } 13977 13978 bool p4PWarpedImfileCreateTable(psDB *dbh) 13979 { 13980 psMetadata *md = psMetadataAlloc(); 13981 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) { 13982 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 13983 psFree(md); 13984 return false; 13985 } 13986 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) { 13987 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 13988 psFree(md); 13989 return false; 13990 } 13991 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) { 13992 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 13993 psFree(md); 13994 return false; 13995 } 13996 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) { 13997 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 13998 psFree(md); 13999 return false; 14000 } 14001 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) { 14002 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 14003 psFree(md); 14004 return false; 14005 } 14006 if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, "255")) { 14007 psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri"); 14008 psFree(md); 14009 return false; 14010 } 14011 if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, "255")) { 14012 psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri"); 14013 psFree(md); 14014 return false; 14015 } 14016 14017 bool status = psDBCreateTable(dbh, P4PWARPEDIMFILE_TABLE_NAME, md); 14018 14019 psFree(md); 14020 14021 return status; 14022 } 14023 14024 bool p4PWarpedImfileDropTable(psDB *dbh) 14025 { 14026 return psDBDropTable(dbh, P4PWARPEDIMFILE_TABLE_NAME); 14027 } 14028 14029 bool p4PWarpedImfileInsert(psDB * dbh, psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri) 14030 { 14031 psMetadata *md = psMetadataAlloc(); 14032 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) { 14033 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 14034 psFree(md); 14035 return false; 14036 } 14037 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) { 14038 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 14039 psFree(md); 14040 return false; 14041 } 14042 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) { 14043 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 14044 psFree(md); 14045 return false; 14046 } 14047 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) { 14048 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 14049 psFree(md); 14050 return false; 14051 } 14052 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) { 14053 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 14054 psFree(md); 14055 return false; 14056 } 14057 if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, b1_uri)) { 14058 psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri"); 14059 psFree(md); 14060 return false; 14061 } 14062 if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, b2_uri)) { 14063 psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri"); 14064 psFree(md); 14065 return false; 14066 } 14067 14068 bool status = psDBInsertOneRow(dbh, P4PWARPEDIMFILE_TABLE_NAME, md); 14069 psFree(md); 14070 14071 return status; 14072 } 14073 14074 long long p4PWarpedImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit) 14075 { 14076 long long deleted = 0; 14077 14078 long long count = psDBDeleteRows(dbh, P4PWARPEDIMFILE_TABLE_NAME, where, limit); 14079 if (count < 0) { 14080 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PWarpedImfile"); 14081 return count; 14082 14083 deleted += count; 14084 } 14085 14086 return deleted; 14087 } 14088 bool p4PWarpedImfileInsertObject(psDB *dbh, p4PWarpedImfileRow *object) 14089 { 14090 return p4PWarpedImfileInsert(dbh, object->p4_id, object->exp_tag, object->p3_version, object->class_id, object->uri, object->b1_uri, object->b2_uri); 14091 } 14092 14093 bool p4PWarpedImfileInsertObjects(psDB *dbh, psArray *objects) 14094 { 14095 for (long i = 0; i < psArrayLength(objects); i++) { 14096 if (!p4PWarpedImfileInsertObject(dbh, objects->data[i])) { 14097 return false; 14098 } 14099 } 14100 14101 return true; 14102 } 14103 14104 bool p4PWarpedImfileInsertFits(psDB *dbh, const psFits *fits) 14105 { 14106 psArray *rowSet; 14107 14108 // move to (the first?) extension named P4PWARPEDIMFILE_TABLE_NAME 14109 if (!psFitsMoveExtName(fits, P4PWARPEDIMFILE_TABLE_NAME)) { 14110 psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4PWARPEDIMFILE_TABLE_NAME); 14111 return false; 14112 } 14113 14114 // check HDU type 14115 if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE) { 14116 psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE"); 14117 return false; 14118 } 14119 14120 // read fits table 14121 rowSet = psFitsReadTable(fits); 14122 if (!rowSet) { 14123 psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty"); 14124 psFree(rowSet); 14125 return false; 14126 } 14127 14128 if (!psDBInsertRows(dbh, P4PWARPEDIMFILE_TABLE_NAME, rowSet)) { 14129 psError(PS_ERR_UNKNOWN, false, "databse insert failed"); 14130 psFree(rowSet); 14131 return false; 14132 } 14133 14134 psFree(rowSet); 14135 14136 return true; 14137 } 14138 14139 bool p4PWarpedImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit) 14140 { 14141 psArray *rowSet; 14142 14143 rowSet = psDBSelectRows(dbh, P4PWARPEDIMFILE_TABLE_NAME, where, limit); 14144 if (!rowSet) { 14145 return false; 14146 } 14147 14148 // output to fits 14149 if (!psFitsWriteTable(fits, NULL, rowSet, P4PWARPEDIMFILE_TABLE_NAME)) { 14150 psError(PS_ERR_UNKNOWN, false, "FITS table write failed"); 14151 psFree(rowSet); 14152 return false; 14153 } 14154 14155 psFree(rowSet); 14156 14157 return true; 14158 } 14159 14160 psMetadata *p4PWarpedImfileMetadataFromObject(const p4PWarpedImfileRow *object) 14161 { 14162 psMetadata *md = psMetadataAlloc(); 14163 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) { 14164 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 14165 psFree(md); 14166 return false; 14167 } 14168 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) { 14169 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 14170 psFree(md); 14171 return false; 14172 } 14173 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) { 14174 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 14175 psFree(md); 14176 return false; 14177 } 14178 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) { 14179 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 14180 psFree(md); 14181 return false; 14182 } 14183 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) { 14184 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 14185 psFree(md); 14186 return false; 14187 } 14188 if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, object->b1_uri)) { 14189 psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri"); 14190 psFree(md); 14191 return false; 14192 } 14193 if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, object->b2_uri)) { 14194 psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri"); 14195 psFree(md); 14196 return false; 14197 } 14198 14199 14200 return md; 14201 } 14202 14203 p4PWarpedImfileRow *p4PWarpedImfileObjectFromMetadata(psMetadata *md) 14204 { 14205 14206 bool status = false; 14207 psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id"); 14208 if (!status) { 14209 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id"); 14210 return false; 14211 } 14212 char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag"); 14213 if (!status) { 14214 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag"); 14215 return false; 14216 } 14217 psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version"); 14218 if (!status) { 14219 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version"); 14220 return false; 14221 } 14222 char* class_id = psMetadataLookupPtr(&status, md, "class_id"); 14223 if (!status) { 14224 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id"); 14225 return false; 14226 } 14227 char* uri = psMetadataLookupPtr(&status, md, "uri"); 14228 if (!status) { 14229 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri"); 14230 return false; 14231 } 14232 char* b1_uri = psMetadataLookupPtr(&status, md, "b1_uri"); 14233 if (!status) { 14234 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b1_uri"); 14235 return false; 14236 } 14237 char* b2_uri = psMetadataLookupPtr(&status, md, "b2_uri"); 14238 if (!status) { 14239 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b2_uri"); 14240 return false; 14241 } 14242 14243 return p4PWarpedImfileRowAlloc(p4_id, exp_tag, p3_version, class_id, uri, b1_uri, b2_uri); 14244 } 14245 psArray *p4PWarpedImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit) 14246 { 14247 psArray *rowSet; 14248 psArray *returnSet; 14249 psU64 i; 14250 14251 rowSet = psDBSelectRows(dbh, P4PWARPEDIMFILE_TABLE_NAME, where, limit); 14252 if (!rowSet) { 14253 return NULL; 14254 } 14255 14256 // convert psMetadata rows to row objects 14257 14258 returnSet = psArrayAllocEmpty(rowSet->n); 14259 14260 for (i = 0; i < rowSet->n; i++) { 14261 p4PWarpedImfileRow *object = p4PWarpedImfileObjectFromMetadata(rowSet->data[i]); 14262 psArrayAdd(returnSet, 0, object); 14263 psFree(object); 14264 } 14265 14266 psFree(rowSet); 14267 14268 return returnSet; 14269 } 14270 bool p4PWarpedImfileDeleteObject(psDB *dbh, const p4PWarpedImfileRow *object) 14271 { 14272 psMetadata *where = p4PWarpedImfileMetadataFromObject(object); 14273 long long count = psDBDeleteRows(dbh, P4PWARPEDIMFILE_TABLE_NAME, where, 0); 14274 psFree(where) 14275 if (count < 0) { 14276 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PWarpedImfile"); 14277 return false; 14278 } 14279 if (count > 1) { 14280 // XXX should this be a psAbort() instead? It is possible that 14281 // having an object match multiple rows was by design. 14282 psError(PS_ERR_UNKNOWN, true, "p4PWarpedImfileRow object matched more then one row. Check your database schema"); 14283 return false; 14284 } 14285 14286 return true; 14287 } 14288 long long p4PWarpedImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit) 14289 { 14290 long long deleted = 0; 14291 14292 for (long long i = 0; i < objects->n; i++) { 14293 p4PWarpedImfileRow *object = objects->data[i]; 14294 psMetadata *where = p4PWarpedImfileMetadataFromObject(object); 14295 long long count = psDBDeleteRows(dbh, P4PWARPEDIMFILE_TABLE_NAME, where, limit); 14296 psFree(where) 14297 if (count < 0) { 14298 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PWarpedImfile"); 14299 return count; 14300 } 14301 14302 deleted += count; 14303 } 14304 14305 return deleted; 14306 } 14307 bool p4PWarpedImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf) 14308 { 14309 PS_ASSERT_PTR_NON_NULL(objects, false); 14310 14311 psMetadata *output = psMetadataAlloc(); 14312 for (long i = 0; i < psArrayLength(objects); i++) { 14313 psMetadata *md = p4PWarpedImfileMetadataFromObject(objects->data[i]); 14314 if (!psMetadataAddMetadata( 14315 output, 14316 PS_LIST_TAIL, 14317 P4PWARPEDIMFILE_TABLE_NAME, 14318 PS_META_DUPLICATE_OK, 14319 NULL, 14320 md 14321 )) { 14322 psError(PS_ERR_UNKNOWN, false, "failed to add metadata"); 14323 psFree(md); 14324 psFree(output); 14325 return false; 14326 } 14327 psFree(md); 14328 } 14329 14330 if (!ippdbPrintMetadataRaw(stream, output, mdcf)) { 14331 psError(PS_ERR_UNKNOWN, false, "failed to print metadata"); 14332 psFree(output); 14333 } 14334 psFree(output); 14335 14336 return true; 14337 } 14338 static void p4PStackedImfileRowFree(p4PStackedImfileRow *object); 14339 14340 p4PStackedImfileRow *p4PStackedImfileRowAlloc(psS32 p4_id, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri) 14341 { 14342 p4PStackedImfileRow *_object; 14343 14344 _object = psAlloc(sizeof(p4PStackedImfileRow)); 14345 psMemSetDeallocator(_object, (psFreeFunc)p4PStackedImfileRowFree); 14346 14347 _object->p4_id = p4_id; 14348 _object->class_id = psStringCopy(class_id); 14349 _object->uri = psStringCopy(uri); 14350 _object->b1_uri = psStringCopy(b1_uri); 14351 _object->b2_uri = psStringCopy(b2_uri); 14352 14353 return _object; 14354 } 14355 14356 static void p4PStackedImfileRowFree(p4PStackedImfileRow *object) 14357 { 14358 psFree(object->class_id); 14359 psFree(object->uri); 14360 psFree(object->b1_uri); 14361 psFree(object->b2_uri); 14362 } 14363 14364 bool p4PStackedImfileCreateTable(psDB *dbh) 14365 { 14366 psMetadata *md = psMetadataAlloc(); 14367 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) { 14368 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 14369 psFree(md); 14370 return false; 14371 } 14372 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) { 14373 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 14374 psFree(md); 14375 return false; 14376 } 14377 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) { 14378 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 14379 psFree(md); 14380 return false; 14381 } 14382 if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, "255")) { 14383 psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri"); 14384 psFree(md); 14385 return false; 14386 } 14387 if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, "255")) { 14388 psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri"); 14389 psFree(md); 14390 return false; 14391 } 14392 14393 bool status = psDBCreateTable(dbh, P4PSTACKEDIMFILE_TABLE_NAME, md); 14394 14395 psFree(md); 14396 14397 return status; 14398 } 14399 14400 bool p4PStackedImfileDropTable(psDB *dbh) 14401 { 14402 return psDBDropTable(dbh, P4PSTACKEDIMFILE_TABLE_NAME); 14403 } 14404 14405 bool p4PStackedImfileInsert(psDB * dbh, psS32 p4_id, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri) 14406 { 14407 psMetadata *md = psMetadataAlloc(); 14408 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) { 14409 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 14410 psFree(md); 14411 return false; 14412 } 14413 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) { 14414 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 14415 psFree(md); 14416 return false; 14417 } 14418 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) { 14419 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 14420 psFree(md); 14421 return false; 14422 } 14423 if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, b1_uri)) { 14424 psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri"); 14425 psFree(md); 14426 return false; 14427 } 14428 if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, b2_uri)) { 14429 psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri"); 14430 psFree(md); 14431 return false; 14432 } 14433 14434 bool status = psDBInsertOneRow(dbh, P4PSTACKEDIMFILE_TABLE_NAME, md); 14435 psFree(md); 14436 14437 return status; 14438 } 14439 14440 long long p4PStackedImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit) 14441 { 14442 long long deleted = 0; 14443 14444 long long count = psDBDeleteRows(dbh, P4PSTACKEDIMFILE_TABLE_NAME, where, limit); 14445 if (count < 0) { 14446 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PStackedImfile"); 14447 return count; 14448 14449 deleted += count; 14450 } 14451 14452 return deleted; 14453 } 14454 bool p4PStackedImfileInsertObject(psDB *dbh, p4PStackedImfileRow *object) 14455 { 14456 return p4PStackedImfileInsert(dbh, object->p4_id, object->class_id, object->uri, object->b1_uri, object->b2_uri); 14457 } 14458 14459 bool p4PStackedImfileInsertObjects(psDB *dbh, psArray *objects) 14460 { 14461 for (long i = 0; i < psArrayLength(objects); i++) { 14462 if (!p4PStackedImfileInsertObject(dbh, objects->data[i])) { 14463 return false; 14464 } 14465 } 14466 14467 return true; 14468 } 14469 14470 bool p4PStackedImfileInsertFits(psDB *dbh, const psFits *fits) 14471 { 14472 psArray *rowSet; 14473 14474 // move to (the first?) extension named P4PSTACKEDIMFILE_TABLE_NAME 14475 if (!psFitsMoveExtName(fits, P4PSTACKEDIMFILE_TABLE_NAME)) { 14476 psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4PSTACKEDIMFILE_TABLE_NAME); 14477 return false; 14478 } 14479 14480 // check HDU type 14481 if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE) { 14482 psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE"); 14483 return false; 14484 } 14485 14486 // read fits table 14487 rowSet = psFitsReadTable(fits); 14488 if (!rowSet) { 14489 psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty"); 14490 psFree(rowSet); 14491 return false; 14492 } 14493 14494 if (!psDBInsertRows(dbh, P4PSTACKEDIMFILE_TABLE_NAME, rowSet)) { 14495 psError(PS_ERR_UNKNOWN, false, "databse insert failed"); 14496 psFree(rowSet); 14497 return false; 14498 } 14499 14500 psFree(rowSet); 14501 14502 return true; 14503 } 14504 14505 bool p4PStackedImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit) 14506 { 14507 psArray *rowSet; 14508 14509 rowSet = psDBSelectRows(dbh, P4PSTACKEDIMFILE_TABLE_NAME, where, limit); 14510 if (!rowSet) { 14511 return false; 14512 } 14513 14514 // output to fits 14515 if (!psFitsWriteTable(fits, NULL, rowSet, P4PSTACKEDIMFILE_TABLE_NAME)) { 14516 psError(PS_ERR_UNKNOWN, false, "FITS table write failed"); 14517 psFree(rowSet); 14518 return false; 14519 } 14520 14521 psFree(rowSet); 14522 14523 return true; 14524 } 14525 14526 psMetadata *p4PStackedImfileMetadataFromObject(const p4PStackedImfileRow *object) 14527 { 14528 psMetadata *md = psMetadataAlloc(); 14529 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) { 14530 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 14531 psFree(md); 14532 return false; 14533 } 14534 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) { 14535 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 14536 psFree(md); 14537 return false; 14538 } 14539 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) { 14540 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 14541 psFree(md); 14542 return false; 14543 } 14544 if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, object->b1_uri)) { 14545 psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri"); 14546 psFree(md); 14547 return false; 14548 } 14549 if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, object->b2_uri)) { 14550 psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri"); 14551 psFree(md); 14552 return false; 14553 } 14554 14555 14556 return md; 14557 } 14558 14559 p4PStackedImfileRow *p4PStackedImfileObjectFromMetadata(psMetadata *md) 14560 { 14561 14562 bool status = false; 14563 psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id"); 14564 if (!status) { 14565 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id"); 14566 return false; 14567 } 14568 char* class_id = psMetadataLookupPtr(&status, md, "class_id"); 14569 if (!status) { 14570 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id"); 14571 return false; 14572 } 14573 char* uri = psMetadataLookupPtr(&status, md, "uri"); 14574 if (!status) { 14575 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri"); 14576 return false; 14577 } 14578 char* b1_uri = psMetadataLookupPtr(&status, md, "b1_uri"); 14579 if (!status) { 14580 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b1_uri"); 14581 return false; 14582 } 14583 char* b2_uri = psMetadataLookupPtr(&status, md, "b2_uri"); 14584 if (!status) { 14585 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b2_uri"); 14586 return false; 14587 } 14588 14589 return p4PStackedImfileRowAlloc(p4_id, class_id, uri, b1_uri, b2_uri); 14590 } 14591 psArray *p4PStackedImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit) 14592 { 14593 psArray *rowSet; 14594 psArray *returnSet; 14595 psU64 i; 14596 14597 rowSet = psDBSelectRows(dbh, P4PSTACKEDIMFILE_TABLE_NAME, where, limit); 14598 if (!rowSet) { 14599 return NULL; 14600 } 14601 14602 // convert psMetadata rows to row objects 14603 14604 returnSet = psArrayAllocEmpty(rowSet->n); 14605 14606 for (i = 0; i < rowSet->n; i++) { 14607 p4PStackedImfileRow *object = p4PStackedImfileObjectFromMetadata(rowSet->data[i]); 14608 psArrayAdd(returnSet, 0, object); 14609 psFree(object); 14610 } 14611 14612 psFree(rowSet); 14613 14614 return returnSet; 14615 } 14616 bool p4PStackedImfileDeleteObject(psDB *dbh, const p4PStackedImfileRow *object) 14617 { 14618 psMetadata *where = p4PStackedImfileMetadataFromObject(object); 14619 long long count = psDBDeleteRows(dbh, P4PSTACKEDIMFILE_TABLE_NAME, where, 0); 14620 psFree(where) 14621 if (count < 0) { 14622 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PStackedImfile"); 14623 return false; 14624 } 14625 if (count > 1) { 14626 // XXX should this be a psAbort() instead? It is possible that 14627 // having an object match multiple rows was by design. 14628 psError(PS_ERR_UNKNOWN, true, "p4PStackedImfileRow object matched more then one row. Check your database schema"); 14629 return false; 14630 } 14631 14632 return true; 14633 } 14634 long long p4PStackedImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit) 14635 { 14636 long long deleted = 0; 14637 14638 for (long long i = 0; i < objects->n; i++) { 14639 p4PStackedImfileRow *object = objects->data[i]; 14640 psMetadata *where = p4PStackedImfileMetadataFromObject(object); 14641 long long count = psDBDeleteRows(dbh, P4PSTACKEDIMFILE_TABLE_NAME, where, limit); 14642 psFree(where) 14643 if (count < 0) { 14644 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PStackedImfile"); 14645 return count; 14646 } 14647 14648 deleted += count; 14649 } 14650 14651 return deleted; 14652 } 14653 bool p4PStackedImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf) 14654 { 14655 PS_ASSERT_PTR_NON_NULL(objects, false); 14656 14657 psMetadata *output = psMetadataAlloc(); 14658 for (long i = 0; i < psArrayLength(objects); i++) { 14659 psMetadata *md = p4PStackedImfileMetadataFromObject(objects->data[i]); 14660 if (!psMetadataAddMetadata( 14661 output, 14662 PS_LIST_TAIL, 14663 P4PSTACKEDIMFILE_TABLE_NAME, 14664 PS_META_DUPLICATE_OK, 14665 NULL, 14666 md 14667 )) { 14668 psError(PS_ERR_UNKNOWN, false, "failed to add metadata"); 14669 psFree(md); 14670 psFree(output); 14671 return false; 14672 } 14673 psFree(md); 14674 } 14675 14676 if (!ippdbPrintMetadataRaw(stream, output, mdcf)) { 14677 psError(PS_ERR_UNKNOWN, false, "failed to print metadata"); 14678 psFree(output); 14679 } 14680 psFree(output); 14681 14682 return true; 14683 } 14684 static void p4PDiffImfileRowFree(p4PDiffImfileRow *object); 14685 14686 p4PDiffImfileRow *p4PDiffImfileRowAlloc(psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri) 14687 { 14688 p4PDiffImfileRow *_object; 14689 14690 _object = psAlloc(sizeof(p4PDiffImfileRow)); 14691 psMemSetDeallocator(_object, (psFreeFunc)p4PDiffImfileRowFree); 14692 14693 _object->p4_id = p4_id; 14694 _object->exp_tag = psStringCopy(exp_tag); 14695 _object->p3_version = p3_version; 14696 _object->class_id = psStringCopy(class_id); 14697 _object->uri = psStringCopy(uri); 14698 _object->b1_uri = psStringCopy(b1_uri); 14699 _object->b2_uri = psStringCopy(b2_uri); 14700 14701 return _object; 14702 } 14703 14704 static void p4PDiffImfileRowFree(p4PDiffImfileRow *object) 14705 { 14706 psFree(object->exp_tag); 14707 psFree(object->class_id); 14708 psFree(object->uri); 14709 psFree(object->b1_uri); 14710 psFree(object->b2_uri); 14711 } 14712 14713 bool p4PDiffImfileCreateTable(psDB *dbh) 14714 { 14715 psMetadata *md = psMetadataAlloc(); 14716 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) { 14717 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 14718 psFree(md); 14719 return false; 14720 } 14721 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) { 14722 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 14723 psFree(md); 14724 return false; 14725 } 14726 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) { 14727 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 14728 psFree(md); 14729 return false; 14730 } 14731 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) { 14732 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 14733 psFree(md); 14734 return false; 14735 } 14736 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) { 14737 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 14738 psFree(md); 14739 return false; 14740 } 14741 if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, "255")) { 14742 psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri"); 14743 psFree(md); 14744 return false; 14745 } 14746 if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, "255")) { 14747 psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri"); 14748 psFree(md); 14749 return false; 14750 } 14751 14752 bool status = psDBCreateTable(dbh, P4PDIFFIMFILE_TABLE_NAME, md); 14753 14754 psFree(md); 14755 14756 return status; 14757 } 14758 14759 bool p4PDiffImfileDropTable(psDB *dbh) 14760 { 14761 return psDBDropTable(dbh, P4PDIFFIMFILE_TABLE_NAME); 14762 } 14763 14764 bool p4PDiffImfileInsert(psDB * dbh, psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri) 14765 { 14766 psMetadata *md = psMetadataAlloc(); 14767 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) { 14768 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 14769 psFree(md); 14770 return false; 14771 } 14772 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) { 14773 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 14774 psFree(md); 14775 return false; 14776 } 14777 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) { 14778 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 14779 psFree(md); 14780 return false; 14781 } 14782 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) { 14783 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 14784 psFree(md); 14785 return false; 14786 } 14787 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) { 14788 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 14789 psFree(md); 14790 return false; 14791 } 14792 if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, b1_uri)) { 14793 psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri"); 14794 psFree(md); 14795 return false; 14796 } 14797 if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, b2_uri)) { 14798 psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri"); 14799 psFree(md); 14800 return false; 14801 } 14802 14803 bool status = psDBInsertOneRow(dbh, P4PDIFFIMFILE_TABLE_NAME, md); 14804 psFree(md); 14805 14806 return status; 14807 } 14808 14809 long long p4PDiffImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit) 14810 { 14811 long long deleted = 0; 14812 14813 long long count = psDBDeleteRows(dbh, P4PDIFFIMFILE_TABLE_NAME, where, limit); 14814 if (count < 0) { 14815 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PDiffImfile"); 14816 return count; 14817 14818 deleted += count; 14819 } 14820 14821 return deleted; 14822 } 14823 bool p4PDiffImfileInsertObject(psDB *dbh, p4PDiffImfileRow *object) 14824 { 14825 return p4PDiffImfileInsert(dbh, object->p4_id, object->exp_tag, object->p3_version, object->class_id, object->uri, object->b1_uri, object->b2_uri); 14826 } 14827 14828 bool p4PDiffImfileInsertObjects(psDB *dbh, psArray *objects) 14829 { 14830 for (long i = 0; i < psArrayLength(objects); i++) { 14831 if (!p4PDiffImfileInsertObject(dbh, objects->data[i])) { 14832 return false; 14833 } 14834 } 14835 14836 return true; 14837 } 14838 14839 bool p4PDiffImfileInsertFits(psDB *dbh, const psFits *fits) 14840 { 14841 psArray *rowSet; 14842 14843 // move to (the first?) extension named P4PDIFFIMFILE_TABLE_NAME 14844 if (!psFitsMoveExtName(fits, P4PDIFFIMFILE_TABLE_NAME)) { 14845 psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4PDIFFIMFILE_TABLE_NAME); 14846 return false; 14847 } 14848 14849 // check HDU type 14850 if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE) { 14851 psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE"); 14852 return false; 14853 } 14854 14855 // read fits table 14856 rowSet = psFitsReadTable(fits); 14857 if (!rowSet) { 14858 psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty"); 14859 psFree(rowSet); 14860 return false; 14861 } 14862 14863 if (!psDBInsertRows(dbh, P4PDIFFIMFILE_TABLE_NAME, rowSet)) { 14864 psError(PS_ERR_UNKNOWN, false, "databse insert failed"); 14865 psFree(rowSet); 14866 return false; 14867 } 14868 14869 psFree(rowSet); 14870 14871 return true; 14872 } 14873 14874 bool p4PDiffImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit) 14875 { 14876 psArray *rowSet; 14877 14878 rowSet = psDBSelectRows(dbh, P4PDIFFIMFILE_TABLE_NAME, where, limit); 14879 if (!rowSet) { 14880 return false; 14881 } 14882 14883 // output to fits 14884 if (!psFitsWriteTable(fits, NULL, rowSet, P4PDIFFIMFILE_TABLE_NAME)) { 14885 psError(PS_ERR_UNKNOWN, false, "FITS table write failed"); 14886 psFree(rowSet); 14887 return false; 14888 } 14889 14890 psFree(rowSet); 14891 14892 return true; 14893 } 14894 14895 psMetadata *p4PDiffImfileMetadataFromObject(const p4PDiffImfileRow *object) 14896 { 14897 psMetadata *md = psMetadataAlloc(); 14898 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) { 14899 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 14900 psFree(md); 14901 return false; 14902 } 14903 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) { 14904 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 14905 psFree(md); 14906 return false; 14907 } 14908 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) { 14909 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 14910 psFree(md); 14911 return false; 14912 } 14913 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) { 14914 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 14915 psFree(md); 14916 return false; 14917 } 14918 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) { 14919 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 14920 psFree(md); 14921 return false; 14922 } 14923 if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, object->b1_uri)) { 14924 psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri"); 14925 psFree(md); 14926 return false; 14927 } 14928 if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, object->b2_uri)) { 14929 psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri"); 14930 psFree(md); 14931 return false; 14932 } 14933 14934 14935 return md; 14936 } 14937 14938 p4PDiffImfileRow *p4PDiffImfileObjectFromMetadata(psMetadata *md) 14939 { 14940 14941 bool status = false; 14942 psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id"); 14943 if (!status) { 14944 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id"); 14945 return false; 14946 } 14947 char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag"); 14948 if (!status) { 14949 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag"); 14950 return false; 14951 } 14952 psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version"); 14953 if (!status) { 14954 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version"); 14955 return false; 14956 } 14957 char* class_id = psMetadataLookupPtr(&status, md, "class_id"); 14958 if (!status) { 14959 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id"); 14960 return false; 14961 } 14962 char* uri = psMetadataLookupPtr(&status, md, "uri"); 14963 if (!status) { 14964 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri"); 14965 return false; 14966 } 14967 char* b1_uri = psMetadataLookupPtr(&status, md, "b1_uri"); 14968 if (!status) { 14969 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b1_uri"); 14970 return false; 14971 } 14972 char* b2_uri = psMetadataLookupPtr(&status, md, "b2_uri"); 14973 if (!status) { 14974 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b2_uri"); 14975 return false; 14976 } 14977 14978 return p4PDiffImfileRowAlloc(p4_id, exp_tag, p3_version, class_id, uri, b1_uri, b2_uri); 14979 } 14980 psArray *p4PDiffImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit) 14981 { 14982 psArray *rowSet; 14983 psArray *returnSet; 14984 psU64 i; 14985 14986 rowSet = psDBSelectRows(dbh, P4PDIFFIMFILE_TABLE_NAME, where, limit); 14987 if (!rowSet) { 14988 return NULL; 14989 } 14990 14991 // convert psMetadata rows to row objects 14992 14993 returnSet = psArrayAllocEmpty(rowSet->n); 14994 14995 for (i = 0; i < rowSet->n; i++) { 14996 p4PDiffImfileRow *object = p4PDiffImfileObjectFromMetadata(rowSet->data[i]); 14997 psArrayAdd(returnSet, 0, object); 14998 psFree(object); 14999 } 15000 15001 psFree(rowSet); 15002 15003 return returnSet; 15004 } 15005 bool p4PDiffImfileDeleteObject(psDB *dbh, const p4PDiffImfileRow *object) 15006 { 15007 psMetadata *where = p4PDiffImfileMetadataFromObject(object); 15008 long long count = psDBDeleteRows(dbh, P4PDIFFIMFILE_TABLE_NAME, where, 0); 15009 psFree(where) 15010 if (count < 0) { 15011 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PDiffImfile"); 15012 return false; 15013 } 15014 if (count > 1) { 15015 // XXX should this be a psAbort() instead? It is possible that 15016 // having an object match multiple rows was by design. 15017 psError(PS_ERR_UNKNOWN, true, "p4PDiffImfileRow object matched more then one row. Check your database schema"); 15018 return false; 15019 } 15020 15021 return true; 15022 } 15023 long long p4PDiffImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit) 15024 { 15025 long long deleted = 0; 15026 15027 for (long long i = 0; i < objects->n; i++) { 15028 p4PDiffImfileRow *object = objects->data[i]; 15029 psMetadata *where = p4PDiffImfileMetadataFromObject(object); 15030 long long count = psDBDeleteRows(dbh, P4PDIFFIMFILE_TABLE_NAME, where, limit); 15031 psFree(where) 15032 if (count < 0) { 15033 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PDiffImfile"); 15034 return count; 15035 } 15036 15037 deleted += count; 15038 } 15039 15040 return deleted; 15041 } 15042 bool p4PDiffImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf) 15043 { 15044 PS_ASSERT_PTR_NON_NULL(objects, false); 15045 15046 psMetadata *output = psMetadataAlloc(); 15047 for (long i = 0; i < psArrayLength(objects); i++) { 15048 psMetadata *md = p4PDiffImfileMetadataFromObject(objects->data[i]); 15049 if (!psMetadataAddMetadata( 15050 output, 15051 PS_LIST_TAIL, 15052 P4PDIFFIMFILE_TABLE_NAME, 15053 PS_META_DUPLICATE_OK, 15054 NULL, 15055 md 15056 )) { 15057 psError(PS_ERR_UNKNOWN, false, "failed to add metadata"); 15058 psFree(md); 15059 psFree(output); 15060 return false; 15061 } 15062 psFree(md); 15063 } 15064 15065 if (!ippdbPrintMetadataRaw(stream, output, mdcf)) { 15066 psError(PS_ERR_UNKNOWN, false, "failed to print metadata"); 15067 psFree(output); 15068 } 15069 psFree(output); 15070 15071 return true; 15072 } 15073 static void p4PMagicMaskImfileRowFree(p4PMagicMaskImfileRow *object); 15074 15075 p4PMagicMaskImfileRow *p4PMagicMaskImfileRowAlloc(psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri) 15076 { 15077 p4PMagicMaskImfileRow *_object; 15078 15079 _object = psAlloc(sizeof(p4PMagicMaskImfileRow)); 15080 psMemSetDeallocator(_object, (psFreeFunc)p4PMagicMaskImfileRowFree); 15081 15082 _object->p4_id = p4_id; 15083 _object->exp_tag = psStringCopy(exp_tag); 15084 _object->p3_version = p3_version; 15085 _object->class_id = psStringCopy(class_id); 15086 _object->uri = psStringCopy(uri); 15087 15088 return _object; 15089 } 15090 15091 static void p4PMagicMaskImfileRowFree(p4PMagicMaskImfileRow *object) 15092 { 15093 psFree(object->exp_tag); 15094 psFree(object->class_id); 15095 psFree(object->uri); 15096 } 15097 15098 bool p4PMagicMaskImfileCreateTable(psDB *dbh) 15099 { 15100 psMetadata *md = psMetadataAlloc(); 15101 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) { 15102 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 15103 psFree(md); 15104 return false; 15105 } 15106 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) { 15107 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 15108 psFree(md); 15109 return false; 15110 } 15111 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) { 15112 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 15113 psFree(md); 15114 return false; 15115 } 15116 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) { 15117 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 15118 psFree(md); 15119 return false; 15120 } 15121 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) { 15122 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 15123 psFree(md); 15124 return false; 15125 } 15126 15127 bool status = psDBCreateTable(dbh, P4PMAGICMASKIMFILE_TABLE_NAME, md); 15128 15129 psFree(md); 15130 15131 return status; 15132 } 15133 15134 bool p4PMagicMaskImfileDropTable(psDB *dbh) 15135 { 15136 return psDBDropTable(dbh, P4PMAGICMASKIMFILE_TABLE_NAME); 15137 } 15138 15139 bool p4PMagicMaskImfileInsert(psDB * dbh, psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri) 15140 { 15141 psMetadata *md = psMetadataAlloc(); 15142 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) { 15143 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 15144 psFree(md); 15145 return false; 15146 } 15147 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) { 15148 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 15149 psFree(md); 15150 return false; 15151 } 15152 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) { 15153 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 15154 psFree(md); 15155 return false; 15156 } 15157 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) { 15158 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 15159 psFree(md); 15160 return false; 15161 } 15162 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) { 15163 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 15164 psFree(md); 15165 return false; 15166 } 15167 15168 bool status = psDBInsertOneRow(dbh, P4PMAGICMASKIMFILE_TABLE_NAME, md); 15169 psFree(md); 15170 15171 return status; 15172 } 15173 15174 long long p4PMagicMaskImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit) 15175 { 15176 long long deleted = 0; 15177 15178 long long count = psDBDeleteRows(dbh, P4PMAGICMASKIMFILE_TABLE_NAME, where, limit); 15179 if (count < 0) { 15180 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PMagicMaskImfile"); 15181 return count; 15182 15183 deleted += count; 15184 } 15185 15186 return deleted; 15187 } 15188 bool p4PMagicMaskImfileInsertObject(psDB *dbh, p4PMagicMaskImfileRow *object) 15189 { 15190 return p4PMagicMaskImfileInsert(dbh, object->p4_id, object->exp_tag, object->p3_version, object->class_id, object->uri); 15191 } 15192 15193 bool p4PMagicMaskImfileInsertObjects(psDB *dbh, psArray *objects) 15194 { 15195 for (long i = 0; i < psArrayLength(objects); i++) { 15196 if (!p4PMagicMaskImfileInsertObject(dbh, objects->data[i])) { 15197 return false; 15198 } 15199 } 15200 15201 return true; 15202 } 15203 15204 bool p4PMagicMaskImfileInsertFits(psDB *dbh, const psFits *fits) 15205 { 15206 psArray *rowSet; 15207 15208 // move to (the first?) extension named P4PMAGICMASKIMFILE_TABLE_NAME 15209 if (!psFitsMoveExtName(fits, P4PMAGICMASKIMFILE_TABLE_NAME)) { 15210 psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4PMAGICMASKIMFILE_TABLE_NAME); 15211 return false; 15212 } 15213 15214 // check HDU type 15215 if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE) { 15216 psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE"); 15217 return false; 15218 } 15219 15220 // read fits table 15221 rowSet = psFitsReadTable(fits); 15222 if (!rowSet) { 15223 psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty"); 15224 psFree(rowSet); 15225 return false; 15226 } 15227 15228 if (!psDBInsertRows(dbh, P4PMAGICMASKIMFILE_TABLE_NAME, rowSet)) { 15229 psError(PS_ERR_UNKNOWN, false, "databse insert failed"); 15230 psFree(rowSet); 15231 return false; 15232 } 15233 15234 psFree(rowSet); 15235 15236 return true; 15237 } 15238 15239 bool p4PMagicMaskImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit) 15240 { 15241 psArray *rowSet; 15242 15243 rowSet = psDBSelectRows(dbh, P4PMAGICMASKIMFILE_TABLE_NAME, where, limit); 15244 if (!rowSet) { 15245 return false; 15246 } 15247 15248 // output to fits 15249 if (!psFitsWriteTable(fits, NULL, rowSet, P4PMAGICMASKIMFILE_TABLE_NAME)) { 15250 psError(PS_ERR_UNKNOWN, false, "FITS table write failed"); 15251 psFree(rowSet); 15252 return false; 15253 } 15254 15255 psFree(rowSet); 15256 15257 return true; 15258 } 15259 15260 psMetadata *p4PMagicMaskImfileMetadataFromObject(const p4PMagicMaskImfileRow *object) 15261 { 15262 psMetadata *md = psMetadataAlloc(); 15263 if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) { 15264 psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id"); 15265 psFree(md); 15266 return false; 15267 } 15268 if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) { 15269 psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag"); 15270 psFree(md); 15271 return false; 15272 } 15273 if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) { 15274 psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version"); 15275 psFree(md); 15276 return false; 15277 } 15278 if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) { 15279 psError(PS_ERR_UNKNOWN, false, "failed to add item class_id"); 15280 psFree(md); 15281 return false; 15282 } 15283 if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) { 15284 psError(PS_ERR_UNKNOWN, false, "failed to add item uri"); 15285 psFree(md); 15286 return false; 15287 } 15288 15289 15290 return md; 15291 } 15292 15293 p4PMagicMaskImfileRow *p4PMagicMaskImfileObjectFromMetadata(psMetadata *md) 15294 { 15295 15296 bool status = false; 15297 psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id"); 15298 if (!status) { 15299 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id"); 15300 return false; 15301 } 15302 char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag"); 15303 if (!status) { 15304 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag"); 15305 return false; 15306 } 15307 psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version"); 15308 if (!status) { 15309 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version"); 15310 return false; 15311 } 15312 char* class_id = psMetadataLookupPtr(&status, md, "class_id"); 15313 if (!status) { 15314 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id"); 15315 return false; 15316 } 15317 char* uri = psMetadataLookupPtr(&status, md, "uri"); 15318 if (!status) { 15319 psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri"); 15320 return false; 15321 } 15322 15323 return p4PMagicMaskImfileRowAlloc(p4_id, exp_tag, p3_version, class_id, uri); 15324 } 15325 psArray *p4PMagicMaskImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit) 15326 { 15327 psArray *rowSet; 15328 psArray *returnSet; 15329 psU64 i; 15330 15331 rowSet = psDBSelectRows(dbh, P4PMAGICMASKIMFILE_TABLE_NAME, where, limit); 15332 if (!rowSet) { 15333 return NULL; 15334 } 15335 15336 // convert psMetadata rows to row objects 15337 15338 returnSet = psArrayAllocEmpty(rowSet->n); 15339 15340 for (i = 0; i < rowSet->n; i++) { 15341 p4PMagicMaskImfileRow *object = p4PMagicMaskImfileObjectFromMetadata(rowSet->data[i]); 15342 psArrayAdd(returnSet, 0, object); 15343 psFree(object); 15344 } 15345 15346 psFree(rowSet); 15347 15348 return returnSet; 15349 } 15350 bool p4PMagicMaskImfileDeleteObject(psDB *dbh, const p4PMagicMaskImfileRow *object) 15351 { 15352 psMetadata *where = p4PMagicMaskImfileMetadataFromObject(object); 15353 long long count = psDBDeleteRows(dbh, P4PMAGICMASKIMFILE_TABLE_NAME, where, 0); 15354 psFree(where) 15355 if (count < 0) { 15356 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PMagicMaskImfile"); 15357 return false; 15358 } 15359 if (count > 1) { 15360 // XXX should this be a psAbort() instead? It is possible that 15361 // having an object match multiple rows was by design. 15362 psError(PS_ERR_UNKNOWN, true, "p4PMagicMaskImfileRow object matched more then one row. Check your database schema"); 15363 return false; 15364 } 15365 15366 return true; 15367 } 15368 long long p4PMagicMaskImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit) 15369 { 15370 long long deleted = 0; 15371 15372 for (long long i = 0; i < objects->n; i++) { 15373 p4PMagicMaskImfileRow *object = objects->data[i]; 15374 psMetadata *where = p4PMagicMaskImfileMetadataFromObject(object); 15375 long long count = psDBDeleteRows(dbh, P4PMAGICMASKIMFILE_TABLE_NAME, where, limit); 15376 psFree(where) 15377 if (count < 0) { 15378 psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4PMagicMaskImfile"); 15379 return count; 15380 } 15381 15382 deleted += count; 15383 } 15384 15385 return deleted; 15386 } 15387 bool p4PMagicMaskImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf) 15388 { 15389 PS_ASSERT_PTR_NON_NULL(objects, false); 15390 15391 psMetadata *output = psMetadataAlloc(); 15392 for (long i = 0; i < psArrayLength(objects); i++) { 15393 psMetadata *md = p4PMagicMaskImfileMetadataFromObject(objects->data[i]); 15394 if (!psMetadataAddMetadata( 15395 output, 15396 PS_LIST_TAIL, 15397 P4PMAGICMASKIMFILE_TABLE_NAME, 15398 PS_META_DUPLICATE_OK, 15399 NULL, 15400 md 15401 )) { 15402 psError(PS_ERR_UNKNOWN, false, "failed to add metadata"); 15403 psFree(md); 15404 psFree(output); 15405 return false; 15406 } 15407 psFree(md); 15408 } 15409 15410 if (!ippdbPrintMetadataRaw(stream, output, mdcf)) { 15411 psError(PS_ERR_UNKNOWN, false, "failed to print metadata"); 15412 psFree(output); 15413 } 15414 psFree(output); 15415 15416 return true; 15417 }
Note:
See TracChangeset
for help on using the changeset viewer.
