summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2005-01-17 01:15:14 +0000
committerWez Furlong <wez@php.net>2005-01-17 01:15:14 +0000
commitca988059354fcee51c6306ff5056fe16b3081f58 (patch)
tree5e95571838b75ca5fe5c77db424b92b2700a7a2b
parentf3d39ff406787514bb36927c0b97979c066f5d5d (diff)
downloadphp-git-ca988059354fcee51c6306ff5056fe16b3081f58.tar.gz
Add a PDO driver for Sybase style DB-lib (including MS SQL).
Only the basics are here right now.
-rw-r--r--ext/pdo_dblib/CREDITS2
-rw-r--r--ext/pdo_dblib/README29
-rwxr-xr-xext/pdo_dblib/config.w3236
-rw-r--r--ext/pdo_dblib/db.php24
-rw-r--r--ext/pdo_dblib/dblib_driver.c212
-rw-r--r--ext/pdo_dblib/dblib_stmt.c252
-rw-r--r--ext/pdo_dblib/pdo_dblib.c129
-rw-r--r--ext/pdo_dblib/php_pdo_dblib.h44
-rw-r--r--ext/pdo_dblib/php_pdo_dblib_int.h124
9 files changed, 852 insertions, 0 deletions
diff --git a/ext/pdo_dblib/CREDITS b/ext/pdo_dblib/CREDITS
new file mode 100644
index 0000000000..91a8057be3
--- /dev/null
+++ b/ext/pdo_dblib/CREDITS
@@ -0,0 +1,2 @@
+DB-LIB (MS SQL, Sybase)
+Wez Furlong, Frank M. Kromann
diff --git a/ext/pdo_dblib/README b/ext/pdo_dblib/README
new file mode 100644
index 0000000000..a32eefcf17
--- /dev/null
+++ b/ext/pdo_dblib/README
@@ -0,0 +1,29 @@
+This is the unified Sybase-DB style driver for PDO.
+There are three implementations of this library that are known to me:
+
+- The Sybase DB lib itself
+- MSSQL DB lib
+- FreeTDS DB lib
+
+This extension will compile and register itself as 'mssql' when built against
+the mssql libraries (and be named php_pdo_mssql.dll), or 'sybase' otherwise
+(php_pdo_sybase.dll)
+
+This extension should also compile and run under unix platforms, but I haven't
+written the config.m4 for that yet (volunteers welcome).
+
+
+If you want to try out the free "desktop" version of SQL Server, known as the MSDE, google to obtain the appropriate download link. Here are some short tips on getting it running:
+
+- Download it and run it to extract it
+- Open up a command prompt
+- cd \MSDERelA
+- setup.exe SQLSECURITY=1 SAPWD=yoursecretpassword
+- cd \Program Files\Microsoft SQL Server\80\Tools\Binn
+- SVRNETCN.exe
+- enable TCP (you MUST do this if you want to access it via FreeTDS/Sybase libs)
+- net start mssqlserver
+
+Consult the MS docs for more information about all this stuff.
+
+
diff --git a/ext/pdo_dblib/config.w32 b/ext/pdo_dblib/config.w32
new file mode 100755
index 0000000000..4528970fb5
--- /dev/null
+++ b/ext/pdo_dblib/config.w32
@@ -0,0 +1,36 @@
+// $Id$
+// vim:ft=javascript
+
+ARG_WITH("pdo-dblib", "dblib (Sybase, MSSQL) support for PDO", "no");
+
+if (PHP_PDO_DBLIB != "no") {
+ /* if they pointed us to a freetds dir, pick that up,
+ * otherwise we'll poke around and look for MSSQL libs */
+
+ if (CHECK_LIB("sybdb.lib", "pdo_dblib", PHP_PDO_DBLIB) &&
+ CHECK_HEADER_ADD_INCLUDE("sybfront.h", "CFLAGS_PDO_DBLIB", PHP_PDO_DBLIB)) {
+ /* smells like FreeTDS (or maybe native sybase dblib) */
+ PDO_DBLIB_FLAVOUR = "freetds";
+ } else if (CHECK_LIB("ntwdblib.lib", "pdo_dblib", "\\MSSQL8\\DevTools\\Lib") &&
+ CHECK_HEADER_ADD_INCLUDE("sqlfront.h", "CFLAGS_PDO_DBLIB")) {
+ PDO_DBLIB_FLAVOUR = 8;
+ } else if (CHECK_LIB("ntwdblib.lib", "pdo_dblib", "\\MSSQL7\\DevTools\\Lib") &&
+ CHECK_HEADER_ADD_INCLUDE("sqlfront.h", "CFLAGS_PDO_DBLIB")) {
+ PDO_DBLIB_FLAVOUR = 7;
+ } else {
+ PDO_DBLIB_FLAVOUR = 0;
+ }
+
+ if (PDO_DBLIB_FLAVOUR != 0) {
+ EXTENSION("pdo_dblib", "pdo_dblib.c dblib_driver.c dblib_stmt.c", null, "",
+ PDO_DBLIB_FLAVOUR == "freetds" ? "php_pdo_sybase.dll" : "php_pdo_mssql.dll");
+ if (PDO_DBLIB_FLAVOUR != "freetds") {
+ ADD_FLAG("CFLAGS_PDO_DBLIB", "/DDBNTWIN32=1 /DMSSQL" + PDO_DBLIB_FLAVOUR + "0=1 /DMSSQL_VERSION \\\"" + PDO_DBLIB_FLAVOUR + ".0\\\"");
+ AC_DEFINE("PDO_DBLIB_IS_MSSQL", PDO_DBLIB_FLAVOUR, "Have MSSQL support");
+ PDO_DBLIB_FLAVOUR = "MSSQL " + PDO_DBLIB_FLAVOUR;
+ }
+ ADD_FLAG('CFLAGS_PDO_DBLIB', "/I ..\\pecl /D PDO_DBLIB_FLAVOUR=\\\"" + PDO_DBLIB_FLAVOUR + "\\\"");
+ }
+ ADD_EXTENSION_DEP('pdo_dblib', 'pdo');
+}
+
diff --git a/ext/pdo_dblib/db.php b/ext/pdo_dblib/db.php
new file mode 100644
index 0000000000..f069c76391
--- /dev/null
+++ b/ext/pdo_dblib/db.php
@@ -0,0 +1,24 @@
+<?php
+
+/* assumes that you have the freetds db.lib on windows */
+
+dl('php_pdo.dll');
+dl('php_pdo_sybase.dll');
+
+$db = new PDO('sybase:', 'pdo', 'pdo');
+debug_zval_dump($db);
+
+$stmt = $db->prepare('sp_helpdb');
+debug_zval_dump($stmt);
+
+$x = $stmt->execute();
+debug_zval_dump($x);
+
+while (($r = $stmt->fetch())) {
+ print_r($r);
+}
+
+$stmt = null;
+$db = null;
+echo "All done\n";
+?>
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
new file mode 100644
index 0000000000..aee84e0dbb
--- /dev/null
+++ b/ext/pdo_dblib/dblib_driver.c
@@ -0,0 +1,212 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 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: Wez Furlong <wez@php.net> |
+ | Frank M. Kromann <frank@kromann.info> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $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_dblib.h"
+#include "php_pdo_dblib_int.h"
+#include "zend_exceptions.h"
+
+static int dblib_handle_closer(pdo_dbh_t *dbh TSRMLS_DC)
+{
+ pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
+
+ if (H) {
+ if (H->link) {
+ dbclose(H->link);
+ H->link = NULL;
+ }
+ if (H->login) {
+ dbfreelogin(H->login);
+ H->login = NULL;
+ }
+ pefree(H, dbh->is_persistent);
+ dbh->driver_data = NULL;
+ }
+ return 0;
+}
+
+static int dblib_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, long options, zval *driver_options TSRMLS_DC)
+{
+ pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
+ pdo_dblib_stmt *S = ecalloc(1, sizeof(*S));
+
+ S->H = H;
+ stmt->driver_data = S;
+ stmt->methods = &dblib_stmt_methods;
+
+ return 1;
+}
+
+static long dblib_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
+{
+ pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
+ RETCODE ret, resret;
+
+ if (FAIL == dbcmd(H->link, sql)) {
+ return -1;
+ }
+
+ if (FAIL == dbsqlexec(H->link)) {
+ return -1;
+ }
+
+ resret = dbresults(H->link);
+
+ if (resret == FAIL) {
+ return -1;
+ }
+
+ ret = dbnextrow(H->link);
+ if (ret == FAIL) {
+ return -1;
+ }
+
+ if (dbnumcols(H->link) <= 0) {
+ return DBCOUNT(H->link);
+ }
+
+ /* throw away any rows it might have returned */
+ dbcanquery(H->link);
+
+ return DBCOUNT(H->link);
+}
+
+static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC)
+{
+ pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
+ char *q;
+ int l = 1;
+
+ *quoted = q = emalloc(2 * unquotedlen + 3);
+ *q++ = '\'';
+
+ while (unquotedlen--) {
+ if (*unquoted == '\'') {
+ *q++ = '\'';
+ *q++ = '\'';
+ l += 2;
+ } else {
+ *q++ = *unquoted;
+ ++l;
+ }
+ unquoted++;
+ }
+
+ *q++ = '\'';
+ *q++ = '\0';
+ *quotedlen = l+1;
+
+ return 1;
+}
+
+static struct pdo_dbh_methods dblib_methods = {
+ dblib_handle_closer,
+ dblib_handle_preparer,
+ dblib_handle_doer,
+ dblib_handle_quoter,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* last insert */
+ NULL, /* fetch error */
+ NULL, /* get attr */
+ NULL, /* check liveness */
+};
+
+static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC)
+{
+ pdo_dblib_db_handle *H;
+ int i, ret = 0;
+ struct pdo_data_src_parser vars[] = {
+ { "charset", NULL, 0 },
+ { "appname", "PHP " PDO_DBLIB_FLAVOUR, 0 },
+ { "host", "127.0.0.1", 0 },
+ { "dbname", NULL, 0 },
+ { "secure", NULL, 0 }, /* DBSETLSECURE */
+ /* TODO: DBSETLVERSION ? */
+ };
+
+ php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5);
+
+ H = pecalloc(1, sizeof(*H), dbh->is_persistent);
+ H->login = dblogin();
+
+ if (!H->login) {
+ goto cleanup;
+ }
+
+ if (dbh->username) {
+ DBSETLUSER(H->login, dbh->username);
+ }
+ if (dbh->password) {
+ DBSETLPWD(H->login, dbh->password);
+ }
+ if (vars[0].optval) {
+ DBSETLCHARSET(H->login, vars[0].optval);
+ }
+ DBSETLAPP(H->login, vars[1].optval);
+
+ H->link = dbopen(H->login, vars[2].optval);
+
+ if (H->link == NULL) {
+ goto cleanup;
+ }
+
+ if (vars[3].optval && FAIL == dbuse(H->link, vars[3].optval)) {
+ goto cleanup;
+ }
+
+ ret = 1;
+ dbh->supports_placeholders = 0;
+ dbh->max_escaped_char_length = 2;
+ dbh->alloc_own_columns = 1;
+
+cleanup:
+ for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
+ if (vars[i].freeme) {
+ efree(vars[i].optval);
+ }
+ }
+
+ dbh->methods = &dblib_methods;
+ dbh->driver_data = H;
+
+ return ret;
+}
+
+pdo_driver_t pdo_dblib_driver = {
+#if PDO_DBLIB_IS_MSSQL
+ PDO_DRIVER_HEADER(mssql),
+#else
+ PDO_DRIVER_HEADER(sybase),
+#endif
+ pdo_dblib_handle_factory
+};
+
diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c
new file mode 100644
index 0000000000..e552c7149e
--- /dev/null
+++ b/ext/pdo_dblib/dblib_stmt.c
@@ -0,0 +1,252 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 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: Wez Furlong <wez@php.net> |
+ | Frank M. Kromann <frank@kromann.info> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $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_dblib.h"
+#include "php_pdo_dblib_int.h"
+#include "zend_exceptions.h"
+
+static void free_rows(pdo_dblib_stmt *S TSRMLS_DC)
+{
+ int i, j;
+
+ for (i = 0; i < S->nrows; i++) {
+ for (j = 0; j < S->ncols; j++) {
+ pdo_dblib_colval *val = &S->rows[i] + j;
+ if (val->data) {
+ efree(val->data);
+ val->data = NULL;
+ }
+ }
+ }
+ efree(S->rows);
+ S->rows = NULL;
+}
+
+static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
+{
+ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+
+ if (S->rows) {
+ free_rows(S TSRMLS_CC);
+ }
+ if (S->cols) {
+ efree(S->cols);
+ }
+ efree(S);
+
+ return 1;
+}
+
+static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
+{
+ pdo_dbh_t *dbh = stmt->dbh;
+ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+ pdo_dblib_db_handle *H = S->H;
+ RETCODE resret, ret;
+ int i, j;
+ int arows;
+ unsigned int size;
+
+ if (S->rows) {
+ /* clean them up */
+ free_rows(S TSRMLS_CC);
+ }
+
+ if (FAIL == dbcmd(H->link, stmt->active_query_string)) {
+ return 0;
+ }
+ if (FAIL == dbsqlexec(H->link)) {
+ return 0;
+ }
+
+ resret = dbresults(H->link);
+ if (resret == FAIL) {
+ return 0;
+ }
+
+ ret = dbnextrow(H->link);
+
+ if (!S->cols) {
+ S->ncols = dbnumcols(H->link);
+
+ if (S->ncols <= 0) {
+ return 1;
+ }
+
+ S->cols = ecalloc(S->ncols, sizeof(pdo_dblib_col));
+ stmt->column_count = S->ncols;
+
+ for (i = 0, j = 0; i < S->ncols; i++) {
+ S->cols[i].coltype = dbcoltype(H->link, i+1);
+ S->cols[i].name = dbcolname(H->link, i+1);
+ if (S->cols[i].name) {
+ S->cols[i].name = estrdup(S->cols[i].name);
+ } else if (j) {
+ spprintf(&S->cols[i].name, 0, "computed%d", j++);
+ } else {
+ S->cols[i].name = estrdup("computed");
+ j++;
+ }
+ S->cols[i].source = dbcolsource(H->link, i+1);
+ S->cols[i].source = estrdup(S->cols[i].source ? S->cols[i].source : "");
+ S->cols[i].maxlen = dbcollen(H->link, i+1);
+ }
+ }
+
+ arows = 100;
+ size = S->ncols * sizeof(pdo_dblib_colval);
+ S->rows = emalloc(arows * size);
+
+ /* let's fetch all the data */
+ do {
+ if (S->nrows >= arows) {
+ arows *= 2;
+ S->rows = erealloc(S->rows, arows * size);
+ }
+ for (i = 0; i < S->ncols; i++) {
+ pdo_dblib_colval *val = &S->rows[S->nrows] + i;
+
+ switch (S->cols[i].coltype) {
+ case SQLCHAR:
+ case SQLTEXT:
+ case SQLVARBINARY:
+ case SQLBINARY:
+ case SQLIMAGE:
+ val->len = dbdatlen(H->link, i+1);
+ val->data = emalloc(val->len + 1);
+ memcpy(val->data, dbdata(H->link, i+1), val->len);
+ val->data[val->len] = '\0';
+ break;
+
+ default:
+ if (dbwillconvert(S->cols[i].coltype, SYBCHAR)) {
+ val->len = 32 + (2 * dbdatlen(H->link, i+1));
+ val->data = emalloc(val->len);
+
+ val->len = dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1),
+ dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
+
+ if (val->len >= 0) {
+ val->data[val->len] = '\0';
+ }
+ } else {
+ val->len = 0;
+ val->data = NULL;
+ }
+ }
+ }
+
+ S->nrows++;
+
+ ret = dbnextrow(H->link);
+
+ if (ret == BUF_FULL) {
+ dbclrbuf(H->link, DBLASTROW(H->link)-1);
+ }
+ } while (ret != FAIL && ret != NO_MORE_ROWS);
+
+
+ if (resret != NO_MORE_RESULTS) {
+ /* there are additional result sets available */
+ dbresults(H->link);
+ /* cancel pending rows */
+ dbcanquery(H->link);
+
+ /* TODO: figure out a sane solution */
+ }
+
+ S->current = -1;
+
+ return 1;
+}
+
+static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
+ enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
+{
+ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+
+ if (!S->rows) {
+ return 0;
+ }
+
+ if (++S->current < S->nrows) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
+{
+ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+ struct pdo_column_data *col = &stmt->columns[colno];
+
+ if (!S->rows) {
+ return 0;
+ }
+
+ col->maxlen = S->cols[colno].maxlen;
+ col->namelen = strlen(S->cols[colno].name);
+ col->name = estrdup(S->cols[colno].name);
+ col->param_type = PDO_PARAM_STR;
+
+ return 1;
+}
+
+static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
+ unsigned long *len TSRMLS_DC)
+{
+ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+ pdo_dblib_colval *val = &S->rows[S->current] + colno;
+
+ *ptr = val->data;
+ *len = val->len;
+ return 1;
+}
+
+static int pdo_dblib_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
+ enum pdo_param_event event_type TSRMLS_DC)
+{
+ return 1;
+}
+
+
+struct pdo_stmt_methods dblib_stmt_methods = {
+ pdo_dblib_stmt_dtor,
+ pdo_dblib_stmt_execute,
+ pdo_dblib_stmt_fetch,
+ pdo_dblib_stmt_describe,
+ pdo_dblib_stmt_get_col,
+ pdo_dblib_stmt_param_hook,
+ NULL, /* set attr */
+ NULL, /* get attr */
+ NULL, /* meta */
+};
+
diff --git a/ext/pdo_dblib/pdo_dblib.c b/ext/pdo_dblib/pdo_dblib.c
new file mode 100644
index 0000000000..0cd6a30de9
--- /dev/null
+++ b/ext/pdo_dblib/pdo_dblib.c
@@ -0,0 +1,129 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 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: Wez Furlong <wez@php.net> |
+ | Frank M. Kromann <frank@kromann.info> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $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_dblib.h"
+#include "php_pdo_dblib_int.h"
+#include "zend_exceptions.h"
+
+function_entry pdo_dblib_functions[] = {
+ {NULL, NULL, NULL}
+};
+
+zend_module_entry pdo_dblib_module_entry = {
+ STANDARD_MODULE_HEADER,
+#if PDO_DBLIB_IS_MSSQL
+ "pdo_mssql",
+#else
+ "pdo_sybase",
+#endif
+ pdo_dblib_functions,
+ PHP_MINIT(pdo_dblib),
+ PHP_MSHUTDOWN(pdo_dblib),
+ NULL,
+ NULL,
+ PHP_MINFO(pdo_dblib),
+ "0.1-dev",
+ STANDARD_MODULE_PROPERTIES
+};
+
+#ifdef COMPILE_DL_PDO_DBLIB
+ZEND_GET_MODULE(pdo_dblib)
+#endif
+
+static int error_handler(DBPROCESS *dbproc, int severity, int dberr,
+ int oserr, char *dberrstr, char *oserrstr)
+{
+ TSRMLS_FETCH();
+
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "dblib error: %s (severity %d)", dberrstr, severity);
+
+ return INT_CANCEL;
+}
+
+static int msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate,
+ int severity, char *msgtext, char *srvname, char *procname, DBUSMALLINT line)
+{
+ TSRMLS_FETCH();
+
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "dblib message: %s (severity %d)", msgtext, severity);
+
+ return 0;
+}
+
+PHP_MINIT_FUNCTION(pdo_dblib)
+{
+ if (FAIL == dbinit()) {
+ return FAILURE;
+ }
+
+ if (FAILURE == php_pdo_register_driver(&pdo_dblib_driver)) {
+ return FAILURE;
+ }
+
+ /* TODO:
+
+ dbsetifile()
+ dbsetmaxprocs()
+ dbsetlogintime()
+ dbsettime()
+
+ */
+
+#if !PHP_DBLIB_IS_MSSQL
+ dberrhandle(error_handler);
+ dbmsghandle(msg_handler);
+#endif
+
+ return SUCCESS;
+}
+
+PHP_MSHUTDOWN_FUNCTION(pdo_dblib)
+{
+ php_pdo_unregister_driver(&pdo_dblib_driver);
+ dbexit();
+ return SUCCESS;
+}
+
+PHP_MINFO_FUNCTION(pdo_dblib)
+{
+ php_info_print_table_start();
+ php_info_print_table_header(2, "PDO Driver for "
+#if PDO_DBLIB_IS_MSSQL
+ "MSSQL"
+#elif defined(PHP_WIN32)
+ "FreeTDS/Sybase/MSSQL"
+#else
+ "Sybase"
+#endif
+ " DB-lib", "enabled");
+ php_info_print_table_row(2, "Flavour", PDO_DBLIB_FLAVOUR);
+ php_info_print_table_end();
+}
+
diff --git a/ext/pdo_dblib/php_pdo_dblib.h b/ext/pdo_dblib/php_pdo_dblib.h
new file mode 100644
index 0000000000..5795b71153
--- /dev/null
+++ b/ext/pdo_dblib/php_pdo_dblib.h
@@ -0,0 +1,44 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 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: Wez Furlong <wez@php.net> |
+ | Frank M. Kromann <frank@kromann.info> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_PDO_DBLIB_H
+#define PHP_PDO_DBLIB_H
+
+
+extern zend_module_entry pdo_dblib_module_entry;
+#define phpext_pdo_dblib_ptr &pdo_dblib_module_entry
+
+#ifdef PHP_WIN32
+# define PHP_PDO_DBLIB_API __declspec(dllexport)
+#else
+# define PHP_PDO_DBLIB_API
+#endif
+
+#ifdef ZTS
+# include "TSRM.h"
+#endif
+
+PHP_MINIT_FUNCTION(pdo_dblib);
+PHP_MSHUTDOWN_FUNCTION(pdo_dblib);
+PHP_MINFO_FUNCTION(pdo_dblib);
+
+#endif
+
diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h
new file mode 100644
index 0000000000..481f3805f5
--- /dev/null
+++ b/ext/pdo_dblib/php_pdo_dblib_int.h
@@ -0,0 +1,124 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 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: Wez Furlong <wez@php.net> |
+ | Frank M. Kromann <frank@kromann.info> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_PDO_DBLIB_INT_H
+#define PHP_PDO_DBLIB_INT_H
+
+#if PHP_DBLIB_IS_MSSQL
+# include <sqlfront.h>
+# include <sqldb.h>
+
+# define DBERRHANDLE(a, b) dbprocerrhandle(a, b)
+# define DBMSGHANDLE(a, b) dbprocmsghandle(a, b)
+# define EHANDLEFUNC DBERRHANDLE_PROC
+# define MHANDLEFUNC DBMSGHANDLE_PROC
+# define DBSETOPT(a, b, b) dbsetopt(a, b, c)
+
+#else
+# include <sybfront.h>
+# include <sybdb.h>
+# include <syberror.h>
+
+/* alias some types */
+# define SQLTEXT SYBTEXT
+# define SQLCHAR SYBCHAR
+# define SQLVARCHAR SYBVARCHAR
+# define SQLINT1 SYBINT1
+# define SQLINT2 SYBINT2
+# define SQLINT4 SYBINT4
+# define SQLINTN SYBINTN
+# define SQLBIT SYBBIT
+# define SQLFLT4 SYBREAL
+# define SQLFLT8 SYBFLT8
+# define SQLFLTN SYBFLTN
+# define SQLDECIMAL SYBDECIMAL
+# define SQLNUMERIC SYBNUMERIC
+# define SQLDATETIME SYBDATETIME
+# define SQLDATETIM4 SYBDATETIME4
+# define SQLDATETIMN SYBDATETIMN
+# define SQLMONEY SYBMONEY
+# define SQLMONEY4 SYBMONEY4
+# define SQLMONEYN SYBMONEYN
+# define SQLIMAGE SYBIMAGE
+# define SQLBINARY SYBBINARY
+# define SQLVARBINARY SYBVARBINARY
+# ifdef SYBUNIQUE
+# define SQLUNIQUE SYBUNIQUE
+# endif
+
+# define DBERRHANDLE(a, b) dberrhandle(b)
+# define DBMSGHANDLE(a, b) dbmsghandle(b)
+# define DBSETOPT(a, b, c) dbsetopt(a, b, c, -1)
+# define NO_MORE_RPC_RESULTS 3
+# define dbfreelogin dbloginfree
+# define dbrpcexec dbrpcsend
+
+typedef short TDS_SHORT;
+# ifndef PHP_WIN32
+typedef unsigned char *LPBYTE;
+# endif
+typedef float DBFLT4;
+#endif
+
+extern pdo_driver_t pdo_dblib_driver;
+extern struct pdo_stmt_methods dblib_stmt_methods;
+
+typedef struct {
+ int severity;
+ int oserr;
+ int dberr;
+ char *oserrstr;
+ char *dberrstr;
+} pdo_dblib_err;
+
+typedef struct {
+ LOGINREC *login;
+ DBPROCESS *link;
+
+ pdo_dblib_err err;
+} pdo_dblib_db_handle;
+
+typedef struct {
+ int coltype;
+ char *name;
+ int maxlen;
+ char *source;
+} pdo_dblib_col;
+
+typedef struct {
+ unsigned long len;
+ char *data;
+} pdo_dblib_colval;
+
+typedef struct {
+ pdo_dblib_db_handle *H;
+
+ int ncols;
+ pdo_dblib_col *cols;
+
+ pdo_dblib_colval *rows;
+ int nrows;
+
+ int current;
+} pdo_dblib_stmt;
+
+#endif
+