/* * must be called after an execute */ static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { int i; int d; SQLCHAR message[SQL_MAX_MESSAGE_LENGTH + 1]; SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1]; SQLINTEGER sqlcode; SQLSMALLINT length; SQLRETURN rc = SQL_SUCCESS; if (!statement->resultset || !statement->bind) { lua_pushnil(L); return 1; } /* fetch each row, and display */ rc = SQLFetch(statement->stmt); if (rc == SQL_NO_DATA_FOUND) { SQLFreeStmt(statement->stmt, SQL_RESET_PARAMS); lua_pushnil(L); return 1; } if (rc != SQL_SUCCESS) { SQLGetDiagRec(SQL_HANDLE_STMT, statement->stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); luaL_error(L, DBI_ERR_FETCH_FAILED, message); } d = 1; lua_newtable(L); for (i = 0; i < statement->num_result_columns; i++) { lua_push_type_t lua_push = db2_to_lua_push(statement->resultset[i].type, statement->bind[i].len); const char *name = strlower(statement->resultset[i].name); double val; char *value = (char *)statement->bind[i].buffer; switch (lua_push) { case LUA_PUSH_NIL: if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } break; case LUA_PUSH_INTEGER: if (named_columns) { LUA_PUSH_ATTRIB_INT(name, atoi(value)); } else { LUA_PUSH_ARRAY_INT(d, atoi(value)); } break; case LUA_PUSH_NUMBER: val = strtod(value, NULL); if (named_columns) { LUA_PUSH_ATTRIB_FLOAT(name, val); } else { LUA_PUSH_ARRAY_FLOAT(d, val); } break; case LUA_PUSH_BOOLEAN: if (named_columns) { LUA_PUSH_ATTRIB_BOOL(name, atoi(value)); } else { LUA_PUSH_ARRAY_BOOL(d, atoi(value)); } break; case LUA_PUSH_STRING: if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, value); } else { LUA_PUSH_ARRAY_STRING(d, value); } break; default: luaL_error(L, DBI_ERR_UNKNOWN_PUSH); } } return 1; }
/* * must be called after an execute */ static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { int rc; sword status; int i; bindparams_t *bind; char errbuf[100]; int errcode; if (!statement->stmt) { luaL_error(L, DBI_ERR_FETCH_INVALID); return 0; } statement_fetch_metadata(L, statement); bind = statement->bind; status = OCIStmtFetch(statement->stmt, statement->conn->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT); if (status == OCI_NO_DATA) { /* No more rows */ lua_pushnil(L); return 1; } else if (status != OCI_SUCCESS) { OCIErrorGet((dvoid *)statement->conn->err, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); luaL_error(L, DBI_ERR_FETCH_FAILED, errbuf); } if (statement->num_columns) { int i; int d = 1; lua_newtable(L); for (i = 0; i < statement->num_columns; i++) { lua_push_type_t lua_push = oracle_to_lua_push(bind[i].data_type, bind[i].null); const char *name = strlower(bind[i].name); const char *data = bind[i].data; if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } } else if (lua_push == LUA_PUSH_INTEGER) { int val = atoi(data); if (named_columns) { LUA_PUSH_ATTRIB_INT(name, val); } else { LUA_PUSH_ARRAY_INT(d, val); } } else if (lua_push == LUA_PUSH_NUMBER) { double val = strtod(data, NULL); if (named_columns) { LUA_PUSH_ATTRIB_FLOAT(name, val); } else { LUA_PUSH_ARRAY_FLOAT(d, val); } } else if (lua_push == LUA_PUSH_STRING) { if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, data); } else { LUA_PUSH_ARRAY_STRING(d, data); } } else if (lua_push == LUA_PUSH_BOOLEAN) { int val = atoi(data); if (named_columns) { LUA_PUSH_ATTRIB_BOOL(name, val); } else { LUA_PUSH_ARRAY_BOOL(d, val); } } else { luaL_error(L, DBI_ERR_UNKNOWN_PUSH); } } } else { /* * no columns returned by statement? */ lua_pushnil(L); } return 1; }
static int statement_fetch_impl (lua_State * L, statement_t * statement, /* {{{ */ int named_columns) { int column_count, fetch_result_ok; MYSQL_BIND *bind = NULL; unsigned long *real_length = NULL; const char *error_message = NULL; if (!statement->stmt) { luaL_error (L, DBI_ERR_FETCH_INVALID); return 0; } if (!statement->metadata) { luaL_error (L, DBI_ERR_FETCH_NO_EXECUTE); return 0; } column_count = mysql_num_fields (statement->metadata); if (column_count > 0) { int i; MYSQL_FIELD *fields; real_length = calloc (column_count, sizeof (unsigned long)); bind = malloc (sizeof (MYSQL_BIND) * column_count); memset (bind, 0, sizeof (MYSQL_BIND) * column_count); fields = mysql_fetch_fields (statement->metadata); for (i = 0; i < column_count; i++) { unsigned int length = mysql_buffer_size (&fields[i]); if (length > sizeof (MYSQL_TIME)) { bind[i].buffer = NULL; bind[i].buffer_length = 0; } else { char *buffer = (char *) malloc (length); memset (buffer, 0, length); bind[i].buffer = buffer; bind[i].buffer_length = length; } bind[i].buffer_type = fields[i].type; bind[i].length = &real_length[i]; } if (mysql_stmt_bind_result (statement->stmt, bind)) { error_message = DBI_ERR_BINDING_RESULTS; goto cleanup; } fetch_result_ok = mysql_stmt_fetch (statement->stmt); if (fetch_result_ok == 0 || fetch_result_ok == MYSQL_DATA_TRUNCATED) { int d = 1; lua_newtable (L); for (i = 0; i < column_count; i++) { lua_push_type_t lua_push = mysql_to_lua_push (fields[i].type); const char *name = fields[i].name; if (bind[i].buffer == NULL) { char *buffer = (char *) calloc (real_length[i] + 1, sizeof (char)); bind[i].buffer = buffer; bind[i].buffer_length = real_length[i]; mysql_stmt_fetch_column (statement->stmt, &bind[i], i, 0); } if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL (name); } else { LUA_PUSH_ARRAY_NIL (d); } } else if (lua_push == LUA_PUSH_INTEGER) { if (fields[i].type == MYSQL_TYPE_YEAR || fields[i].type == MYSQL_TYPE_SHORT) { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, *(short *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, *(short *) (bind[i].buffer)); } } else if (fields[i].type == MYSQL_TYPE_TINY) { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, (int) *(char *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, (int) *(char *) (bind[i].buffer)); } } else { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, *(int *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, *(int *) (bind[i].buffer)); } } } else if (lua_push == LUA_PUSH_NUMBER) { if (named_columns) { LUA_PUSH_ATTRIB_FLOAT (name, *(double *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_FLOAT (d, *(double *) (bind[i].buffer)); } } else if (lua_push == LUA_PUSH_STRING) { if (fields[i].type == MYSQL_TYPE_TIMESTAMP || fields[i].type == MYSQL_TYPE_DATETIME) { char str[20]; struct st_mysql_time *t = bind[i].buffer; snprintf (str, 20, "%d-%02d-%02d %02d:%02d:%02d", t->year, t->month, t->day, t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else if (fields[i].type == MYSQL_TYPE_TIME) { char str[9]; struct st_mysql_time *t = bind[i].buffer; snprintf (str, 9, "%02d:%02d:%02d", t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else if (fields[i].type == MYSQL_TYPE_DATE) { char str[20]; struct st_mysql_time *t = bind[i].buffer; snprintf (str, 11, "%d-%02d-%02d", t->year, t->month, t->day); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else { if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, bind[i].buffer); } else { LUA_PUSH_ARRAY_STRING (d, bind[i].buffer); } } } else if (lua_push == LUA_PUSH_BOOLEAN) { if (named_columns) { LUA_PUSH_ATTRIB_BOOL (name, *(int *) (bind[i].buffer)); } else { LUA_PUSH_ARRAY_BOOL (d, *(int *) (bind[i].buffer)); } } else { luaL_error (L, DBI_ERR_UNKNOWN_PUSH); } } } else { lua_pushnil (L); } } cleanup: free (real_length); if (bind) { int i; for (i = 0; i < column_count; i++) { free (bind[i].buffer); } free (bind); } if (error_message) { luaL_error (L, error_message, mysql_stmt_error (statement->stmt)); return 0; } return 1; } /* }}} */
static int statement_fetch_impl_cont (lua_State * L, statement_t * statement, /* {{{ */ int event, int named_columns) { int column_count; unsigned long *real_length = NULL; int values = 0; column_count = mysql_num_fields (statement->metadata); if (column_count > 0) { int i; real_length = calloc (column_count, sizeof (unsigned long)); statement->event = mysql_stmt_fetch_cont (&(statement->ret), statement->stmt, event); if (statement->event & MYSQL_WAIT_EXCEPT) { lua_pushnil (L); lua_pushfstring (L, mysql_stmt_error (statement->stmt)); values = 2; } if (statement->event & MYSQL_WAIT_TIMEOUT) { statement->timeout = 1000 * mysql_get_timeout_value_ms (statement->mysql); } /* Pretty sure statement->ret should be the return value, but it seems to return 1 */ /* using mysql_stmt_errno instead */ if (mysql_stmt_errno (statement->stmt) != 0) { lua_pushnil (L); lua_pushstring (L, mysql_stmt_error (statement->stmt)); values = 2; } if (statement->event > 0) { lua_pushboolean (L, 0); lua_pushnumber (L, convert_mysql_to_ev (statement->event)); values = 2; } if (mysql_stmt_errno (statement->stmt) == 0 || statement->ret == MYSQL_DATA_TRUNCATED) { int d = 1; lua_pushboolean (L, 1); lua_newtable (L); values = 2; for (i = 0; i < column_count; i++) { lua_push_type_t lua_push = mysql_to_lua_push (statement->fields[i].type); const char *name = statement->fields[i].name; if (statement->bind[i].buffer == NULL) { char *buffer = (char *) calloc (real_length[i] + 1, sizeof (char)); statement->bind[i].buffer = buffer; statement->bind[i].buffer_length = real_length[i]; mysql_stmt_fetch_column (statement->stmt, &(statement->bind[i]), i, 0); } if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL (name); } else { LUA_PUSH_ARRAY_NIL (d); } } else if (lua_push == LUA_PUSH_INTEGER) { if (statement->fields[i].type == MYSQL_TYPE_YEAR || statement->fields[i].type == MYSQL_TYPE_SHORT) { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, *(short *) (statement-> bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, *(short *) (statement-> bind[i].buffer)); } } else if (statement->fields[i].type == MYSQL_TYPE_TINY) { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, (int) *(char *) (statement->bind [i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, (int) *(char *) (statement->bind [i].buffer)); } } else { if (named_columns) { LUA_PUSH_ATTRIB_INT (name, *(int *) (statement-> bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT (d, *(int *) (statement-> bind[i].buffer)); } } } else if (lua_push == LUA_PUSH_NUMBER) { if (named_columns) { LUA_PUSH_ATTRIB_FLOAT (name, *(double *) (statement-> bind[i].buffer)); } else { LUA_PUSH_ARRAY_FLOAT (d, *(double *) (statement->bind[i].buffer)); } } else if (lua_push == LUA_PUSH_STRING) { if (statement->fields[i].type == MYSQL_TYPE_TIMESTAMP || statement->fields[i].type == MYSQL_TYPE_DATETIME) { char str[20]; struct st_mysql_time *t = statement->bind[i].buffer; snprintf (str, 20, "%d-%02d-%02d %02d:%02d:%02d", t->year, t->month, t->day, t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else if (statement->fields[i].type == MYSQL_TYPE_TIME) { char str[9]; struct st_mysql_time *t = statement->bind[i].buffer; snprintf (str, 9, "%02d:%02d:%02d", t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else if (statement->fields[i].type == MYSQL_TYPE_DATE) { char str[20]; struct st_mysql_time *t = statement->bind[i].buffer; snprintf (str, 11, "%d-%02d-%02d", t->year, t->month, t->day); if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, str); } else { LUA_PUSH_ARRAY_STRING (d, str); } } else { if (named_columns) { LUA_PUSH_ATTRIB_STRING (name, statement->bind[i].buffer); } else { LUA_PUSH_ARRAY_STRING (d, statement->bind[i].buffer); } } } else if (lua_push == LUA_PUSH_BOOLEAN) { if (named_columns) { LUA_PUSH_ATTRIB_BOOL (name, *(int *) (statement-> bind[i].buffer)); } else { LUA_PUSH_ARRAY_BOOL (d, *(int *) (statement-> bind[i].buffer)); } } else { luaL_error (L, DBI_ERR_UNKNOWN_PUSH); values = 1; } } } else { lua_pushnil (L); values = 1; } } if (statement->bind) { int i; for (i = 0; i < column_count; i++) { free (statement->bind[i].buffer); } free (statement->bind); } return values; } /* }}} */
/* * must be called after an execute */ static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { int num_columns; if (!statement->stmt) { luaL_error(L, DBI_ERR_FETCH_INVALID); return 0; } if (!statement->more_data) { /* * Result set is empty, or not result set returned */ lua_pushnil(L); return 1; } num_columns = sqlite3_column_count(statement->stmt); if (num_columns) { int i; int d = 1; lua_newtable(L); for (i = 0; i < num_columns; i++) { lua_push_type_t lua_push = sqlite_to_lua_push(sqlite3_column_type(statement->stmt, i)); const char *name = sqlite3_column_name(statement->stmt, i); if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } } else if (lua_push == LUA_PUSH_INTEGER) { int val = sqlite3_column_int(statement->stmt, i); if (named_columns) { LUA_PUSH_ATTRIB_INT(name, val); } else { LUA_PUSH_ARRAY_INT(d, val); } } else if (lua_push == LUA_PUSH_NUMBER) { double val = sqlite3_column_double(statement->stmt, i); if (named_columns) { LUA_PUSH_ATTRIB_FLOAT(name, val); } else { LUA_PUSH_ARRAY_FLOAT(d, val); } } else if (lua_push == LUA_PUSH_STRING) { const char *val = (const char *)sqlite3_column_text(statement->stmt, i); if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, val); } else { LUA_PUSH_ARRAY_STRING(d, val); } } else if (lua_push == LUA_PUSH_BOOLEAN) { int val = sqlite3_column_int(statement->stmt, i); if (named_columns) { LUA_PUSH_ATTRIB_BOOL(name, val); } else { LUA_PUSH_ARRAY_BOOL(d, val); } } else { luaL_error(L, DBI_ERR_UNKNOWN_PUSH); } } } else { /* * no columns returned by statement? */ lua_pushnil(L); } if (step(statement) == 0) { if (sqlite3_reset(statement->stmt) != SQLITE_OK) { /* * reset needs to be called to retrieve the 'real' error message */ luaL_error(L, DBI_ERR_FETCH_FAILED, sqlite3_errmsg(statement->conn->sqlite)); } } return 1; }
static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { int column_count; MYSQL_BIND *bind = NULL; const char *error_message = NULL; if (!statement->stmt) { luaL_error(L, DBI_ERR_FETCH_INVALID); return 0; } if (!statement->metadata) { luaL_error(L, DBI_ERR_FETCH_NO_EXECUTE); return 0; } column_count = mysql_num_fields(statement->metadata); if (column_count > 0) { int i; MYSQL_FIELD *fields; bind = malloc(sizeof(MYSQL_BIND) * column_count); memset(bind, 0, sizeof(MYSQL_BIND) * column_count); fields = mysql_fetch_fields(statement->metadata); for (i = 0; i < column_count; i++) { unsigned int length = mysql_buffer_size(&fields[i]); char *buffer = (char *) malloc(length); memset(buffer, 0, length); bind[i].buffer_type = fields[i].type; bind[i].buffer = buffer; bind[i].buffer_length = length; } if (mysql_stmt_bind_result(statement->stmt, bind)) { error_message = DBI_ERR_BINDING_RESULTS; goto cleanup; } if (!mysql_stmt_fetch(statement->stmt)) { int d = 1; lua_newtable(L); for (i = 0; i < column_count; i++) { lua_push_type_t lua_push = mysql_to_lua_push(fields[i].type); const char *name = fields[i].name; if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } } else if (lua_push == LUA_PUSH_INTEGER) { if (fields[i].type == MYSQL_TYPE_YEAR || fields[i].type == MYSQL_TYPE_SHORT) { if (named_columns) { LUA_PUSH_ATTRIB_INT(name, *(short *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT(d, *(short *)(bind[i].buffer)); } } else if (fields[i].type == MYSQL_TYPE_TINY) { if (named_columns) { LUA_PUSH_ATTRIB_INT(name, (int)*(char *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT(d, (int)*(char *)(bind[i].buffer)); } } else { if (named_columns) { LUA_PUSH_ATTRIB_INT(name, *(int *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT(d, *(int *)(bind[i].buffer)); } } } else if (lua_push == LUA_PUSH_NUMBER) { if (named_columns) { LUA_PUSH_ATTRIB_FLOAT(name, *(double *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_FLOAT(d, *(double *)(bind[i].buffer)); } } else if (lua_push == LUA_PUSH_STRING) { if (fields[i].type == MYSQL_TYPE_TIMESTAMP || fields[i].type == MYSQL_TYPE_DATETIME) { char str[20]; struct st_mysql_time *t = bind[i].buffer; snprintf(str, 20, "%d-%02d-%02d %02d:%02d:%02d", t->year, t->month, t->day, t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, str); } else { LUA_PUSH_ARRAY_STRING(d, str); } } else if (fields[i].type == MYSQL_TYPE_TIME) { char str[9]; struct st_mysql_time *t = bind[i].buffer; snprintf(str, 9, "%02d:%02d:%02d", t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, str); } else { LUA_PUSH_ARRAY_STRING(d, str); } } else if (fields[i].type == MYSQL_TYPE_DATE) { char str[20]; struct st_mysql_time *t = bind[i].buffer; snprintf(str, 11, "%d-%02d-%02d", t->year, t->month, t->day); if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, str); } else { LUA_PUSH_ARRAY_STRING(d, str); } } else { size_t length = bind[i].buffer_length; // // hack for strings. have no idea what 8 means but it is different from value for binary blobs, which is good enough // if (fields[i].charsetnr == 8) { length = min(bind[i].buffer_length, strlen(bind[i].buffer)); } if (named_columns) { LUA_PUSH_ATTRIB_LSTRING(name, bind[i].buffer, length); } else { LUA_PUSH_ARRAY_LSTRING(d, bind[i].buffer, length); } } } else if (lua_push == LUA_PUSH_BOOLEAN) { if (named_columns) { LUA_PUSH_ATTRIB_BOOL(name, *(int *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_BOOL(d, *(int *)(bind[i].buffer)); } } else { luaL_error(L, DBI_ERR_UNKNOWN_PUSH); } } } else { lua_pushnil(L); } } cleanup: if (bind) { int i; for (i = 0; i < column_count; i++) { free(bind[i].buffer); } free(bind); } if (error_message) { luaL_error(L, error_message, mysql_stmt_error(statement->stmt)); return 0; } return 1; }