#ifndef PHP_PDO_DRIVER_H
#define PHP_PDO_DRIVER_H
#include "php_pdo.h"
typedef struct _pdo_dbh_t pdo_dbh_t;
typedef struct _pdo_stmt_t pdo_stmt_t;
struct pdo_bound_param_data;
#ifdef PHP_WIN32
typedef __int64 pdo_int64_t;
typedef unsigned __int64 pdo_uint64_t;
#else
typedef long long int pdo_int64_t;
typedef unsigned long long int pdo_uint64_t;
#endif
PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC);
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
#define PDO_DRIVER_API 20080721
enum pdo_param_type {
PDO_PARAM_NULL,
PDO_PARAM_INT,
PDO_PARAM_STR,
PDO_PARAM_LOB,
PDO_PARAM_STMT,
PDO_PARAM_BOOL,
PDO_PARAM_ZVAL,
PDO_PARAM_INPUT_OUTPUT = 0x80000000
};
#define PDO_PARAM_FLAGS 0xFFFF0000
#define PDO_PARAM_TYPE(x) ((x) & ~PDO_PARAM_FLAGS)
enum pdo_fetch_type {
PDO_FETCH_USE_DEFAULT,
PDO_FETCH_LAZY,
PDO_FETCH_ASSOC,
PDO_FETCH_NUM,
PDO_FETCH_BOTH,
PDO_FETCH_OBJ,
PDO_FETCH_BOUND,
PDO_FETCH_COLUMN,
PDO_FETCH_CLASS,
PDO_FETCH_INTO,
PDO_FETCH_FUNC,
PDO_FETCH_NAMED,
PDO_FETCH_KEY_PAIR,
PDO_FETCH__MAX
};
#define PDO_FETCH_FLAGS 0xFFFF0000
#define PDO_FETCH_GROUP 0x00010000
#define PDO_FETCH_UNIQUE 0x00030000
#define PDO_FETCH_CLASSTYPE 0x00040000
#define PDO_FETCH_SERIALIZE 0x00080000
#define PDO_FETCH_PROPS_LATE 0x00100000
enum pdo_fetch_orientation {
PDO_FETCH_ORI_NEXT,
PDO_FETCH_ORI_PRIOR,
PDO_FETCH_ORI_FIRST,
PDO_FETCH_ORI_LAST,
PDO_FETCH_ORI_ABS,
PDO_FETCH_ORI_REL
};
enum pdo_attribute_type {
PDO_ATTR_AUTOCOMMIT,
PDO_ATTR_PREFETCH,
PDO_ATTR_TIMEOUT,
PDO_ATTR_ERRMODE,
PDO_ATTR_SERVER_VERSION,
PDO_ATTR_CLIENT_VERSION,
PDO_ATTR_SERVER_INFO,
PDO_ATTR_CONNECTION_STATUS,
PDO_ATTR_CASE,
PDO_ATTR_CURSOR_NAME,
PDO_ATTR_CURSOR,
PDO_ATTR_ORACLE_NULLS,
PDO_ATTR_PERSISTENT,
PDO_ATTR_STATEMENT_CLASS,
PDO_ATTR_FETCH_TABLE_NAMES,
PDO_ATTR_FETCH_CATALOG_NAMES,
PDO_ATTR_DRIVER_NAME,
PDO_ATTR_STRINGIFY_FETCHES,
PDO_ATTR_MAX_COLUMN_LEN,
PDO_ATTR_DEFAULT_FETCH_MODE,
PDO_ATTR_EMULATE_PREPARES,
PDO_ATTR_DRIVER_SPECIFIC = 1000
};
enum pdo_cursor_type {
PDO_CURSOR_FWDONLY,
PDO_CURSOR_SCROLL
};
typedef char pdo_error_type[6];
#define PDO_ERR_NONE "00000"
enum pdo_error_mode {
PDO_ERRMODE_SILENT,
PDO_ERRMODE_WARNING,
PDO_ERRMODE_EXCEPTION
};
enum pdo_case_conversion {
PDO_CASE_NATURAL,
PDO_CASE_UPPER,
PDO_CASE_LOWER
};
enum pdo_null_handling {
PDO_NULL_NATURAL = 0,
PDO_NULL_EMPTY_STRING = 1,
PDO_NULL_TO_STRING = 2
};
static inline long pdo_attr_lval(zval *options, enum pdo_attribute_type option_name, long defval TSRMLS_DC)
{
zval **v;
if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
if (Z_TYPE_PP(v) != IS_LONG) {
zval tmp = **v;
zval_copy_ctor(&tmp);
convert_to_long(&tmp);
return Z_LVAL(tmp);
}
return Z_LVAL_PP(v);
}
return defval;
}
static inline char *pdo_attr_strval(zval *options, enum pdo_attribute_type option_name, char *defval TSRMLS_DC)
{
zval **v;
if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
if (Z_TYPE_PP(v) != IS_STRING) {
zval tmp = **v;
zval_copy_ctor(&tmp);
convert_to_string(&tmp);
return Z_STRVAL(tmp);
}
return estrndup(Z_STRVAL_PP(v), Z_STRLEN_PP(v));
}
return defval ? estrdup(defval) : NULL;
}
typedef struct {
const char *driver_name;
unsigned long driver_name_len;
unsigned long api_version;
#define PDO_DRIVER_HEADER(name) \
#name, sizeof(#name)-1, \
PDO_DRIVER_API
int (*db_handle_factory)(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC);
} pdo_driver_t;
typedef int (*pdo_dbh_close_func)(pdo_dbh_t *dbh TSRMLS_DC);
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);
typedef long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC);
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);
typedef int (*pdo_dbh_txn_func)(pdo_dbh_t *dbh TSRMLS_DC);
typedef int (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC);
typedef int (*pdo_dbh_fetch_error_func)(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC);
typedef int (*pdo_dbh_get_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
typedef int (*pdo_dbh_check_liveness_func)(pdo_dbh_t *dbh TSRMLS_DC);
typedef void (*pdo_dbh_request_shutdown)(pdo_dbh_t *dbh TSRMLS_DC);
enum {
PDO_DBH_DRIVER_METHOD_KIND_DBH = 0,
PDO_DBH_DRIVER_METHOD_KIND_STMT,
PDO_DBH_DRIVER_METHOD_KIND__MAX
};
typedef const zend_function_entry *(*pdo_dbh_get_driver_methods_func)(pdo_dbh_t *dbh, int kind TSRMLS_DC);
struct pdo_dbh_methods {
pdo_dbh_close_func closer;
pdo_dbh_prepare_func preparer;
pdo_dbh_do_func doer;
pdo_dbh_quote_func quoter;
pdo_dbh_txn_func begin;
pdo_dbh_txn_func commit;
pdo_dbh_txn_func rollback;
pdo_dbh_set_attr_func set_attribute;
pdo_dbh_last_id_func last_id;
pdo_dbh_fetch_error_func fetch_err;
pdo_dbh_get_attr_func get_attribute;
pdo_dbh_check_liveness_func check_liveness;
pdo_dbh_get_driver_methods_func get_driver_methods;
pdo_dbh_request_shutdown persistent_shutdown;
pdo_dbh_txn_func in_transaction;
};
typedef int (*pdo_stmt_dtor_func)(pdo_stmt_t *stmt TSRMLS_DC);
typedef int (*pdo_stmt_execute_func)(pdo_stmt_t *stmt TSRMLS_DC);
typedef int (*pdo_stmt_fetch_func)(pdo_stmt_t *stmt,
enum pdo_fetch_orientation ori, long offset TSRMLS_DC);
typedef int (*pdo_stmt_describe_col_func)(pdo_stmt_t *stmt, int colno TSRMLS_DC);
typedef int (*pdo_stmt_get_col_data_func)(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC);
enum pdo_param_event {
PDO_PARAM_EVT_ALLOC,
PDO_PARAM_EVT_FREE,
PDO_PARAM_EVT_EXEC_PRE,
PDO_PARAM_EVT_EXEC_POST,
PDO_PARAM_EVT_FETCH_PRE,
PDO_PARAM_EVT_FETCH_POST,
PDO_PARAM_EVT_NORMALIZE
};
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);
typedef int (*pdo_stmt_set_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);
typedef int (*pdo_stmt_get_attr_func)(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC);
typedef int (*pdo_stmt_get_column_meta_func)(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC);
typedef int (*pdo_stmt_next_rowset_func)(pdo_stmt_t *stmt TSRMLS_DC);
typedef int (*pdo_stmt_cursor_closer_func)(pdo_stmt_t *stmt TSRMLS_DC);
struct pdo_stmt_methods {
pdo_stmt_dtor_func dtor;
pdo_stmt_execute_func executer;
pdo_stmt_fetch_func fetcher;
pdo_stmt_describe_col_func describer;
pdo_stmt_get_col_data_func get_col;
pdo_stmt_param_hook_func param_hook;
pdo_stmt_set_attr_func set_attribute;
pdo_stmt_get_attr_func get_attribute;
pdo_stmt_get_column_meta_func get_column_meta;
pdo_stmt_next_rowset_func next_rowset;
pdo_stmt_cursor_closer_func cursor_closer;
};
enum pdo_placeholder_support {
PDO_PLACEHOLDER_NONE=0,
PDO_PLACEHOLDER_NAMED=1,
PDO_PLACEHOLDER_POSITIONAL=2
};
struct _pdo_dbh_t {
zend_object std;
struct pdo_dbh_methods *methods;
void *driver_data;
char *username, *password;
unsigned is_persistent:1;
unsigned auto_commit:1;
unsigned is_closed:1;
unsigned alloc_own_columns:1;
unsigned in_txn:1;
unsigned max_escaped_char_length:3;
unsigned oracle_nulls:2;
unsigned stringify:1;
unsigned _reserved_flags:21;
const char *data_source;
unsigned long data_source_len;
pdo_error_type error_code;
enum pdo_error_mode error_mode;
enum pdo_case_conversion native_case, desired_case;
const char *persistent_id;
int persistent_id_len;
unsigned int refcount;
HashTable *cls_methods[PDO_DBH_DRIVER_METHOD_KIND__MAX];
pdo_driver_t *driver;
zend_class_entry *def_stmt_ce;
zval *def_stmt_ctor_args;
pdo_stmt_t *query_stmt;
zval query_stmt_zval;
enum pdo_fetch_type default_fetch_type;
};
struct pdo_column_data {
char *name;
int namelen;
unsigned long maxlen;
enum pdo_param_type param_type;
unsigned long precision;
void *dbdo_data;
};
struct pdo_bound_param_data {
long paramno;
char *name;
int namelen;
long max_value_len;
zval *parameter;
enum pdo_param_type param_type;
zval *driver_params;
void *driver_data;
pdo_stmt_t *stmt;
int is_param;
};
struct _pdo_stmt_t {
zend_object std;
struct pdo_stmt_methods *methods;
void *driver_data;
unsigned executed:1;
unsigned supports_placeholders:2;
unsigned _reserved:29;
int column_count;
struct pdo_column_data *columns;
zval database_object_handle;
pdo_dbh_t *dbh;
HashTable *bound_params;
HashTable *bound_param_map;
HashTable *bound_columns;
long row_count;
char *query_string;
int query_stringlen;
char *active_query_string;
int active_query_stringlen;
pdo_error_type error_code;
zval lazy_object_ref;
unsigned long refcount;
enum pdo_fetch_type default_fetch_type;
union {
int column;
struct {
zend_class_entry *ce;
zval *ctor_args;
zval *retval_ptr;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
} cls;
struct {
zval *function;
zval *fetch_args;
zval *object;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
zval **values;
} func;
zval *into;
} fetch;
const char *named_rewrite_template;
};
PDO_API int php_pdo_register_driver(pdo_driver_t *driver);
PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver);
struct pdo_data_src_parser {
const char *optname;
char *optval;
int freeme;
};
PDO_API int php_pdo_parse_data_source(const char *data_source,
unsigned long data_source_len, struct pdo_data_src_parser *parsed,
int nparams);
PDO_API zend_class_entry *php_pdo_get_dbh_ce(void);
PDO_API zend_class_entry *php_pdo_get_exception(void);
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
char **outquery, int *outquery_len TSRMLS_DC);
PDO_API void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt,
const char *sqlstate, const char *supp TSRMLS_DC);
PDO_API void php_pdo_dbh_addref(pdo_dbh_t *dbh TSRMLS_DC);
PDO_API void php_pdo_dbh_delref(pdo_dbh_t *dbh TSRMLS_DC);
PDO_API void php_pdo_stmt_addref(pdo_stmt_t *stmt TSRMLS_DC);
PDO_API void php_pdo_stmt_delref(pdo_stmt_t *stmt TSRMLS_DC);
#endif