static int statement_fetch_impl_start (lua_State * L, statement_t * statement) /* {{{ */ { int column_count; 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; real_length = calloc (column_count, sizeof (unsigned long)); statement->bind = malloc (sizeof (MYSQL_BIND) * column_count); memset (statement->bind, 0, sizeof (MYSQL_BIND) * column_count); statement->fields = mysql_fetch_fields (statement->metadata); for (i = 0; i < column_count; i++) { unsigned int length = mysql_buffer_size (&statement->fields[i]); if (length > sizeof (MYSQL_TIME)) { statement->bind[i].buffer = NULL; statement->bind[i].buffer_length = 0; } else { char *buffer = (char *) malloc (length); memset (buffer, 0, length); statement->bind[i].buffer = buffer; statement->bind[i].buffer_length = length; } statement->bind[i].buffer_type = statement->fields[i].type; statement->bind[i].length = &real_length[i]; } if (mysql_stmt_bind_result (statement->stmt, statement->bind)) { error_message = DBI_ERR_BINDING_RESULTS; goto cleanup; } statement->event = mysql_stmt_fetch_start (&(statement->ret), statement->stmt); if (statement->event & MYSQL_WAIT_EXCEPT) { lua_pushnil (L); return 1; } if (statement->event & MYSQL_WAIT_TIMEOUT) { statement->timeout = 1000 * mysql_get_timeout_value_ms (statement->mysql); } lua_pushboolean (L, 1); lua_pushnumber (L, statement->event); return 2; } else { lua_pushnil (L); return 1; } cleanup: free (real_length); if (statement->bind) { int i; for (i = 0; i < column_count; i++) { free (statement->bind[i].buffer); } free (statement->bind); } if (error_message) { luaL_error (L, error_message, mysql_stmt_error (statement->stmt)); return 0; } 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(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; }