dbd/postgresql/connection.c

changeset 13
10c8c6f0da14
parent 4
c50b0e6f25d6
child 14
98192b7d4e89
equal deleted inserted replaced
12:014ba3ab3903 13:10c8c6f0da14
1 #include "dbd_postgresql.h" 1 #include "dbd_postgresql.h"
2 2
3 int dbd_postgresql_statement_create(lua_State *L, connection_t *conn, const char *sql_query); 3 int dbd_postgresql_statement_create(lua_State *L, connection_t *conn, const char *sql_query);
4
5 static int run(connection_t *conn, const char *command) {
6 PGresult *result = PQexec(conn->postgresql, command);
7 ExecStatusType status;
8
9 if (!result)
10 return 1;
11
12 status = PQresultStatus(result);
13 PQclear(result);
14
15 if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK)
16 return 1;
17
18 return 0;
19 }
20
21 static int commit(connection_t *conn) {
22 return run(conn, "COMMIT");
23 }
24
25
26 static int begin(connection_t *conn) {
27 return run(conn, "BEGIN");
28 }
29
30
31 static int rollback(connection_t *conn) {
32 return run(conn, "ROLLBACK");
33 }
34
4 35
5 /* 36 /*
6 * connection = DBD.PostgreSQL.New(dbname, user, password, host, port) 37 * connection = DBD.PostgreSQL.New(dbname, user, password, host, port)
7 */ 38 */
8 static int connection_new(lua_State *L) { 39 static int connection_new(lua_State *L) {
50 81
51 conn = (connection_t *)lua_newuserdata(L, sizeof(connection_t)); 82 conn = (connection_t *)lua_newuserdata(L, sizeof(connection_t));
52 83
53 conn->postgresql = PQsetdbLogin(host, port, options, tty, db, user, password); 84 conn->postgresql = PQsetdbLogin(host, port, options, tty, db, user, password);
54 conn->statement_id = 0; 85 conn->statement_id = 0;
86 conn->autocommit = 0;
87 begin(conn);
55 88
56 if (PQstatus(conn->postgresql) != CONNECTION_OK) { 89 if (PQstatus(conn->postgresql) != CONNECTION_OK) {
57 lua_pushnil(L); 90 lua_pushnil(L);
58 lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, PQerrorMessage(conn->postgresql)); 91 lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, PQerrorMessage(conn->postgresql));
59 return 2; 92 return 2;
64 97
65 return 1; 98 return 1;
66 } 99 }
67 100
68 /* 101 /*
102 * success = connection:autocommit(on)
103 */
104 static int connection_autocommit(lua_State *L) {
105 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION);
106 int on = lua_toboolean(L, 2);
107 int err = 0;
108
109 if (conn->postgresql) {
110 if (on)
111 err = rollback(conn);
112 else
113 err = begin(conn);
114
115 conn->autocommit = on;
116 }
117
118 lua_pushboolean(L, !err);
119 return 1;
120 }
121
122 /*
69 * success = connection:close() 123 * success = connection:close()
70 */ 124 */
71 static int connection_close(lua_State *L) { 125 static int connection_close(lua_State *L) {
72 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); 126 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION);
73 int disconnect = 0; 127 int disconnect = 0;
74 128
75 if (conn->postgresql) { 129 if (conn->postgresql) {
130 /*
131 * if autocommit is turned off, we probably
132 * want to rollback any outstanding transactions.
133 */
134 if (!conn->autocommit)
135 rollback(conn);
136
76 PQfinish(conn->postgresql); 137 PQfinish(conn->postgresql);
77 disconnect = 1; 138 disconnect = 1;
78 conn->postgresql = NULL; 139 conn->postgresql = NULL;
79 } 140 }
80 141
81 lua_pushboolean(L, disconnect); 142 lua_pushboolean(L, disconnect);
82 return 1; 143 return 1;
83 } 144 }
84 145
85 /* 146 /*
147 * success = connection:commit()
148 */
149 static int connection_commit(lua_State *L) {
150 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION);
151 int err = 0;
152
153 if (conn->postgresql) {
154 commit(conn);
155
156 if (!conn->autocommit)
157 err = begin(conn);
158 else
159 err = 1;
160 }
161
162 lua_pushboolean(L, !err);
163 return 1;
164 }
165
166 /*
86 * ok = connection:ping() 167 * ok = connection:ping()
87 */ 168 */
88 static int connection_ping(lua_State *L) { 169 static int connection_ping(lua_State *L) {
89 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); 170 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION);
90 int ok = 0; 171 int ok = 0;
114 lua_pushstring(L, DBI_ERR_DB_UNAVAILABLE); 195 lua_pushstring(L, DBI_ERR_DB_UNAVAILABLE);
115 return 2; 196 return 2;
116 } 197 }
117 198
118 /* 199 /*
200 * success = connection:rollback()
201 */
202 static int connection_rollback(lua_State *L) {
203 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION);
204 int err = 0;
205
206 if (conn->postgresql) {
207 rollback(conn);
208
209 if (!conn->autocommit)
210 err = begin(conn);
211 else
212 err = 1;
213 }
214
215 lua_pushboolean(L, !err);
216 return 1;
217 }
218
219 /*
119 * __gc 220 * __gc
120 */ 221 */
121 static int connection_gc(lua_State *L) { 222 static int connection_gc(lua_State *L) {
122 /* always close the connection */ 223 /* always close the connection */
123 connection_close(L); 224 connection_close(L);
125 return 0; 226 return 0;
126 } 227 }
127 228
128 int dbd_postgresql_connection(lua_State *L) { 229 int dbd_postgresql_connection(lua_State *L) {
129 static const luaL_Reg connection_methods[] = { 230 static const luaL_Reg connection_methods[] = {
231 {"autocommit", connection_autocommit},
130 {"close", connection_close}, 232 {"close", connection_close},
233 {"commit", connection_commit},
131 {"ping", connection_ping}, 234 {"ping", connection_ping},
132 {"prepare", connection_prepare}, 235 {"prepare", connection_prepare},
236 {"rollback", connection_rollback},
133 {NULL, NULL} 237 {NULL, NULL}
134 }; 238 };
135 239
136 static const luaL_Reg connection_class_methods[] = { 240 static const luaL_Reg connection_class_methods[] = {
137 {"New", connection_new}, 241 {"New", connection_new},

mercurial