Changeset 7278 for trunk/psModules/src/concepts/pmConceptsWrite.c
- Timestamp:
- Jun 1, 2006, 2:55:23 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/concepts/pmConceptsWrite.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/concepts/pmConceptsWrite.c
r7017 r7278 1 1 #include <stdio.h> 2 #include <assert.h> 2 3 #include <strings.h> 3 4 #include "pslib.h" … … 110 111 ) 111 112 { 113 assert(spec); 114 assert(cameraFormat); 115 112 116 if (concept) { 113 117 psMetadataItem *formatted = NULL; // The formatted concept … … 129 133 ) 130 134 { 135 assert(hdu); 136 assert(keyword && strlen(keyword) > 0); 137 assert(item); 138 131 139 if (!hdu->header) { 132 140 return false; … … 166 174 ) 167 175 { 176 assert(hdu); 177 assert(keywords); 178 assert(item); 179 168 180 bool status = true; // Status of writing headers, to be returned 169 181 if (item->type == PS_DATA_LIST) { … … 204 216 ) 205 217 { 206 if (cell) { 207 pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level 208 if (!hdu) { 209 return false; 210 } 211 psMetadata *cameraFormat = hdu->format; // The camera format 212 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 213 psMetadataItem *specItem = NULL; // Item from the specs metadata 214 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 215 pmConceptSpec *spec = specItem->data.V; // The specification 216 psString name = specItem->name; // The concept name 217 psMetadataItem *cameraItem = psMetadataLookup(cell->config, name); // The concept from the camera, 218 // or NULL 219 if (cameraItem) { 220 // Grab the concept 221 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The concept 222 // Formatted version 223 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, NULL, NULL, cell); 224 if (!formatted) { 225 continue; 226 } 227 psString nameSource = NULL; // String with the concept name and ".SOURCE" added 228 psStringAppend(&nameSource, "%s.SOURCE", name); 229 bool mdok = true; // Status of MD lookup 230 psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source 231 if (mdok && strlen(source) > 0) { 232 psTrace(__func__, 8, "%s is %s\n", nameSource, source); 233 if (strcasecmp(source, "HEADER") == 0) { 234 if (cameraItem->type != PS_DATA_STRING) { 235 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by header, but is not " 236 "of type STR --- ignored.\n", conceptItem->name); 237 continue; 238 } 239 psTrace(__func__, 8, "Writing %s to header %s\n", name, cameraItem->data.V); 240 writeHeader(hdu, cameraItem->data.V, formatted); 241 } else if (strcasecmp(source, "VALUE") == 0) { 242 psTrace(__func__, 8, "Checking %s against camera format.\n", name); 243 if (! compareConcepts(formatted, cameraItem)) { 244 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera " 245 "format, but the values don't match.\n", name); 246 } 247 } else { 248 psLogMsg(__func__, PS_LOG_WARN, "Concept source %s isn't HEADER or VALUE --- can't " 249 "write\n", nameSource); 218 PS_ASSERT_PTR_NON_NULL(specs, false); 219 PS_ASSERT_PTR_NON_NULL(concepts, false); 220 if (!cell) { 221 return false; 222 } 223 224 pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level 225 if (!hdu) { 226 return false; 227 } 228 psMetadata *cameraFormat = hdu->format; // The camera format 229 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 230 psMetadataItem *specItem = NULL; // Item from the specs metadata 231 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 232 pmConceptSpec *spec = specItem->data.V; // The specification 233 psString name = specItem->name; // The concept name 234 psMetadataItem *cameraItem = psMetadataLookup(cell->config, name); // The concept from the camera, 235 // or NULL 236 if (cameraItem) { 237 // Grab the concept 238 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The concept 239 // Formatted version 240 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, NULL, NULL, cell); 241 if (!formatted) { 242 continue; 243 } 244 psString nameSource = NULL; // String with the concept name and ".SOURCE" added 245 psStringAppend(&nameSource, "%s.SOURCE", name); 246 bool mdok = true; // Status of MD lookup 247 psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source 248 if (mdok && strlen(source) > 0) { 249 psTrace(__func__, 8, "%s is %s\n", nameSource, source); 250 if (strcasecmp(source, "HEADER") == 0) { 251 if (cameraItem->type != PS_DATA_STRING) { 252 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by header, but is not " 253 "of type STR --- ignored.\n", conceptItem->name); 254 continue; 250 255 } 251 } else if (! compareConcepts(formatted, cameraItem)) { 252 // Assume it's specified by value 253 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera " 254 "format, but the values don't match.\n", name); 255 } 256 psFree(formatted); 257 psFree(nameSource); 258 } 259 260 } 261 psFree(specsIter); 262 return true; 263 } 264 return false; 256 psTrace(__func__, 8, "Writing %s to header %s\n", name, cameraItem->data.V); 257 writeHeader(hdu, cameraItem->data.V, formatted); 258 } else if (strcasecmp(source, "VALUE") == 0) { 259 psTrace(__func__, 8, "Checking %s against camera format.\n", name); 260 if (! compareConcepts(formatted, cameraItem)) { 261 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera " 262 "format, but the values don't match.\n", name); 263 } 264 } else { 265 psLogMsg(__func__, PS_LOG_WARN, "Concept source %s isn't HEADER or VALUE --- can't " 266 "write\n", nameSource); 267 } 268 } else if (! compareConcepts(formatted, cameraItem)) { 269 // Assume it's specified by value 270 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera " 271 "format, but the values don't match.\n", name); 272 } 273 psFree(formatted); 274 psFree(nameSource); 275 } 276 277 } 278 psFree(specsIter); 279 return true; 265 280 } 266 281 … … 272 287 ) 273 288 { 289 PS_ASSERT_PTR_NON_NULL(specs, false); 290 PS_ASSERT_PTR_NON_NULL(concepts, false); 291 274 292 pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level 275 293 if (!hdu) { … … 279 297 bool mdok = true; // Status of MD lookup 280 298 psMetadata *defaults = psMetadataLookupMD(&mdok, cameraFormat, "DEFAULTS"); // The DEFAULTS spec 281 if (mdok && defaults) { 282 pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level 283 psMetadata *cameraFormat = hdu->format; // The camera format 284 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 285 psMetadataItem *specItem = NULL; // Item from the specs metadata 286 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 287 pmConceptSpec *spec = specItem->data.V; // The specification 288 psString name = specItem->name; // The concept name 289 psMetadataItem *defaultItem = psMetadataLookup(defaults, name); // The item from the DEFAULTS 290 if (defaultItem) { 291 psMetadataItem *conceptItem = NULL; // The item from the concepts 292 if (defaultItem->type == PS_DATA_METADATA) { 293 // It's a menu --- need to look up the .DEPEND 294 psString dependName = NULL; // The concept name with ".DEPEND" on the end 295 psStringAppend(&dependName, ".DEPEND"); 296 psString dependKey = psMetadataLookupStr(&mdok, defaults, dependName); // The keyword 297 psFree(dependName); 298 if (!mdok || !dependKey || strlen(dependKey) == 0) { 299 psLogMsg(__func__, PS_LOG_WARN, "Can't find %s in the DEFAULTS for %s --- ignored.\n", 300 dependName, name); 301 continue; 302 } 303 psString dependValue = psMetadataLookupStr(&mdok, concepts, dependName); // The value 304 if (!mdok || !dependKey || strlen(dependKey) == 0) { 305 psLogMsg(__func__, PS_LOG_WARN, "Concept %s specified by %s isn't of type STR -- " 306 "ignored.\n", name, dependName); 307 continue; 308 } 309 conceptItem = psMetadataLookup(defaultItem->data.V, dependValue); 310 } else { 311 conceptItem = psMetadataLookup(concepts, name); // The item from the concepts 312 } 313 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell); 314 if (!formatted) { 299 if (!mdok || !defaults) { 300 return false; 301 } 302 303 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 304 psMetadataItem *specItem = NULL; // Item from the specs metadata 305 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 306 pmConceptSpec *spec = specItem->data.V; // The specification 307 psString name = specItem->name; // The concept name 308 psMetadataItem *defaultItem = psMetadataLookup(defaults, name); // The item from the DEFAULTS 309 if (defaultItem) { 310 psMetadataItem *conceptItem = NULL; // The item from the concepts 311 if (defaultItem->type == PS_DATA_METADATA) { 312 // It's a menu --- need to look up the .DEPEND 313 psString dependName = NULL; // The concept name with ".DEPEND" on the end 314 psStringAppend(&dependName, ".DEPEND"); 315 psString dependKey = psMetadataLookupStr(&mdok, defaults, dependName); // The keyword 316 psFree(dependName); 317 if (!mdok || !dependKey || strlen(dependKey) == 0) { 318 psLogMsg(__func__, PS_LOG_WARN, "Can't find %s in the DEFAULTS for %s --- ignored.\n", 319 dependName, name); 315 320 continue; 316 321 } 317 if (! compareConcepts(formatted, defaultItem)) { 318 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by the DEFAULTS in the camera " 319 "format, but the values don't match.\n", name); 320 } 321 psFree(formatted); 322 } 323 } 324 psFree(specsIter); 325 return true; 326 } 327 return false; 322 psString dependValue = psMetadataLookupStr(&mdok, concepts, dependName); // The value 323 if (!mdok || !dependKey || strlen(dependKey) == 0) { 324 psLogMsg(__func__, PS_LOG_WARN, "Concept %s specified by %s isn't of type STR -- " 325 "ignored.\n", name, dependName); 326 continue; 327 } 328 conceptItem = psMetadataLookup(defaultItem->data.V, dependValue); 329 } else { 330 conceptItem = psMetadataLookup(concepts, name); // The item from the concepts 331 } 332 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell); 333 if (!formatted) { 334 continue; 335 } 336 if (! compareConcepts(formatted, defaultItem)) { 337 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by the DEFAULTS in the camera " 338 "format, but the values don't match.\n", name); 339 } 340 psFree(formatted); 341 } 342 } 343 psFree(specsIter); 344 return true; 328 345 } 329 346 … … 336 353 ) 337 354 { 355 PS_ASSERT_PTR_NON_NULL(specs, false); 356 PS_ASSERT_PTR_NON_NULL(concepts, false); 357 338 358 pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level 339 359 if (!hdu) { … … 343 363 bool mdok = true; // Status of MD lookup 344 364 psMetadata *translation = psMetadataLookupMD(&mdok, cameraFormat, "TRANSLATION"); // The TRANSLATION spec 345 if (mdok && translation) { 346 pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level 347 psMetadata *cameraFormat = hdu->format; // The camera format 348 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 349 psMetadataItem *specItem = NULL; // Item from the specs metadata 350 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 351 pmConceptSpec *spec = specItem->data.V; // The specification 352 psString name = specItem->name; // The concept name 353 psMetadataItem *headerItem = psMetadataLookup(translation, name); // The item from the TRANSLATION 354 if (headerItem) { 355 if (headerItem->type != PS_DATA_STRING) { 356 psLogMsg(__func__, PS_LOG_WARN, "TRANSLATION keyword for concept %s isn't of type STR ---" 357 " ignored.", name); 358 continue; 359 } 360 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts 361 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell); 362 if (!formatted) { 363 continue; 364 } 365 psList *keywords = psStringSplit(headerItem->data.V, " ,;", true); // List of header keywords 366 if (formatted->type == PS_DATA_LIST) { 367 psList *values = formatted->data.V; // The values for the headers 368 if (values->n != keywords->n) { 369 psLogMsg(__func__, PS_LOG_WARN, "Number of headers specified does not match number " 370 "of values for concept %s.\n", name); 365 if (!mdok || !translation) { 366 return false; 367 } 368 369 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 370 psMetadataItem *specItem = NULL; // Item from the specs metadata 371 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 372 pmConceptSpec *spec = specItem->data.V; // The specification 373 psString name = specItem->name; // The concept name 374 psMetadataItem *headerItem = psMetadataLookup(translation, name); // The item from the TRANSLATION 375 if (headerItem) { 376 if (headerItem->type != PS_DATA_STRING) { 377 psLogMsg(__func__, PS_LOG_WARN, "TRANSLATION keyword for concept %s isn't of type STR ---" 378 " ignored.", name); 379 continue; 380 } 381 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts 382 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell); 383 if (!formatted) { 384 continue; 385 } 386 psList *keywords = psStringSplit(headerItem->data.V, " ,;", true); // List of header keywords 387 if (formatted->type == PS_DATA_LIST) { 388 psList *values = formatted->data.V; // The values for the headers 389 if (values->n != keywords->n) { 390 psLogMsg(__func__, PS_LOG_WARN, "Number of headers specified does not match number " 391 "of values for concept %s.\n", name); 392 } 393 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator 394 psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false); 395 psMetadataItem *valuesItem = NULL; // Item from list 396 while ((valuesItem = psListGetAndIncrement(valuesIter))) { 397 psString keyword = psListGetAndIncrement(keywordsIter); // Keyword from the list 398 if (strlen(keyword) > 0) { 399 writeHeader(hdu, keyword, formatted); 371 400 } 372 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator 373 psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false); 374 psMetadataItem *valuesItem = NULL; // Item from list 375 while ((valuesItem = psListGetAndIncrement(valuesIter))) { 376 psString keyword = psListGetAndIncrement(keywordsIter); // Keyword from the list 377 if (strlen(keyword) > 0) { 378 writeHeader(hdu, keyword, formatted); 379 } 380 } 381 psFree(valuesIter); 382 psFree(keywordsIter); 383 } else { 384 psString keyword = psListGet(keywords, PS_LIST_HEAD); // The keyword 385 writeHeader(hdu, keyword, formatted); 386 } 387 psFree(formatted); 388 psFree(keywords); 389 } 390 } 391 psFree(specsIter); 392 return true; 393 } 394 return false; 401 } 402 psFree(valuesIter); 403 psFree(keywordsIter); 404 } else { 405 psString keyword = psListGet(keywords, PS_LIST_HEAD); // The keyword 406 writeHeader(hdu, keyword, formatted); 407 } 408 psFree(formatted); 409 psFree(keywords); 410 } 411 } 412 psFree(specsIter); 413 return true; 395 414 } 396 415 … … 404 423 ) 405 424 { 425 PS_ASSERT_PTR_NON_NULL(specs, false); 426 PS_ASSERT_PTR_NON_NULL(concepts, false); 427 428 if (!db) { 429 return false; 430 } 431 406 432 #ifdef OMIT_PSDB 407 433 return false; … … 415 441 bool mdok = true; // Status of MD lookup 416 442 psMetadata *database = psMetadataLookupMD(&mdok, cameraFormat, "DATABASE"); // The DATABASE spec 417 if (mdok && database) { 418 pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level 419 psMetadata *cameraFormat = hdu->format; // The camera format 420 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 421 psMetadataItem *specItem = NULL; // Item from the specs metadata 422 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 423 pmConceptSpec *spec = specItem->data.V; // The specification 424 psString name = specItem->name; // The concept name 425 426 psMetadataItem *dbItem = psMetadataLookup(database, name); // The item from the DATABASE 427 if (dbItem) { 428 if (dbItem->type != PS_DATA_METADATA) { 429 psLogMsg(__func__, PS_LOG_WARN, "DATABASE keyword for concept %s isn't of type METADATA " 430 "--- ignored.\n", name); 431 continue; 432 } 433 434 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts 435 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell); 436 if (!formatted) { 437 continue; 438 } 439 440 psMetadata *dbLookup = dbItem->data.V; // How to look up the value of interest 441 // Name of the table 442 const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE"); 443 // Name of "where" columns 444 const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL"); 445 // Values for "where" columns 446 const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS"); 447 448 // Now, need to get the "given"s 449 if (strlen(givenCols) || strlen(givenPS)) { 450 psList *cols = psStringSplit(givenCols, ",;", true); // List of column names 451 psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns 452 psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB 453 if (cols->n != values->n) { 454 psLogMsg(__func__, PS_LOG_WARN, 455 "The GIVENDBCOL and GIVENPS entries for %s do not have " 456 "the same number of entries --- ignored.\n", name); 443 if (!mdok || !database) { 444 return false; 445 } 446 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 447 psMetadataItem *specItem = NULL; // Item from the specs metadata 448 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 449 pmConceptSpec *spec = specItem->data.V; // The specification 450 psString name = specItem->name; // The concept name 451 452 psMetadataItem *dbItem = psMetadataLookup(database, name); // The item from the DATABASE 453 if (dbItem) { 454 if (dbItem->type != PS_DATA_METADATA) { 455 psLogMsg(__func__, PS_LOG_WARN, "DATABASE keyword for concept %s isn't of type METADATA " 456 "--- ignored.\n", name); 457 continue; 458 } 459 460 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts 461 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell); 462 if (!formatted) { 463 continue; 464 } 465 466 psMetadata *dbLookup = dbItem->data.V; // How to look up the value of interest 467 // Name of the table 468 const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE"); 469 // Name of "where" columns 470 const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL"); 471 // Values for "where" columns 472 const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS"); 473 474 // Now, need to get the "given"s 475 if (strlen(givenCols) || strlen(givenPS)) { 476 psList *cols = psStringSplit(givenCols, ",;", true); // List of column names 477 psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns 478 psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB 479 if (cols->n != values->n) { 480 psLogMsg(__func__, PS_LOG_WARN, 481 "The GIVENDBCOL and GIVENPS entries for %s do not have " 482 "the same number of entries --- ignored.\n", name); 483 } else { 484 // Iterators for the lists 485 psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false); 486 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); 487 char *column = NULL; // Name of the column 488 while ((column = psListGetAndIncrement(colsIter))) { 489 char *dependName = psListGetAndIncrement(valuesIter); // Name for the value 490 if (!strlen(column) || !strlen(name)) { 491 psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is " 492 " empty --- ignored.\n", name); 493 } else { 494 // Search for the value name 495 psMetadataItem *item = NULL; // The value 496 if (!item && cell) { 497 item = psMetadataLookup(cell->concepts, dependName); 498 } 499 if (!item && chip) { 500 item = psMetadataLookup(chip->concepts, dependName); 501 } 502 if (!item && fpa) { 503 item = psMetadataLookup(fpa->concepts, dependName); 504 } 505 if (! item) { 506 psLogMsg(__func__, PS_LOG_ERROR, 507 "Unable to find the value name %s for DB " 508 " lookup on %s --- ignored.\n", dependName, name); 509 } else { 510 // We need to create a new psMetadataItem. I don't think we can't simply 511 // hack the existing one, since that could conceivably cause memory leaks 512 psMetadataAddItem(selection, formatted, PS_LIST_TAIL, PS_META_REPLACE); 513 psFree(formatted); 514 } 515 } 516 psFree(dependName); 517 psFree(column); 518 } // Iterating through the columns 519 psFree(colsIter); 520 psFree(valuesIter); 521 522 // Check first to make sure we're only going to touch one row 523 psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result 524 // Note that we use limit=2 in order to test if there are multiple rows returned 525 if (! dbResult || dbResult->n == 0) { 526 psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- " 527 "ignored\n", name); 528 return false; 457 529 } else { 458 // Iterators for the lists 459 psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false); 460 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); 461 char *column = NULL; // Name of the column 462 while ((column = psListGetAndIncrement(colsIter))) { 463 char *dependName = psListGetAndIncrement(valuesIter); // Name for the value 464 if (!strlen(column) || !strlen(name)) { 465 psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is " 466 " empty --- ignored.\n", name); 467 } else { 468 // Search for the value name 469 psMetadataItem *item = NULL; // The value 470 if (!item && cell) { 471 item = psMetadataLookup(cell->concepts, dependName); 472 } 473 if (!item && chip) { 474 item = psMetadataLookup(chip->concepts, dependName); 475 } 476 if (!item && fpa) { 477 item = psMetadataLookup(fpa->concepts, dependName); 478 } 479 if (! item) { 480 psLogMsg(__func__, PS_LOG_ERROR, 481 "Unable to find the value name %s for DB " 482 " lookup on %s --- ignored.\n", dependName, name); 483 } else { 484 // We need to create a new psMetadataItem. I don't think we can't simply 485 // hack the existing one, since that could conceivably cause memory leaks 486 psMetadataAddItem(selection, formatted, PS_LIST_TAIL, PS_META_REPLACE); 487 psFree(formatted); 488 } 489 } 490 psFree(dependName); 491 psFree(column); 492 } // Iterating through the columns 493 psFree(colsIter); 494 psFree(valuesIter); 495 496 // Check first to make sure we're only going to touch one row 497 psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result 498 // Note that we use limit=2 in order to test if there are multiple rows returned 499 if (! dbResult || dbResult->n == 0) { 500 psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- " 501 "ignored\n", name); 502 return false; 503 } else { 504 if (dbResult->n > 1) { 505 psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s " 506 "--- ignored.\n", name); 507 } 508 // Update the DB 509 psMetadata *update = psMetadataAlloc(); 510 psMetadataAddItem(update, conceptItem, PS_LIST_HEAD, 0); 511 psDBUpdateRows(db, tableName, selection, update); 512 psFree(update); 513 return true; 530 if (dbResult->n > 1) { 531 psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s " 532 "--- ignored.\n", name); 514 533 } 534 // Update the DB 535 psMetadata *update = psMetadataAlloc(); 536 psMetadataAddItem(update, conceptItem, PS_LIST_HEAD, 0); 537 psDBUpdateRows(db, tableName, selection, update); 538 psFree(update); 539 return true; 515 540 } 516 psFree(cols); 517 psFree(values); 518 } // Doing the "given"s. 519 } 520 } 521 psFree(specsIter); 522 return true; 523 } 524 return false; 541 } 542 psFree(cols); 543 psFree(values); 544 } // Doing the "given"s. 545 } 546 } 547 psFree(specsIter); 548 return true; 525 549 #endif 526 550 } 527 551 528 529 530 531 #if 0532 533 // Well, not really "write", but check to make sure it's there and matches534 bool pmConceptWriteToCamera(pmCell *cell, // The cell535 psMetadataItem *concept // Concept536 )537 {538 if (! cell->config) {539 return false;540 }541 if (cell) {542 psMetadataItem *item = psMetadataLookup(cell->config, concept->name); // Info we want543 return compareConcepts(item, concept);544 }545 546 return false;547 }548 549 // Write the concept to the header in the appropriate location550 bool pmConceptWriteToHeader(pmFPA *fpa, // The FPA that contains the chip551 pmChip *chip, // The chip that contains the cell552 pmCell *cell, // The cell553 psMetadataItem *concept // Concept554 )555 {556 bool mdok = true; // Status of MD lookup557 bool status = false; // Status of setting header558 if (! fpa->camera) {559 return false;560 }561 psMetadata *translation = psMetadataLookupMD(&mdok, fpa->camera, "TRANSLATION"); // FITS translation562 if (! mdok) {563 psError(PS_ERR_IO, false, "Unable to find TRANSLATION in camera configuration.\n");564 return false;565 }566 567 // Look for how to translate the concept into a FITS header name568 const char *keyword = psMetadataLookupStr(&mdok, translation, concept->name);569 if (mdok && strlen(keyword) > 0) {570 psTrace(__func__, 6, "It's in keyword %s\n", keyword);571 psMetadataItem *headerItem = NULL; // Item to add to header572 // XXX: Need to expand range of types573 switch (concept->type) {574 case PS_DATA_STRING:575 headerItem = psMetadataItemAllocStr(keyword, concept->comment, concept->data.V);576 break;577 case PS_DATA_S32:578 headerItem = psMetadataItemAllocS32(keyword, concept->comment, concept->data.S32);579 break;580 case PS_DATA_F32:581 headerItem = psMetadataItemAllocF32(keyword, concept->comment, concept->data.F32);582 break;583 case PS_DATA_F64:584 headerItem = psMetadataItemAllocF64(keyword, concept->comment, concept->data.F64);585 break;586 default:587 headerItem = psMetadataItemAlloc(keyword, concept->type, concept->comment,588 concept->data.V); // Item for the header589 }590 591 // We have a FITS header to look up --- search each level592 if (cell && cell->hdu) {593 psTrace(__func__, 7, "Adding to the cell level header...\n");594 psMetadataAddItem(cell->hdu->header, headerItem, PS_LIST_TAIL, PS_META_REPLACE);595 status = true;596 } else if (chip && chip->hdu) {597 psTrace(__func__, 7, "Adding to the chip level header...\n");598 psMetadataAddItem(chip->hdu->header, headerItem, PS_LIST_TAIL, PS_META_REPLACE);599 status = true;600 } else if (fpa->hdu) {601 psTrace(__func__, 7, "Adding to the FPA level header...\n");602 psMetadataAddItem(fpa->hdu->header, headerItem, PS_LIST_TAIL, PS_META_REPLACE);603 status = true;604 }605 psFree(headerItem);606 }607 608 // No header value609 return status;610 }611 612 613 // Well, not really "write", but check to see if it's there, and matches614 bool pmConceptWriteToDefault(pmFPA *fpa, // The FPA that contains the chip615 pmChip *chip, // The chip that contains the cell616 pmCell *cell, // The cell617 psMetadataItem *concept // Concept618 )619 {620 bool mdOK = true; // Status of MD lookup621 if (! fpa->camera) {622 return false;623 }624 psMetadata *defaults = psMetadataLookupMD(&mdOK, fpa->camera, "DEFAULTS");625 if (! mdOK || ! defaults) {626 psError(PS_ERR_IO, false, "Unable to find DEFAULTS in camera configuration.\n");627 return false;628 }629 630 psMetadataItem *defItem = psMetadataLookup(defaults, concept->name);631 bool status = false; // Result of checking the database632 if (defItem) {633 if (defItem->type == PS_DATA_METADATA) {634 // A dependent default635 psTrace(__func__, 7, "Evaluating dependent default....\n");636 psMetadata *dependents = defItem->data.V; // The list of dependents637 // Find out what it depends on638 psString dependName = psStringCopy(concept->name);639 psStringAppend(&dependName, ".DEPEND");640 psString dependsOn = psMetadataLookupStr(&mdOK, defaults, dependName);641 if (! mdOK) {642 psError(PS_ERR_IO, false, "Unable to find %s in camera configuration for dependent default"643 " --- ignored\n", dependName);644 // XXX: Need to clean up before returning645 return false;646 }647 psFree(dependName);648 // Find the value of the dependent concept649 psMetadataItem *depItem = pmConceptReadFromHeader(fpa, chip, cell, dependsOn);650 if (! depItem) {651 psError(PS_ERR_IO, true, "Unable to find value for %s (required for %s)\n", dependsOn,652 concept->name);653 return false;654 }655 if (depItem->type != PS_DATA_STRING) {656 psError(PS_ERR_IO, true, "Value of %s is not of type string, as required for dependency"657 " --- ignored.\n", dependsOn);658 }659 660 defItem = psMetadataLookup(dependents, depItem->data.V); // This is now what we were after661 }662 663 status = compareConcepts(defItem, concept);664 if (! status) {665 psError(PS_ERR_IO, true, "Concept %s is specified by default in the camera configuration, "666 "but doesn't match the actual value.\n", concept->name);667 }668 }669 670 // XXX: Need to clean up before returning671 return status;672 }673 674 675 // XXX: Not tested at all676 // XXX I WOULD NOT TRUST THIS FUNCTION IN THE SLIGHTEST YET! --- PAP677 bool pmConceptWriteToDB(pmFPA *fpa, // The FPA that contains the chip678 pmChip *chip, // The chip that contains the cell679 pmCell *cell, // The cell680 psDB *db, // DB handle681 psMetadataItem *concept // Concept682 )683 {684 if (! db) {685 // No database initialised686 return false;687 }688 689 bool mdStatus = true; // Status of MD lookup690 if (! fpa->camera) {691 return false;692 }693 psMetadata *database = psMetadataLookupMD(&mdStatus, fpa->camera, "DATABASE");694 if (! mdStatus) {695 // No error, because not everyone needs to use the DB696 return NULL;697 }698 699 psMetadata *dbLookup = psMetadataLookupMD(&mdStatus, database, concept->name);700 if (dbLookup) {701 const char *tableName = psMetadataLookupStr(&mdStatus, dbLookup, "TABLE"); // Name of the table702 // const char *colName = psMetadataLookupStr(&mdStatus, dbLookup, "COLUMN"); // Name of the column703 const char *givenCols = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENDBCOL"); // Name of "where"704 // columns705 const char *givenPS = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENPS"); // Values for "where"706 // columns707 708 // Now, need to get the "given"s709 if (strlen(givenCols) || strlen(givenPS)) {710 psList *cols = psStringSplit(givenCols, ",;", true); // List of column names711 psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns712 psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB713 if (cols->n != values->n) {714 psLogMsg(__func__, PS_LOG_WARN, "The GIVENDBCOL and GIVENPS entries for %s do not have "715 "the same number of entries --- ignored.\n", concept);716 } else {717 // Iterators for the lists718 psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);719 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);720 char *column = NULL; // Name of the column721 while ((column = psListGetAndIncrement(colsIter))) {722 char *name = psListGetAndIncrement(valuesIter); // Name for the value723 if (!strlen(column) || !strlen(name)) {724 psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "725 " empty --- ignored.\n", concept);726 } else {727 // Search for the value name728 psMetadataItem *item = pmConceptReadFromHeader(fpa, chip, cell, name);729 if (! item) {730 item = pmConceptReadFromDefault(fpa, chip, cell, name);731 }732 if (! item) {733 psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB "734 " lookup on %s --- ignored.\n", name, concept);735 } else {736 // We need to create a new psMetadataItem. I don't think we can't simply hack737 // the existing one, since that could conceivably cause memory leaks738 psMetadataItem *newItem = psMetadataItemAlloc(concept->name, item->type,739 item->comment, item->data.V);740 psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);741 psFree(newItem);742 }743 }744 psFree(name);745 psFree(column);746 } // Iterating through the columns747 psFree(colsIter);748 psFree(valuesIter);749 750 // Check first to make sure we're only going to touch one row751 psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result752 // Note that we use limit=2 in order to test if there are multiple rows returned753 if (! dbResult || dbResult->n == 0) {754 psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- ignored\n",755 concept->name);756 return false;757 } else {758 if (dbResult->n > 1) {759 psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s --- "760 " ignored.\n", concept->name);761 }762 // Update the DB763 psMetadata *update = psMetadataAlloc();764 psMetadataAddItem(update, concept, PS_LIST_HEAD, 0);765 psDBUpdateRows(db, tableName, selection, update);766 psFree(update);767 return true;768 }769 }770 psFree(cols);771 psFree(values);772 }773 } // Doing the "given"s.774 775 psAbort(__func__, "Shouldn't ever get here?\n");776 return false;777 }778 779 780 // Concept write from item781 bool pmConceptWriteItem(pmFPA *fpa, // The FPA782 pmChip *chip, // The chip783 pmCell *cell, // The cell784 psDB *db, // DB handle785 psMetadataItem *concept // Concept item786 )787 {788 if (! fpa->camera) {789 return false;790 }791 792 // Try headers, database, defaults in order793 psTrace(__func__, 3, "Trying to set concept %s...\n", concept->name);794 bool status = pmConceptWriteToCamera(cell, concept); // Status for return795 if (! status) {796 psTrace(__func__, 5, "Trying header....\n");797 status = pmConceptWriteToHeader(fpa, chip, cell, concept);798 }799 if (! status) {800 psTrace(__func__, 5, "Trying database....\n");801 status = pmConceptWriteToDB(fpa, chip, cell, db, concept);802 }803 if (! status) {804 psTrace(__func__, 5, "Checking defaults....\n");805 status = pmConceptWriteToDefault(fpa, chip, cell, concept);806 }807 808 if (! status) {809 psError(PS_ERR_IO, true, "Unable to set %s (%s).\n", concept->name, concept->comment);810 }811 812 return status;813 }814 815 816 // Concept write817 bool pmConceptWrite(pmFPA *fpa, // The FPA818 pmChip *chip,// The chip819 pmCell *cell, // The cell820 psDB *db, // DB handle821 psMetadata *concepts, // Concepts MD from which to set822 const char *name // Name of the concept823 )824 {825 psMetadataItem *concept = psMetadataLookup(concepts, name);826 if (! concept) {827 psError(PS_ERR_IO, true, "No such concept as %s\n", name);828 return false;829 }830 return pmConceptWriteItem(fpa, chip, cell, db, concept);831 }832 833 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
