* Add `columns' method for DB2 and Oracle statment handles

Sat, 13 Jun 2009 08:55:44 +0000

author
nrich@ii.net
date
Sat, 13 Jun 2009 08:55:44 +0000
changeset 31
999ef93f0dbc
parent 30
8599f34c139b
child 32
03ed0ca09837

* Add `columns' method for DB2 and Oracle statment handles
* Misc cleanup

dbd/common.c file | annotate | diff | comparison | revisions
dbd/db2/statement.c file | annotate | diff | comparison | revisions
dbd/oracle/dbd_oracle.h file | annotate | diff | comparison | revisions
dbd/oracle/statement.c file | annotate | diff | comparison | revisions
--- a/dbd/common.c	Fri Apr 17 23:46:12 2009 +0000
+++ b/dbd/common.c	Sat Jun 13 08:55:44 2009 +0000
@@ -45,7 +45,7 @@
     
     /*
      * this is MAX_PLACEHOLDER_SIZE-1 because the '?' is 
-     * replaced with '$'
+     * replaced with '{native_prefix}'
      */ 
     extra_space = num_placeholders * (MAX_PLACEHOLDER_SIZE-1); 
 
--- a/dbd/db2/statement.c	Fri Apr 17 23:46:12 2009 +0000
+++ b/dbd/db2/statement.c	Sat Jun 13 08:55:44 2009 +0000
@@ -77,10 +77,32 @@
 /*
  *  column_names = statement:columns()
  */
-static int statement_rowcount(lua_State *L) {
-    luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_DB2_STATEMENT, "columns");
+static int statement_columns(lua_State *L) {
+    statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_DB2_STATEMENT);
+
+    int i;
+    int d;
+
+    SQLCHAR message[SQL_MAX_MESSAGE_LENGTH + 1];
+    SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
+    SQLINTEGER sqlcode;
+    SQLSMALLINT length;
 
-    return 0;
+    SQLRETURN rc = SQL_SUCCESS;
+ 
+    if (!statement->resultset || !statement->bind) {
+	lua_pushnil(L);
+	return 1;
+    }
+
+    d = 1; 
+    lua_newtable(L);
+    for (i = 0; i < statement->num_result_columns; i++) {
+	const char *name = strlower(statement->resultset[i].name);
+	LUA_PUSH_ARRAY_STRING(d, name);
+    }
+
+    return 1;
 }
 
 /*
--- a/dbd/oracle/dbd_oracle.h	Fri Apr 17 23:46:12 2009 +0000
+++ b/dbd/oracle/dbd_oracle.h	Sat Jun 13 08:55:44 2009 +0000
@@ -35,5 +35,7 @@
     connection_t *conn;
     int num_columns;
     bindparams_t *bind;
+
+    int metadata;
 } statement_t;
 
--- a/dbd/oracle/statement.c	Fri Apr 17 23:46:12 2009 +0000
+++ b/dbd/oracle/statement.c	Sat Jun 13 08:55:44 2009 +0000
@@ -25,6 +25,62 @@
 }
 
 /*
+ * Fetch metadata from the database
+ */
+
+static void statement_fetch_metadata(lua_State *L, statement_t *statement) {
+    bindparams_t *bind;
+    int i;
+
+    char errbuf[100];
+    int errcode;
+    int rc;
+
+    if (statement->metadata)
+	return;
+
+    statement->bind = (bindparams_t *)malloc(sizeof(bindparams_t) * statement->num_columns);
+    memset(statement->bind, 0, sizeof(bindparams_t) * statement->num_columns);
+    bind = statement->bind;
+
+    for (i = 0; i < statement->num_columns; i++) {
+	rc = OCIParamGet(statement->stmt, OCI_HTYPE_STMT, statement->conn->err, (dvoid **)&bind[i].param, i+1);
+	if (rc) {
+	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
+	    luaL_error(L, "param get %s", errbuf);
+	}
+
+	rc = OCIAttrGet(bind[i].param, OCI_DTYPE_PARAM, (dvoid *)&(bind[i].name), (ub4 *)&(bind[i].name_len), OCI_ATTR_NAME, statement->conn->err);
+	if (rc) {
+	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
+	    luaL_error(L, "name get %s", errbuf);
+	}
+
+	rc = OCIAttrGet(bind[i].param, OCI_DTYPE_PARAM, (dvoid *)&(bind[i].data_type), (ub4 *)0, OCI_ATTR_DATA_TYPE, statement->conn->err);
+	if (rc) {
+	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
+	    luaL_error(L, "datatype get %s", errbuf);
+	}
+
+	rc = OCIAttrGet(bind[i].param, OCI_DTYPE_PARAM, (dvoid *)&(bind[i].max_len), 0, OCI_ATTR_DATA_SIZE, statement->conn->err);
+	if (rc) {
+	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
+	    luaL_error(L, "datasize get %s", errbuf);
+	}
+
+	bind[i].data = calloc(bind[i].max_len+1, sizeof(char));
+	rc = OCIDefineByPos(statement->stmt, &bind[i].define, statement->conn->err, (ub4)i+1, bind[i].data, bind[i].max_len, SQLT_STR, (dvoid *)&(bind[i].null), (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT);
+	if (rc) {
+	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
+	    luaL_error(L, "define by pos %s", errbuf);
+	}
+    }
+
+    statement->metadata = 1;
+}
+
+
+/*
  * num_affected_rows = statement:affected()
  */
 static int statement_affected(lua_State *L) {
@@ -80,10 +136,33 @@
 /*
  *  column_names = statement:columns()
  */
-static int statement_rowcount(lua_State *L) {
-    luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_ORACLE_STATEMENT, "columns");
+static int statement_columns(lua_State *L) {
+    statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_ORACLE_STATEMENT);
+    int rc;
+
+    bindparams_t *bind;
+
+    char errbuf[100];
+    int errcode;
+
+    int i;
+    int d = 1;
 
-    return 0;
+    if (!statement->stmt) {
+        luaL_error(L, DBI_ERR_INVALID_STATEMENT);
+        return 0;
+    }
+
+    statement_fetch_metadata(L, statement);    
+
+    lua_newtable(L);
+    for (i = 0; i < statement->num_columns; i++) {
+	const char *name = strlower(statement->bind[i].name);
+
+	LUA_PUSH_ARRAY_STRING(d, name);
+    }
+
+    return 1;
 }
 
 
@@ -269,43 +348,9 @@
 	return 0;
     }
 
-    statement->bind = (bindparams_t *)malloc(sizeof(bindparams_t) * statement->num_columns);
-    memset(statement->bind, 0, sizeof(bindparams_t) * statement->num_columns);
+    statement_fetch_metadata(L, statement);    
     bind = statement->bind;
 
-    for (i = 0; i < statement->num_columns; i++) {
-	rc = OCIParamGet(statement->stmt, OCI_HTYPE_STMT, statement->conn->err, (dvoid **)&bind[i].param, i+1);
-	if (rc) {
-	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
-	    luaL_error(L, "param get %s", errbuf);
-	}
-
-	rc = OCIAttrGet(bind[i].param, OCI_DTYPE_PARAM, (dvoid *)&(bind[i].name), (ub4 *)&(bind[i].name_len), OCI_ATTR_NAME, statement->conn->err);
-	if (rc) {
-	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
-	    luaL_error(L, "name get %s", errbuf);
-	}
-
-	rc = OCIAttrGet(bind[i].param, OCI_DTYPE_PARAM, (dvoid *)&(bind[i].data_type), (ub4 *)0, OCI_ATTR_DATA_TYPE, statement->conn->err);
-	if (rc) {
-	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
-	    luaL_error(L, "datatype get %s", errbuf);
-	}
-
-	rc = OCIAttrGet(bind[i].param, OCI_DTYPE_PARAM, (dvoid *)&(bind[i].max_len), 0, OCI_ATTR_DATA_SIZE, statement->conn->err);
-	if (rc) {
-	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
-	    luaL_error(L, "datasize get %s", errbuf);
-	}
-
-	bind[i].data = calloc(bind[i].max_len+1, sizeof(char));
-	rc = OCIDefineByPos(statement->stmt, &bind[i].define, statement->conn->err, (ub4)i+1, bind[i].data, bind[i].max_len, SQLT_STR, (dvoid *)&(bind[i].null), (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT);
-	if (rc) {
-	    OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
-	    luaL_error(L, "define by pos %s", errbuf);
-	}
-    }
-
     status = OCIStmtFetch(statement->stmt, statement->conn->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
 
     if (status == OCI_NO_DATA) {
@@ -451,6 +496,7 @@
     statement->stmt = stmt;
     statement->num_columns = 0;
     statement->bind = NULL;
+    statement->metadata = 0;
 
     luaL_getmetatable(L, DBD_ORACLE_STATEMENT);
     lua_setmetatable(L, -2);

mercurial