#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION >= 1
REGISTER_LONG_CONSTANT("PDO_FETCH_SERIALIZE",(long)PDO_FETCH_SERIALIZE, CONST_CS|CONST_PERSISTENT);
#endif
+ REGISTER_LONG_CONSTANT("PDO_FETCH_NAMED",(long)PDO_FETCH_NAMED, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_ATTR_AUTOCOMMIT", (long)PDO_ATTR_AUTOCOMMIT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_ATTR_PREFETCH", (long)PDO_ATTR_PREFETCH, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_ATTR_ORACLE_NULLS", (long)PDO_ATTR_ORACLE_NULLS, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_ATTR_PERSISTENT", (long)PDO_ATTR_PERSISTENT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_ATTR_STATEMENT_CLASS", (long)PDO_ATTR_STATEMENT_CLASS, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PDO_ATTR_FETCH_TABLE_NAMES", (long)PDO_ATTR_FETCH_TABLE_NAMES, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PDO_ATTR_FETCH_CATALOG_NAMES", (long)PDO_ATTR_FETCH_CATALOG_NAMES, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_ERRMODE_SILENT", (long)PDO_ERRMODE_SILENT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PDO_ERRMODE_WARNING", (long)PDO_ERRMODE_WARNING, CONST_CS|CONST_PERSISTENT);
case PDO_FETCH_ASSOC:
case PDO_FETCH_BOTH:
case PDO_FETCH_NUM:
+ case PDO_FETCH_NAMED:
array_init(return_value);
break;
add_next_index_zval(return_value, val);
break;
+ case PDO_FETCH_NAMED:
+ /* already have an item with this name? */
+ {
+ zval **curr_val = NULL;
+ if (zend_hash_find(Z_ARRVAL_P(return_value), stmt->columns[i].name,
+ strlen(stmt->columns[i].name)+1,
+ (void**)&curr_val) == SUCCESS) {
+ zval *arr;
+ if (Z_TYPE_PP(curr_val) != IS_ARRAY) {
+ /* a little bit of black magic here:
+ * we're creating a new array and swapping it for the
+ * zval that's already stored in the hash under the name
+ * we want. We then add that zval to the array.
+ * This is effectively the same thing as:
+ * if (!is_array($hash[$name])) {
+ * $hash[$name] = array($hash[$name]);
+ * }
+ * */
+ zval *cur;
+
+ MAKE_STD_ZVAL(arr);
+ array_init(arr);
+
+ cur = *curr_val;
+ *curr_val = arr;
+
+ add_next_index_zval(arr, cur);
+ } else {
+ arr = *curr_val;
+ }
+ add_next_index_zval(arr, val);
+ } else {
+ add_assoc_zval(return_value, stmt->columns[i].name, val);
+ }
+ }
+ break;
+
case PDO_FETCH_NUM:
add_next_index_zval(return_value, val);
break;
# define FALSE 0
#endif
-#define PDO_DRIVER_API 20050610
+#define PDO_DRIVER_API 20050702
enum pdo_param_type {
PDO_PARAM_NULL,
PDO_FETCH_CLASS, /* create an instance of named class, call ctor and set properties */
PDO_FETCH_INTO, /* fetch row into an existing object */
PDO_FETCH_FUNC, /* fetch into function and return its result */
+ PDO_FETCH_NAMED, /* like PDO_FETCH_ASSOC, but can handle duplicate names */
PDO_FETCH__MAX /* must be last */
};
PDO_ATTR_ORACLE_NULLS, /* convert empty strings to NULL */
PDO_ATTR_PERSISTENT, /* pconnect style connection */
PDO_ATTR_STATEMENT_CLASS, /* array(classname, array(ctor_args)) to specify the class of the constructed statement */
+ PDO_ATTR_FETCH_TABLE_NAMES, /* include table names in the column names, where available */
+ PDO_ATTR_FETCH_CATALOG_NAMES, /* include the catalog/db name names in the column names, where available */
/* this defines the start of the range for driver specific options.
* Drivers should define their own attribute constants beginning with this
#define PDO_ERR_NONE "00000"
-#if 0
-/* generic error code values.
- * Don't want to go overboard with these.
- * */
-#define PDO_ERR_SYNTAX "42000"
-#define PDO_ERR_CONSTRAINT "23000"
-#define PDO_ERR_NOT_FOUND ""
-#define PDO_ERR_ALREADY_EXISTS,
-#define PDO_ERR_NOT_IMPLEMENTED,
-#define PDO_ERR_MISMATCH,
-#define PDO_ERR_TRUNCATED,
-#define PDO_ERR_DISCONNECTED,
-#define PDO_ERR_NO_PERM,
-
- PDO_ERR_CANT_MAP /* no way to map native error to the generic
- * codes; consult the native error for more info */
-};
-#endif
enum pdo_error_mode {
PDO_ERRMODE_SILENT, /* just set error codes */