Initial revision (incomplete)

This commit is contained in:
Ard Biesheuvel 2004-06-11 01:37:06 +00:00
parent d0c4b3d3ec
commit 1e3854597c
13 changed files with 746 additions and 0 deletions

2
ext/pdo_firebird/CREDITS Normal file
View File

@ -0,0 +1,2 @@
Firebird/InterBase PDO module
Ard Biesheuvel

View File

View File

@ -0,0 +1,39 @@
dnl
dnl $Id$
dnl
PHP_ARG_WITH(pdo-firebird,for Firebird support for PDO,
[ --with-pdo-firebird[=DIR] Include Firebird support for PDO. DIR is the Firebird base
install directory, defaults to /opt/firebird])
if test "$PHP_PDO_FIREBIRD" != "no"; then
if test "$PHP_PDO_FIREBIRD" = "yes"; then
FIREBIRD_INCDIR=/opt/firebird/include
FIREBIRD_LIBDIR=/opt/firebird/lib
else
FIREBIRD_INCDIR=$PHP_PDO_FIREBIRD/include
FIREBIRD_LIBDIR=$PHP_PDO_FIREBIRD/lib
fi
PHP_CHECK_LIBRARY(gds, isc_detach_database,
[
FIREBIRD_LIBNAME=gds
], [
PHP_CHECK_LIBRARY(fbclient, isc_detach_database,
[
FIREBIRD_LIBNAME=fbclient
], [
AC_MSG_ERROR([libgds or libfbclient not found! Check config.log for more information.])
], [
-L$FIREBIRD_LIBDIR
])
], [
-L$FIREBIRD_LIBDIR
])
PHP_ADD_LIBRARY_WITH_PATH($FIREBIRD_LIBNAME, $FIREBIRD_LIBDIR, PDO_FIREBIRD_SHARED_LIBADD)
PHP_ADD_INCLUDE($FIREBIRD_INCDIR)
AC_DEFINE(HAVE_PDO_FIREBIRD,1,[ ])
PHP_NEW_EXTENSION(pdo_firebird, pdo_firebird.c firebird_driver.c firebird_statement.c, $ext_shared)
PHP_SUBST(PDO_FIREBIRD_SHARED_LIBADD)
fi

View File

@ -0,0 +1,15 @@
// $Id$
// vim:ft=javascript
ARG_WITH("pdo-firebird", "Firebird support for PDO", "no");
if (PHP_PDO_FIREBIRD != "no") {
if (CHECK_LIB("fbclient_ms.lib", "pdo_firebird", PHP_PDO_FIREBIRD) &&
CHECK_HEADER_ADD_INCLUDE("ibase.h", "CFLAGS_PDO_FIREBIRD", PHP_PHP_BUILD + "\\include\\firebird;" + PHP_PDO_FIREBIRD)) {
EXTENSION("pdo_firebird", "pdo_firebird.c firebird_driver.c firebird_statement.c");
ADD_FLAG('CFLAGS_PDO_FIREBIRD', "/I ..\\pecl");
} else {
WARNING("pdo_firebird not enabled; libraries and headers not found");
}
ADD_EXTENSION_DEP('pdo_firebird', 'pdo');
}

View File

@ -0,0 +1,309 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2004 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.0 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_0.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Ard Biesheuvel <abies@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "pdo/php_pdo.h"
#include "pdo/php_pdo_driver.h"
#include "php_pdo_firebird.h"
#include "php_pdo_firebird_int.h"
static int pdo_firebird_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
{
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
ISC_STATUS *s = H->isc_status;
char buf[128];
add_next_index_long(info, isc_sqlcode(s));
while (isc_interprete(buf,&s)) {
add_next_index_string(info, buf, 1);
}
return 1;
}
static int firebird_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
{
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
if (dbh->in_txn) {
if (dbh->auto_commit) {
if (isc_commit_transaction(H->isc_status, &H->tr)) {
/* error */
}
} else {
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
/* error */
}
}
}
if (isc_detach_database(H->isc_status, &H->db)) {
/* error */
}
pefree(H, dbh->is_persistent);
return 0;
}
/* }}} */
static int firebird_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt,
long options, zval *driver_options TSRMLS_DC)
{
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
pdo_firebird_stmt *S = NULL;
do {
isc_stmt_handle s = NULL;
XSQLDA num_sqlda;
num_sqlda.version = PDO_FB_SQLDA_VERSION;
num_sqlda.sqln = 1;
/* prepare the statement */
if (isc_dsql_prepare(H->isc_status, &H->tr, &s, (short)sql_len, /* sigh */ (char*) sql,
PDO_FB_DIALECT, &num_sqlda)) {
/* error */
break;
}
/* allocate a statement handle of the right size */
S = ecalloc(1, sizeof(*S)-sizeof(XSQLDA) + XSQLDA_LENGTH(num_sqlda.sqld));
S->H = H;
S->stmt = s;
if (isc_dsql_describe(H->isc_status, &s, PDO_FB_SQLDA_VERSION, S->out_sqlda)) {
/* error */
break;
}
/* TODO what about input params */
stmt->driver_data = S;
stmt->methods = &firebird_stmt_methods;
return 1;
} while (0);
if (S) {
efree(S);
}
return 0;
}
static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
{
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
isc_stmt_handle stmt = NULL;
static char info_count[] = { isc_info_sql_records };
char result[64];
int ret = 0;
if (dbh->auto_commit && !dbh->in_txn) {
if (isc_start_transaction(H->isc_status, &H->tr, 1, &H->db, 0, NULL)) {
/* error */
return -1;
}
dbh->in_txn = 1;
}
/* prepare */
if (isc_dsql_prepare(H->isc_status, &H->tr, &stmt, 0, (char*) sql, PDO_FB_DIALECT, NULL)) {
/* error */
return -1;
}
/* execute */
if (isc_dsql_execute2(H->isc_status, &H->tr, &stmt, PDO_FB_SQLDA_VERSION, NULL, NULL)) {
/* error */
return -1;
}
/* return the number of affected rows */
if (isc_dsql_sql_info(H->isc_status, &stmt, sizeof(info_count), info_count, sizeof(result),
result)) {
/* error */
return -1;
}
if (result[0] == isc_info_sql_records) {
unsigned i = 3, result_size = isc_vax_integer(&result[1],2);
while (result[i] != isc_info_end && i < result_size) {
short len = (short)isc_vax_integer(&result[i+1],2);
if (result[i] != isc_info_req_select_count) {
ret += isc_vax_integer(&result[i+3],len);
}
i += len+3;
}
}
/* commit? */
if (dbh->auto_commit && isc_commit_retaining(H->isc_status, &H->tr)) {
/* error */
}
return ret;
}
static int firebird_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
{
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
if (isc_commit_transaction(H->isc_status, &H->tr)) {
/* error */
return 0;
}
return 1;
}
static int firebird_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
{
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
if (isc_rollback_transaction(H->isc_status, &H->tr)) {
/* error */
return 0;
}
return 1;
}
static int firebird_handle_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
{
pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
switch (attr) {
case PDO_ATTR_AUTOCOMMIT:
if (dbh->in_txn) {
/* Assume they want to commit whatever is outstanding */
if (isc_commit_retaining(H->isc_status, &H->tr)) {
/* error */
return 0;
}
dbh->in_txn = 0;
}
convert_to_long(val);
dbh->auto_commit = Z_LVAL_P(val);
return 1;
default:
return 0;
}
}
static struct pdo_dbh_methods firebird_methods = {
firebird_handle_closer,
firebird_handle_preparer,
firebird_handle_doer,
NULL,
NULL,
firebird_handle_commit,
firebird_handle_rollback,
firebird_handle_set_attribute,
NULL,
pdo_firebird_fetch_error_func,
};
static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
{
struct pdo_data_src_parser vars[] = {
{ "dbname", NULL, 0 },
{ "charset", NULL, 0 },
{ "role", NULL, 0 }
};
int i, ret = 0;
pdo_firebird_db_handle *H = dbh->driver_data = pecalloc(1,sizeof(*H),dbh->is_persistent);
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 2);
do {
static char const dpb_flags[] = {
isc_dpb_user_name, isc_dpb_password, isc_dpb_lc_ctype, isc_dpb_sql_role_name };
char const *dpb_values[] = { dbh->username, dbh->password, vars[1].optval, vars[2].optval };
char dpb_buffer[256] = { isc_dpb_version1 }, *dpb;
short len;
dpb = dpb_buffer + 1;
/* loop through all the provided arguments and set dpb fields accordingly */
for (i = 0; i < sizeof(dpb_flags); ++i) {
if (dpb_values[i]) {
dpb += sprintf(dpb, "%c%c%s", dpb_flags[i], (unsigned char)strlen(dpb_values[i]),
dpb_values[i]);
}
}
/* fire it up baby! */
if (isc_attach_database(H->isc_status, 0, vars[0].optval, &H->db,(short)(dpb-dpb_buffer),
dpb_buffer)) {
break;
}
dbh->methods = &firebird_methods;
dbh->alloc_own_columns = 0;
dbh->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL;
dbh->native_case = PDO_CASE_UPPER;
ret = 1;
} while (0);
for (i = 0; i < sizeof(vars)/sizeof(vars[0]); ++i) {
if (vars[i].freeme) {
efree(vars[i].optval);
}
}
if (!ret) {
firebird_handle_closer(dbh TSRMLS_CC);
}
return ret;
}
/* }}} */
pdo_driver_t pdo_firebird_driver = {
PDO_DRIVER_HEADER(firebird),
pdo_firebird_handle_factory
};
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

View File

@ -0,0 +1,48 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2004 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.0 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_0.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Ard Biesheuvel <abies@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "pdo/php_pdo.h"
#include "pdo/php_pdo_driver.h"
struct pdo_stmt_methods firebird_stmt_methods = {0,0,0,0,0,0};
/*
firebird_stmt_dtor,
firebird_stmt_execute,
firebird_stmt_fetch,
firebird_stmt_describe,
firebird_stmt_get_col,
firebird_stmt_param_hook
};
*/
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE package SYSTEM "../pear/package.dtd">
<package version="1.0">
<name>PDO_Firebird</name>
<summary>Firebird/InterBase support for PDO</summary>
<maintainers>
<maintainer>
<user>abies</user>
<name>Ard Biesheuvel</name>
<email>abies@php.net</email>
<role>lead</role>
</maintainer>
</maintainers>
<configureoptions>
<configureoption name="with-pdo-firebird" prompt="dir"/>
</configureoptions>
<description>
This extension provides a Firebird/InterBase driver for PDO. It supports
InterBase versions 6.x/7.x and Firebird 1.x.
</description>
<license>PHP</license>
<release>
<state>pre-alpha</state>
<version>0.1</version>
<date>2004-06-11</date>
<notes>
To compile and run this module, you will need to have the main PDO module and Firebird's
client library installed on your system.
</notes>
<filelist>
<file role="src" name="config.m4"/>
<file role="src" name="config.w32"/>
<file role="src" name="firebird_driver.c"/>
<file role="src" name="firebird_statement.c"/>
<file role="src" name="pdo_firebird.c"/>
<file role="src" name="php_pdo_firebird.h"/>
<file role="src" name="php_pdo_firebird_int.h"/>
<file role="doc" name="CREDITS"/>
</filelist>
<deps>
<dep type="php" rel="ge" version="5.0.0RC3"/>
<dep type="ext" rel="ge" name="pdo" version="0.1"/>
</deps>
</release>
</package>

View File

@ -0,0 +1,95 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2004 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.0 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_0.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Ard Biesheuvel <abies@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "pdo/php_pdo.h"
#include "pdo/php_pdo_driver.h"
#include "php_pdo_firebird.h"
#include "php_pdo_firebird_int.h"
/* {{{ pdo_firebird_functions[] */
function_entry pdo_firebird_functions[] = {
{NULL, NULL, NULL}
};
/* }}} */
/* {{{ pdo_firebird_module_entry */
zend_module_entry pdo_firebird_module_entry = {
STANDARD_MODULE_HEADER,
"PDO_Firebird",
pdo_firebird_functions,
PHP_MINIT(pdo_firebird),
PHP_MSHUTDOWN(pdo_firebird),
NULL,
NULL,
PHP_MINFO(pdo_firebird),
"0.1",
STANDARD_MODULE_PROPERTIES
};
/* }}} */
#ifdef COMPILE_DL_PDO_FIREBIRD
ZEND_GET_MODULE(pdo_firebird)
#endif
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(pdo_firebird)
{
php_pdo_register_driver(&pdo_firebird_driver);
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(pdo_firebird)
{
php_pdo_unregister_driver(&pdo_firebird_driver);
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(pdo_firebird)
{
php_info_print_table_start();
php_info_print_table_header(2, "PDO Driver for Firebird/InterBase", "enabled");
php_info_print_table_end();
}
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

View File

@ -0,0 +1,52 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2004 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.0 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_0.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Ard Biesheuvel <abies@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef PHP_PDO_FIREBIRD_H
#define PHP_PDO_FIREBIRD_H
extern zend_module_entry pdo_firebird_module_entry;
#define phpext_pdo_firebird_ptr &pdo_firebird_module_entry
#ifdef PHP_WIN32
#define PHP_PDO_FB_API __declspec(dllexport)
#else
#define PHP_PDO_FB_API
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
PHP_MINIT_FUNCTION(pdo_firebird);
PHP_MSHUTDOWN_FUNCTION(pdo_firebird);
PHP_RINIT_FUNCTION(pdo_firebird);
PHP_RSHUTDOWN_FUNCTION(pdo_firebird);
PHP_MINFO_FUNCTION(pdo_firebird);
#endif /* PHP_PDO_FIREBIRD_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

View File

@ -0,0 +1,83 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2004 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.0 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_0.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Ard Biesheuvel <abies@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef PHP_PDO_FIREBIRD_INT_H
#define PHP_PDO_FIREBIRD_INT_H
#include <ibase.h>
#ifdef SQLDA_VERSION
#define PDO_FB_SQLDA_VERSION SQLDA_VERSION
#else
#define PDO_FB_SQLDA_VERSION 1
#endif
#define PDO_FB_DIALECT 3
typedef struct {
const char *file;
int line;
long errcode;
char *errmsg;
} pdo_firebird_error_info;
typedef struct {
/* the result of the last API call */
ISC_STATUS isc_status[20];
/* the connection handle */
isc_db_handle db;
/* the transaction handle */
isc_tr_handle tr;
} pdo_firebird_db_handle;
typedef struct {
/* the link that owns this statement */
pdo_firebird_db_handle *H;
/* the statement handle */
isc_stmt_handle stmt;
/* the output SQLDA */
XSQLDA out_sqlda[1]; /* last member */
} pdo_firebird_stmt;
extern pdo_driver_t pdo_firebird_driver;
extern struct pdo_stmt_methods firebird_stmt_methods;
#endif /* PHP_PDO_FIREBIRD_INT_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

View File

@ -0,0 +1,16 @@
--TEST--
PDO_Firebird: connect/disconnect
--SKIPIF--
<?php include("skipif.inc"); ?>
--FILE--
<?php /* $Id$ */
require("testdb.inc");
$db = new PDO("firebird:dbname=$test_base",$user,$password) or die;
unset($db);
echo "done\n";
?>
--EXPECT--
done

View File

@ -0,0 +1,5 @@
<?php /* $Id$ */
if (!extension_loaded("interbase") || !extension_loaded("pdo_firebird")) print "skip";
?>

View File

@ -0,0 +1,34 @@
<?php /* $Id$ */
$user = 'SYSDBA';
$password = 'masterkey';
ini_set('ibase.default_user',$user);
ini_set('ibase.default_password',$password);
/* we need just the generated name, not the file itself */
unlink($test_base = tempnam('/tmp',"php_ibase_test"));
function init_db()
{
global $test_base, $user, $password;
$test_db = ibase_query(IBASE_CREATE,sprintf("CREATE DATABASE '%s' USER '%s' PASSWORD '%s'",
$test_base, $user, $password));
$tr = ibase_trans($test_db);
ibase_query($tr,"create table test1 (i integer, c varchar(100))");
ibase_commit_ret($tr);
ibase_query($tr,"insert into test1(i, c) values(1, 'test table not created with isql')");
ibase_commit($tr);
ibase_close($test_db);
}
function cleanup_db()
{
global $test_base;
$r = ibase_connect($test_base);
ibase_drop_db($r);
}
register_shutdown_function('cleanup_db');
init_db();