Back to index

php5  5.3.10
php_pdo_driver.h
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.01 of the PHP license,      |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available through the world-wide-web at the following url:           |
00010   | http://www.php.net/license/3_01.txt                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Author: Wez Furlong <wez@php.net>                                    |
00016   +----------------------------------------------------------------------+
00017 */
00018 
00019 /* $Id: php_pdo_driver.h 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #ifndef PHP_PDO_DRIVER_H
00022 #define PHP_PDO_DRIVER_H
00023 
00024 #include "php_pdo.h"
00025 
00026 /* forward declarations */
00027 typedef struct _pdo_dbh_t   pdo_dbh_t;
00028 typedef struct _pdo_stmt_t  pdo_stmt_t;
00029 struct pdo_bound_param_data;
00030 
00031 #ifdef PHP_WIN32
00032 typedef __int64 pdo_int64_t;
00033 typedef unsigned __int64 pdo_uint64_t;
00034 #else
00035 typedef long long int pdo_int64_t;
00036 typedef unsigned long long int pdo_uint64_t;
00037 #endif
00038 PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC);
00039 
00040 #ifndef TRUE
00041 # define TRUE 1
00042 #endif
00043 #ifndef FALSE
00044 # define FALSE 0
00045 #endif
00046 
00047 #define PDO_DRIVER_API      20080721
00048 
00049 enum pdo_param_type {
00050        PDO_PARAM_NULL,
00051 
00052        /* int as in long (the php native int type).
00053         * If you mark a column as an int, PDO expects get_col to return
00054         * a pointer to a long */
00055        PDO_PARAM_INT,
00056 
00057        /* get_col ptr should point to start of the string buffer */
00058        PDO_PARAM_STR,
00059 
00060        /* get_col: when len is 0 ptr should point to a php_stream *,
00061         * otherwise it should behave like a string. Indicate a NULL field
00062         * value by setting the ptr to NULL */
00063        PDO_PARAM_LOB,
00064 
00065        /* get_col: will expect the ptr to point to a new PDOStatement object handle,
00066         * but this isn't wired up yet */
00067        PDO_PARAM_STMT, /* hierarchical result set */
00068 
00069        /* get_col ptr should point to a zend_bool */
00070        PDO_PARAM_BOOL,
00071 
00072        /* get_col ptr should point to a zval*
00073           and the driver is responsible for adding correct type information to get_column_meta()
00074         */
00075        PDO_PARAM_ZVAL
00076 };
00077 
00078 /* magic flag to denote a parameter as being input/output */
00079 #define       PDO_PARAM_INPUT_OUTPUT      0x80000000    
00080 
00081 #define PDO_PARAM_FLAGS                   0xFFFF0000
00082 
00083 #define PDO_PARAM_TYPE(x)          ((x) & ~PDO_PARAM_FLAGS)
00084 
00085 enum pdo_fetch_type {
00086        PDO_FETCH_USE_DEFAULT,
00087        PDO_FETCH_LAZY,
00088        PDO_FETCH_ASSOC,
00089        PDO_FETCH_NUM,
00090        PDO_FETCH_BOTH,
00091        PDO_FETCH_OBJ,
00092        PDO_FETCH_BOUND, /* return true/false only; rely on bound columns */
00093        PDO_FETCH_COLUMN,    /* fetch a numbered column only */
00094        PDO_FETCH_CLASS,     /* create an instance of named class, call ctor and set properties */
00095        PDO_FETCH_INTO,             /* fetch row into an existing object */
00096        PDO_FETCH_FUNC,             /* fetch into function and return its result */
00097        PDO_FETCH_NAMED,    /* like PDO_FETCH_ASSOC, but can handle duplicate names */
00098        PDO_FETCH_KEY_PAIR,  /* fetch into an array where the 1st column is a key and all subsequent columns are values */
00099        PDO_FETCH__MAX /* must be last */
00100 };
00101 
00102 #define PDO_FETCH_FLAGS     0xFFFF0000  /* fetchAll() modes or'd to PDO_FETCH_XYZ */
00103 #define PDO_FETCH_GROUP     0x00010000  /* fetch into groups */
00104 #define PDO_FETCH_UNIQUE    0x00030000  /* fetch into groups assuming first col is unique */
00105 #define PDO_FETCH_CLASSTYPE 0x00040000  /* fetch class gets its class name from 1st column */
00106 #define PDO_FETCH_SERIALIZE 0x00080000  /* fetch class instances by calling serialize */
00107 #define PDO_FETCH_PROPS_LATE 0x00100000  /* fetch props after calling ctor */
00108 
00109 /* fetch orientation for scrollable cursors */
00110 enum pdo_fetch_orientation {
00111        PDO_FETCH_ORI_NEXT,         /* default: fetch the next available row */
00112        PDO_FETCH_ORI_PRIOR, /* scroll back to prior row and fetch that */
00113        PDO_FETCH_ORI_FIRST, /* scroll to the first row and fetch that */
00114        PDO_FETCH_ORI_LAST,         /* scroll to the last row and fetch that */
00115        PDO_FETCH_ORI_ABS,          /* scroll to an absolute numbered row and fetch that */
00116        PDO_FETCH_ORI_REL           /* scroll relative to the current row, and fetch that */
00117 };
00118 
00119 enum pdo_attribute_type {
00120        PDO_ATTR_AUTOCOMMIT, /* use to turn on or off auto-commit mode */
00121        PDO_ATTR_PREFETCH,          /* configure the prefetch size for drivers that support it. Size is in KB */
00122        PDO_ATTR_TIMEOUT,           /* connection timeout in seconds */
00123        PDO_ATTR_ERRMODE,           /* control how errors are handled */
00124        PDO_ATTR_SERVER_VERSION,    /* database server version */
00125        PDO_ATTR_CLIENT_VERSION,    /* client library version */
00126        PDO_ATTR_SERVER_INFO,              /* server information */
00127        PDO_ATTR_CONNECTION_STATUS, /* connection status */
00128        PDO_ATTR_CASE,                            /* control case folding for portability */
00129        PDO_ATTR_CURSOR_NAME,              /* name a cursor for use in "WHERE CURRENT OF <name>" */
00130        PDO_ATTR_CURSOR,                   /* cursor type */
00131        PDO_ATTR_ORACLE_NULLS,             /* convert empty strings to NULL */
00132        PDO_ATTR_PERSISTENT,        /* pconnect style connection */
00133        PDO_ATTR_STATEMENT_CLASS,   /* array(classname, array(ctor_args)) to specify the class of the constructed statement */
00134        PDO_ATTR_FETCH_TABLE_NAMES, /* include table names in the column names, where available */
00135        PDO_ATTR_FETCH_CATALOG_NAMES, /* include the catalog/db name names in the column names, where available */
00136        PDO_ATTR_DRIVER_NAME,                /* name of the driver (as used in the constructor) */
00137        PDO_ATTR_STRINGIFY_FETCHES, /* converts integer/float types to strings during fetch */
00138        PDO_ATTR_MAX_COLUMN_LEN,    /* make database calculate maximum length of data found in a column */
00139        PDO_ATTR_DEFAULT_FETCH_MODE, /* Set the default fetch mode */
00140        PDO_ATTR_EMULATE_PREPARES,  /* use query emulation rather than native */
00141 
00142        /* this defines the start of the range for driver specific options.
00143         * Drivers should define their own attribute constants beginning with this
00144         * value. */
00145        PDO_ATTR_DRIVER_SPECIFIC = 1000
00146 };
00147 
00148 enum pdo_cursor_type {
00149        PDO_CURSOR_FWDONLY,         /* forward only cursor (default) */
00150        PDO_CURSOR_SCROLL           /* scrollable cursor */
00151 };
00152 
00153 /* SQL-92 SQLSTATE error codes.
00154 
00155 The character string value returned for an SQLSTATE consists of a two-character
00156 class value followed by a three-character subclass value. A class value of 01
00157 indicates a warning and is accompanied by a return code of
00158 SQL_SUCCESS_WITH_INFO.
00159 
00160 Class values other than '01', except for the class 'IM',
00161 indicate an error and are accompanied by a return code of SQL_ERROR. The class
00162 'IM' is specific to warnings and errors that derive from the implementation of
00163 ODBC itself.
00164 
00165 The subclass value '000' in any class indicates that there is no
00166 subclass for that SQLSTATE. The assignment of class and subclass values is
00167 defined by SQL-92.
00168 */
00169 
00170 typedef char pdo_error_type[6]; /* SQLSTATE */
00171 
00172 
00173 #define PDO_ERR_NONE                      "00000"
00174 
00175 enum pdo_error_mode {
00176        PDO_ERRMODE_SILENT,         /* just set error codes */
00177        PDO_ERRMODE_WARNING, /* raise E_WARNING */
00178        PDO_ERRMODE_EXCEPTION       /* throw exceptions */
00179 };
00180 
00181 enum pdo_case_conversion {
00182        PDO_CASE_NATURAL,
00183        PDO_CASE_UPPER,
00184        PDO_CASE_LOWER
00185 };
00186 
00187 /* oracle interop settings */
00188 enum pdo_null_handling {
00189        PDO_NULL_NATURAL = 0,
00190        PDO_NULL_EMPTY_STRING = 1,
00191        PDO_NULL_TO_STRING = 2
00192 };
00193 
00194 /* {{{ utils for reading attributes set as driver_options */
00195 static inline long pdo_attr_lval(zval *options, enum pdo_attribute_type option_name, long defval TSRMLS_DC)
00196 {
00197        zval **v;
00198 
00199        if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
00200               convert_to_long_ex(v);
00201               return Z_LVAL_PP(v);
00202        }
00203        return defval;
00204 }
00205 static inline char *pdo_attr_strval(zval *options, enum pdo_attribute_type option_name, char *defval TSRMLS_DC)
00206 {
00207        zval **v;
00208 
00209        if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
00210               convert_to_string_ex(v);
00211               return estrndup(Z_STRVAL_PP(v), Z_STRLEN_PP(v));
00212        }
00213        return defval ? estrdup(defval) : NULL;
00214 }
00215 /* }}} */
00216 
00217 /* This structure is registered with PDO when a PDO driver extension is
00218  * initialized */
00219 typedef struct {
00220        const char           *driver_name;
00221        unsigned long driver_name_len;
00222        unsigned long api_version; /* needs to be compatible with PDO */
00223 
00224 #define PDO_DRIVER_HEADER(name)    \
00225        #name, sizeof(#name)-1, \
00226        PDO_DRIVER_API
00227        
00228        /* create driver specific portion of the database handle and stash it into
00229         * the dbh.  dbh contains the data source string and flags for this
00230         * instance.  You MUST respect dbh->is_persistent and pass that flag to
00231         * pemalloc() for all allocations that are stored in the dbh or your instance
00232         * data in the db, otherwise you will crash PHP when persistent connections
00233         * are used.
00234         */
00235        int (*db_handle_factory)(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC);
00236 
00237 } pdo_driver_t;
00238 
00239 /* {{{ methods for a database handle */
00240 
00241 /* close or otherwise disconnect the database */
00242 typedef int (*pdo_dbh_close_func)(pdo_dbh_t *dbh TSRMLS_DC);
00243 
00244 /* prepare a statement and stash driver specific portion into stmt */
00245 typedef int (*pdo_dbh_prepare_func)(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC);
00246 
00247 /* execute a statement (that does not return a result set) */
00248 typedef long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC);
00249 
00250 /* quote a string */
00251 typedef int (*pdo_dbh_quote_func)(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC);
00252 
00253 /* transaction related */
00254 typedef int (*pdo_dbh_txn_func)(pdo_dbh_t *dbh TSRMLS_DC);
00255 
00256 /* setting of attributes */
00257 typedef int (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
00258 
00259 /* return last insert id.  NULL indicates error condition, otherwise, the return value
00260  * MUST be an emalloc'd NULL terminated string. */
00261 typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC);
00262 
00263 /* fetch error information.  if stmt is not null, fetch information pertaining
00264  * to the statement, otherwise fetch global error information.  The driver
00265  * should add the following information to the array "info" in this order:
00266  * - native error code
00267  * - string representation of the error code ... any other optional driver
00268  *   specific data ...  */
00269 typedef       int (*pdo_dbh_fetch_error_func)(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC);
00270 
00271 /* fetching of attributes */
00272 typedef int (*pdo_dbh_get_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
00273 
00274 /* checking/pinging persistent connections; return SUCCESS if the connection
00275  * is still alive and ready to be used, FAILURE otherwise.
00276  * You may set this handler to NULL, which is equivalent to returning SUCCESS. */
00277 typedef int (*pdo_dbh_check_liveness_func)(pdo_dbh_t *dbh TSRMLS_DC);
00278 
00279 /* called at request end for each persistent dbh; this gives the driver
00280  * the opportunity to safely release resources that only have per-request
00281  * scope */
00282 typedef void (*pdo_dbh_request_shutdown)(pdo_dbh_t *dbh TSRMLS_DC);
00283 
00284 /* for adding methods to the dbh or stmt objects 
00285 pointer to a list of driver specific functions. The convention is
00286 to prefix the function names using the PDO driver name; this will
00287 reduce the chance of collisions with future functionality in the
00288 PDO class or in user code (they can extend the PDO object).
00289 */
00290 enum {
00291        PDO_DBH_DRIVER_METHOD_KIND_DBH = 0,
00292        PDO_DBH_DRIVER_METHOD_KIND_STMT,
00293        PDO_DBH_DRIVER_METHOD_KIND__MAX
00294 };
00295 
00296 typedef const zend_function_entry *(*pdo_dbh_get_driver_methods_func)(pdo_dbh_t *dbh, int kind TSRMLS_DC);
00297 
00298 struct pdo_dbh_methods {
00299        pdo_dbh_close_func          closer;
00300        pdo_dbh_prepare_func preparer;
00301        pdo_dbh_do_func                    doer;
00302        pdo_dbh_quote_func          quoter;
00303        pdo_dbh_txn_func            begin;
00304        pdo_dbh_txn_func            commit;
00305        pdo_dbh_txn_func            rollback;
00306        pdo_dbh_set_attr_func       set_attribute;
00307        pdo_dbh_last_id_func        last_id;
00308        pdo_dbh_fetch_error_func    fetch_err;
00309        pdo_dbh_get_attr_func       get_attribute;
00310        pdo_dbh_check_liveness_func check_liveness;
00311        pdo_dbh_get_driver_methods_func get_driver_methods;
00312        pdo_dbh_request_shutdown    persistent_shutdown;
00313 };
00314 
00315 /* }}} */
00316 
00317 /* {{{ methods for a statement handle */
00318 
00319 /* free the statement handle */
00320 typedef int (*pdo_stmt_dtor_func)(pdo_stmt_t *stmt TSRMLS_DC);
00321 
00322 /* start the query */
00323 typedef int (*pdo_stmt_execute_func)(pdo_stmt_t *stmt TSRMLS_DC);
00324 
00325 /* causes the next row in the set to be fetched; indicates if there are no
00326  * more rows.  The ori and offset params modify which row should be returned,
00327  * if the stmt represents a scrollable cursor */
00328 typedef int (*pdo_stmt_fetch_func)(pdo_stmt_t *stmt, 
00329        enum pdo_fetch_orientation ori, long offset TSRMLS_DC);
00330 
00331 /* queries information about the type of a column, by index (0 based).
00332  * Driver should populate stmt->columns[colno] with appropriate info */
00333 typedef int (*pdo_stmt_describe_col_func)(pdo_stmt_t *stmt, int colno TSRMLS_DC);
00334 
00335 /* retrieves pointer and size of the value for a column.
00336  * Note that PDO expects the driver to manage the lifetime of this data;
00337  * it will copy the value into a zval on behalf of the script.
00338  * If the driver sets caller_frees, ptr should point to emalloc'd memory
00339  * and PDO will free it as soon as it is done using it.
00340  */
00341 typedef int (*pdo_stmt_get_col_data_func)(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC);
00342 
00343 /* hook for bound params */
00344 enum pdo_param_event {
00345        PDO_PARAM_EVT_ALLOC,
00346        PDO_PARAM_EVT_FREE,
00347        PDO_PARAM_EVT_EXEC_PRE,
00348        PDO_PARAM_EVT_EXEC_POST,
00349        PDO_PARAM_EVT_FETCH_PRE,
00350        PDO_PARAM_EVT_FETCH_POST,
00351        PDO_PARAM_EVT_NORMALIZE
00352 };
00353 
00354 typedef int (*pdo_stmt_param_hook_func)(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC);
00355 
00356 /* setting of attributes */
00357 typedef int (*pdo_stmt_set_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);
00358 
00359 /* fetching of attributes */
00360 typedef int (*pdo_stmt_get_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);
00361 
00362 /* retrieves meta data for a numbered column.
00363  * Returns SUCCESS/FAILURE.
00364  * On SUCCESS, fill in return_value with an array with the following fields.
00365  * If a particular field is not supported, then the driver simply does not add it to
00366  * the array, so that scripts can use isset() to check for it.
00367  *
00368  * ### this is just a rough first cut, and subject to change ###
00369  *
00370  * these are added by PDO itself, based on data from the describe handler:
00371  *   name => the column name
00372  *   len => the length/size of the column
00373  *   precision => precision of the column
00374  *   pdo_type => an integer, one of the PDO_PARAM_XXX values
00375  *
00376  *   scale => the floating point scale
00377  *   table => the table for that column
00378  *   type => a string representation of the type, mapped to the PHP equivalent type name
00379  *   native_type => a string representation of the type, native style, if different from
00380  *                  the mapped name.
00381  *   flags => an array of flags including zero or more of the following:
00382  *            primary_key, not_null, unique_key, multiple_key, unsigned, auto_increment, blob
00383  *
00384  * Any driver specific data should be returned using a prefixed key or value.
00385  * Eg: custom data for the mysql driver would use either
00386  *   'mysql:foobar' => 'some data' // to add a new key to the array
00387  * or
00388  *   'flags' => array('not_null', 'mysql:some_flag'); // to add data to an existing key
00389  */
00390 typedef int (*pdo_stmt_get_column_meta_func)(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC);
00391 
00392 /* advances the statement to the next rowset of the batch.
00393  * If it returns 1, PDO will tear down its idea of columns
00394  * and meta data.  If it returns 0, PDO will indicate an error
00395  * to the caller. */
00396 typedef int (*pdo_stmt_next_rowset_func)(pdo_stmt_t *stmt TSRMLS_DC);
00397 
00398 /* closes the active cursor on a statement, leaving the prepared
00399  * statement ready for re-execution.  Useful to explicitly state
00400  * that you are done with a given rowset, without having to explicitly
00401  * fetch all the rows. */
00402 typedef int (*pdo_stmt_cursor_closer_func)(pdo_stmt_t *stmt TSRMLS_DC);
00403 
00404 struct pdo_stmt_methods {
00405        pdo_stmt_dtor_func                 dtor;
00406        pdo_stmt_execute_func              executer;
00407        pdo_stmt_fetch_func                fetcher;
00408        pdo_stmt_describe_col_func  describer;
00409        pdo_stmt_get_col_data_func  get_col;
00410        pdo_stmt_param_hook_func    param_hook;
00411        pdo_stmt_set_attr_func             set_attribute;
00412        pdo_stmt_get_attr_func             get_attribute;
00413        pdo_stmt_get_column_meta_func get_column_meta;
00414        pdo_stmt_next_rowset_func          next_rowset;
00415        pdo_stmt_cursor_closer_func        cursor_closer;
00416 };
00417 
00418 /* }}} */
00419 
00420 enum pdo_placeholder_support {
00421        PDO_PLACEHOLDER_NONE=0,
00422        PDO_PLACEHOLDER_NAMED=1,
00423        PDO_PLACEHOLDER_POSITIONAL=2
00424 };
00425 
00426 /* represents a connection to a database */
00427 struct _pdo_dbh_t {
00428        /* these items must appear in this order at the beginning of the
00429        struct so that this can be cast as a zend_object.  we need this
00430        to allow the extending class to escape all the custom handlers
00431           that PDO declares.
00432     */
00433        zend_class_entry *ce; 
00434        HashTable *properties;
00435        unsigned int in_get:1;
00436        unsigned int in_set:1;
00437 
00438        /* driver specific methods */
00439        struct pdo_dbh_methods *methods;
00440        /* driver specific data */
00441        void *driver_data;
00442 
00443        /* credentials */
00444        char *username, *password;
00445        
00446        /* if true, then data stored and pointed at by this handle must all be
00447         * persistently allocated */
00448        unsigned is_persistent:1;
00449 
00450        /* if true, driver should act as though a COMMIT were executed between
00451         * each executed statement; otherwise, COMMIT must be carried out manually
00452         * */
00453        unsigned auto_commit:1;
00454 
00455        /* if true, the handle has been closed and will not function anymore */
00456        unsigned is_closed:1;
00457 
00458        /* if true, the driver requires that memory be allocated explicitly for
00459         * the columns that are returned */
00460        unsigned alloc_own_columns:1;
00461 
00462        /* if true, commit or rollBack is allowed to be called */
00463        unsigned in_txn:1;
00464 
00465        /* max length a single character can become after correct quoting */
00466        unsigned max_escaped_char_length:3;
00467 
00468        /* oracle compat; see enum pdo_null_handling */
00469        unsigned oracle_nulls:2;
00470 
00471        /* when set, convert int/floats to strings */
00472        unsigned stringify:1;
00473 
00474        /* the sum of the number of bits here and the bit fields preceeding should
00475         * equal 32 */
00476        unsigned _reserved_flags:21;
00477 
00478        /* data source string used to open this handle */
00479        const char *data_source;
00480        unsigned long data_source_len;
00481 
00482        /* the global error code. */
00483        pdo_error_type error_code;
00484 
00485        enum pdo_error_mode error_mode;
00486 
00487        enum pdo_case_conversion native_case, desired_case;
00488 
00489        /* persistent hash key associated with this handle */
00490        const char *persistent_id;
00491        int persistent_id_len;
00492        unsigned int refcount;
00493 
00494        /* driver specific "class" methods for the dbh and stmt */
00495        HashTable *cls_methods[PDO_DBH_DRIVER_METHOD_KIND__MAX];
00496 
00497        pdo_driver_t *driver;
00498        
00499        zend_class_entry *def_stmt_ce;
00500 
00501        zval *def_stmt_ctor_args;
00502 
00503        /* when calling PDO::query(), we need to keep the error
00504         * context from the statement around until we next clear it.
00505         * This will allow us to report the correct error message
00506         * when PDO::query() fails */
00507        pdo_stmt_t *query_stmt;
00508        zval query_stmt_zval;
00509 
00510        /* defaults for fetches */
00511        enum pdo_fetch_type default_fetch_type;
00512 };
00513 
00514 /* describes a column */
00515 struct pdo_column_data {
00516        char *name;
00517        int namelen;
00518        unsigned long maxlen;
00519        enum pdo_param_type param_type;
00520        unsigned long precision;
00521 
00522        /* don't touch this unless your name is dbdo */
00523        void *dbdo_data;
00524 };
00525 
00526 /* describes a bound parameter */
00527 struct pdo_bound_param_data {
00528        long paramno; /* if -1, then it has a name, and we don't know the index *yet* */
00529        char *name;
00530        int namelen;
00531 
00532        long max_value_len;  /* as a hint for pre-allocation */
00533        
00534        zval *parameter;                          /* the variable itself */
00535        enum pdo_param_type param_type; /* desired or suggested type */
00536 
00537        zval *driver_params;               /* optional parameter(s) for the driver */
00538        void *driver_data;
00539 
00540        pdo_stmt_t *stmt;    /* for convenience in dtor */
00541        int is_param;        /* parameter or column ? */
00542 };
00543 
00544 /* represents a prepared statement */
00545 struct _pdo_stmt_t {
00546        /* these items must appear in this order at the beginning of the
00547        struct so that this can be cast as a zend_object.  we need this
00548        to allow the extending class to escape all the custom handlers
00549           that PDO declares.
00550     */
00551        zend_class_entry *ce; 
00552        HashTable *properties;
00553        unsigned int in_get:1;
00554        unsigned int in_set:1;
00555 
00556        /* driver specifics */
00557        struct pdo_stmt_methods *methods;
00558        void *driver_data;
00559 
00560        /* if true, we've already successfully executed this statement at least
00561         * once */
00562        unsigned executed:1;
00563        /* if true, the statement supports placeholders and can implement
00564         * bindParam() for its prepared statements, if false, PDO should
00565         * emulate prepare and bind on its behalf */
00566        unsigned supports_placeholders:2;
00567 
00568        unsigned _reserved:29;
00569 
00570        /* the number of columns in the result set; not valid until after
00571         * the statement has been executed at least once.  In some cases, might
00572         * not be valid until fetch (at the driver level) has been called at least once.
00573         * */
00574        int column_count;
00575        struct pdo_column_data *columns;
00576        
00577        /* we want to keep the dbh alive while we live, so we own a reference */
00578        zval database_object_handle;
00579        pdo_dbh_t *dbh;
00580 
00581        /* keep track of bound input parameters.  Some drivers support
00582         * input/output parameters, but you can't rely on that working */
00583        HashTable *bound_params;
00584        /* When rewriting from named to positional, this maps positions to names */
00585        HashTable *bound_param_map;
00586        /* keep track of PHP variables bound to named (or positional) columns
00587         * in the result set */
00588        HashTable *bound_columns;
00589 
00590        /* not always meaningful */
00591        long row_count;
00592 
00593        /* used to hold the statement's current query */
00594        char *query_string;
00595        int query_stringlen;
00596 
00597        /* the copy of the query with expanded binds ONLY for emulated-prepare drivers */
00598        char *active_query_string;
00599        int active_query_stringlen;
00600 
00601        /* the cursor specific error code. */
00602        pdo_error_type error_code;
00603 
00604        /* for lazy fetches, we always return the same lazy object handle.
00605         * Let's keep it here. */
00606        zval lazy_object_ref;
00607        unsigned long refcount;
00608 
00609        /* defaults for fetches */
00610        enum pdo_fetch_type default_fetch_type;
00611        union {
00612               int column;
00613               struct {
00614                      zend_class_entry *ce;       
00615                      zval *ctor_args;            /* freed */
00616                      zval *retval_ptr; 
00617                      zend_fcall_info fci;
00618                      zend_fcall_info_cache fcc;
00619               } cls;
00620               struct {
00621                      zval *function;
00622                      zval *fetch_args;           /* freed */
00623                      zval *object;
00624                      zend_fcall_info fci;
00625                      zend_fcall_info_cache fcc;
00626                      zval **values;              /* freed */
00627               } func;
00628               zval *into;
00629        } fetch;
00630 
00631        /* used by the query parser for driver specific
00632         * parameter naming (see pgsql driver for example) */
00633        const char *named_rewrite_template;
00634 };
00635 
00636 /* call this in MINIT to register your PDO driver */
00637 PDO_API int php_pdo_register_driver(pdo_driver_t *driver);
00638 /* call this in MSHUTDOWN to unregister your PDO driver */
00639 PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver);
00640 
00641 /* For the convenience of drivers, this function will parse a data source
00642  * string, of the form "name=value; name2=value2" and populate variables
00643  * according to the data you pass in and array of pdo_data_src_parser structures */
00644 struct pdo_data_src_parser {
00645        const char *optname;
00646        char *optval;
00647        int freeme;
00648 };
00649 
00650 PDO_API int php_pdo_parse_data_source(const char *data_source,
00651               unsigned long data_source_len, struct pdo_data_src_parser *parsed,
00652               int nparams);
00653 
00654 PDO_API zend_class_entry *php_pdo_get_dbh_ce(void);
00655 PDO_API zend_class_entry *php_pdo_get_exception(void);
00656 
00657 PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, 
00658        char **outquery, int *outquery_len TSRMLS_DC);
00659 
00660 PDO_API void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt,
00661        const char *sqlstate, const char *supp TSRMLS_DC);
00662 
00663 PDO_API void php_pdo_dbh_addref(pdo_dbh_t *dbh TSRMLS_DC);
00664 PDO_API void php_pdo_dbh_delref(pdo_dbh_t *dbh TSRMLS_DC);
00665 
00666 PDO_API void php_pdo_stmt_addref(pdo_stmt_t *stmt TSRMLS_DC);
00667 PDO_API void php_pdo_stmt_delref(pdo_stmt_t *stmt TSRMLS_DC);
00668 
00669 
00670 #endif /* PHP_PDO_DRIVER_H */
00671 /*
00672  * Local variables:
00673  * tab-width: 4
00674  * c-basic-offset: 4
00675  * End:
00676  * vim600: noet sw=4 ts=4 fdm=marker
00677  * vim<600: noet sw=4 ts=4
00678  */