wez             Fri Jul  8 11:27:35 2005 EDT

  Modified files:              
    /php-src/ext/pdo_pgsql      config.m4 pgsql_driver.c pgsql_statement.c 
                                php_pdo_pgsql_int.h 
  Log:
  Add early support for native prepared statements in pgsql.
  Note that some tests now fail; if we can't resolve this in time for the beta,
  the prepare code should be disabled (I'll add a flag for this later today).
  
  
  
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/config.m4?r1=1.11&r2=1.12&ty=u
Index: php-src/ext/pdo_pgsql/config.m4
diff -u php-src/ext/pdo_pgsql/config.m4:1.11 
php-src/ext/pdo_pgsql/config.m4:1.12
--- php-src/ext/pdo_pgsql/config.m4:1.11        Thu Jul  7 09:35:39 2005
+++ php-src/ext/pdo_pgsql/config.m4     Fri Jul  8 11:27:34 2005
@@ -1,5 +1,5 @@
 dnl
-dnl $Id: config.m4,v 1.11 2005/07/07 13:35:39 iliaa Exp $
+dnl $Id: config.m4,v 1.12 2005/07/08 15:27:34 wez Exp $
 dnl
 
 if test "$PHP_PDO" != "no"; then
@@ -93,6 +93,9 @@
   AC_CHECK_LIB(pq, PQExecParams,AC_DEFINE(HAVE_PQEXECPARAMS,1,[PostgreSQL 7.4 
or later]))
   AC_CHECK_LIB(pq, 
PQresultErrorField,AC_DEFINE(HAVE_PQRESULTERRORFIELD,1,[PostgreSQL 7.4 or 
later]))
   AC_CHECK_LIB(pq, 
pg_encoding_to_char,AC_DEFINE(HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT,1,[Whether 
libpq is compiled with --enable-multibyte]))
+  
+  AC_CHECK_LIB(pq, PQprepare,AC_DEFINE(HAVE_PQPREPARE,1,[prepared statements]))
+
   LIBS=$old_LIBS
   LDFLAGS=$old_LDFLAGS
 
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pgsql_driver.c?r1=1.49&r2=1.50&ty=u
Index: php-src/ext/pdo_pgsql/pgsql_driver.c
diff -u php-src/ext/pdo_pgsql/pgsql_driver.c:1.49 
php-src/ext/pdo_pgsql/pgsql_driver.c:1.50
--- php-src/ext/pdo_pgsql/pgsql_driver.c:1.49   Thu Jul  7 09:35:39 2005
+++ php-src/ext/pdo_pgsql/pgsql_driver.c        Fri Jul  8 11:27:34 2005
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: pgsql_driver.c,v 1.49 2005/07/07 13:35:39 iliaa Exp $ */
+/* $Id: pgsql_driver.c,v 1.50 2005/07/08 15:27:34 wez Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -132,19 +132,77 @@
        pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
        pdo_pgsql_stmt *S = ecalloc(1, sizeof(pdo_pgsql_stmt));
        int scrollable;
+#if HAVE_PQPREPARE
+       PGresult *res;
+       int ret;
+       char *nsql = NULL;
+       int nsql_len = 0;
+       ExecStatusType status;
+#endif
 
        S->H = H;
        stmt->driver_data = S;
        stmt->methods = &pgsql_stmt_methods;
-       stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
 
        scrollable = pdo_attr_lval(driver_options, PDO_ATTR_CURSOR,
                PDO_CURSOR_FWDONLY TSRMLS_CC) == PDO_CURSOR_SCROLL;
 
        if (scrollable) {
+               /* TODO: check how scrollable cursors related to prepared 
statements */
                spprintf(&S->cursor_name, 0, "pdo_pgsql_cursor_%08x", (unsigned 
int) stmt);
        }
 
+#if HAVE_PQPREPARE
+       stmt->supports_placeholders = PDO_PLACEHOLDER_NAMED;
+       stmt->named_rewrite_template = "$%d";
+       ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len 
TSRMLS_CC);
+       
+       if (ret == 1) {
+               /* query was re-written */
+               sql = nsql;
+       } else if (ret == -1) {
+               /* couldn't grok it */
+               strcpy(dbh->error_code, stmt->error_code);
+               return 0;
+       }
+       
+       spprintf(&S->stmt_name, 0, "pdo_pgsql_stmt_%08x", (unsigned int)stmt);
+       res = PQprepare(H->server, S->stmt_name, sql, 0, NULL);
+       if (nsql) {
+               efree(nsql);
+       }
+       if (!res) {
+               pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, NULL);
+               return 0;
+       }
+
+       /* check if the connection is using protocol version 2.0.
+        * if that is the reason that the prepare failed, we want to fall
+        * through and let PDO emulate it for us */
+       status = PQresultStatus(res);
+       switch (status) {
+               case PGRES_COMMAND_OK:
+               case PGRES_TUPLES_OK:
+                       /* it worked */
+                       return 1;
+
+               case PGRES_BAD_RESPONSE:
+                       /* server is probably too old; fall through and let
+                        * PDO emulate it */
+                       efree(S->stmt_name);
+                       S->stmt_name = NULL;
+                       break;
+
+               default:
+                       /* protocol 3.0 and above; hard error */
+                       pdo_pgsql_error(dbh, status, pdo_pgsql_sqlstate(res));
+                       PQclear(res);
+                       return 0;
+       }
+       /* fall through */
+#endif
+
+       stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
        return 1;
 }
 
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pgsql_statement.c?r1=1.24&r2=1.25&ty=u
Index: php-src/ext/pdo_pgsql/pgsql_statement.c
diff -u php-src/ext/pdo_pgsql/pgsql_statement.c:1.24 
php-src/ext/pdo_pgsql/pgsql_statement.c:1.25
--- php-src/ext/pdo_pgsql/pgsql_statement.c:1.24        Sat Jul  2 23:04:13 2005
+++ php-src/ext/pdo_pgsql/pgsql_statement.c     Fri Jul  8 11:27:34 2005
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: pgsql_statement.c,v 1.24 2005/07/03 03:04:13 wez Exp $ */
+/* $Id: pgsql_statement.c,v 1.25 2005/07/08 15:27:34 wez Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -49,6 +49,29 @@
                S->result = NULL;
        }
 
+#if HAVE_PQPREPARE
+       if (S->stmt_name) {
+               pdo_pgsql_db_handle *H = S->H;
+               char *q = NULL;
+               PGresult *res;
+
+               spprintf(&q, 0, "DEALLOCATE %s", S->stmt_name);
+               res = PQexec(H->server, q);
+               efree(q);
+               if (res) PQclear(res);
+               efree(S->stmt_name);
+               S->stmt_name = NULL;
+       }
+       if (S->param_lengths) {
+               efree(S->param_lengths);
+               S->param_lengths = NULL;
+       }
+       if (S->param_values) {
+               efree(S->param_values);
+               S->param_values = NULL;
+       }
+#endif
+
        if (S->cursor_name) {
                pdo_pgsql_db_handle *H = S->H;
                char *q = NULL;
@@ -67,6 +90,7 @@
                S->cols = NULL;
        }
        efree(S);
+       stmt->driver_data = NULL;
        return 1;
 }
 
@@ -86,6 +110,20 @@
        
        S->current_row = 0;
 
+#if HAVE_PQPREPARE
+       if (S->stmt_name) {
+               /* using a prepared statement */
+
+               S->result = PQexecPrepared(H->server, S->stmt_name,
+                               stmt->bound_params ?
+                                       
zend_hash_num_elements(stmt->bound_params) :
+                                       0,
+                               (const char**)S->param_values,
+                               S->param_lengths,
+                               NULL,
+                               0);
+       } else
+#endif
        if (S->cursor_name) {
                char *q = NULL;
                spprintf(&q, 0, "DECLARE %s CURSOR FOR %s", S->cursor_name, 
stmt->active_query_string);
@@ -119,6 +157,44 @@
 static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data 
*param,
                enum pdo_param_event event_type TSRMLS_DC)
 {
+       pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
+
+       if (S->stmt_name && param->is_param) {
+               switch (event_type) {
+                       case PDO_PARAM_EVT_ALLOC:
+                               /* decode name from $1, $2 into 0, 1 etc. */
+                               if (param->name) {
+                                       param->paramno = atoi(param->name + 1);
+                               }
+                               break;
+
+                       case PDO_PARAM_EVT_EXEC_PRE:
+                               if (!S->param_values) {
+                                       S->param_values = ecalloc(
+                                                       
zend_hash_num_elements(stmt->bound_params),
+                                                       sizeof(char*));
+                                       S->param_lengths = ecalloc(
+                                                       
zend_hash_num_elements(stmt->bound_params),
+                                                       sizeof(int));
+                                       S->param_formats = ecalloc(
+                                                       
zend_hash_num_elements(stmt->bound_params),
+                                                       sizeof(int));
+
+                               }
+                               if (PDO_PARAM_TYPE(param->param_type) == 
PDO_PARAM_NULL ||
+                                               Z_TYPE_P(param->parameter) == 
IS_NULL) {
+                                       S->param_values[param->paramno] = NULL;
+                                       S->param_lengths[param->paramno] = 0;
+                               } else {
+                                       convert_to_string(param->parameter);
+                                       S->param_values[param->paramno] = 
Z_STRVAL_P(param->parameter);
+                                       S->param_lengths[param->paramno] = 
Z_STRLEN_P(param->parameter);
+                                       S->param_formats[param->paramno] = 1;
+                               }
+
+                               break;
+               }
+       }
        return 1;
 }
 
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h?r1=1.11&r2=1.12&ty=u
Index: php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h
diff -u php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.11 
php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.12
--- php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.11      Fri Jul  1 18:30:55 2005
+++ php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h   Fri Jul  8 11:27:34 2005
@@ -2,7 +2,7 @@
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
-  | Copyright (c) 1997-2004 The PHP Group                                |
+  | 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        |
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: php_pdo_pgsql_int.h,v 1.11 2005/07/01 22:30:55 edink Exp $ */
+/* $Id: php_pdo_pgsql_int.h,v 1.12 2005/07/08 15:27:34 wez Exp $ */
 
 #ifndef PHP_PDO_PGSQL_INT_H
 #define PHP_PDO_PGSQL_INT_H
@@ -55,6 +55,12 @@
        int                     current_row;
        pdo_pgsql_column        *cols;
        char *cursor_name;
+#if HAVE_PQPREPARE
+       char *stmt_name;
+       char **param_values;
+       int *param_lengths;
+       int *param_formats;
+#endif
 } pdo_pgsql_stmt;
 
 typedef struct {

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to