IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 7, 2005, 4:55:32 PM (21 years ago)
Author:
jhoblitt
Message:

misc code tidying
fix memory leak in STRINGARRAYTOPTYPE macro
completed psDBInsertRow()
add psDBDumpRows()
add support for NULL where in psDBGenerateInsertRowSQL()
rename psDBGetPTypeNull() to psDBGetPTypeNaN()
add psDBIsPTypeNaN()
rename psDBAllocMySQLType() to psDBMySQLTypeAlloc()
add psDBAddVoidToLookupTable()

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/archive/psdb/psDB.c

    r3138 r3154  
    88 *  @author Joshua Hoblitt
    99 *
    10  *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2005-02-05 01:01:57 $
     10 *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2005-02-08 02:55:32 $
    1212 *
    1313 *  Copyright 2005 Joshua Hoblitt, University of Hawaii
     
    2929} mysqlType;
    3030
    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
     32static void     psDBAddToLookupTable(psHash *lookupTable, const psU32 type, const char *string);
     33static void     psDBAddVoidToLookupTable(psHash *lookupTable, const psU32 type, psPtr value);
     34static psHash  *psDBGetMySQLToSQLTable(void);
     35static void     psDBMySQLToSQLTableCleanup(void);
     36static psHash  *psDBGetPSToSQLTable(void);
     37static void     psDBPSToSQLTableCleanup(void);
     38static psHash  *psDBGetSQLToPSTable(void);
     39static void     psDBSQLToPSTableCleanup(void);
     40static psHash  *psDBGetPSToMySQLTable(void);
     41static void     psDBPSToMySQLTableCleanup(void);
     42static psPtr    psDBMySQLTypeAlloc(enum enum_field_types type, bool isUnsigned);
     43
     44// pType utility functions
     45static psPtr    psDBGetPTypeNaN(psElemType pType);
     46static char    *psDBPTypeAsString(psPtr data, psElemType pType);
     47static bool     psDBIsPTypeNaN(psElemType pType, psPtr data);
     48
     49// general utility functions
     50static char    *psDBIntToString(psU64 n);
     51static size_t   psStringAppend(char **dest, const char *source);
     52static size_t   psStringPrepend(char **dest, const char *source);
     53
     54// database utility functions
     55static bool     psDBRunQuery(psDB *dbh, const char *query);
     56
     57// SQL generation functions
     58static char    *psDBGenerateWhereSQL(psMetadata *where);
     59static char    *psDBGenerateInsertRowSQL(const char *tableName, psMetadata *row);
     60static char    *psDBGenerateCreateTableSQL(const char *tableName, psMetadata *where);
     61static char    *psDBGenerateSelectColumnSQL(const char *tableName, const char *col, const psU64 limit);
     62static char    *psDBGenerateSelectRowsSQL(const char *tableName, psMetadata *where);
    5163
    5264psDB *psDBInit(const char *host, const char *user, const char *passwd, const char *dbname)
     
    230242// a = assign too, b = source psArray, c = conversion function, d = type to cast to, e = psElemType
    231243#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                                                } \
    235251                                            }
    236252
     
    240256    psVector        *column;
    241257    int             i;
     258    psPtr           myNaN;
    242259
    243260    stringColumn = psDBSelectColumn(dbh, tableName, col, limit);
     
    383400                    type = PS_META_STR;
    384401                    data = fieldLength[i] ? psStringNCopy(row[i], fieldLength[i])
    385                                           : psDBGetPTypeNull(pType);
     402                                          : psDBGetPTypeNaN(pType);
    386403                } else {
    387404                    type = PS_META_PRIMITIVE;
     
    390407                        memcpy(data, row[i], fieldLength[i]);
    391408                    } else {
    392                         data = psDBGetPTypeNull(pType);
     409                        data = psDBGetPTypeNaN(pType);
    393410                    }
    394411                }
     
    434451    MYSQL_BIND      *bind;
    435452    psU32           paramCount;
     453    psHash          *mysqlFieldType;
     454    mysqlType       *mType;
     455    char            *key;
     456    psMetadataItem  *item;
     457    psListIterator  *cursor;
     458    psU32           i;
     459    bool            isNull = true;
    436460
    437461    query = psDBGenerateInsertRowSQL(tableName, row);
     
    459483
    460484    bind = psAlloc(sizeof(MYSQL_BIND) * paramCount);
    461 
    462485    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);
    463528
    464529    if (mysql_stmt_bind_param(stmt, bind)) {
     
    472537    }
    473538
    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
    478550    mysql_commit(dbh->mysql);
    479551
     552    psFree(bind);
    480553    mysql_stmt_close(stmt);
    481554    psFree(query);
    482555
    483556    return true;
     557}
     558
     559psArray *psDBDumpRows(psDB *dbh, const char *tableName)
     560{
     561    return psDBSelectRows(dbh, tableName, NULL);
    484562}
    485563
     
    680758    query = psStringCopy("SELECT * FROM ");
    681759    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    }
    688771
    689772    return query;
     
    693776                    *(a *)myNaN = b;
    694777
    695 static psPtr psDBGetPTypeNull(psElemType pType)
     778static psPtr psDBGetPTypeNaN(psElemType pType)
    696779{
    697780    psPtr           myNaN;
     
    746829
    747830    return myNaN;
     831}
     832
     833// a = type , b = data, c = NaN value
     834#define ISPTYPENAN(a, b, c) *(a *)b == c;
     835
     836static 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;
    748888}
    749889
     
    9871127
    9881128    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));
    10051147    }
    10061148
     
    10111153}
    10121154
    1013 static psPtr psDBAllocMySQLType(enum enum_field_types type, bool isUnsigned)
     1155static void psDBPSToMySQLTableCleanup(void)
     1156{
     1157    psHash          *lookupTable;
     1158
     1159    lookupTable = psDBGetPSToMySQLTable();
     1160
     1161    psMemDecrRefCounter(lookupTable);
     1162    psFree(lookupTable);
     1163}
     1164
     1165static psPtr psDBMySQLTypeAlloc(enum enum_field_types type, bool isUnsigned)
    10141166{
    10151167    mysqlType       *mType;
     
    10191171    mType->isUnsigned = isUnsigned;
    10201172
    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;
    10321174}
    10331175
     
    10441186    psFree(key);
    10451187    psFree(value);
     1188}
     1189
     1190static 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);
    10461201}
    10471202
Note: See TracChangeset for help on using the changeset viewer.