Mon, 20 Dec 2010 23:03:00 +0000
Use SQLite built in mechanism for tracking transactions
1 | 1 | #include "dbd_sqlite3.h" |
2 | ||
3 | int dbd_sqlite3_statement_create(lua_State *L, connection_t *conn, const char *sql_query); | |
4 | ||
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
5 | static int run(connection_t *conn, const char *command) { |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
6 | int res = sqlite3_exec(conn->sqlite, command, NULL, NULL, NULL); |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
7 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
8 | return res != SQLITE_OK; |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
9 | } |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
10 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
11 | static int commit(connection_t *conn) { |
41 | 12 | return run(conn, "COMMIT TRANSACTION"); |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
13 | } |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
14 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
15 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
16 | static int begin(connection_t *conn) { |
41 | 17 | int err = 0; |
18 | ||
43
356dcb1d455c
Use SQLite built in mechanism for tracking transactions
nrich@ii.net
parents:
42
diff
changeset
|
19 | if (sqlite3_get_autocommit(conn->sqlite)) { |
356dcb1d455c
Use SQLite built in mechanism for tracking transactions
nrich@ii.net
parents:
42
diff
changeset
|
20 | err = run(conn, "BEGIN TRANSACTION"); |
41 | 21 | } else { |
43
356dcb1d455c
Use SQLite built in mechanism for tracking transactions
nrich@ii.net
parents:
42
diff
changeset
|
22 | err = 0; |
41 | 23 | } |
24 | ||
25 | return err; | |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
26 | } |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
27 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
28 | static int rollback(connection_t *conn) { |
41 | 29 | return run(conn, "ROLLBACK TRANSACTION"); |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
30 | } |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
31 | |
41 | 32 | int try_begin_transaction(connection_t *conn) { |
33 | if (conn->autocommit) { | |
34 | return 1; | |
35 | } | |
36 | ||
37 | return begin(conn) == 0; | |
38 | } | |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
39 | |
2 | 40 | /* |
3 | 41 | * connection,err = DBD.SQLite3.New(dbfile) |
2 | 42 | */ |
1 | 43 | static int connection_new(lua_State *L) { |
44 | int n = lua_gettop(L); | |
45 | ||
46 | const char *db = NULL; | |
47 | connection_t *conn = NULL; | |
48 | ||
49 | /* db */ | |
9 | 50 | switch(n) { |
51 | default: | |
14 | 52 | /* |
53 | * db is the only mandatory parameter | |
54 | */ | |
55 | db = luaL_checkstring(L, 1); | |
1 | 56 | } |
57 | ||
58 | conn = (connection_t *)lua_newuserdata(L, sizeof(connection_t)); | |
59 | ||
3 | 60 | if (sqlite3_open(db, &conn->sqlite) != SQLITE_OK) { |
1 | 61 | lua_pushnil(L); |
4 | 62 | lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, sqlite3_errmsg(conn->sqlite)); |
3 | 63 | return 2; |
1 | 64 | } |
65 | ||
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
66 | conn->autocommit = 0; |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
67 | |
3 | 68 | luaL_getmetatable(L, DBD_SQLITE_CONNECTION); |
69 | lua_setmetatable(L, -2); | |
70 | ||
1 | 71 | return 1; |
72 | } | |
73 | ||
2 | 74 | /* |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
75 | * success = connection:autocommit(on) |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
76 | */ |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
77 | static int connection_autocommit(lua_State *L) { |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
78 | connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
79 | int on = lua_toboolean(L, 2); |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
80 | int err = 1; |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
81 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
82 | if (conn->sqlite) { |
41 | 83 | if (on) { |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
84 | err = rollback(conn); |
41 | 85 | } |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
86 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
87 | conn->autocommit = on; |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
88 | } |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
89 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
90 | lua_pushboolean(L, !err); |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
91 | return 1; |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
92 | } |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
93 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
94 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
95 | /* |
2 | 96 | * success = connection:close() |
97 | */ | |
1 | 98 | static int connection_close(lua_State *L) { |
99 | connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); | |
100 | int disconnect = 0; | |
101 | ||
102 | if (conn->sqlite) { | |
41 | 103 | rollback(conn); |
3 | 104 | sqlite3_close(conn->sqlite); |
105 | disconnect = 1; | |
106 | conn->sqlite = NULL; | |
1 | 107 | } |
108 | ||
109 | lua_pushboolean(L, disconnect); | |
110 | return 1; | |
111 | } | |
112 | ||
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
113 | /* |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
114 | * success = connection:commit() |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
115 | */ |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
116 | static int connection_commit(lua_State *L) { |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
117 | connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
118 | int err = 1; |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
119 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
120 | if (conn->sqlite) { |
41 | 121 | err = commit(conn); |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
122 | } |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
123 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
124 | lua_pushboolean(L, !err); |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
125 | return 1; |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
126 | } |
3 | 127 | |
2 | 128 | /* |
129 | * ok = connection:ping() | |
130 | */ | |
1 | 131 | static int connection_ping(lua_State *L) { |
132 | connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); | |
133 | int ok = 0; | |
134 | ||
135 | if (conn->sqlite) { | |
136 | ok = 1; | |
137 | } | |
138 | ||
139 | lua_pushboolean(L, ok); | |
140 | return 1; | |
141 | } | |
142 | ||
2 | 143 | /* |
3 | 144 | * statement,err = connection:prepare(sql_str) |
2 | 145 | */ |
1 | 146 | static int connection_prepare(lua_State *L) { |
147 | connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); | |
148 | ||
149 | if (conn->sqlite) { | |
150 | return dbd_sqlite3_statement_create(L, conn, luaL_checkstring(L, 2)); | |
151 | } | |
152 | ||
153 | lua_pushnil(L); | |
4 | 154 | lua_pushstring(L, DBI_ERR_DB_UNAVAILABLE); |
3 | 155 | return 2; |
1 | 156 | } |
157 | ||
2 | 158 | /* |
22 | 159 | * quoted = connection:quote(str) |
160 | */ | |
161 | static int connection_quote(lua_State *L) { | |
162 | connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); | |
163 | size_t len; | |
164 | const char *from = luaL_checklstring(L, 2, &len); | |
165 | char *to; | |
166 | ||
167 | if (!conn->sqlite) { | |
168 | luaL_error(L, DBI_ERR_DB_UNAVAILABLE); | |
169 | } | |
170 | ||
171 | to = sqlite3_mprintf("%q", from); | |
172 | ||
173 | lua_pushstring(L, to); | |
174 | sqlite3_free(to); | |
175 | ||
176 | return 1; | |
177 | } | |
178 | ||
179 | /* | |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
180 | * success = connection:rollback() |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
181 | */ |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
182 | static int connection_rollback(lua_State *L) { |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
183 | connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
184 | int err = 1; |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
185 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
186 | if (conn->sqlite) { |
41 | 187 | err =rollback(conn); |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
188 | } |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
189 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
190 | lua_pushboolean(L, !err); |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
191 | return 1; |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
192 | } |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
193 | |
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
194 | /* |
2 | 195 | * __gc |
196 | */ | |
1 | 197 | static int connection_gc(lua_State *L) { |
198 | /* always close the connection */ | |
199 | connection_close(L); | |
200 | ||
201 | return 0; | |
202 | } | |
203 | ||
32
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
204 | /* |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
205 | * __tostring |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
206 | */ |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
207 | static int connection_tostring(lua_State *L) { |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
208 | connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
209 | |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
210 | lua_pushfstring(L, "%s: %p", DBD_SQLITE_CONNECTION, conn); |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
211 | |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
212 | return 1; |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
213 | } |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
214 | |
2 | 215 | int dbd_sqlite3_connection(lua_State *L) { |
216 | /* | |
217 | * instance methods | |
218 | */ | |
219 | static const luaL_Reg connection_methods[] = { | |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
220 | {"autocommit", connection_autocommit}, |
2 | 221 | {"close", connection_close}, |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
222 | {"commit", connection_commit}, |
2 | 223 | {"ping", connection_ping}, |
224 | {"prepare", connection_prepare}, | |
22 | 225 | {"quote", connection_quote}, |
13
10c8c6f0da14
Added connection:autocommit(), connection:commit(), and connection:rollback() to control transactions.
nrich@ii.net
parents:
9
diff
changeset
|
226 | {"rollback", connection_rollback}, |
2 | 227 | {NULL, NULL} |
228 | }; | |
1 | 229 | |
2 | 230 | /* |
231 | * class methods | |
232 | */ | |
233 | static const luaL_Reg connection_class_methods[] = { | |
234 | {"New", connection_new}, | |
235 | {NULL, NULL} | |
236 | }; | |
1 | 237 | |
238 | luaL_newmetatable(L, DBD_SQLITE_CONNECTION); | |
239 | luaL_register(L, 0, connection_methods); | |
240 | lua_pushvalue(L,-1); | |
241 | lua_setfield(L, -2, "__index"); | |
242 | ||
243 | lua_pushcfunction(L, connection_gc); | |
244 | lua_setfield(L, -2, "__gc"); | |
245 | ||
32
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
246 | lua_pushcfunction(L, connection_tostring); |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
247 | lua_setfield(L, -2, "__tostring"); |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
22
diff
changeset
|
248 | |
1 | 249 | luaL_register(L, DBD_SQLITE_CONNECTION, connection_class_methods); |
250 | ||
251 | return 1; | |
252 | } |