# HG changeset patch # User nrich@ii.net # Date 1244883344 0 # Node ID 999ef93f0dbc0e572ab33fc79aadf74b144ece48 # Parent 8599f34c139b715b9306b92a08b4c438117dfe53 * Add `columns' method for DB2 and Oracle statment handles * Misc cleanup diff -r 8599f34c139b -r 999ef93f0dbc dbd/common.c --- 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); diff -r 8599f34c139b -r 999ef93f0dbc dbd/db2/statement.c --- 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; } /* diff -r 8599f34c139b -r 999ef93f0dbc dbd/oracle/dbd_oracle.h --- 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; diff -r 8599f34c139b -r 999ef93f0dbc dbd/oracle/statement.c --- 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);