Changeset 7294
- Timestamp:
- Jun 2, 2006, 9:21:49 AM (20 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/db/psDB.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/db/psDB.c
r7143 r7294 12 12 * @author Joshua Hoblitt 13 13 * 14 * @version $Revision: 1.5 2$ $Name: not supported by cvs2svn $15 * @date $Date: 2006-0 5-18 20:08:33$14 * @version $Revision: 1.53 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2006-06-02 19:21:49 $ 16 16 * 17 17 * Copyright 2005 Joshua Hoblitt, University of Hawaii … … 64 64 static char *psDBGenerateSetSQL(const psMetadata *set 65 65 ); 66 static char *psDBGenerateConditionalSQL(const psMetadataItem *item); 66 67 // lookup table functions 67 68 static psElemType psDBMySQLToPType(enum enum_field_types type, unsigned int flags); … … 1350 1351 { 1351 1352 char *query = NULL; 1352 psListIterator *cursor;1353 psMetadataItem *item;1354 1353 1355 1354 if (!where) { … … 1360 1359 query = psStringCopy("WHERE "); 1361 1360 1362 cursor = psListIteratorAlloc(where->list, 0, false); 1361 // we need to know if an item is 'MULTI' so we have to march through the 1362 // list by key name and not by items 1363 psList *keys = psHashKeyList(where->hash); 1364 psListIterator *cursor = psListIteratorAlloc(keys, 0, false); 1363 1365 1364 1366 // find column name and match pattern 1365 while ((item = psListGetAndIncrement(cursor))) { 1366 // item->data must be a string 1367 if ((item->type == PS_DATA_S32) || (item->type == PS_TYPE_S32)) { 1368 psStringAppend(&query, "%s=%d", item->name, (int)(item->data.S32)); 1369 } else if ((item->type == PS_DATA_F32) || (item->type == PS_TYPE_F32)) { 1370 psStringAppend(&query, "%s=%g", item->name, (double)(item->data.F32)); 1371 } else if ((item->type == PS_DATA_F64) || (item->type == PS_TYPE_F64)) { 1372 psStringAppend(&query, "%s=%g", item->name, (double)(item->data.F64)); 1373 } else if ((item->type == PS_DATA_BOOL) || (item->type == PS_TYPE_BOOL)) { 1374 psStringAppend(&query, "%s=%d", item->name, (int)(item->data.B)); 1375 } else if (item->type == PS_DATA_STRING) { 1376 // + column name + _ + like + _ + ' + value + ' 1377 // check for NULL and empty ("") strings 1378 if (item->data.V == NULL || *(char *)item->data.V == '\0') { 1379 psStringAppend(&query, "%s IS NULL", item->name); 1380 } else { 1381 // XXX ASC NOTE: we should have a better match for 1382 // char & varchar columns than this. LIKE is OK for 1383 // very large TEXT columns that really shouldn't be 1384 // used in a where clause... 1385 psStringAppend(&query, "%s LIKE '%s'", item->name, item->data.V); 1367 psString itemName = NULL; 1368 while ((itemName = psListGetAndIncrement(cursor))) { 1369 psMetadataItem *item = psMetadataLookup(where, itemName); 1370 1371 if (item->type == PS_DATA_METADATA_MULTI) { 1372 char *logicalOp = "AND"; 1373 1374 // scan through the list and change the logicalOp joining 1375 // conditionals together to "OR" if a comment of "==" is found 1376 psListIterator *mCursor = psListIteratorAlloc(item->data.list, 0, 1377 false); 1378 psMetadataItem *mItem = NULL; 1379 while ((mItem = psListGetAndIncrement(mCursor))) { 1380 if (mItem->comment && strstr(mItem->comment, "==")) { 1381 logicalOp = "OR"; 1382 break; 1383 } 1386 1384 } 1385 1386 // "(" + conditional [ + " AND/OR " + conditional ] + ")" 1387 // reset the iterator 1388 psListIteratorSet(mCursor, 0); 1389 psStringAppend(&query, "("); 1390 while ((mItem = psListGetAndIncrement(mCursor))) { 1391 char *conditional = psDBGenerateConditionalSQL(mItem); 1392 if (!conditional) { 1393 psError(PS_ERR_UNKNOWN, false, 1394 "SQL conditional generation failed."); 1395 psFree(mCursor); 1396 psFree(cursor); 1397 psFree(keys); 1398 psFree(query); 1399 return NULL; 1400 } 1401 1402 psStringAppend(&query, "%s", conditional); 1403 psFree(conditional); 1404 1405 // + " AND/OR " 1406 if (!mCursor->offEnd) { 1407 psStringAppend(&query, " %s ", logicalOp); 1408 } 1409 1410 } 1411 psFree(mCursor); 1412 1413 psStringAppend(&query, ")"); 1387 1414 } else { 1388 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1389 "Only types PS_DATA_S32, PS_DATA_F32, PS_DATA_F64, PS_DATA_BOOL, PS_DATA_STRING are supported"); 1390 1391 psFree(cursor); 1392 psFree(query); 1393 1394 return NULL; 1395 } 1396 1397 // + " and " after every column declaration except the last one 1398 if (!cursor->offEnd) { 1399 psStringAppend(&query, " AND "); 1400 } 1401 } 1402 1403 psFree(cursor); 1415 char *conditional = psDBGenerateConditionalSQL(item); 1416 if (!conditional) { 1417 psError(PS_ERR_UNKNOWN, false, 1418 "SQL conditional generation failed."); 1419 psFree(cursor); 1420 psFree(keys); 1421 psFree(query); 1422 return NULL; 1423 } 1424 1425 psStringAppend(&query, "%s", conditional); 1426 psFree(conditional); 1427 1428 // + " and " after every column declaration except the last one 1429 if (!cursor->offEnd) { 1430 psStringAppend(&query, " AND "); 1431 } 1432 } 1433 } 1434 1435 // psFree(cursor); 1436 psFree(keys); 1404 1437 1405 1438 return query; … … 1437 1470 1438 1471 psFree(cursor); 1472 1473 return query; 1474 } 1475 1476 static char *psDBGenerateConditionalSQL(const psMetadataItem *item) 1477 { 1478 char *query = NULL; 1479 1480 PS_ASSERT_PTR_NON_NULL(item, NULL); 1481 1482 // stringify the psMetadataItem into a SQL search specification 1483 if ((item->type == PS_DATA_S32) || (item->type == PS_TYPE_S32)) { 1484 psStringAppend(&query, "%s=%d", item->name, (int)(item->data.S32)); 1485 } else if ((item->type == PS_DATA_F32) || (item->type == PS_TYPE_F32)) { 1486 psStringAppend(&query, "%s=%g", item->name, (double)(item->data.F32)); 1487 } else if ((item->type == PS_DATA_F64) || (item->type == PS_TYPE_F64)) { 1488 psStringAppend(&query, "%s=%g", item->name, (double)(item->data.F64)); 1489 } else if ((item->type == PS_DATA_BOOL) || (item->type == PS_TYPE_BOOL)) { 1490 psStringAppend(&query, "%s=%d", item->name, (int)(item->data.B)); 1491 } else if (item->type == PS_DATA_STRING) { 1492 // + column name + _ + like + _ + ' + value + ' 1493 // check for NULL and empty ("") strings 1494 if (item->data.V == NULL || *(char *)item->data.V == '\0') { 1495 psStringAppend(&query, "%s IS NULL", item->name); 1496 } else { 1497 // XXX ASC NOTE: we should have a better match for 1498 // char & varchar columns than this. LIKE is OK for 1499 // very large TEXT columns that really shouldn't be 1500 // used in a where clause... 1501 psStringAppend(&query, "%s LIKE '%s'", item->name, item->data.V); 1502 } 1503 } else { 1504 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 1505 "Only types PS_DATA_S32, PS_DATA_F32, PS_DATA_F64, PS_DATA_BOOL, PS_DATA_STRING are supported"); 1506 1507 return NULL; 1508 } 1439 1509 1440 1510 return query;
Note:
See TracChangeset
for help on using the changeset viewer.
