IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 9, 2005, 2:02:16 PM (21 years ago)
Author:
jhoblitt
Message:

add psDBInsertRows()
change mysqlType typdef to use enum_field_types
test tweaks

File:
1 edited

Legend:

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

    r3166 r3175  
    88 *  @author Joshua Hoblitt
    99 *
    10  *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
    11  *  @date $Date: 2005-02-09 01:15:39 $
     10 *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
     11 *  @date $Date: 2005-02-10 00:02:16 $
    1212 *
    1313 *  Copyright 2005 Joshua Hoblitt, University of Hawaii
     
    2525typedef struct
    2626{
    27     psU32  type;
    28     bool    isUnsigned;
     27    enum enum_field_types type;
     28    bool            isUnsigned;
    2929} mysqlType;
    3030
     
    564564        return false;
    565565    }
     566
     567    // point of no return
     568    mysql_commit(dbh->mysql);
     569
     570    psFree(bind);
     571    mysql_stmt_close(stmt);
     572
     573    return true;
     574}
     575
     576bool psDBInsertRows(psDB *dbh, const char *tableName, psArray *rowSet)
     577{
     578    psMetadata      *row;               // row of data
     579    char            *query;             // SQL query
     580    MYSQL_STMT      *stmt;              // prepared db statement
     581    MYSQL_BIND      *bind;              // field values to insert
     582    psU32           paramCount;         // number of placeholders in query
     583    psHash          *mysqlFieldType;    // type lookup table
     584    mysqlType       *mType;             // type tmp variable
     585    char            *key;               // hash tmp variable
     586    psMetadataItem  *item;              // field in row
     587    psListIterator  *cursor;            // row iterator
     588    psU32           i;                  // field index
     589    psU64           j;                  // row index
     590    bool            isNull = true;      // used in a MYSQL_BIND to indicate NULL
     591
     592    // we are assuming that all rows in the set have an identical with reguard
     593    // to field count and type
     594    row = rowSet->data[0];
     595
     596    query = psDBGenerateInsertRowSQL(tableName, row);
     597    if (!query) {
     598        return NULL;
     599    }
     600
     601    stmt = mysql_stmt_init(dbh->mysql);
     602    if (!stmt) {
     603        // call abort?
     604        fprintf(stderr, " mysql_stmt_init(), out of memory\n");
     605
     606        return false;
     607    }
     608
     609    if (mysql_stmt_prepare(stmt, query, (unsigned long)strlen(query))) {
     610            fprintf(stderr, "Failed to prepare query.  Error: %s\n", mysql_stmt_error(stmt));
     611
     612            mysql_stmt_close(stmt);
     613            psFree(query);
     614
     615            return false;
     616    }
     617
     618    psFree(query);
     619
     620    // how many place holders are in our query
     621    paramCount = (psU32)mysql_stmt_param_count(stmt);
     622
     623    // structure larger enough to hold one field of data per place holder
     624    bind = psAlloc(sizeof(MYSQL_BIND) * paramCount);
     625
     626    mysqlFieldType = psDBGetPSToMySQLTable();
     627
     628    // loop over rows
     629    for (j = 0; j < rowSet->n; j++) {
     630        cursor = psListIteratorAlloc(row->list, 0);
     631
     632        // reset bind for each row
     633        memset(bind, 0, sizeof(MYSQL_BIND) * paramCount);
     634
     635        // loop over fields
     636        i = 0;
     637        while ((item = psListGetNext(cursor))) {
     638            key = psDBIntToString((psU64)item->pType);
     639            mType = psHashLookup(mysqlFieldType, key);
     640            psFree(key);
     641
     642            // input data length is determined by the MYSQL_TYPE_* unless it's a string
     643            bind[i].buffer  = (char *)item->data.V;
     644            bind[i].buffer_type = mType->type;
     645            bind[i].is_unsigned = mType->isUnsigned;
     646
     647            // convert NaNs to NULL
     648            bind[i].is_null = psDBIsPTypeNaN(item->pType, item->data.V)
     649                            ? (my_bool *)&isNull
     650                            : NULL;
     651
     652            if (item->pType == PS_TYPE_PTR) {
     653                if (item->type == PS_META_STR) {
     654                    if (*(char *)item->data.V == '\0') {
     655                        bind[i].is_null = (my_bool *)&isNull;
     656                    } else {
     657                        bind[i].buffer_length = (unsigned long)strlen((char *)item->data.V);
     658                        bind[i].is_null = NULL;
     659                    }
     660                } else {
     661                    // error, not a pointer to a string
     662                }
     663            }
     664
     665            // increment field index
     666            i++;
     667        }
     668
     669        psFree(cursor);
     670
     671        if (mysql_stmt_bind_param(stmt, bind)) {
     672            fprintf(stderr, "Failed to bind params.  Error: %s\n", mysql_stmt_error(stmt));
     673
     674            psFree(bind);
     675            mysql_stmt_close(stmt);
     676
     677            return false;
     678        }
     679
     680        if (mysql_stmt_execute(stmt)) {
     681            fprintf(stderr, "Failed to execute prepared statement.  Error: %s\n", mysql_stmt_error(stmt));
     682
     683            psFree(bind);
     684            mysql_stmt_close(stmt);
     685
     686            return false;
     687        }
     688    } // end loop over rows
     689
     690    psFree(mysqlFieldType);
    566691
    567692    // point of no return
Note: See TracChangeset for help on using the changeset viewer.