1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 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_01.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: Wez Furlong <wez@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: php_pdo_driver.h 272374 2008-12-31 11:17:49Z sebastian $ */
20 :
21 : #ifndef PHP_PDO_DRIVER_H
22 : #define PHP_PDO_DRIVER_H
23 :
24 : #include "php_pdo.h"
25 :
26 : /* forward declarations */
27 : typedef struct _pdo_dbh_t pdo_dbh_t;
28 : typedef struct _pdo_stmt_t pdo_stmt_t;
29 : struct pdo_bound_param_data;
30 :
31 : #ifdef PHP_WIN32
32 : typedef __int64 pdo_int64_t;
33 : typedef unsigned __int64 pdo_uint64_t;
34 : #else
35 : typedef long long int pdo_int64_t;
36 : typedef unsigned long long int pdo_uint64_t;
37 : #endif
38 : PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC);
39 :
40 : #ifndef TRUE
41 : # define TRUE 1
42 : #endif
43 : #ifndef FALSE
44 : # define FALSE 0
45 : #endif
46 :
47 : #define PDO_DRIVER_API 20060511
48 :
49 : enum pdo_param_type {
50 : PDO_PARAM_NULL,
51 :
52 : /* int as in long (the php native int type).
53 : * If you mark a column as an int, PDO expects get_col to return
54 : * a pointer to a long */
55 : PDO_PARAM_INT,
56 :
57 : /* get_col ptr should point to start of the string buffer */
58 : PDO_PARAM_STR,
59 :
60 : /* get_col: when len is 0 ptr should point to a php_stream *,
61 : * otherwise it should behave like a string. Indicate a NULL field
62 : * value by setting the ptr to NULL */
63 : PDO_PARAM_LOB,
64 :
65 : /* get_col: will expect the ptr to point to a new PDOStatement object handle,
66 : * but this isn't wired up yet */
67 : PDO_PARAM_STMT, /* hierarchical result set */
68 :
69 : /* get_col ptr should point to a zend_bool */
70 : PDO_PARAM_BOOL
71 : };
72 :
73 : /* magic flag to denote a parameter as being input/output */
74 : #define PDO_PARAM_INPUT_OUTPUT 0x80000000
75 :
76 : #define PDO_PARAM_FLAGS 0xFFFF0000
77 :
78 : #define PDO_PARAM_TYPE(x) ((x) & ~PDO_PARAM_FLAGS)
79 :
80 : enum pdo_fetch_type {
81 : PDO_FETCH_USE_DEFAULT,
82 : PDO_FETCH_LAZY,
83 : PDO_FETCH_ASSOC,
84 : PDO_FETCH_NUM,
85 : PDO_FETCH_BOTH,
86 : PDO_FETCH_OBJ,
87 : PDO_FETCH_BOUND, /* return true/false only; rely on bound columns */
88 : PDO_FETCH_COLUMN, /* fetch a numbered column only */
89 : PDO_FETCH_CLASS, /* create an instance of named class, call ctor and set properties */
90 : PDO_FETCH_INTO, /* fetch row into an existing object */
91 : PDO_FETCH_FUNC, /* fetch into function and return its result */
92 : PDO_FETCH_NAMED, /* like PDO_FETCH_ASSOC, but can handle duplicate names */
93 : PDO_FETCH_KEY_PAIR, /* fetch into an array where the 1st column is a key and all subsequent columns are values */
94 : PDO_FETCH__MAX /* must be last */
95 : };
96 :
97 : #define PDO_FETCH_FLAGS 0xFFFF0000 /* fetchAll() modes or'd to PDO_FETCH_XYZ */
98 : #define PDO_FETCH_GROUP 0x00010000 /* fetch into groups */
99 : #define PDO_FETCH_UNIQUE 0x00030000 /* fetch into groups assuming first col is unique */
100 : #define PDO_FETCH_CLASSTYPE 0x00040000 /* fetch class gets its class name from 1st column */
101 : #define PDO_FETCH_SERIALIZE 0x00080000 /* fetch class instances by calling serialize */
102 : #define PDO_FETCH_PROPS_LATE 0x00100000 /* fetch props after calling ctor */
103 :
104 : /* fetch orientation for scrollable cursors */
105 : enum pdo_fetch_orientation {
106 : PDO_FETCH_ORI_NEXT, /* default: fetch the next available row */
107 : PDO_FETCH_ORI_PRIOR, /* scroll back to prior row and fetch that */
108 : PDO_FETCH_ORI_FIRST, /* scroll to the first row and fetch that */
109 : PDO_FETCH_ORI_LAST, /* scroll to the last row and fetch that */
110 : PDO_FETCH_ORI_ABS, /* scroll to an absolute numbered row and fetch that */
111 : PDO_FETCH_ORI_REL /* scroll relative to the current row, and fetch that */
112 : };
113 :
114 : enum pdo_attribute_type {
115 : PDO_ATTR_AUTOCOMMIT, /* use to turn on or off auto-commit mode */
116 : PDO_ATTR_PREFETCH, /* configure the prefetch size for drivers that support it. Size is in KB */
117 : PDO_ATTR_TIMEOUT, /* connection timeout in seconds */
118 : PDO_ATTR_ERRMODE, /* control how errors are handled */
119 : PDO_ATTR_SERVER_VERSION, /* database server version */
120 : PDO_ATTR_CLIENT_VERSION, /* client library version */
121 : PDO_ATTR_SERVER_INFO, /* server information */
122 : PDO_ATTR_CONNECTION_STATUS, /* connection status */
123 : PDO_ATTR_CASE, /* control case folding for portability */
124 : PDO_ATTR_CURSOR_NAME, /* name a cursor for use in "WHERE CURRENT OF <name>" */
125 : PDO_ATTR_CURSOR, /* cursor type */
126 : PDO_ATTR_ORACLE_NULLS, /* convert empty strings to NULL */
127 : PDO_ATTR_PERSISTENT, /* pconnect style connection */
128 : PDO_ATTR_STATEMENT_CLASS, /* array(classname, array(ctor_args)) to specify the class of the constructed statement */
129 : PDO_ATTR_FETCH_TABLE_NAMES, /* include table names in the column names, where available */
130 : PDO_ATTR_FETCH_CATALOG_NAMES, /* include the catalog/db name names in the column names, where available */
131 : PDO_ATTR_DRIVER_NAME, /* name of the driver (as used in the constructor) */
132 : PDO_ATTR_STRINGIFY_FETCHES, /* converts integer/float types to strings during fetch */
133 : PDO_ATTR_MAX_COLUMN_LEN, /* make database calculate maximum length of data found in a column */
134 : PDO_ATTR_DEFAULT_FETCH_MODE, /* Set the default fetch mode */
135 : PDO_ATTR_EMULATE_PREPARES, /* use query emulation rather than native */
136 :
137 : /* this defines the start of the range for driver specific options.
138 : * Drivers should define their own attribute constants beginning with this
139 : * value. */
140 : PDO_ATTR_DRIVER_SPECIFIC = 1000
141 : };
142 :
143 : enum pdo_cursor_type {
144 : PDO_CURSOR_FWDONLY, /* forward only cursor (default) */
145 : PDO_CURSOR_SCROLL /* scrollable cursor */
146 : };
147 :
148 : /* SQL-92 SQLSTATE error codes.
149 :
150 : The character string value returned for an SQLSTATE consists of a two-character
151 : class value followed by a three-character subclass value. A class value of 01
152 : indicates a warning and is accompanied by a return code of
153 : SQL_SUCCESS_WITH_INFO.
154 :
155 : Class values other than '01', except for the class 'IM',
156 : indicate an error and are accompanied by a return code of SQL_ERROR. The class
157 : 'IM' is specific to warnings and errors that derive from the implementation of
158 : ODBC itself.
159 :
160 : The subclass value '000' in any class indicates that there is no
161 : subclass for that SQLSTATE. The assignment of class and subclass values is
162 : defined by SQL-92.
163 : */
164 :
165 : typedef char pdo_error_type[6]; /* SQLSTATE */
166 :
167 :
168 : #define PDO_ERR_NONE "00000"
169 :
170 : enum pdo_error_mode {
171 : PDO_ERRMODE_SILENT, /* just set error codes */
172 : PDO_ERRMODE_WARNING, /* raise E_WARNING */
173 : PDO_ERRMODE_EXCEPTION /* throw exceptions */
174 : };
175 :
176 : enum pdo_case_conversion {
177 : PDO_CASE_NATURAL,
178 : PDO_CASE_UPPER,
179 : PDO_CASE_LOWER
180 : };
181 :
182 : /* oracle interop settings */
183 : enum pdo_null_handling {
184 : PDO_NULL_NATURAL = 0,
185 : PDO_NULL_EMPTY_STRING = 1,
186 : PDO_NULL_TO_STRING = 2,
187 : };
188 :
189 : /* {{{ utils for reading attributes set as driver_options */
190 : static inline long pdo_attr_lval(zval *options, enum pdo_attribute_type option_name, long defval TSRMLS_DC)
191 1315 : {
192 : zval **v;
193 :
194 1315 : if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
195 16 : convert_to_long_ex(v);
196 16 : return Z_LVAL_PP(v);
197 : }
198 1299 : return defval;
199 : }
200 : static inline char *pdo_attr_strval(zval *options, enum pdo_attribute_type option_name, char *defval TSRMLS_DC)
201 0 : {
202 : zval **v;
203 :
204 0 : if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
205 0 : convert_to_string_ex(v);
206 0 : return estrndup(Z_STRVAL_PP(v), Z_STRLEN_PP(v));
207 : }
208 0 : return defval ? estrdup(defval) : NULL;
209 : }
210 : /* }}} */
211 :
212 : /* This structure is registered with PDO when a PDO driver extension is
213 : * initialized */
214 : typedef struct {
215 : const char *driver_name;
216 : unsigned long driver_name_len;
217 : unsigned long api_version; /* needs to be compatible with PDO */
218 :
219 : #define PDO_DRIVER_HEADER(name) \
220 : #name, sizeof(#name)-1, \
221 : PDO_DRIVER_API
222 :
223 : /* create driver specific portion of the database handle and stash it into
224 : * the dbh. dbh contains the data source string and flags for this
225 : * instance. You MUST respect dbh->is_persistent and pass that flag to
226 : * pemalloc() for all allocations that are stored in the dbh or your instance
227 : * data in the db, otherwise you will crash PHP when persistent connections
228 : * are used.
229 : */
230 : int (*db_handle_factory)(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC);
231 :
232 : } pdo_driver_t;
233 :
234 : /* {{{ methods for a database handle */
235 :
236 : /* close or otherwise disconnect the database */
237 : typedef int (*pdo_dbh_close_func)(pdo_dbh_t *dbh TSRMLS_DC);
238 :
239 : /* prepare a statement and stash driver specific portion into stmt */
240 : 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);
241 :
242 : /* execute a statement (that does not return a result set) */
243 : typedef long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC);
244 :
245 : /* quote a string */
246 : 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);
247 :
248 : /* transaction related */
249 : typedef int (*pdo_dbh_txn_func)(pdo_dbh_t *dbh TSRMLS_DC);
250 :
251 : /* setting of attributes */
252 : typedef int (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
253 :
254 : /* return last insert id. NULL indicates error condition, otherwise, the return value
255 : * MUST be an emalloc'd NULL terminated string. */
256 : typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC);
257 :
258 : /* fetch error information. if stmt is not null, fetch information pertaining
259 : * to the statement, otherwise fetch global error information. The driver
260 : * should add the following information to the array "info" in this order:
261 : * - native error code
262 : * - string representation of the error code ... any other optional driver
263 : * specific data ... */
264 : typedef int (*pdo_dbh_fetch_error_func)(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC);
265 :
266 : /* fetching of attributes */
267 : typedef int (*pdo_dbh_get_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
268 :
269 : /* checking/pinging persistent connections; return SUCCESS if the connection
270 : * is still alive and ready to be used, FAILURE otherwise.
271 : * You may set this handler to NULL, which is equivalent to returning SUCCESS. */
272 : typedef int (*pdo_dbh_check_liveness_func)(pdo_dbh_t *dbh TSRMLS_DC);
273 :
274 : /* called at request end for each persistent dbh; this gives the driver
275 : * the opportunity to safely release resources that only have per-request
276 : * scope */
277 : typedef void (*pdo_dbh_request_shutdown)(pdo_dbh_t *dbh TSRMLS_DC);
278 :
279 : /* for adding methods to the dbh or stmt objects
280 : pointer to a list of driver specific functions. The convention is
281 : to prefix the function names using the PDO driver name; this will
282 : reduce the chance of collisions with future functionality in the
283 : PDO class or in user code (they can extend the PDO object).
284 : */
285 : enum {
286 : PDO_DBH_DRIVER_METHOD_KIND_DBH = 0,
287 : PDO_DBH_DRIVER_METHOD_KIND_STMT,
288 : PDO_DBH_DRIVER_METHOD_KIND__MAX
289 : };
290 :
291 : typedef zend_function_entry *(*pdo_dbh_get_driver_methods_func)(pdo_dbh_t *dbh, int kind TSRMLS_DC);
292 :
293 : struct pdo_dbh_methods {
294 : pdo_dbh_close_func closer;
295 : pdo_dbh_prepare_func preparer;
296 : pdo_dbh_do_func doer;
297 : pdo_dbh_quote_func quoter;
298 : pdo_dbh_txn_func begin;
299 : pdo_dbh_txn_func commit;
300 : pdo_dbh_txn_func rollback;
301 : pdo_dbh_set_attr_func set_attribute;
302 : pdo_dbh_last_id_func last_id;
303 : pdo_dbh_fetch_error_func fetch_err;
304 : pdo_dbh_get_attr_func get_attribute;
305 : pdo_dbh_check_liveness_func check_liveness;
306 : pdo_dbh_get_driver_methods_func get_driver_methods;
307 : pdo_dbh_request_shutdown persistent_shutdown;
308 : };
309 :
310 : /* }}} */
311 :
312 : /* {{{ methods for a statement handle */
313 :
314 : /* free the statement handle */
315 : typedef int (*pdo_stmt_dtor_func)(pdo_stmt_t *stmt TSRMLS_DC);
316 :
317 : /* start the query */
318 : typedef int (*pdo_stmt_execute_func)(pdo_stmt_t *stmt TSRMLS_DC);
319 :
320 : /* causes the next row in the set to be fetched; indicates if there are no
321 : * more rows. The ori and offset params modify which row should be returned,
322 : * if the stmt represents a scrollable cursor */
323 : typedef int (*pdo_stmt_fetch_func)(pdo_stmt_t *stmt,
324 : enum pdo_fetch_orientation ori, long offset TSRMLS_DC);
325 :
326 : /* queries information about the type of a column, by index (0 based).
327 : * Driver should populate stmt->columns[colno] with appropriate info */
328 : typedef int (*pdo_stmt_describe_col_func)(pdo_stmt_t *stmt, int colno TSRMLS_DC);
329 :
330 : /* retrieves pointer and size of the value for a column.
331 : * Note that PDO expects the driver to manage the lifetime of this data;
332 : * it will copy the value into a zval on behalf of the script.
333 : * If the driver sets caller_frees, ptr should point to emalloc'd memory
334 : * and PDO will free it as soon as it is done using it.
335 : */
336 : typedef int (*pdo_stmt_get_col_data_func)(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC);
337 :
338 : /* hook for bound params */
339 : enum pdo_param_event {
340 : PDO_PARAM_EVT_ALLOC,
341 : PDO_PARAM_EVT_FREE,
342 : PDO_PARAM_EVT_EXEC_PRE,
343 : PDO_PARAM_EVT_EXEC_POST,
344 : PDO_PARAM_EVT_FETCH_PRE,
345 : PDO_PARAM_EVT_FETCH_POST,
346 : PDO_PARAM_EVT_NORMALIZE,
347 : };
348 :
349 : 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);
350 :
351 : /* setting of attributes */
352 : typedef int (*pdo_stmt_set_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);
353 :
354 : /* fetching of attributes */
355 : typedef int (*pdo_stmt_get_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);
356 :
357 : /* retrieves meta data for a numbered column.
358 : * Returns SUCCESS/FAILURE.
359 : * On SUCCESS, fill in return_value with an array with the following fields.
360 : * If a particular field is not supported, then the driver simply does not add it to
361 : * the array, so that scripts can use isset() to check for it.
362 : *
363 : * ### this is just a rough first cut, and subject to change ###
364 : *
365 : * these are added by PDO itself, based on data from the describe handler:
366 : * name => the column name
367 : * len => the length/size of the column
368 : * precision => precision of the column
369 : * pdo_type => an integer, one of the PDO_PARAM_XXX values
370 : *
371 : * scale => the floating point scale
372 : * table => the table for that column
373 : * type => a string representation of the type, mapped to the PHP equivalent type name
374 : * native_type => a string representation of the type, native style, if different from
375 : * the mapped name.
376 : * flags => an array of flags including zero or more of the following:
377 : * primary_key, not_null, unique_key, multiple_key, unsigned, auto_increment, blob
378 : *
379 : * Any driver specific data should be returned using a prefixed key or value.
380 : * Eg: custom data for the mysql driver would use either
381 : * 'mysql:foobar' => 'some data' // to add a new key to the array
382 : * or
383 : * 'flags' => array('not_null', 'mysql:some_flag'); // to add data to an existing key
384 : */
385 : typedef int (*pdo_stmt_get_column_meta_func)(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC);
386 :
387 : /* advances the statement to the next rowset of the batch.
388 : * If it returns 1, PDO will tear down its idea of columns
389 : * and meta data. If it returns 0, PDO will indicate an error
390 : * to the caller. */
391 : typedef int (*pdo_stmt_next_rowset_func)(pdo_stmt_t *stmt TSRMLS_DC);
392 :
393 : /* closes the active cursor on a statement, leaving the prepared
394 : * statement ready for re-execution. Useful to explicitly state
395 : * that you are done with a given rowset, without having to explicitly
396 : * fetch all the rows. */
397 : typedef int (*pdo_stmt_cursor_closer_func)(pdo_stmt_t *stmt TSRMLS_DC);
398 :
399 : struct pdo_stmt_methods {
400 : pdo_stmt_dtor_func dtor;
401 : pdo_stmt_execute_func executer;
402 : pdo_stmt_fetch_func fetcher;
403 : pdo_stmt_describe_col_func describer;
404 : pdo_stmt_get_col_data_func get_col;
405 : pdo_stmt_param_hook_func param_hook;
406 : pdo_stmt_set_attr_func set_attribute;
407 : pdo_stmt_get_attr_func get_attribute;
408 : pdo_stmt_get_column_meta_func get_column_meta;
409 : pdo_stmt_next_rowset_func next_rowset;
410 : pdo_stmt_cursor_closer_func cursor_closer;
411 : };
412 :
413 : /* }}} */
414 :
415 : enum pdo_placeholder_support {
416 : PDO_PLACEHOLDER_NONE=0,
417 : PDO_PLACEHOLDER_NAMED=1,
418 : PDO_PLACEHOLDER_POSITIONAL=2
419 : };
420 :
421 : /* represents a connection to a database */
422 : struct _pdo_dbh_t {
423 : /* these items must appear in this order at the beginning of the
424 : struct so that this can be cast as a zend_object. we need this
425 : to allow the extending class to escape all the custom handlers
426 : that PDO declares.
427 : */
428 : zend_class_entry *ce;
429 : HashTable *properties;
430 : unsigned int in_get:1;
431 : unsigned int in_set:1;
432 :
433 : /* driver specific methods */
434 : struct pdo_dbh_methods *methods;
435 : /* driver specific data */
436 : void *driver_data;
437 :
438 : /* credentials */
439 : char *username, *password;
440 :
441 : /* if true, then data stored and pointed at by this handle must all be
442 : * persistently allocated */
443 : unsigned is_persistent:1;
444 :
445 : /* if true, driver should act as though a COMMIT were executed between
446 : * each executed statement; otherwise, COMMIT must be carried out manually
447 : * */
448 : unsigned auto_commit:1;
449 :
450 : /* if true, the handle has been closed and will not function anymore */
451 : unsigned is_closed:1;
452 :
453 : /* if true, the driver requires that memory be allocated explicitly for
454 : * the columns that are returned */
455 : unsigned alloc_own_columns:1;
456 :
457 : /* if true, commit or rollBack is allowed to be called */
458 : unsigned in_txn:1;
459 :
460 : /* max length a single character can become after correct quoting */
461 : unsigned max_escaped_char_length:3;
462 :
463 : /* oracle compat; see enum pdo_null_handling */
464 : unsigned oracle_nulls:2;
465 :
466 : /* when set, convert int/floats to strings */
467 : unsigned stringify:1;
468 :
469 : /* the sum of the number of bits here and the bit fields preceeding should
470 : * equal 32 */
471 : unsigned _reserved_flags:21;
472 :
473 : /* data source string used to open this handle */
474 : const char *data_source;
475 : unsigned long data_source_len;
476 :
477 : /* the global error code. */
478 : pdo_error_type error_code;
479 :
480 : enum pdo_error_mode error_mode;
481 :
482 : enum pdo_case_conversion native_case, desired_case;
483 :
484 : /* persistent hash key associated with this handle */
485 : const char *persistent_id;
486 : int persistent_id_len;
487 : unsigned int refcount;
488 :
489 : /* driver specific "class" methods for the dbh and stmt */
490 : HashTable *cls_methods[PDO_DBH_DRIVER_METHOD_KIND__MAX];
491 :
492 : pdo_driver_t *driver;
493 :
494 : zend_class_entry *def_stmt_ce;
495 :
496 : zval *def_stmt_ctor_args;
497 :
498 : /* when calling PDO::query(), we need to keep the error
499 : * context from the statement around until we next clear it.
500 : * This will allow us to report the correct error message
501 : * when PDO::query() fails */
502 : pdo_stmt_t *query_stmt;
503 : zval query_stmt_zval;
504 :
505 : /* defaults for fetches */
506 : enum pdo_fetch_type default_fetch_type;
507 : };
508 :
509 : /* describes a column */
510 : struct pdo_column_data {
511 : char *name;
512 : int namelen;
513 : unsigned long maxlen;
514 : enum pdo_param_type param_type;
515 : unsigned long precision;
516 :
517 : /* don't touch this unless your name is dbdo */
518 : void *dbdo_data;
519 : };
520 :
521 : /* describes a bound parameter */
522 : struct pdo_bound_param_data {
523 : long paramno; /* if -1, then it has a name, and we don't know the index *yet* */
524 : char *name;
525 : int namelen;
526 :
527 : long max_value_len; /* as a hint for pre-allocation */
528 :
529 : zval *parameter; /* the variable itself */
530 : enum pdo_param_type param_type; /* desired or suggested type */
531 :
532 : zval *driver_params; /* optional parameter(s) for the driver */
533 : void *driver_data;
534 :
535 : pdo_stmt_t *stmt; /* for convenience in dtor */
536 : int is_param; /* parameter or column ? */
537 : };
538 :
539 : /* represents a prepared statement */
540 : struct _pdo_stmt_t {
541 : /* these items must appear in this order at the beginning of the
542 : struct so that this can be cast as a zend_object. we need this
543 : to allow the extending class to escape all the custom handlers
544 : that PDO declares.
545 : */
546 : zend_class_entry *ce;
547 : HashTable *properties;
548 : unsigned int in_get:1;
549 : unsigned int in_set:1;
550 :
551 : /* driver specifics */
552 : struct pdo_stmt_methods *methods;
553 : void *driver_data;
554 :
555 : /* if true, we've already successfully executed this statement at least
556 : * once */
557 : unsigned executed:1;
558 : /* if true, the statement supports placeholders and can implement
559 : * bindParam() for its prepared statements, if false, PDO should
560 : * emulate prepare and bind on its behalf */
561 : unsigned supports_placeholders:2;
562 :
563 : unsigned _reserved:29;
564 :
565 : /* the number of columns in the result set; not valid until after
566 : * the statement has been executed at least once. In some cases, might
567 : * not be valid until fetch (at the driver level) has been called at least once.
568 : * */
569 : int column_count;
570 : struct pdo_column_data *columns;
571 :
572 : /* we want to keep the dbh alive while we live, so we own a reference */
573 : zval database_object_handle;
574 : pdo_dbh_t *dbh;
575 :
576 : /* keep track of bound input parameters. Some drivers support
577 : * input/output parameters, but you can't rely on that working */
578 : HashTable *bound_params;
579 : /* When rewriting from named to positional, this maps positions to names */
580 : HashTable *bound_param_map;
581 : /* keep track of PHP variables bound to named (or positional) columns
582 : * in the result set */
583 : HashTable *bound_columns;
584 :
585 : /* not always meaningful */
586 : long row_count;
587 :
588 : /* used to hold the statement's current query */
589 : char *query_string;
590 : int query_stringlen;
591 :
592 : /* the copy of the query with expanded binds ONLY for emulated-prepare drivers */
593 : char *active_query_string;
594 : int active_query_stringlen;
595 :
596 : /* the cursor specific error code. */
597 : pdo_error_type error_code;
598 :
599 : /* for lazy fetches, we always return the same lazy object handle.
600 : * Let's keep it here. */
601 : zval lazy_object_ref;
602 : unsigned long refcount;
603 :
604 : /* defaults for fetches */
605 : enum pdo_fetch_type default_fetch_type;
606 : union {
607 : int column;
608 : struct {
609 : zend_class_entry *ce;
610 : zval *ctor_args; /* freed */
611 : zval *retval_ptr;
612 : zend_fcall_info fci;
613 : zend_fcall_info_cache fcc;
614 : } cls;
615 : struct {
616 : zval *function;
617 : zval *fetch_args; /* freed */
618 : zval *object;
619 : zend_fcall_info fci;
620 : zend_fcall_info_cache fcc;
621 : zval **values; /* freed */
622 : } func;
623 : zval *into;
624 : } fetch;
625 :
626 : /* used by the query parser for driver specific
627 : * parameter naming (see pgsql driver for example) */
628 : const char *named_rewrite_template;
629 : };
630 :
631 : /* call this in MINIT to register your PDO driver */
632 : PDO_API int php_pdo_register_driver(pdo_driver_t *driver);
633 : /* call this in MSHUTDOWN to unregister your PDO driver */
634 : PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver);
635 :
636 : /* For the convenience of drivers, this function will parse a data source
637 : * string, of the form "name=value; name2=value2" and populate variables
638 : * according to the data you pass in and array of pdo_data_src_parser structures */
639 : struct pdo_data_src_parser {
640 : const char *optname;
641 : char *optval;
642 : int freeme;
643 : };
644 :
645 : PDO_API int php_pdo_parse_data_source(const char *data_source,
646 : unsigned long data_source_len, struct pdo_data_src_parser *parsed,
647 : int nparams);
648 :
649 : PDO_API zend_class_entry *php_pdo_get_dbh_ce(void);
650 : PDO_API zend_class_entry *php_pdo_get_exception(void);
651 :
652 : PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
653 : char **outquery, int *outquery_len TSRMLS_DC);
654 :
655 : PDO_API void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt,
656 : const char *sqlstate, const char *supp TSRMLS_DC);
657 :
658 : PDO_API void php_pdo_dbh_addref(pdo_dbh_t *dbh TSRMLS_DC);
659 : PDO_API void php_pdo_dbh_delref(pdo_dbh_t *dbh TSRMLS_DC);
660 :
661 : PDO_API void php_pdo_stmt_addref(pdo_stmt_t *stmt TSRMLS_DC);
662 : PDO_API void php_pdo_stmt_delref(pdo_stmt_t *stmt TSRMLS_DC);
663 :
664 :
665 : #endif /* PHP_PDO_DRIVER_H */
666 : /*
667 : * Local variables:
668 : * tab-width: 4
669 : * c-basic-offset: 4
670 : * End:
671 : * vim600: noet sw=4 ts=4 fdm=marker
672 : * vim<600: noet sw=4 ts=4
673 : */
|