Skip to content

Commit 1e38545

Browse files
author
Ard Biesheuvel
committed
Initial revision (incomplete)
1 parent d0c4b3d commit 1e38545

13 files changed

+746
-0
lines changed

ext/pdo_firebird/CREDITS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Firebird/InterBase PDO module
2+
Ard Biesheuvel

ext/pdo_firebird/EXPERIMENTAL

Whitespace-only changes.

ext/pdo_firebird/config.m4

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
dnl
2+
dnl $Id$
3+
dnl
4+
5+
PHP_ARG_WITH(pdo-firebird,for Firebird support for PDO,
6+
[ --with-pdo-firebird[=DIR] Include Firebird support for PDO. DIR is the Firebird base
7+
install directory, defaults to /opt/firebird])
8+
9+
if test "$PHP_PDO_FIREBIRD" != "no"; then
10+
if test "$PHP_PDO_FIREBIRD" = "yes"; then
11+
FIREBIRD_INCDIR=/opt/firebird/include
12+
FIREBIRD_LIBDIR=/opt/firebird/lib
13+
else
14+
FIREBIRD_INCDIR=$PHP_PDO_FIREBIRD/include
15+
FIREBIRD_LIBDIR=$PHP_PDO_FIREBIRD/lib
16+
fi
17+
18+
PHP_CHECK_LIBRARY(gds, isc_detach_database,
19+
[
20+
FIREBIRD_LIBNAME=gds
21+
], [
22+
PHP_CHECK_LIBRARY(fbclient, isc_detach_database,
23+
[
24+
FIREBIRD_LIBNAME=fbclient
25+
], [
26+
AC_MSG_ERROR([libgds or libfbclient not found! Check config.log for more information.])
27+
], [
28+
-L$FIREBIRD_LIBDIR
29+
])
30+
], [
31+
-L$FIREBIRD_LIBDIR
32+
])
33+
34+
PHP_ADD_LIBRARY_WITH_PATH($FIREBIRD_LIBNAME, $FIREBIRD_LIBDIR, PDO_FIREBIRD_SHARED_LIBADD)
35+
PHP_ADD_INCLUDE($FIREBIRD_INCDIR)
36+
AC_DEFINE(HAVE_PDO_FIREBIRD,1,[ ])
37+
PHP_NEW_EXTENSION(pdo_firebird, pdo_firebird.c firebird_driver.c firebird_statement.c, $ext_shared)
38+
PHP_SUBST(PDO_FIREBIRD_SHARED_LIBADD)
39+
fi

ext/pdo_firebird/config.w32

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// $Id$
2+
// vim:ft=javascript
3+
4+
ARG_WITH("pdo-firebird", "Firebird support for PDO", "no");
5+
6+
if (PHP_PDO_FIREBIRD != "no") {
7+
if (CHECK_LIB("fbclient_ms.lib", "pdo_firebird", PHP_PDO_FIREBIRD) &&
8+
CHECK_HEADER_ADD_INCLUDE("ibase.h", "CFLAGS_PDO_FIREBIRD", PHP_PHP_BUILD + "\\include\\firebird;" + PHP_PDO_FIREBIRD)) {
9+
EXTENSION("pdo_firebird", "pdo_firebird.c firebird_driver.c firebird_statement.c");
10+
ADD_FLAG('CFLAGS_PDO_FIREBIRD', "/I ..\\pecl");
11+
} else {
12+
WARNING("pdo_firebird not enabled; libraries and headers not found");
13+
}
14+
ADD_EXTENSION_DEP('pdo_firebird', 'pdo');
15+
}

ext/pdo_firebird/firebird_driver.c

Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| PHP Version 5 |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) 1997-2004 The PHP Group |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 3.0 of the PHP license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.php.net/license/3_0.txt. |
11+
| If you did not receive a copy of the PHP license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| license@php.net so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Author: Ard Biesheuvel <abies@php.net> |
16+
+----------------------------------------------------------------------+
17+
*/
18+
19+
/* $Id$ */
20+
21+
#ifdef HAVE_CONFIG_H
22+
#include "config.h"
23+
#endif
24+
25+
#include "php.h"
26+
#include "php_ini.h"
27+
#include "ext/standard/info.h"
28+
#include "pdo/php_pdo.h"
29+
#include "pdo/php_pdo_driver.h"
30+
#include "php_pdo_firebird.h"
31+
#include "php_pdo_firebird_int.h"
32+
33+
static int pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
34+
{
35+
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
36+
ISC_STATUS *s = H->isc_status;
37+
char buf[128];
38+
39+
add_next_index_long(info, isc_sqlcode(s));
40+
41+
while (isc_interprete(buf,&s)) {
42+
add_next_index_string(info, buf, 1);
43+
}
44+
45+
return 1;
46+
}
47+
48+
static int firebird_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
49+
{
50+
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
51+
52+
if (dbh->in_txn) {
53+
if (dbh->auto_commit) {
54+
if (isc_commit_transaction(H->isc_status, &H->tr)) {
55+
/* error */
56+
}
57+
} else {
58+
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
59+
/* error */
60+
}
61+
}
62+
}
63+
64+
if (isc_detach_database(H->isc_status, &H->db)) {
65+
/* error */
66+
}
67+
68+
pefree(H, dbh->is_persistent);
69+
70+
return 0;
71+
}
72+
/* }}} */
73+
74+
static int firebird_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt,
75+
long options, zval *driver_options TSRMLS_DC)
76+
{
77+
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
78+
pdo_firebird_stmt *S = NULL;
79+
80+
do {
81+
isc_stmt_handle s = NULL;
82+
XSQLDA num_sqlda;
83+
84+
num_sqlda.version = PDO_FB_SQLDA_VERSION;
85+
num_sqlda.sqln = 1;
86+
87+
/* prepare the statement */
88+
if (isc_dsql_prepare(H->isc_status, &H->tr, &s, (short)sql_len, /* sigh */ (char*) sql,
89+
PDO_FB_DIALECT, &num_sqlda)) {
90+
/* error */
91+
break;
92+
}
93+
94+
/* allocate a statement handle of the right size */
95+
S = ecalloc(1, sizeof(*S)-sizeof(XSQLDA) + XSQLDA_LENGTH(num_sqlda.sqld));
96+
S->H = H;
97+
S->stmt = s;
98+
99+
if (isc_dsql_describe(H->isc_status, &s, PDO_FB_SQLDA_VERSION, S->out_sqlda)) {
100+
/* error */
101+
break;
102+
}
103+
104+
/* TODO what about input params */
105+
106+
stmt->driver_data = S;
107+
stmt->methods = &firebird_stmt_methods;
108+
109+
return 1;
110+
111+
} while (0);
112+
113+
if (S) {
114+
efree(S);
115+
}
116+
117+
return 0;
118+
}
119+
120+
static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
121+
{
122+
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
123+
isc_stmt_handle stmt = NULL;
124+
static char info_count[] = { isc_info_sql_records };
125+
char result[64];
126+
int ret = 0;
127+
128+
if (dbh->auto_commit && !dbh->in_txn) {
129+
if (isc_start_transaction(H->isc_status, &H->tr, 1, &H->db, 0, NULL)) {
130+
/* error */
131+
return -1;
132+
}
133+
dbh->in_txn = 1;
134+
}
135+
136+
/* prepare */
137+
if (isc_dsql_prepare(H->isc_status, &H->tr, &stmt, 0, (char*) sql, PDO_FB_DIALECT, NULL)) {
138+
/* error */
139+
return -1;
140+
}
141+
142+
/* execute */
143+
if (isc_dsql_execute2(H->isc_status, &H->tr, &stmt, PDO_FB_SQLDA_VERSION, NULL, NULL)) {
144+
/* error */
145+
return -1;
146+
}
147+
148+
/* return the number of affected rows */
149+
if (isc_dsql_sql_info(H->isc_status, &stmt, sizeof(info_count), info_count, sizeof(result),
150+
result)) {
151+
/* error */
152+
return -1;
153+
}
154+
155+
if (result[0] == isc_info_sql_records) {
156+
unsigned i = 3, result_size = isc_vax_integer(&result[1],2);
157+
158+
while (result[i] != isc_info_end && i < result_size) {
159+
short len = (short)isc_vax_integer(&result[i+1],2);
160+
if (result[i] != isc_info_req_select_count) {
161+
ret += isc_vax_integer(&result[i+3],len);
162+
}
163+
i += len+3;
164+
}
165+
}
166+
167+
/* commit? */
168+
if (dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
169+
/* error */
170+
}
171+
172+
return ret;
173+
}
174+
175+
static int firebird_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
176+
{
177+
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
178+
179+
if (isc_commit_transaction(H->isc_status, &H->tr)) {
180+
/* error */
181+
return 0;
182+
}
183+
return 1;
184+
}
185+
186+
static int firebird_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
187+
{
188+
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
189+
190+
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
191+
/* error */
192+
return 0;
193+
}
194+
return 1;
195+
}
196+
197+
static int firebird_handle_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
198+
{
199+
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
200+
201+
switch (attr) {
202+
203+
case PDO_ATTR_AUTOCOMMIT:
204+
205+
if (dbh->in_txn) {
206+
/* Assume they want to commit whatever is outstanding */
207+
if (isc_commit_retaining(H->isc_status, &H->tr)) {
208+
/* error */
209+
return 0;
210+
}
211+
dbh->in_txn = 0;
212+
}
213+
214+
convert_to_long(val);
215+
216+
dbh->auto_commit = Z_LVAL_P(val);
217+
218+
return 1;
219+
220+
default:
221+
222+
return 0;
223+
}
224+
}
225+
226+
static struct pdo_dbh_methods firebird_methods = {
227+
firebird_handle_closer,
228+
firebird_handle_preparer,
229+
firebird_handle_doer,
230+
NULL,
231+
NULL,
232+
firebird_handle_commit,
233+
firebird_handle_rollback,
234+
firebird_handle_set_attribute,
235+
NULL,
236+
pdo_firebird_fetch_error_func,
237+
};
238+
239+
static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
240+
{
241+
struct pdo_data_src_parser vars[] = {
242+
{ "dbname", NULL, 0 },
243+
{ "charset", NULL, 0 },
244+
{ "role", NULL, 0 }
245+
};
246+
int i, ret = 0;
247+
pdo_firebird_db_handle *H = dbh->driver_data = pecalloc(1,sizeof(*H),dbh->is_persistent);
248+
249+
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 2);
250+
251+
do {
252+
static char const dpb_flags[] = {
253+
isc_dpb_user_name, isc_dpb_password, isc_dpb_lc_ctype, isc_dpb_sql_role_name };
254+
char const *dpb_values[] = { dbh->username, dbh->password, vars[1].optval, vars[2].optval };
255+
char dpb_buffer[256] = { isc_dpb_version1 }, *dpb;
256+
short len;
257+
258+
dpb = dpb_buffer + 1;
259+
260+
/* loop through all the provided arguments and set dpb fields accordingly */
261+
for (i = 0; i < sizeof(dpb_flags); ++i) {
262+
if (dpb_values[i]) {
263+
dpb += sprintf(dpb, "%c%c%s", dpb_flags[i], (unsigned char)strlen(dpb_values[i]),
264+
dpb_values[i]);
265+
}
266+
}
267+
268+
/* fire it up baby! */
269+
if (isc_attach_database(H->isc_status, 0, vars[0].optval, &H->db,(short)(dpb-dpb_buffer),
270+
dpb_buffer)) {
271+
break;
272+
}
273+
274+
dbh->methods = &firebird_methods;
275+
dbh->alloc_own_columns = 0;
276+
dbh->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL;
277+
dbh->native_case = PDO_CASE_UPPER;
278+
279+
ret = 1;
280+
281+
} while (0);
282+
283+
for (i = 0; i < sizeof(vars)/sizeof(vars[0]); ++i) {
284+
if (vars[i].freeme) {
285+
efree(vars[i].optval);
286+
}
287+
}
288+
289+
if (!ret) {
290+
firebird_handle_closer(dbh TSRMLS_CC);
291+
}
292+
293+
return ret;
294+
}
295+
/* }}} */
296+
297+
pdo_driver_t pdo_firebird_driver = {
298+
PDO_DRIVER_HEADER(firebird),
299+
pdo_firebird_handle_factory
300+
};
301+
302+
/*
303+
* Local variables:
304+
* tab-width: 4
305+
* c-basic-offset: 4
306+
* End:
307+
* vim600: noet sw=4 ts=4 fdm=marker
308+
* vim<600: noet sw=4 ts=4
309+
*/

0 commit comments

Comments
 (0)