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