dbd/oracle/connection.c

changeset 17
21c4feaeafe7
child 22
fd78e9cdc6e9
equal deleted inserted replaced
16:318e5dfd03b8 17:21c4feaeafe7
1 #include "dbd_oracle.h"
2
3 int dbd_oracle_statement_create(lua_State *L, connection_t *conn, const char *sql_query);
4
5 static int commit(connection_t *conn) {
6 int rc = OCITransCommit(conn->svc, conn->err, OCI_DEFAULT);
7 return rc;
8 }
9
10 static int rollback(connection_t *conn) {
11 int rc = OCITransRollback(conn->svc, conn->err, OCI_DEFAULT);
12 return rc;
13 }
14
15
16 /*
17 * connection,err = DBD.Oracle.New(dbfile)
18 */
19 static int connection_new(lua_State *L) {
20 int n = lua_gettop(L);
21
22 int rc = 0;
23
24 const char *user = NULL;
25 const char *password = NULL;
26 const char *db = NULL;
27
28 OCIEnv *env = NULL;
29 OCIError *err = NULL;
30 OCISvcCtx *svc = NULL;
31
32 connection_t *conn = NULL;
33
34 /* db, user, password */
35 switch(n) {
36 case 5:
37 case 4:
38 case 3:
39 if (lua_isnil(L, 3) == 0)
40 password = luaL_checkstring(L, 3);
41 case 2:
42 if (lua_isnil(L, 2) == 0)
43 user = luaL_checkstring(L, 2);
44 case 1:
45 /*
46 * db is the only mandatory parameter
47 */
48 db = luaL_checkstring(L, 1);
49 }
50
51 /*
52 * initialise OCI
53 */
54 OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t))0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0);
55
56 /*
57 * initialise environment
58 */
59 OCIEnvInit((OCIEnv **)&env, OCI_DEFAULT, 0, (dvoid **)0);
60
61 /*
62 * server contexts
63 */
64 OCIHandleAlloc((dvoid *)env, (dvoid **)&err, OCI_HTYPE_ERROR, 0, (dvoid **)0);
65 OCIHandleAlloc((dvoid *)env, (dvoid **)&svc, OCI_HTYPE_SVCCTX, 0, (dvoid **)0);
66
67 /*
68 * connect to database server
69 */
70 rc = OCILogon(env, err, &svc, user, strlen(user), password, strlen(password), db, strlen(db));
71 if (rc != 0) {
72 char errbuf[100];
73 int errcode;
74
75 OCIErrorGet((dvoid *)err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
76
77 lua_pushnil(L);
78 lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, errbuf);
79
80 return 2;
81 }
82
83 conn = (connection_t *)lua_newuserdata(L, sizeof(connection_t));
84 conn->oracle = env;
85 conn->err = err;
86 conn->svc = svc;
87 conn->autocommit = 0;
88
89 luaL_getmetatable(L, DBD_ORACLE_CONNECTION);
90 lua_setmetatable(L, -2);
91
92 return 1;
93 }
94
95 /*
96 * success = connection:autocommit(on)
97 */
98 static int connection_autocommit(lua_State *L) {
99 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION);
100 int on = lua_toboolean(L, 2);
101 int err = 1;
102
103 if (conn->oracle) {
104 if (on)
105 rollback(conn);
106
107 conn->autocommit = on;
108 err = 0;
109 }
110
111 lua_pushboolean(L, !err);
112 return 1;
113 }
114
115
116 /*
117 * success = connection:close()
118 */
119 static int connection_close(lua_State *L) {
120 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION);
121 int disconnect = 0;
122
123 if (conn->oracle) {
124 rollback(conn);
125
126 OCILogoff(conn->svc, conn->err);
127
128 if (conn->svc)
129 OCIHandleFree((dvoid *)conn->svc, OCI_HTYPE_ENV);
130 if (conn->err)
131 OCIHandleFree((dvoid *)conn->err, OCI_HTYPE_ERROR);
132
133 disconnect = 1;
134 conn->oracle = NULL;
135 }
136
137 lua_pushboolean(L, disconnect);
138 return 1;
139 }
140
141 /*
142 * success = connection:commit()
143 */
144 static int connection_commit(lua_State *L) {
145 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION);
146 int err = 1;
147
148 if (conn->oracle) {
149 err = commit(conn);
150 }
151
152 lua_pushboolean(L, !err);
153 return 1;
154 }
155
156 /*
157 * ok = connection:ping()
158 */
159 static int connection_ping(lua_State *L) {
160 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION);
161 int ok = 0;
162
163 if (conn->oracle) {
164 ok = 1;
165 }
166
167 lua_pushboolean(L, ok);
168 return 1;
169 }
170
171 /*
172 * statement,err = connection:prepare(sql_str)
173 */
174 static int connection_prepare(lua_State *L) {
175 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION);
176
177 if (conn->oracle) {
178 return dbd_oracle_statement_create(L, conn, luaL_checkstring(L, 2));
179 }
180
181 lua_pushnil(L);
182 lua_pushstring(L, DBI_ERR_DB_UNAVAILABLE);
183 return 2;
184 }
185
186 /*
187 * success = connection:rollback()
188 */
189 static int connection_rollback(lua_State *L) {
190 connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION);
191 int err = 1;
192
193 if (conn->oracle) {
194 err = rollback(conn);
195 }
196
197 lua_pushboolean(L, !err);
198 return 1;
199 }
200
201 /*
202 * __gc
203 */
204 static int connection_gc(lua_State *L) {
205 /* always close the connection */
206 connection_close(L);
207
208 return 0;
209 }
210
211 int dbd_oracle_connection(lua_State *L) {
212 /*
213 * instance methods
214 */
215 static const luaL_Reg connection_methods[] = {
216 {"autocommit", connection_autocommit},
217 {"close", connection_close},
218 {"commit", connection_commit},
219 {"ping", connection_ping},
220 {"prepare", connection_prepare},
221 {"rollback", connection_rollback},
222 {NULL, NULL}
223 };
224
225 /*
226 * class methods
227 */
228 static const luaL_Reg connection_class_methods[] = {
229 {"New", connection_new},
230 {NULL, NULL}
231 };
232
233 luaL_newmetatable(L, DBD_ORACLE_CONNECTION);
234 luaL_register(L, 0, connection_methods);
235 lua_pushvalue(L,-1);
236 lua_setfield(L, -2, "__index");
237
238 lua_pushcfunction(L, connection_gc);
239 lua_setfield(L, -2, "__gc");
240
241 luaL_register(L, DBD_ORACLE_CONNECTION, connection_class_methods);
242
243 return 1;
244 }

mercurial