Changeset 3154 for trunk/archive/psdb/psDB.c
- Timestamp:
- Feb 7, 2005, 4:55:32 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/archive/psdb/psDB.c (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/archive/psdb/psDB.c
r3138 r3154 8 8 * @author Joshua Hoblitt 9 9 * 10 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $11 * @date $Date: 2005-02-0 5 01:01:57$10 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2005-02-08 02:55:32 $ 12 12 * 13 13 * Copyright 2005 Joshua Hoblitt, University of Hawaii … … 29 29 } mysqlType; 30 30 31 static char *psDBIntToString(psU64 n); 32 static void psDBAddToLookupTable(psHash *lookupTable, const psU32 type, const char *string); 33 static psHash *psDBGetMySQLToSQLTable(void); 34 static void psDBMySQLToSQLTableCleanup(void); 35 static psHash *psDBGetPSToSQLTable(void); 36 static void psDBPSToSQLTableCleanup(void); 37 static psHash *psDBGetSQLToPSTable(void); 38 static void psDBSQLToPSTableCleanup(void); 39 static void psDBPSToMySQLTableCleanup(void); 40 static size_t psStringAppend(char **dest, const char *source); 41 static bool psDBRunQuery(psDB *dbh, const char *query); 42 static char *psDBGenerateWhereSQL(psMetadata *where); 43 static size_t psStringPrepend(char **dest, const char *source); 44 static psPtr psDBGetPTypeNull(psElemType pType); 45 static char *psDBGenerateInsertRowSQL(const char *tableName, psMetadata *row); 46 static char *psDBPTypeAsString(psPtr data, psElemType pType); 47 static char *psDBGenerateCreateTableSQL(const char *tableName, psMetadata *where); 48 static char *psDBGenerateSelectColumnSQL(const char *tableName, const char *col, const psU64 limit); 49 static char *psDBGenerateSelectRowsSQL(const char *tableName, psMetadata *where); 50 static psPtr psDBAllocMySQLType(enum enum_field_types type, bool isUnsigned); 31 // lookup table functions 32 static void psDBAddToLookupTable(psHash *lookupTable, const psU32 type, const char *string); 33 static void psDBAddVoidToLookupTable(psHash *lookupTable, const psU32 type, psPtr value); 34 static psHash *psDBGetMySQLToSQLTable(void); 35 static void psDBMySQLToSQLTableCleanup(void); 36 static psHash *psDBGetPSToSQLTable(void); 37 static void psDBPSToSQLTableCleanup(void); 38 static psHash *psDBGetSQLToPSTable(void); 39 static void psDBSQLToPSTableCleanup(void); 40 static psHash *psDBGetPSToMySQLTable(void); 41 static void psDBPSToMySQLTableCleanup(void); 42 static psPtr psDBMySQLTypeAlloc(enum enum_field_types type, bool isUnsigned); 43 44 // pType utility functions 45 static psPtr psDBGetPTypeNaN(psElemType pType); 46 static char *psDBPTypeAsString(psPtr data, psElemType pType); 47 static bool psDBIsPTypeNaN(psElemType pType, psPtr data); 48 49 // general utility functions 50 static char *psDBIntToString(psU64 n); 51 static size_t psStringAppend(char **dest, const char *source); 52 static size_t psStringPrepend(char **dest, const char *source); 53 54 // database utility functions 55 static bool psDBRunQuery(psDB *dbh, const char *query); 56 57 // SQL generation functions 58 static char *psDBGenerateWhereSQL(psMetadata *where); 59 static char *psDBGenerateInsertRowSQL(const char *tableName, psMetadata *row); 60 static char *psDBGenerateCreateTableSQL(const char *tableName, psMetadata *where); 61 static char *psDBGenerateSelectColumnSQL(const char *tableName, const char *col, const psU64 limit); 62 static char *psDBGenerateSelectRowsSQL(const char *tableName, psMetadata *where); 51 63 52 64 psDB *psDBInit(const char *host, const char *user, const char *passwd, const char *dbname) … … 230 242 // a = assign too, b = source psArray, c = conversion function, d = type to cast to, e = psElemType 231 243 #define STRINGARRAYTOPTYPE(a, b, c, d, e) for (i = 0; i < b->n; i++) { \ 232 a = (d)(strlen(b->data[i]) \ 233 ? atoi(b->data[i]) \ 234 : *(d *)psDBGetPTypeNull(e)); \ 244 if (strlen(b->data[i])) { \ 245 a = (d)atoi(b->data[i]); \ 246 } else { \ 247 myNaN = psDBGetPTypeNaN(e); \ 248 a = *(d *)myNaN; \ 249 psFree(myNaN); \ 250 } \ 235 251 } 236 252 … … 240 256 psVector *column; 241 257 int i; 258 psPtr myNaN; 242 259 243 260 stringColumn = psDBSelectColumn(dbh, tableName, col, limit); … … 383 400 type = PS_META_STR; 384 401 data = fieldLength[i] ? psStringNCopy(row[i], fieldLength[i]) 385 : psDBGetPTypeN ull(pType);402 : psDBGetPTypeNaN(pType); 386 403 } else { 387 404 type = PS_META_PRIMITIVE; … … 390 407 memcpy(data, row[i], fieldLength[i]); 391 408 } else { 392 data = psDBGetPTypeN ull(pType);409 data = psDBGetPTypeNaN(pType); 393 410 } 394 411 } … … 434 451 MYSQL_BIND *bind; 435 452 psU32 paramCount; 453 psHash *mysqlFieldType; 454 mysqlType *mType; 455 char *key; 456 psMetadataItem *item; 457 psListIterator *cursor; 458 psU32 i; 459 bool isNull = true; 436 460 437 461 query = psDBGenerateInsertRowSQL(tableName, row); … … 459 483 460 484 bind = psAlloc(sizeof(MYSQL_BIND) * paramCount); 461 462 485 memset(bind, 0, sizeof(MYSQL_BIND) * paramCount); 486 487 mysqlFieldType = psDBGetPSToMySQLTable(); 488 489 cursor = psListIteratorAlloc(row->list, 0); 490 491 i = 0; 492 while ((item = psListGetNext(cursor))) { 493 key = psDBIntToString((psU64)item->pType); 494 mType = psHashLookup(mysqlFieldType, key); 495 psFree(key); 496 497 // input data length is determined by the MYSQL_TYPE_* unless it's a string 498 bind[i].buffer = (char *)item->data.V; 499 bind[i].buffer_type = mType->type; 500 bind[i].is_unsigned = mType->isUnsigned; 501 502 bind[i].is_null = psDBIsPTypeNaN(item->pType, item->data.V) 503 ? (my_bool *)&isNull 504 : NULL; 505 506 if (item->pType == PS_TYPE_PTR) { 507 if (item->type == PS_META_STR) { 508 if (*(char *)item->data.V == '\0') { 509 bind[i].is_null = (my_bool *)&isNull; 510 } else { 511 bind[i].buffer_length = (unsigned long)strlen((char *)item->data.V); 512 bind[i].is_null = NULL; 513 } 514 } else { 515 // error, not a pointer to a string 516 } 517 } 518 519 if (!cursor->offEnd) { 520 // + , + _ 521 psStringAppend(&query, ", "); 522 } 523 524 i++; 525 } 526 527 psFree(mysqlFieldType); 463 528 464 529 if (mysql_stmt_bind_param(stmt, bind)) { … … 472 537 } 473 538 474 bind[0].buffer_type; 475 bind[0].is_null; 476 bind[0].is_unsigned; 477 539 if (mysql_stmt_execute(stmt)) { 540 fprintf(stderr, "Failed to execute prepared statement. Error: %s\n", mysql_stmt_error(stmt)); 541 542 psFree(bind); 543 mysql_stmt_close(stmt); 544 psFree(query); 545 546 return false; 547 } 548 549 // point of no return 478 550 mysql_commit(dbh->mysql); 479 551 552 psFree(bind); 480 553 mysql_stmt_close(stmt); 481 554 psFree(query); 482 555 483 556 return true; 557 } 558 559 psArray *psDBDumpRows(psDB *dbh, const char *tableName) 560 { 561 return psDBSelectRows(dbh, tableName, NULL); 484 562 } 485 563 … … 680 758 query = psStringCopy("SELECT * FROM "); 681 759 psStringAppend(&query, tableName); 682 psStringAppend(&query, " "); 683 684 string = psDBGenerateWhereSQL(where); 685 // FIXME check for error 686 psStringAppend(&query, string); 687 psFree(string); 760 761 // select everything if where is NULL 762 if (where != NULL) { 763 psStringAppend(&query, " "); 764 string = psDBGenerateWhereSQL(where); 765 if (string == NULL) { 766 return NULL; 767 } 768 psStringAppend(&query, string); 769 psFree(string); 770 } 688 771 689 772 return query; … … 693 776 *(a *)myNaN = b; 694 777 695 static psPtr psDBGetPTypeN ull(psElemType pType)778 static psPtr psDBGetPTypeNaN(psElemType pType) 696 779 { 697 780 psPtr myNaN; … … 746 829 747 830 return myNaN; 831 } 832 833 // a = type , b = data, c = NaN value 834 #define ISPTYPENAN(a, b, c) *(a *)b == c; 835 836 static bool psDBIsPTypeNaN(psElemType pType, psPtr data) 837 { 838 bool isNaN; 839 840 switch (pType) { 841 case PS_TYPE_S8: 842 isNaN = ISPTYPENAN(psS8, data, PS_MAX_S8) 843 break; 844 case PS_TYPE_S16: 845 isNaN = ISPTYPENAN(psS16, data, PS_MAX_S16) 846 break; 847 case PS_TYPE_S32: 848 isNaN = ISPTYPENAN(psS32, data, PS_MAX_S32) 849 break; 850 case PS_TYPE_S64: 851 isNaN = ISPTYPENAN(psS64, data, PS_MAX_S64) 852 break; 853 case PS_TYPE_U8: 854 isNaN = ISPTYPENAN(psU8, data, PS_MAX_U8) 855 break; 856 case PS_TYPE_U16: 857 isNaN = ISPTYPENAN(psU16, data, PS_MAX_U16) 858 break; 859 case PS_TYPE_U32: 860 isNaN = ISPTYPENAN(psU32, data, PS_MAX_U32) 861 break; 862 case PS_TYPE_U64: 863 isNaN = ISPTYPENAN(psU64, data, PS_MAX_U64) 864 break; 865 case PS_TYPE_F32: 866 isNaN = ISPTYPENAN(psF32, data, NAN) 867 break; 868 case PS_TYPE_F64: 869 isNaN = ISPTYPENAN(psF64, data, NAN) 870 break; 871 case PS_TYPE_C32: 872 // this is a bogus SQL type 873 isNaN = ISPTYPENAN(psC32, data, NAN) 874 break; 875 case PS_TYPE_C64: 876 // this is a bogus SQL type 877 isNaN = ISPTYPENAN(psC64, data, NAN) 878 break; 879 case PS_TYPE_BOOL: 880 // what is NaN for a bool? 881 break; 882 case PS_TYPE_PTR: 883 isNaN = ISPTYPENAN(char, data, '\0') 884 break; 885 } 886 887 return isNaN; 748 888 } 749 889 … … 987 1127 988 1128 if (!lookupTable) { 989 lookupTable = psHashAlloc(16); 990 991 psDBAddToLookupTable(lookupTable, PS_TYPE_S8, psDBAllocMySQLType(MYSQL_TYPE_TINY, false)); 992 psDBAddToLookupTable(lookupTable, PS_TYPE_S16, psDBAllocMySQLType(MYSQL_TYPE_SHORT, false)); 993 psDBAddToLookupTable(lookupTable, PS_TYPE_S32, psDBAllocMySQLType(MYSQL_TYPE_LONG, false)); 994 psDBAddToLookupTable(lookupTable, PS_TYPE_S64, psDBAllocMySQLType(MYSQL_TYPE_LONGLONG, false)); 995 psDBAddToLookupTable(lookupTable, PS_TYPE_U8, psDBAllocMySQLType(MYSQL_TYPE_TINY, true)); 996 psDBAddToLookupTable(lookupTable, PS_TYPE_U16, psDBAllocMySQLType(MYSQL_TYPE_SHORT, true)); 997 psDBAddToLookupTable(lookupTable, PS_TYPE_U32, psDBAllocMySQLType(MYSQL_TYPE_LONG, true)); 998 psDBAddToLookupTable(lookupTable, PS_TYPE_U64, psDBAllocMySQLType(MYSQL_TYPE_LONGLONG, true)); 999 psDBAddToLookupTable(lookupTable, PS_TYPE_F32, psDBAllocMySQLType(MYSQL_TYPE_FLOAT, false)); 1000 psDBAddToLookupTable(lookupTable, PS_TYPE_F64, psDBAllocMySQLType(MYSQL_TYPE_DOUBLE, false)); 1001 psDBAddToLookupTable(lookupTable, PS_TYPE_C32, NULL); // unsupported 1002 psDBAddToLookupTable(lookupTable, PS_TYPE_C64, NULL); // unsupported 1003 psDBAddToLookupTable(lookupTable, PS_TYPE_BOOL, psDBAllocMySQLType(MYSQL_TYPE_TINY, true)); 1004 psDBAddToLookupTable(lookupTable, PS_TYPE_PTR, psDBAllocMySQLType(MYSQL_TYPE_VAR_STRING, false)); 1129 lookupTable = psHashAlloc(14); 1130 1131 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_S8, psDBMySQLTypeAlloc(MYSQL_TYPE_TINY, false)); 1132 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_S16, psDBMySQLTypeAlloc(MYSQL_TYPE_SHORT, false)); 1133 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_S32, psDBMySQLTypeAlloc(MYSQL_TYPE_LONG, false)); 1134 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_S64, psDBMySQLTypeAlloc(MYSQL_TYPE_LONGLONG, false)); 1135 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_U8, psDBMySQLTypeAlloc(MYSQL_TYPE_TINY, true)); 1136 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_U16, psDBMySQLTypeAlloc(MYSQL_TYPE_SHORT, true)); 1137 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_U32, psDBMySQLTypeAlloc(MYSQL_TYPE_LONG, true)); 1138 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_U64, psDBMySQLTypeAlloc(MYSQL_TYPE_LONGLONG, true)); 1139 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_F32, psDBMySQLTypeAlloc(MYSQL_TYPE_FLOAT, false)); 1140 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_F64, psDBMySQLTypeAlloc(MYSQL_TYPE_DOUBLE, false)); 1141 // bogus type 1142 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_C32, psDBMySQLTypeAlloc(MYSQL_TYPE_VAR_STRING, false)); 1143 // bogus type 1144 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_C64, psDBMySQLTypeAlloc(MYSQL_TYPE_VAR_STRING, false)); 1145 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_BOOL, psDBMySQLTypeAlloc(MYSQL_TYPE_TINY, true)); 1146 psDBAddVoidToLookupTable(lookupTable, PS_TYPE_PTR, psDBMySQLTypeAlloc(MYSQL_TYPE_VAR_STRING, false)); 1005 1147 } 1006 1148 … … 1011 1153 } 1012 1154 1013 static psPtr psDBAllocMySQLType(enum enum_field_types type, bool isUnsigned) 1155 static void psDBPSToMySQLTableCleanup(void) 1156 { 1157 psHash *lookupTable; 1158 1159 lookupTable = psDBGetPSToMySQLTable(); 1160 1161 psMemDecrRefCounter(lookupTable); 1162 psFree(lookupTable); 1163 } 1164 1165 static psPtr psDBMySQLTypeAlloc(enum enum_field_types type, bool isUnsigned) 1014 1166 { 1015 1167 mysqlType *mType; … … 1019 1171 mType->isUnsigned = isUnsigned; 1020 1172 1021 return (psPtr)mType; 1022 } 1023 1024 static void psDBPSToMySQLTableCleanup(void) 1025 { 1026 psHash *lookupTable; 1027 1028 lookupTable = psDBGetPSToMySQLTable(); 1029 1030 psMemDecrRefCounter(lookupTable); 1031 psFree(lookupTable); 1173 return mType; 1032 1174 } 1033 1175 … … 1044 1186 psFree(key); 1045 1187 psFree(value); 1188 } 1189 1190 static void psDBAddVoidToLookupTable(psHash *lookupTable, const psU32 type, psPtr value) 1191 { 1192 char *key; 1193 1194 key = psDBIntToString((psU64)type); 1195 1196 psHashAdd(lookupTable, key, value); 1197 1198 // destructive of value parameter 1199 psFree(value); 1200 psFree(key); 1046 1201 } 1047 1202
Note:
See TracChangeset
for help on using the changeset viewer.
