diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/common.c luadbi/dbd/common.c
--- lua-dbi-0.5/dbd/common.c 2009-06-13 04:50:59.000000000 -0400
+++ luadbi/dbd/common.c 2015-01-15 13:38:28.163032130 -0500
@@ -52,9 +52,12 @@
/*
* allocate a new string for the converted SQL statement
*/
- newsql = malloc(sizeof(char) * (len+extra_space+1));
- memset(newsql, 0, sizeof(char) * (len+extra_space+1));
-
+ newsql = calloc(len+extra_space+1, sizeof(char));
+ if(!newsql) {
+ lua_pushliteral(L, "out of memory");
+ return lua_error(L);
+ }
+
/*
* copy first char. In valid SQL this cannot be a placeholder
*/
diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/common.h luadbi/dbd/common.h
--- lua-dbi-0.5/dbd/common.h 2010-05-01 00:25:11.000000000 -0400
+++ luadbi/dbd/common.h 2015-01-15 13:38:28.163032130 -0500
@@ -39,6 +39,11 @@
lua_pushnumber(L, v); \
lua_rawset(L, -3);
+#define LUA_PUSH_ATTRIB_STRING_BY_LENGTH(n, v, len) \
+ lua_pushstring(L, n); \
+ lua_pushlstring(L, v, len); \
+ lua_rawset(L, -3);
+
#define LUA_PUSH_ATTRIB_STRING(n, v) \
lua_pushstring(L, n); \
lua_pushstring(L, v); \
@@ -71,6 +76,11 @@
lua_rawseti(L, -2, n); \
n++;
+#define LUA_PUSH_ARRAY_STRING_BY_LENGTH(n, v, len) \
+ lua_pushlstring(L, v, len); \
+ lua_rawseti(L, -2, n); \
+ n++;
+
#define LUA_PUSH_ARRAY_BOOL(n, v) \
lua_pushboolean(L, v); \
lua_rawseti(L, -2, n); \
diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/mysql/connection.c luadbi/dbd/mysql/connection.c
--- lua-dbi-0.5/dbd/mysql/connection.c 2010-05-01 00:25:12.000000000 -0400
+++ luadbi/dbd/mysql/connection.c 2015-01-15 13:38:28.171032087 -0500
@@ -16,7 +16,7 @@
const char *db = NULL;
int port = 0;
- const char *unix_socket = NULL; /* TODO always NULL */
+ const char *unix_socket = NULL;
int client_flag = 0; /* TODO always 0, set flags from options table */
/* db, user, password, host, port */
@@ -27,6 +27,10 @@
case 4:
if (lua_isnil(L, 4) == 0)
host = luaL_checkstring(L, 4);
+ if (host[0] == '/') {
+ unix_socket = host;
+ host = NULL;
+ };
case 3:
if (lua_isnil(L, 3) == 0)
password = luaL_checkstring(L, 3);
@@ -178,6 +182,16 @@
}
/*
+ * last_id = statement:last_id()
+ */
+static int connection_lastid(lua_State *L) {
+ connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION);
+
+ lua_pushinteger(L, mysql_insert_id( conn->mysql ));
+ return 1;
+}
+
+/*
* __gc
*/
static int connection_gc(lua_State *L) {
@@ -207,6 +221,7 @@
{"prepare", connection_prepare},
{"quote", connection_quote},
{"rollback", connection_rollback},
+ {"last_id", connection_lastid},
{NULL, NULL}
};
diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/mysql/dbd_mysql.h luadbi/dbd/mysql/dbd_mysql.h
--- lua-dbi-0.5/dbd/mysql/dbd_mysql.h 2010-05-01 00:25:12.000000000 -0400
+++ luadbi/dbd/mysql/dbd_mysql.h 2015-01-15 13:38:28.172032081 -0500
@@ -22,6 +22,10 @@
typedef struct _statement {
MYSQL *mysql;
MYSQL_STMT *stmt;
- MYSQL_RES *metadata; /* result dataset metadata */
+ MYSQL_RES *metadata; /* result dataset metadata */
+
+ unsigned long *lengths; /* length of retrieved data
+ we have to keep this from bind time to
+ result retrival time */
} statement_t;
diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/mysql/statement.c luadbi/dbd/mysql/statement.c
--- lua-dbi-0.5/dbd/mysql/statement.c 2010-05-21 18:49:59.000000000 -0400
+++ luadbi/dbd/mysql/statement.c 2015-01-15 13:38:28.173032076 -0500
@@ -11,10 +11,12 @@
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_SHORT:
- case MYSQL_TYPE_LONG:
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_LONG:
lua_type = LUA_PUSH_INTEGER;
break;
+ case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_LONGLONG:
lua_type = LUA_PUSH_NUMBER;
@@ -89,13 +91,18 @@
statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT);
if (statement->metadata) {
- mysql_free_result(statement->metadata);
- statement->metadata = NULL;
+ mysql_free_result(statement->metadata);
+ statement->metadata = NULL;
}
+ if (statement->lengths) {
+ free(statement->lengths);
+ statement->lengths = NULL;
+ }
+
if (statement->stmt) {
- mysql_stmt_close(statement->stmt);
- statement->stmt = NULL;
+ mysql_stmt_close(statement->stmt);
+ statement->stmt = NULL;
}
lua_pushboolean(L, 1);
@@ -286,7 +293,7 @@
}
static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) {
- int column_count;
+ int column_count, fetch_result_ok;
MYSQL_BIND *bind = NULL;
const char *error_message = NULL;
@@ -306,6 +313,13 @@
int i;
MYSQL_FIELD *fields;
+ if (statement->lengths) {
+ free(statement->lengths);
+ statement->lengths = NULL;
+ }
+
+ statement->lengths = calloc(column_count, sizeof(unsigned long));
+
bind = malloc(sizeof(MYSQL_BIND) * column_count);
memset(bind, 0, sizeof(MYSQL_BIND) * column_count);
@@ -313,12 +327,19 @@
for (i = 0; i < column_count; i++) {
unsigned int length = mysql_buffer_size(&fields[i]);
- char *buffer = (char *)malloc(length);
- memset(buffer, 0, length);
+ 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].buffer = buffer;
- bind[i].buffer_length = length;
+ bind[i].length = &(statement->lengths[i]);
}
if (mysql_stmt_bind_result(statement->stmt, bind)) {
@@ -326,7 +347,8 @@
goto cleanup;
}
- if (!mysql_stmt_fetch(statement->stmt)) {
+ 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);
@@ -334,6 +356,13 @@
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(statement->lengths[i]+1, sizeof(char));
+ bind[i].buffer = buffer;
+ bind[i].buffer_length = statement->lengths[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);
@@ -361,11 +390,25 @@
}
}
} 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));
- }
+ if (fields[i].type == MYSQL_TYPE_FLOAT) {
+ if (named_columns) {
+ LUA_PUSH_ATTRIB_FLOAT(name, *(float *)(bind[i].buffer));
+ } else {
+ LUA_PUSH_ARRAY_FLOAT(d, *(float *)(bind[i].buffer));
+ }
+ } else if (fields[i].type == MYSQL_TYPE_DOUBLE) {
+ if (named_columns) {
+ LUA_PUSH_ATTRIB_FLOAT(name, *(double *)(bind[i].buffer));
+ } else {
+ LUA_PUSH_ARRAY_FLOAT(d, *(double *)(bind[i].buffer));
+ }
+ } else {
+ if (named_columns) {
+ LUA_PUSH_ATTRIB_FLOAT(name, *(long long *)(bind[i].buffer));
+ } else {
+ LUA_PUSH_ARRAY_FLOAT(d, *(long long *)(bind[i].buffer));
+ }
+ }
} else if (lua_push == LUA_PUSH_STRING) {
if (fields[i].type == MYSQL_TYPE_TIMESTAMP || fields[i].type == MYSQL_TYPE_DATETIME) {
@@ -404,9 +447,9 @@
} else {
if (named_columns) {
- LUA_PUSH_ATTRIB_STRING(name, bind[i].buffer);
+ LUA_PUSH_ATTRIB_STRING_BY_LENGTH(name, bind[i].buffer, *bind[i].length);
} else {
- LUA_PUSH_ARRAY_STRING(d, bind[i].buffer);
+ LUA_PUSH_ARRAY_STRING_BY_LENGTH(d, bind[i].buffer, *bind[i].length);
}
}
} else if (lua_push == LUA_PUSH_BOOLEAN) {
@@ -425,6 +468,7 @@
}
cleanup:
+
if (bind) {
int i;
@@ -535,6 +579,7 @@
statement->mysql = conn->mysql;
statement->stmt = stmt;
statement->metadata = NULL;
+ statement->lengths = NULL;
/*
mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (my_bool*)0);
diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/postgresql/connection.c luadbi/dbd/postgresql/connection.c
--- lua-dbi-0.5/dbd/postgresql/connection.c 2010-05-01 00:25:12.000000000 -0400
+++ luadbi/dbd/postgresql/connection.c 2015-01-15 13:38:28.176032059 -0500
@@ -109,10 +109,12 @@
int err = 0;
if (conn->postgresql) {
- if (on)
- err = rollback(conn);
- else
- err = begin(conn);
+ if (on != conn->autocommit) {
+ if (on)
+ err = rollback(conn);
+ else
+ err = begin(conn);
+ }
conn->autocommit = on;
}
diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/postgresql/dbd_postgresql.h luadbi/dbd/postgresql/dbd_postgresql.h
--- lua-dbi-0.5/dbd/postgresql/dbd_postgresql.h 2010-05-01 00:25:12.000000000 -0400
+++ luadbi/dbd/postgresql/dbd_postgresql.h 2015-01-15 13:38:28.176032059 -0500
@@ -1,5 +1,4 @@
#include <libpq-fe.h>
-#include <postgres_fe.h>
#include <dbd/common.h>
/*
diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/sqlite3/connection.c luadbi/dbd/sqlite3/connection.c
--- lua-dbi-0.5/dbd/sqlite3/connection.c 2010-05-01 00:25:12.000000000 -0400
+++ luadbi/dbd/sqlite3/connection.c 2015-01-15 13:38:28.178032048 -0500
@@ -9,19 +9,33 @@
}
static int commit(connection_t *conn) {
- return run(conn, "COMMIT");
+ return run(conn, "COMMIT TRANSACTION");
}
static int begin(connection_t *conn) {
- return run(conn, "BEGIN");
-}
+ int err = 0;
+ if (sqlite3_get_autocommit(conn->sqlite)) {
+ err = run(conn, "BEGIN TRANSACTION");
+ } else {
+ err = 0;
+ }
+
+ return err;
+}
static int rollback(connection_t *conn) {
- return run(conn, "ROLLBACK");
+ return run(conn, "ROLLBACK TRANSACTION");
}
+int try_begin_transaction(connection_t *conn) {
+ if (conn->autocommit) {
+ return 1;
+ }
+
+ return begin(conn) == 0;
+}
/*
* connection,err = DBD.SQLite3.New(dbfile)
@@ -50,7 +64,6 @@
}
conn->autocommit = 0;
- begin(conn);
luaL_getmetatable(L, DBD_SQLITE_CONNECTION);
lua_setmetatable(L, -2);
@@ -67,10 +80,9 @@
int err = 1;
if (conn->sqlite) {
- if (on)
+ if (on) {
err = rollback(conn);
- else
- err = begin(conn);
+ }
conn->autocommit = on;
}
@@ -88,6 +100,7 @@
int disconnect = 0;
if (conn->sqlite) {
+ rollback(conn);
sqlite3_close(conn->sqlite);
disconnect = 1;
conn->sqlite = NULL;
@@ -105,12 +118,7 @@
int err = 1;
if (conn->sqlite) {
- commit(conn);
-
- if (!conn->autocommit)
- err = begin(conn);
- else
- err = 1;
+ err = commit(conn);
}
lua_pushboolean(L, !err);
@@ -176,12 +184,7 @@
int err = 1;
if (conn->sqlite) {
- rollback(conn);
-
- if (!conn->autocommit)
- err = begin(conn);
- else
- err = 1;
+ err =rollback(conn);
}
lua_pushboolean(L, !err);
diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/sqlite3/dbd_sqlite3.h luadbi/dbd/sqlite3/dbd_sqlite3.h
--- lua-dbi-0.5/dbd/sqlite3/dbd_sqlite3.h 2008-12-19 01:33:32.000000000 -0500
+++ luadbi/dbd/sqlite3/dbd_sqlite3.h 2015-01-15 13:38:28.178032048 -0500
@@ -10,14 +10,15 @@
typedef struct _connection {
sqlite3 *sqlite;
int autocommit;
+// int txn_in_progress;
} connection_t;
/*
* statement object
*/
typedef struct _statement {
+ connection_t *conn;
sqlite3_stmt *stmt;
- sqlite3 *sqlite;
int more_data;
int affected;
} statement_t;
diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/sqlite3/statement.c luadbi/dbd/sqlite3/statement.c
--- lua-dbi-0.5/dbd/sqlite3/statement.c 2010-05-01 00:25:12.000000000 -0400
+++ luadbi/dbd/sqlite3/statement.c 2015-01-15 13:38:28.179032043 -0500
@@ -1,5 +1,8 @@
#include "dbd_sqlite3.h"
+extern int try_begin_transaction(connection_t *conn);
+extern int try_end_transaction(connection_t *conn);
+
/*
* Converts SQLite types to Lua types
*/
@@ -128,10 +131,12 @@
*/
if (sqlite3_reset(statement->stmt) != SQLITE_OK) {
lua_pushboolean(L, 0);
- lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->sqlite));
+ lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->conn->sqlite));
return 2;
}
+ sqlite3_clear_bindings(statement->stmt);
+
expected_params = sqlite3_bind_parameter_count(statement->stmt);
if (expected_params != num_bind_params) {
/*
@@ -156,10 +161,13 @@
case LUA_TNUMBER:
errflag = sqlite3_bind_double(statement->stmt, i, lua_tonumber(L, p)) != SQLITE_OK;
break;
- case LUA_TSTRING:
- errflag = sqlite3_bind_text(statement->stmt, i, lua_tostring(L, p), -1, SQLITE_STATIC) != SQLITE_OK;
+ case LUA_TSTRING: {
+ size_t len = -1;
+ const char *str = lua_tolstring(L, p, &len);
+ errflag = sqlite3_bind_text(statement->stmt, i, str, len, SQLITE_STATIC) != SQLITE_OK;
break;
- case LUA_TBOOLEAN:
+ }
+ case LUA_TBOOLEAN:
errflag = sqlite3_bind_int(statement->stmt, i, lua_toboolean(L, p)) != SQLITE_OK;
break;
default:
@@ -180,18 +188,20 @@
if (errstr)
lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr);
else
- lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, sqlite3_errmsg(statement->sqlite));
+ lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, sqlite3_errmsg(statement->conn->sqlite));
return 2;
}
+
+ try_begin_transaction(statement->conn);
if (!step(statement)) {
lua_pushboolean(L, 0);
- lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->sqlite));
+ lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->conn->sqlite));
return 2;
}
- statement->affected = sqlite3_changes(statement->sqlite);
+ statement->affected = sqlite3_changes(statement->conn->sqlite);
lua_pushboolean(L, 1);
return 1;
@@ -283,7 +293,7 @@
/*
* reset needs to be called to retrieve the 'real' error message
*/
- luaL_error(L, DBI_ERR_FETCH_FAILED, sqlite3_errmsg(statement->sqlite));
+ luaL_error(L, DBI_ERR_FETCH_FAILED, sqlite3_errmsg(statement->conn->sqlite));
}
}
@@ -327,9 +337,9 @@
* num_rows = statement:rowcount()
*/
static int statement_rowcount(lua_State *L) {
- luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_SQLITE_STATEMENT, "rowcount");
-
- return 0;
+ statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT);
+ lua_pushinteger(L, sqlite3_data_count(statement->stmt));
+ return 1;
}
/*
@@ -357,14 +367,14 @@
statement_t *statement = NULL;
statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t));
- statement->sqlite = conn->sqlite;
+ statement->conn = conn;
statement->stmt = NULL;
statement->more_data = 0;
statement->affected = 0;
- if (sqlite3_prepare_v2(statement->sqlite, sql_query, strlen(sql_query), &statement->stmt, NULL) != SQLITE_OK) {
+ if (sqlite3_prepare_v2(statement->conn->sqlite, sql_query, strlen(sql_query), &statement->stmt, NULL) != SQLITE_OK) {
lua_pushnil(L);
- lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, sqlite3_errmsg(statement->sqlite));
+ lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, sqlite3_errmsg(statement->conn->sqlite));
return 2;
}