Index: /trunk/archive/psdb/psDB.c
===================================================================
--- /trunk/archive/psdb/psDB.c	(revision 3195)
+++ /trunk/archive/psdb/psDB.c	(revision 3196)
@@ -8,6 +8,6 @@
  *  @author Joshua Hoblitt
  *
- *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-02-11 21:52:33 $
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-02-11 23:19:25 $
  *
  *  Copyright 2005 Joshua Hoblitt, University of Hawaii
@@ -54,4 +54,5 @@
 // database utility functions
 static bool     psDBRunQuery(psDB *dbh, const char *query);
+static inline bool psDBPackRow(MYSQL_BIND *bind, psMetadata *values, psU32 paramCount);
 
 // SQL generation functions
@@ -407,5 +408,5 @@
         md = psMetadataAlloc();
 
-        fieldLength = (psU64 *)(mysql_fetch_lengths(result));
+        fieldLength = (psU64 *)mysql_fetch_lengths(result);
 
         for (i = 0; i < fieldCount; i++) {
@@ -636,4 +637,5 @@
         i = 0;
         while ((item = psListGetNext(cursor))) {
+            // lookup pType -> mysql type
             key = psDBIntToString((psU64)item->pType);
             mType = psHashLookup(mysqlFieldType, key);
@@ -752,6 +754,16 @@
     paramCount = (psU32)mysql_stmt_param_count(stmt);
 
-    // structure larger enough to hold one field of data per place holder
+    // structure large enough to hold one field of data per place holder
     bind = psAlloc(sizeof(MYSQL_BIND) * paramCount);
+
+    // init bind
+    memset(bind, 0, sizeof(MYSQL_BIND) * paramCount);
+
+    if (!psDBPackRow(bind, values, paramCount)) {
+        psFree(bind);
+        mysql_stmt_close(stmt);
+
+        return -1;
+    }
 
     if (mysql_stmt_bind_param(stmt, bind)) {
@@ -787,4 +799,64 @@
 
     return rowsAffected;
+}
+
+static inline bool psDBPackRow(MYSQL_BIND *bind, psMetadata *values, psU32 paramCount)
+{
+    psListIterator  *cursor;            // row iterator
+    psMetadataItem  *item;              // field in row
+    psHash          *mysqlFieldType;    // type lookup table
+    mysqlType       *mType;             // type tmp variable
+    bool            isNull = true;      // used in a MYSQL_BIND to indicate NULL
+    char            *key;               // hash tmp variable
+    int             i;
+
+    // check size of values == paramCount ?
+
+    cursor = psListIteratorAlloc(values->list, 0);
+
+    mysqlFieldType = psDBGetPSToMySQLTable();
+
+    // loop over fields
+    i = 0;
+    while ((item = psListGetNext(cursor))) {
+        // lookup pType -> mysql type
+        key = psDBIntToString((psU64)item->pType);
+        mType = psHashLookup(mysqlFieldType, key);
+        psFree(key);
+
+        // input data length is determined by the MYSQL_TYPE_* unless it's a string
+        bind[i].buffer  = (char *)item->data.V;
+        bind[i].buffer_type = mType->type;
+        bind[i].is_unsigned = mType->isUnsigned;
+
+        // convert NaNs to NULL
+        bind[i].is_null = psDBIsPTypeNaN(item->pType, item->data.V) 
+                        ? (my_bool *)&isNull
+                        : NULL;
+
+        if (item->pType == PS_TYPE_PTR) {
+            if (item->type == PS_META_STR) {
+                if (*(char *)item->data.V == '\0') {
+                    bind[i].is_null = (my_bool *)&isNull;
+                } else {
+                    bind[i].buffer_length = (unsigned long)strlen((char *)item->data.V);
+                    bind[i].is_null = NULL;
+                }
+            } else {
+                // error, not a pointer to a string
+                psFree(cursor);
+
+                return false;
+            }
+        }
+
+        // increment field index
+        i++;
+    }
+
+    psFree(cursor);
+    psFree(mysqlFieldType);
+
+    return true;
 }
 
