Added new typechecks and errors

Mon, 01 Dec 2008 07:22:44 +0000

author
nrich@ii.net
date
Mon, 01 Dec 2008 07:22:44 +0000
changeset 10
3aa8a37a3dd8
parent 9
06eb2850703f
child 11
b3e05e361f46

Added new typechecks and errors

dbd/common.h file | annotate | diff | comparison | revisions
dbd/mysql/statement.c file | annotate | diff | comparison | revisions
dbd/postgresql/statement.c file | annotate | diff | comparison | revisions
dbd/sqlite3/statement.c file | annotate | diff | comparison | revisions
--- a/dbd/common.h	Mon Dec 01 02:56:40 2008 +0000
+++ b/dbd/common.h	Mon Dec 01 07:22:44 2008 +0000
@@ -101,7 +101,6 @@
 #define DBI_ERR_FETCH_INVALID	    "Fetch called on a closed or invalid statement"
 #define DBI_ERR_FETCH_FAILED	    "Fetch failed %s"
 #define DBI_ERR_PARAM_MISCOUNT	    "Statement expected %d parameters but received %d"
-#define	DBI_ERR_BINDING_UNKNOWN	    "Binding unknown or unsupported type"
 #define DBI_ERR_BINDING_PARAMS	    "Error binding statement parameters: %s"
 #define DBI_ERR_BINDING_EXEC	    "Error executing statement parameters: %s"
 #define DBI_ERR_FETCH_NO_EXECUTE    "Fetch called before execute"
@@ -111,3 +110,4 @@
 #define DBI_ERR_PREP_STATEMENT	    "Error preparing statement handle: %s"
 #define DBI_ERR_INVALID_PORT	    "Invalid port: %d"
 #define DBI_ERR_ALLOC_RESULT	    "Error allocating result set: %s"
+#define DBI_ERR_BINDING_TYPE_ERR    "Unknown or unsupported type `%s'"
--- a/dbd/mysql/statement.c	Mon Dec 01 02:56:40 2008 +0000
+++ b/dbd/mysql/statement.c	Mon Dec 01 07:22:44 2008 +0000
@@ -59,6 +59,7 @@
     MYSQL_RES *metadata = NULL;
 
     char *error_message = NULL;
+    char *errstr = NULL;
 
     int p;
 
@@ -72,7 +73,7 @@
 
     if (expected_params != num_bind_params) {
 	/*
-         * mysql_stmt_bind_param does not handle this conndition,
+         * mysql_stmt_bind_param does not handle this condition,
          * and the client library will segfault if these do no match
          */ 
 	lua_pushboolean(L, 0);
@@ -91,6 +92,7 @@
 	size_t *str_len = NULL;
 	double *num = NULL;
 	int *boolean = NULL;
+	char err[64];
 
 	switch(type) {
 	    case LUA_TNIL:
@@ -132,7 +134,9 @@
 		break;
 
 	    default:
-		error_message = DBI_ERR_BINDING_UNKNOWN; 
+		snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type));
+		errstr = err;
+		error_message = DBI_ERR_BINDING_PARAMS;
 		goto cleanup;
 	}
     }
@@ -175,7 +179,7 @@
 
     if (error_message) {
 	lua_pushboolean(L, 0);
-	lua_pushfstring(L, error_message, mysql_stmt_error(statement->stmt));
+	lua_pushfstring(L, error_message, errstr ? errstr : mysql_stmt_error(statement->stmt));
 	return 2;
     }
 
--- a/dbd/postgresql/statement.c	Mon Dec 01 02:56:40 2008 +0000
+++ b/dbd/postgresql/statement.c	Mon Dec 01 07:22:44 2008 +0000
@@ -131,6 +131,7 @@
     int num_bind_params = n - 1;   
     ExecStatusType status;
     int p;
+    const char *errstr = NULL;
 
     const char **params;
     PGresult *result = NULL;
@@ -144,21 +145,31 @@
      */ 
     for (p = 2; p <= n; p++) {
 	int i = p - 2;	
+	int type = lua_type(L, p);
+	char err[64];
 
-	if (lua_isnil(L, p)) {
+	switch(type) {
+	case LUA_TNIL:
 	    params[i] = NULL;
-	} else {
-	    if (lua_isboolean(L, p)) 
-		/*
-		 * boolean values in postgresql can either be
-		 * t/f or 1/0. Pass integer values rather than
-		 * strings to maintain semantic compatibility
-		 * with other DBD drivers that pass booleans
-		 * as integers.
-		 */
-		params[i] = lua_toboolean(L, p) ?  "1" : "0";
-	    else 
-		params[i] = lua_tostring(L, p);
+	    break;
+	case LUA_TBOOLEAN:
+	    /*
+	     * boolean values in postgresql can either be
+	     * t/f or 1/0. Pass integer values rather than
+	     * strings to maintain semantic compatibility
+	     * with other DBD drivers that pass booleans
+	     * as integers.
+	     */
+	    params[i] = lua_toboolean(L, p) ?  "1" : "0";
+	    break;
+	case LUA_TNUMBER:
+	case LUA_TSTRING:
+	    params[i] = lua_tostring(L, p);
+	    break;
+	default:
+	    snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type));
+	    errstr = err;
+	    goto cleanup;
 	}
     }
 
@@ -172,8 +183,15 @@
         0
     );
 
+cleanup:
     free(params);
 
+    if (errstr) {
+	lua_pushboolean(L, 0);
+	lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr);
+	return 2;
+    }
+
     if (!result) {
 	lua_pushboolean(L, 0);
 	lua_pushfstring(L, DBI_ERR_ALLOC_RESULT,  PQerrorMessage(statement->postgresql));
--- a/dbd/sqlite3/statement.c	Mon Dec 01 02:56:40 2008 +0000
+++ b/dbd/sqlite3/statement.c	Mon Dec 01 07:22:44 2008 +0000
@@ -69,8 +69,10 @@
     int n = lua_gettop(L);
     statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT);
     int p;
-    int err = 0;
-
+    int errflag = 0;
+    const char *errstr = NULL;
+    int expected_params;
+    int num_bind_params = n - 1;
 
     if (!statement->stmt) {
 	lua_pushboolean(L, 0);
@@ -89,39 +91,56 @@
 	return 2;
     }
 
+    expected_params = sqlite3_bind_parameter_count(statement->stmt);
+    if (expected_params != num_bind_params) {
+	/*
+         * sqlite3_reset does not handle this condition,
+         * and the client library will fill unset params
+         * with NULLs
+         */ 
+	lua_pushboolean(L, 0);
+	lua_pushfstring(L, DBI_ERR_PARAM_MISCOUNT, expected_params, num_bind_params); 
+	return 2;
+    }
+
     for (p = 2; p <= n; p++) {
 	int i = p - 1;
-
 	int type = lua_type(L, p);
+	char err[64];
 
 	switch(type) {
 	case LUA_TNIL:
-	    err = sqlite3_bind_null(statement->stmt, i) != SQLITE_OK;
+	    errflag = sqlite3_bind_null(statement->stmt, i) != SQLITE_OK;
 	    break;
 	case LUA_TNUMBER:
-	    err = sqlite3_bind_double(statement->stmt, i, lua_tonumber(L, p)) != SQLITE_OK;
+	    errflag = sqlite3_bind_double(statement->stmt, i, lua_tonumber(L, p)) != SQLITE_OK;
 	    break;
 	case LUA_TSTRING:
-	    err = sqlite3_bind_text(statement->stmt, i, lua_tostring(L, p), -1, SQLITE_STATIC) != SQLITE_OK;
+	    errflag = sqlite3_bind_text(statement->stmt, i, lua_tostring(L, p), -1, SQLITE_STATIC) != SQLITE_OK;
 	    break;
 	case LUA_TBOOLEAN:
-	    err = sqlite3_bind_int(statement->stmt, i, lua_toboolean(L, p)) != SQLITE_OK;
+	    errflag = sqlite3_bind_int(statement->stmt, i, lua_toboolean(L, p)) != SQLITE_OK;
 	    break;
 	default:
 	    /*
 	     * Unknown/unsupported value type
 	     */
-	    err = 1;
+	    errflag = 1;
+            snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type));
+            errstr = err;
 	}
 
-
-	if (err)
+	if (errflag)
 	    break;
     }   
 
-    if (err) {
+    if (errflag) {
 	lua_pushboolean(L, 0);
-	lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, sqlite3_errmsg(statement->sqlite));
+	if (errstr)
+	    lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr);
+	else
+	    lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, sqlite3_errmsg(statement->sqlite));
+    
 	return 2;
     }
 

mercurial