diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index 6dc947e3cc839..30a63a9d06869 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -316,31 +316,6 @@ static const func_info_t func_infos[] = { FN("oci_get_implicit_resultset", MAY_BE_RESOURCE|MAY_BE_FALSE), FN("oci_password_change", MAY_BE_RESOURCE|MAY_BE_BOOL), FN("oci_new_cursor", MAY_BE_RESOURCE|MAY_BE_FALSE), - FN("odbc_prepare", MAY_BE_RESOURCE|MAY_BE_FALSE), - FN("odbc_exec", MAY_BE_RESOURCE|MAY_BE_FALSE), - FN("odbc_connect", MAY_BE_RESOURCE|MAY_BE_FALSE), - FN("odbc_pconnect", MAY_BE_RESOURCE|MAY_BE_FALSE), - FN("odbc_tables", MAY_BE_RESOURCE|MAY_BE_FALSE), - FN("odbc_columns", MAY_BE_RESOURCE|MAY_BE_FALSE), - FN("odbc_gettypeinfo", MAY_BE_RESOURCE|MAY_BE_FALSE), - FN("odbc_primarykeys", MAY_BE_RESOURCE|MAY_BE_FALSE), -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) - FN("odbc_procedurecolumns", MAY_BE_RESOURCE|MAY_BE_FALSE), -#endif -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) - FN("odbc_procedures", MAY_BE_RESOURCE|MAY_BE_FALSE), -#endif -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) - FN("odbc_foreignkeys", MAY_BE_RESOURCE|MAY_BE_FALSE), -#endif - FN("odbc_specialcolumns", MAY_BE_RESOURCE|MAY_BE_FALSE), - FN("odbc_statistics", MAY_BE_RESOURCE|MAY_BE_FALSE), -#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) - FN("odbc_tableprivileges", MAY_BE_RESOURCE|MAY_BE_FALSE), -#endif -#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) - FN("odbc_columnprivileges", MAY_BE_RESOURCE|MAY_BE_FALSE), -#endif F1("opcache_get_status", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_FALSE), F1("opcache_get_configuration", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_FALSE), F1("openssl_x509_parse", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE), diff --git a/ext/odbc/odbc.stub.php b/ext/odbc/odbc.stub.php index 9606a38633f34..3c03090ed08e5 100644 --- a/ext/odbc/odbc.stub.php +++ b/ext/odbc/odbc.stub.php @@ -2,520 +2,442 @@ /** @generate-class-entries */ -/** - * @var string - * @cvalue PHP_ODBC_TYPE - */ -const ODBC_TYPE = UNKNOWN; -/** - * @var int - * @cvalue PHP_ODBC_BINMODE_PASSTHRU - */ -const ODBC_BINMODE_PASSTHRU = UNKNOWN; -/** - * @var int - * @cvalue PHP_ODBC_BINMODE_RETURN - */ -const ODBC_BINMODE_RETURN = UNKNOWN; -/** - * @var int - * @cvalue PHP_ODBC_BINMODE_CONVERT - */ -const ODBC_BINMODE_CONVERT = UNKNOWN; - -/* Define Constants for options. These Constants are defined in */ - -/** - * @var int - * @cvalue SQL_ODBC_CURSORS - */ -const SQL_ODBC_CURSORS = UNKNOWN; -/** - * @var int - * @cvalue SQL_CUR_USE_DRIVER - */ -const SQL_CUR_USE_DRIVER = UNKNOWN; -/** - * @var int - * @cvalue SQL_CUR_USE_IF_NEEDED - */ -const SQL_CUR_USE_IF_NEEDED = UNKNOWN; -/** - * @var int - * @cvalue SQL_CUR_USE_ODBC - */ -const SQL_CUR_USE_ODBC = UNKNOWN; - -/** - * @var int - * @cvalue SQL_CONCURRENCY - */ -const SQL_CONCURRENCY = UNKNOWN; -/** - * @var int - * @cvalue SQL_CONCUR_READ_ONLY - */ -const SQL_CONCUR_READ_ONLY = UNKNOWN; -/** - * @var int - * @cvalue SQL_CONCUR_LOCK - */ -const SQL_CONCUR_LOCK = UNKNOWN; -/** - * @var int - * @cvalue SQL_CONCUR_ROWVER - */ -const SQL_CONCUR_ROWVER = UNKNOWN; -/** - * @var int - * @cvalue SQL_CONCUR_VALUES - */ -const SQL_CONCUR_VALUES = UNKNOWN; - -/** - * @var int - * @cvalue SQL_CURSOR_TYPE - */ -const SQL_CURSOR_TYPE = UNKNOWN; -/** - * @var int - * @cvalue SQL_CURSOR_FORWARD_ONLY - */ -const SQL_CURSOR_FORWARD_ONLY = UNKNOWN; -/** - * @var int - * @cvalue SQL_CURSOR_KEYSET_DRIVEN - */ -const SQL_CURSOR_KEYSET_DRIVEN = UNKNOWN; -/** - * @var int - * @cvalue SQL_CURSOR_DYNAMIC - */ -const SQL_CURSOR_DYNAMIC = UNKNOWN; -/** - * @var int - * @cvalue SQL_CURSOR_STATIC - */ -const SQL_CURSOR_STATIC = UNKNOWN; - -/** - * @var int - * @cvalue SQL_KEYSET_SIZE - */ -const SQL_KEYSET_SIZE = UNKNOWN; - -/* these are for the Data Source type */ - -/** - * @var int - * @cvalue SQL_FETCH_FIRST - */ -const SQL_FETCH_FIRST = UNKNOWN; -/** - * @var int - * @cvalue SQL_FETCH_NEXT - */ -const SQL_FETCH_NEXT = UNKNOWN; - -/* register the standard data types */ - -/** - * @var int - * @cvalue SQL_CHAR - */ -const SQL_CHAR = UNKNOWN; -/** - * @var int - * @cvalue SQL_VARCHAR - */ -const SQL_VARCHAR = UNKNOWN; -/** - * @var int - * @cvalue SQL_LONGVARCHAR - */ -const SQL_LONGVARCHAR = UNKNOWN; -/** - * @var int - * @cvalue SQL_DECIMAL - */ -const SQL_DECIMAL = UNKNOWN; -/** - * @var int - * @cvalue SQL_NUMERIC - */ -const SQL_NUMERIC = UNKNOWN; -/** - * @var int - * @cvalue SQL_BIT - */ -const SQL_BIT = UNKNOWN; -/** - * @var int - * @cvalue SQL_TINYINT - */ -const SQL_TINYINT = UNKNOWN; -/** - * @var int - * @cvalue SQL_SMALLINT - */ -const SQL_SMALLINT = UNKNOWN; -/** - * @var int - * @cvalue SQL_INTEGER - */ -const SQL_INTEGER = UNKNOWN; -/** - * @var int - * @cvalue SQL_BIGINT - */ -const SQL_BIGINT = UNKNOWN; -/** - * @var int - * @cvalue SQL_REAL - */ -const SQL_REAL = UNKNOWN; -/** - * @var int - * @cvalue SQL_FLOAT - */ -const SQL_FLOAT = UNKNOWN; -/** - * @var int - * @cvalue SQL_DOUBLE - */ -const SQL_DOUBLE = UNKNOWN; -/** - * @var int - * @cvalue SQL_BINARY - */ -const SQL_BINARY = UNKNOWN; -/** - * @var int - * @cvalue SQL_VARBINARY - */ -const SQL_VARBINARY = UNKNOWN; -/** - * @var int - * @cvalue SQL_LONGVARBINARY - */ -const SQL_LONGVARBINARY = UNKNOWN; -/** - * @var int - * @cvalue SQL_DATE - */ -const SQL_DATE = UNKNOWN; -/** - * @var int - * @cvalue SQL_TIME - */ -const SQL_TIME = UNKNOWN; -/** - * @var int - * @cvalue SQL_TIMESTAMP - */ -const SQL_TIMESTAMP = UNKNOWN; - -#if (defined(ODBCVER) && (ODBCVER >= 0x0300)) -/** - * @var int - * @cvalue SQL_TYPE_DATE - */ -const SQL_TYPE_DATE = UNKNOWN; -/** - * @var int - * @cvalue SQL_TYPE_TIME - */ -const SQL_TYPE_TIME = UNKNOWN; -/** - * @var int - * @cvalue SQL_TYPE_TIMESTAMP - */ -const SQL_TYPE_TIMESTAMP = UNKNOWN; -/** - * @var int - * @cvalue SQL_WCHAR - */ -const SQL_WCHAR = UNKNOWN; -/** - * @var int - * @cvalue SQL_WVARCHAR - */ -const SQL_WVARCHAR = UNKNOWN; -/** - * @var int - * @cvalue SQL_WLONGVARCHAR - */ -const SQL_WLONGVARCHAR = UNKNOWN; - -/* SQLSpecialColumns values */ - -/** - * @var int - * @cvalue SQL_BEST_ROWID - */ -const SQL_BEST_ROWID = UNKNOWN; -/** - * @var int - * @cvalue SQL_ROWVER - */ -const SQL_ROWVER = UNKNOWN; -/** - * @var int - * @cvalue SQL_SCOPE_CURROW - */ -const SQL_SCOPE_CURROW = UNKNOWN; -/** - * @var int - * @cvalue SQL_SCOPE_TRANSACTION - */ -const SQL_SCOPE_TRANSACTION = UNKNOWN; -/** - * @var int - * @cvalue SQL_SCOPE_SESSION - */ -const SQL_SCOPE_SESSION = UNKNOWN; -/** - * @var int - * @cvalue SQL_NO_NULLS - */ -const SQL_NO_NULLS = UNKNOWN; -/** - * @var int - * @cvalue SQL_NULLABLE - */ -const SQL_NULLABLE = UNKNOWN; - -/* SQLStatistics values */ - -/** - * @var int - * @cvalue SQL_INDEX_UNIQUE - */ -const SQL_INDEX_UNIQUE = UNKNOWN; -/** - * @var int - * @cvalue SQL_INDEX_ALL - */ -const SQL_INDEX_ALL = UNKNOWN; -/** - * @var int - * @cvalue SQL_ENSURE - */ -const SQL_ENSURE = UNKNOWN; -/** - * @var int - * @cvalue SQL_QUICK - */ -const SQL_QUICK = UNKNOWN; - -#endif - - - -function odbc_close_all(): void {} - -/** @param resource $statement */ -function odbc_binmode($statement, int $mode): bool {} - -/** @param resource $statement */ -function odbc_longreadlen($statement, int $length): bool {} - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_prepare($odbc, string $query) {} - -/** @param resource $statement */ -function odbc_execute($statement, array $params = []): bool {} - -/** @param resource $statement */ -function odbc_cursor($statement): string|false {} - -#ifdef HAVE_SQLDATASOURCES -/** @param resource $odbc */ -function odbc_data_source($odbc, int $fetch_type): array|null|false {} -#endif - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_exec($odbc, string $query) {} - -/** - * @param resource $odbc - * @return resource|false - * @alias odbc_exec - */ -function odbc_do($odbc, string $query) {} - -#ifdef PHP_ODBC_HAVE_FETCH_HASH -/** @param resource $statement */ -function odbc_fetch_object($statement, int $row = -1): stdClass|false {} - -/** @param resource $statement */ -function odbc_fetch_array($statement, int $row = -1): array|false {} -#endif - -/** - * @param resource $statement - * @param array $array - */ -function odbc_fetch_into($statement, &$array, int $row = 0): int|false {} - -/** @param resource $statement */ -function odbc_fetch_row($statement, ?int $row = null): bool {} - -/** @param resource $statement */ -function odbc_result($statement, string|int $field): string|bool|null {} - -/** - * @param resource $statement - * @deprecated - */ -function odbc_result_all($statement, string $format = ""): int|false {} - -/** @param resource $statement */ -function odbc_free_result($statement): bool {} - -/** - * @return resource|false - */ -function odbc_connect(string $dsn, string $user, #[\SensitiveParameter] string $password, int $cursor_option = SQL_CUR_USE_DRIVER) {} - -/** - * @return resource|false - */ -function odbc_pconnect(string $dsn, string $user, #[\SensitiveParameter] string $password, int $cursor_option = SQL_CUR_USE_DRIVER) {} - -/** @param resource $odbc */ -function odbc_close($odbc): void {} - -/** @param resource $statement */ -function odbc_num_rows($statement): int {} - -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) -/** @param resource $statement */ -function odbc_next_result($statement): bool {} -#endif - -/** @param resource $statement */ -function odbc_num_fields($statement): int {} - -/** @param resource $statement */ -function odbc_field_name($statement, int $field): string|false {} - -/** @param resource $statement */ -function odbc_field_type($statement, int $field): string|false {} - -/** @param resource $statement */ -function odbc_field_len($statement, int $field): int|false {} - -/** - * @param resource $statement - * @alias odbc_field_len - */ -function odbc_field_precision($statement, int $field): int|false {} - -/** @param resource $statement */ -function odbc_field_scale($statement, int $field): int|false {} - -/** @param resource $statement */ -function odbc_field_num($statement, string $field): int|false {} - -/** @param resource $odbc */ -function odbc_autocommit($odbc, ?bool $enable = null): int|bool {} - -/** @param resource $odbc */ -function odbc_commit($odbc): bool {} - -/** @param resource $odbc */ -function odbc_rollback($odbc): bool {} - -/** @param resource|null $odbc */ -function odbc_error($odbc = null): string {} - -/** @param resource|null $odbc */ -function odbc_errormsg($odbc = null): string {} - -/** @param resource $odbc */ -function odbc_setoption($odbc, int $which, int $option, int $value): bool {} - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_tables($odbc, ?string $catalog = null, ?string $schema = null, ?string $table = null, ?string $types = null) {} - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_columns($odbc, ?string $catalog = null, ?string $schema = null, ?string $table = null, ?string $column = null) {} - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_gettypeinfo($odbc, int $data_type = 0) {} - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_primarykeys($odbc, ?string $catalog, string $schema, string $table) {} - -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_procedurecolumns($odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null, ?string $column = null) {} - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_procedures($odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null) {} - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_foreignkeys($odbc, ?string $pk_catalog, string $pk_schema, string $pk_table, string $fk_catalog, string $fk_schema, string $fk_table) {} -#endif - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_specialcolumns($odbc, int $type, ?string $catalog, string $schema, string $table, int $scope, int $nullable) {} - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_statistics($odbc, ?string $catalog, string $schema, string $table, int $unique, int $accuracy) {} - -#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_tableprivileges($odbc, ?string $catalog, string $schema, string $table) {} - -/** - * @param resource $odbc - * @return resource|false - */ -function odbc_columnprivileges($odbc, ?string $catalog, string $schema, string $table, string $column) {} -#endif - -/* odbc_utils.c */ - -function odbc_connection_string_is_quoted(string $str): bool {} - -function odbc_connection_string_should_quote(string $str): bool {} - -function odbc_connection_string_quote(string $str): string {} +namespace ODBC { + /** + * @strict-properties + * @not-serializable + */ + class Connection + { + } + + /** + * @strict-properties + * @not-serializable + */ + class Result + { + } +} + +namespace { + /** + * @var string + * @cvalue PHP_ODBC_TYPE + */ + const ODBC_TYPE = UNKNOWN; + /** + * @var int + * @cvalue PHP_ODBC_BINMODE_PASSTHRU + */ + const ODBC_BINMODE_PASSTHRU = UNKNOWN; + /** + * @var int + * @cvalue PHP_ODBC_BINMODE_RETURN + */ + const ODBC_BINMODE_RETURN = UNKNOWN; + /** + * @var int + * @cvalue PHP_ODBC_BINMODE_CONVERT + */ + const ODBC_BINMODE_CONVERT = UNKNOWN; + + /* Define Constants for options. These Constants are defined in */ + + /** + * @var int + * @cvalue SQL_ODBC_CURSORS + */ + const SQL_ODBC_CURSORS = UNKNOWN; + /** + * @var int + * @cvalue SQL_CUR_USE_DRIVER + */ + const SQL_CUR_USE_DRIVER = UNKNOWN; + /** + * @var int + * @cvalue SQL_CUR_USE_IF_NEEDED + */ + const SQL_CUR_USE_IF_NEEDED = UNKNOWN; + /** + * @var int + * @cvalue SQL_CUR_USE_ODBC + */ + const SQL_CUR_USE_ODBC = UNKNOWN; + + /** + * @var int + * @cvalue SQL_CONCURRENCY + */ + const SQL_CONCURRENCY = UNKNOWN; + /** + * @var int + * @cvalue SQL_CONCUR_READ_ONLY + */ + const SQL_CONCUR_READ_ONLY = UNKNOWN; + /** + * @var int + * @cvalue SQL_CONCUR_LOCK + */ + const SQL_CONCUR_LOCK = UNKNOWN; + /** + * @var int + * @cvalue SQL_CONCUR_ROWVER + */ + const SQL_CONCUR_ROWVER = UNKNOWN; + /** + * @var int + * @cvalue SQL_CONCUR_VALUES + */ + const SQL_CONCUR_VALUES = UNKNOWN; + + /** + * @var int + * @cvalue SQL_CURSOR_TYPE + */ + const SQL_CURSOR_TYPE = UNKNOWN; + /** + * @var int + * @cvalue SQL_CURSOR_FORWARD_ONLY + */ + const SQL_CURSOR_FORWARD_ONLY = UNKNOWN; + /** + * @var int + * @cvalue SQL_CURSOR_KEYSET_DRIVEN + */ + const SQL_CURSOR_KEYSET_DRIVEN = UNKNOWN; + /** + * @var int + * @cvalue SQL_CURSOR_DYNAMIC + */ + const SQL_CURSOR_DYNAMIC = UNKNOWN; + /** + * @var int + * @cvalue SQL_CURSOR_STATIC + */ + const SQL_CURSOR_STATIC = UNKNOWN; + + /** + * @var int + * @cvalue SQL_KEYSET_SIZE + */ + const SQL_KEYSET_SIZE = UNKNOWN; + + /* these are for the Data Source type */ + + /** + * @var int + * @cvalue SQL_FETCH_FIRST + */ + const SQL_FETCH_FIRST = UNKNOWN; + /** + * @var int + * @cvalue SQL_FETCH_NEXT + */ + const SQL_FETCH_NEXT = UNKNOWN; + + /* register the standard data types */ + + /** + * @var int + * @cvalue SQL_CHAR + */ + const SQL_CHAR = UNKNOWN; + /** + * @var int + * @cvalue SQL_VARCHAR + */ + const SQL_VARCHAR = UNKNOWN; + /** + * @var int + * @cvalue SQL_LONGVARCHAR + */ + const SQL_LONGVARCHAR = UNKNOWN; + /** + * @var int + * @cvalue SQL_DECIMAL + */ + const SQL_DECIMAL = UNKNOWN; + /** + * @var int + * @cvalue SQL_NUMERIC + */ + const SQL_NUMERIC = UNKNOWN; + /** + * @var int + * @cvalue SQL_BIT + */ + const SQL_BIT = UNKNOWN; + /** + * @var int + * @cvalue SQL_TINYINT + */ + const SQL_TINYINT = UNKNOWN; + /** + * @var int + * @cvalue SQL_SMALLINT + */ + const SQL_SMALLINT = UNKNOWN; + /** + * @var int + * @cvalue SQL_INTEGER + */ + const SQL_INTEGER = UNKNOWN; + /** + * @var int + * @cvalue SQL_BIGINT + */ + const SQL_BIGINT = UNKNOWN; + /** + * @var int + * @cvalue SQL_REAL + */ + const SQL_REAL = UNKNOWN; + /** + * @var int + * @cvalue SQL_FLOAT + */ + const SQL_FLOAT = UNKNOWN; + /** + * @var int + * @cvalue SQL_DOUBLE + */ + const SQL_DOUBLE = UNKNOWN; + /** + * @var int + * @cvalue SQL_BINARY + */ + const SQL_BINARY = UNKNOWN; + /** + * @var int + * @cvalue SQL_VARBINARY + */ + const SQL_VARBINARY = UNKNOWN; + /** + * @var int + * @cvalue SQL_LONGVARBINARY + */ + const SQL_LONGVARBINARY = UNKNOWN; + /** + * @var int + * @cvalue SQL_DATE + */ + const SQL_DATE = UNKNOWN; + /** + * @var int + * @cvalue SQL_TIME + */ + const SQL_TIME = UNKNOWN; + /** + * @var int + * @cvalue SQL_TIMESTAMP + */ + const SQL_TIMESTAMP = UNKNOWN; + + #if (defined(ODBCVER) && (ODBCVER >= 0x0300)) + /** + * @var int + * @cvalue SQL_TYPE_DATE + */ + const SQL_TYPE_DATE = UNKNOWN; + /** + * @var int + * @cvalue SQL_TYPE_TIME + */ + const SQL_TYPE_TIME = UNKNOWN; + /** + * @var int + * @cvalue SQL_TYPE_TIMESTAMP + */ + const SQL_TYPE_TIMESTAMP = UNKNOWN; + /** + * @var int + * @cvalue SQL_WCHAR + */ + const SQL_WCHAR = UNKNOWN; + /** + * @var int + * @cvalue SQL_WVARCHAR + */ + const SQL_WVARCHAR = UNKNOWN; + /** + * @var int + * @cvalue SQL_WLONGVARCHAR + */ + const SQL_WLONGVARCHAR = UNKNOWN; + + /* SQLSpecialColumns values */ + + /** + * @var int + * @cvalue SQL_BEST_ROWID + */ + const SQL_BEST_ROWID = UNKNOWN; + /** + * @var int + * @cvalue SQL_ROWVER + */ + const SQL_ROWVER = UNKNOWN; + /** + * @var int + * @cvalue SQL_SCOPE_CURROW + */ + const SQL_SCOPE_CURROW = UNKNOWN; + /** + * @var int + * @cvalue SQL_SCOPE_TRANSACTION + */ + const SQL_SCOPE_TRANSACTION = UNKNOWN; + /** + * @var int + * @cvalue SQL_SCOPE_SESSION + */ + const SQL_SCOPE_SESSION = UNKNOWN; + /** + * @var int + * @cvalue SQL_NO_NULLS + */ + const SQL_NO_NULLS = UNKNOWN; + /** + * @var int + * @cvalue SQL_NULLABLE + */ + const SQL_NULLABLE = UNKNOWN; + + /* SQLStatistics values */ + + /** + * @var int + * @cvalue SQL_INDEX_UNIQUE + */ + const SQL_INDEX_UNIQUE = UNKNOWN; + /** + * @var int + * @cvalue SQL_INDEX_ALL + */ + const SQL_INDEX_ALL = UNKNOWN; + /** + * @var int + * @cvalue SQL_ENSURE + */ + const SQL_ENSURE = UNKNOWN; + /** + * @var int + * @cvalue SQL_QUICK + */ + const SQL_QUICK = UNKNOWN; + + #endif + + function odbc_close_all(): void {} + + function odbc_binmode(ODBC\Result $statement, int $mode): bool {} + + function odbc_longreadlen(ODBC\Result $statement, int $length): bool {} + + function odbc_prepare(ODBC\Connection $odbc, string $query): ODBC\Result|false {} + + function odbc_execute(ODBC\Result $statement, array $params = []): bool {} + + function odbc_cursor(ODBC\Result $statement): string|false {} + + #ifdef HAVE_SQLDATASOURCES + function odbc_data_source(ODBC\Connection $odbc, int $fetch_type): array|null|false {} + #endif + + function odbc_exec(ODBC\Connection $odbc, string $query): ODBC\Result|false {} + + /** @alias odbc_exec */ + function odbc_do(ODBC\Connection $odbc, string $query): ODBC\Result|false {} + + #ifdef PHP_ODBC_HAVE_FETCH_HASH + function odbc_fetch_object(ODBC\Result $statement, ?int $row = null): stdClass|false {} + + function odbc_fetch_array(ODBC\Result $statement, ?int $row = null): array|false {} + #endif + + /** @param array $array */ + function odbc_fetch_into(ODBC\Result $statement, &$array, ?int $row = null): int|false {} + + function odbc_fetch_row(ODBC\Result $statement, ?int $row = null): bool {} + + function odbc_result(ODBC\Result $statement, string|int $field): string|bool|null {} + + /** @deprecated */ + function odbc_result_all(ODBC\Result $statement, string $format = ""): int|false {} + + function odbc_free_result(ODBC\Result $statement): bool {} + + function odbc_connect(string $dsn, string $user, #[\SensitiveParameter] string $password, int $cursor_option = SQL_CUR_USE_DRIVER): ODBC\Connection|false {} + + function odbc_pconnect(string $dsn, string $user, #[\SensitiveParameter] string $password, int $cursor_option = SQL_CUR_USE_DRIVER): ODBC\Connection|false {} + + function odbc_close(ODBC\Connection $odbc): void {} + + function odbc_num_rows(ODBC\Result $statement): int {} + + #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) + function odbc_next_result(ODBC\Result $statement): bool {} + #endif + + function odbc_num_fields(ODBC\Result $statement): int {} + + function odbc_field_name(ODBC\Result $statement, int $field): string|false {} + + function odbc_field_type(ODBC\Result $statement, int $field): string|false {} + + function odbc_field_len(ODBC\Result $statement, int $field): int|false {} + + /** @alias odbc_field_len */ + function odbc_field_precision(ODBC\Result $statement, int $field): int|false {} + + function odbc_field_scale(ODBC\Result $statement, int $field): int|false {} + + function odbc_field_num(ODBC\Result $statement, string $field): int|false {} + + function odbc_autocommit(ODBC\Connection $odbc, ?bool $enable = null): int|bool {} + + function odbc_commit(ODBC\Connection $odbc): bool {} + + function odbc_rollback(ODBC\Connection $odbc): bool {} + + function odbc_error(?ODBC\Connection $odbc = null): string {} + + function odbc_errormsg(?ODBC\Connection $odbc = null): string {} + + function odbc_setoption(ODBC\Connection|ODBC\Result $odbc, int $which, int $option, int $value): bool {} + + function odbc_tables(ODBC\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $table = null, ?string $types = null): ODBC\Result|false {} + + function odbc_columns(ODBC\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $table = null, ?string $column = null): ODBC\Result|false {} + + function odbc_gettypeinfo(ODBC\Connection $odbc, int $data_type = 0): ODBC\Result|false {} + + function odbc_primarykeys(ODBC\Connection $odbc, ?string $catalog, string $schema, string $table): ODBC\Result|false {} + + #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) + function odbc_procedurecolumns(ODBC\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null, ?string $column = null): ODBC\Result|false {} + + function odbc_procedures(ODBC\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null): ODBC\Result|false {} + + function odbc_foreignkeys(ODBC\Connection $odbc, ?string $pk_catalog, string $pk_schema, string $pk_table, string $fk_catalog, string $fk_schema, string $fk_table): ODBC\Result|false {} + #endif + + function odbc_specialcolumns(ODBC\Connection $odbc, int $type, ?string $catalog, string $schema, string $table, int $scope, int $nullable): ODBC\Result|false {} + + function odbc_statistics(ODBC\Connection $odbc, ?string $catalog, string $schema, string $table, int $unique, int $accuracy): ODBC\Result|false {} + + #if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) + function odbc_tableprivileges(ODBC\Connection $odbc, ?string $catalog, string $schema, string $table): ODBC\Result|false {} + + function odbc_columnprivileges(ODBC\Connection $odbc, ?string $catalog, string $schema, string $table, string $column): ODBC\Result|false {} + #endif + + /* odbc_utils.c */ + + function odbc_connection_string_is_quoted(string $str): bool {} + + function odbc_connection_string_should_quote(string $str): bool {} + + function odbc_connection_string_quote(string $str): string {} +} diff --git a/ext/odbc/odbc_arginfo.h b/ext/odbc/odbc_arginfo.h index 574d829daad42..b2f1619ce2d96 100644 --- a/ext/odbc/odbc_arginfo.h +++ b/ext/odbc/odbc_arginfo.h @@ -1,36 +1,36 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0417b68a519527b0ee916bad75116ffe4a3ad304 */ + * Stub hash: 4d41f8189da5268979026fa5f54d6acacc17e5be */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_close_all, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_binmode, 0, 2, _IS_BOOL, 0) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_TYPE_INFO(0, mode, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_longreadlen, 0, 2, _IS_BOOL, 0) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_prepare, 0, 0, 2) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_prepare, 0, 2, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_execute, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, params, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_cursor, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_END_ARG_INFO() #if defined(HAVE_SQLDATASOURCES) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_data_source, 0, 2, MAY_BE_ARRAY|MAY_BE_NULL|MAY_BE_FALSE) - ZEND_ARG_INFO(0, odbc) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO(0, fetch_type, IS_LONG, 0) ZEND_END_ARG_INFO() #endif @@ -41,44 +41,44 @@ ZEND_END_ARG_INFO() #if defined(PHP_ODBC_HAVE_FETCH_HASH) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_fetch_object, 0, 1, stdClass, MAY_BE_FALSE) - ZEND_ARG_INFO(0, statement) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 0, "-1") + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #endif #if defined(PHP_ODBC_HAVE_FETCH_HASH) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_fetch_array, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_INFO(0, statement) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 0, "-1") + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #endif ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_fetch_into, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_INFO(1, array) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_fetch_row, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_result, 0, 2, MAY_BE_STRING|MAY_BE_BOOL|MAY_BE_NULL) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_TYPE_MASK(0, field, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_result_all, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, format, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_free_result, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_connect, 0, 0, 3) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_connect, 0, 3, ODBC\\Connection, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, dsn, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, user, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, password, IS_STRING, 0) @@ -88,30 +88,30 @@ ZEND_END_ARG_INFO() #define arginfo_odbc_pconnect arginfo_odbc_connect ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_close, 0, 1, IS_VOID, 0) - ZEND_ARG_INFO(0, odbc) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_num_rows, 0, 1, IS_LONG, 0) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_END_ARG_INFO() #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_next_result, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_END_ARG_INFO() #endif #define arginfo_odbc_num_fields arginfo_odbc_num_rows ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_field_name, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_END_ARG_INFO() #define arginfo_odbc_field_type arginfo_odbc_field_name ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_field_len, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_TYPE_INFO(0, field, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -120,65 +120,65 @@ ZEND_END_ARG_INFO() #define arginfo_odbc_field_scale arginfo_odbc_field_len ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_field_num, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_INFO(0, statement) + ZEND_ARG_OBJ_INFO(0, statement, ODBC\\Result, 0) ZEND_ARG_TYPE_INFO(0, field, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_autocommit, 0, 1, MAY_BE_LONG|MAY_BE_BOOL) - ZEND_ARG_INFO(0, odbc) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, enable, _IS_BOOL, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_commit, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, odbc) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_END_ARG_INFO() #define arginfo_odbc_rollback arginfo_odbc_commit ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_error, 0, 0, IS_STRING, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, odbc, "null") + ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, odbc, ODBC\\Connection, 1, "null") ZEND_END_ARG_INFO() #define arginfo_odbc_errormsg arginfo_odbc_error ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_setoption, 0, 4, _IS_BOOL, 0) - ZEND_ARG_INFO(0, odbc) + ZEND_ARG_OBJ_TYPE_MASK(0, odbc, ODBC\\Connection|ODBC\\Result, 0, NULL) ZEND_ARG_TYPE_INFO(0, which, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, option, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, value, IS_LONG, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_tables, 0, 0, 1) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_tables, 0, 1, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, catalog, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, schema, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, table, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, types, IS_STRING, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_columns, 0, 0, 1) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_columns, 0, 1, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, catalog, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, schema, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, table, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, column, IS_STRING, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_gettypeinfo, 0, 0, 1) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_gettypeinfo, 0, 1, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, data_type, IS_LONG, 0, "0") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_primarykeys, 0, 0, 4) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_primarykeys, 0, 4, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO(0, catalog, IS_STRING, 1) ZEND_ARG_TYPE_INFO(0, schema, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, table, IS_STRING, 0) ZEND_END_ARG_INFO() #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_procedurecolumns, 0, 0, 1) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_procedurecolumns, 0, 1, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, catalog, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, schema, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, procedure, IS_STRING, 1, "null") @@ -187,8 +187,8 @@ ZEND_END_ARG_INFO() #endif #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_procedures, 0, 0, 1) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_procedures, 0, 1, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, catalog, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, schema, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, procedure, IS_STRING, 1, "null") @@ -196,8 +196,8 @@ ZEND_END_ARG_INFO() #endif #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_foreignkeys, 0, 0, 7) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_foreignkeys, 0, 7, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO(0, pk_catalog, IS_STRING, 1) ZEND_ARG_TYPE_INFO(0, pk_schema, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, pk_table, IS_STRING, 0) @@ -207,8 +207,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_foreignkeys, 0, 0, 7) ZEND_END_ARG_INFO() #endif -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_specialcolumns, 0, 0, 7) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_specialcolumns, 0, 7, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, catalog, IS_STRING, 1) ZEND_ARG_TYPE_INFO(0, schema, IS_STRING, 0) @@ -217,8 +217,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_specialcolumns, 0, 0, 7) ZEND_ARG_TYPE_INFO(0, nullable, IS_LONG, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_statistics, 0, 0, 6) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_statistics, 0, 6, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO(0, catalog, IS_STRING, 1) ZEND_ARG_TYPE_INFO(0, schema, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, table, IS_STRING, 0) @@ -227,8 +227,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_statistics, 0, 0, 6) ZEND_END_ARG_INFO() #if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_tableprivileges, 0, 0, 4) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_tableprivileges, 0, 4, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO(0, catalog, IS_STRING, 1) ZEND_ARG_TYPE_INFO(0, schema, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, table, IS_STRING, 0) @@ -236,8 +236,8 @@ ZEND_END_ARG_INFO() #endif #if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) -ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_columnprivileges, 0, 0, 5) - ZEND_ARG_INFO(0, odbc) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_columnprivileges, 0, 5, ODBC\\Result, MAY_BE_FALSE) + ZEND_ARG_OBJ_INFO(0, odbc, ODBC\\Connection, 0) ZEND_ARG_TYPE_INFO(0, catalog, IS_STRING, 1) ZEND_ARG_TYPE_INFO(0, schema, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, table, IS_STRING, 0) @@ -392,6 +392,16 @@ static const zend_function_entry ext_functions[] = { ZEND_FE_END }; + +static const zend_function_entry class_ODBC_Connection_methods[] = { + ZEND_FE_END +}; + + +static const zend_function_entry class_ODBC_Result_methods[] = { + ZEND_FE_END +}; + static void register_odbc_symbols(int module_number) { REGISTER_STRING_CONSTANT("ODBC_TYPE", PHP_ODBC_TYPE, CONST_PERSISTENT); @@ -491,3 +501,25 @@ static void register_odbc_symbols(int module_number) zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "odbc_pconnect", sizeof("odbc_pconnect") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); } + +static zend_class_entry *register_class_ODBC_Connection(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ODBC", "Connection", class_ODBC_Connection_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + + return class_entry; +} + +static zend_class_entry *register_class_ODBC_Result(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "ODBC", "Result", class_ODBC_Result_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; + + return class_entry; +} diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 804e79b063636..59513c9777684 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -29,6 +29,8 @@ #include "ext/standard/info.h" #include "ext/standard/php_string.h" #include "ext/standard/php_standard.h" +#include "Zend/zend_interfaces.h" +#include "zend_smart_str.h" #include "php_odbc.h" #include "php_odbc_includes.h" @@ -49,18 +51,140 @@ #include "odbc_arginfo.h" -/* - * not defined elsewhere - */ +#define CHECK_ODBC_CONNECTION(conn) \ + if (conn == NULL) { \ + zend_throw_error(NULL, "ODBC connection has already been closed"); \ + RETURN_THROWS(); \ + } -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif +#define CHECK_ODBC_RESULT(result) \ + if (result->conn_ptr == NULL) { \ + zend_throw_error(NULL, "ODBC result has already been closed"); \ + RETURN_THROWS(); \ + } void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent); +static void safe_odbc_disconnect(void *handle); + +static int le_pconn; + +static zend_class_entry *odbc_connection_ce, *odbc_result_ce; +static zend_object_handlers odbc_connection_object_handlers, odbc_result_object_handlers; + +static inline odbc_link *odbc_link_from_obj(zend_object *obj) { + return (odbc_link *)((char *)(obj) - XtOffsetOf(odbc_link, std)); +} + +#define Z_ODBC_LINK_P(zv) odbc_link_from_obj(Z_OBJ_P(zv)) +#define Z_ODBC_CONNECTION_P(zv) Z_ODBC_LINK_P(zv)->connection + +static zend_object *odbc_connection_create_object(zend_class_entry *class_type) { + odbc_link *intern = zend_object_alloc(sizeof(odbc_link), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &odbc_connection_object_handlers; + + return &intern->std; +} + +static zend_function *odbc_connection_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct ODBC\\Connection, use odbc_connect() or odbc_pconnect() instead"); + return NULL; +} + +static void odbc_link_free(odbc_link *link) +{ + /* If aborted via timer expiration, don't try to call any unixODBC function */ + if (!(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) { + safe_odbc_disconnect(link->connection->hdbc); + SQLFreeConnect(link->connection->hdbc); + SQLFreeEnv(link->connection->henv); + } + efree(link->connection); + link->connection = NULL; + ODBCG(num_links)--; + if (!link->persistent) { + zend_hash_del(&ODBCG(connections), link->hash); + } + zend_string_release(link->hash); +} + +static void odbc_connection_free_obj(zend_object *obj) +{ + odbc_link *link = odbc_link_from_obj(obj); + + if (!link->connection) { + zend_object_std_dtor(&link->std); + return; + } + + odbc_link_free(link); + zend_object_std_dtor(&link->std); +} + +static inline odbc_result *odbc_result_from_obj(zend_object *obj) { + return (odbc_result *)((char *)(obj) - XtOffsetOf(odbc_result, std)); +} + +#define Z_ODBC_RESULT_P(zv) odbc_result_from_obj(Z_OBJ_P(zv)) + +static zend_object *odbc_result_create_object(zend_class_entry *class_type) { + odbc_result *intern = zend_object_alloc(sizeof(odbc_result), class_type); -static int le_result, le_conn, le_pconn; + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &odbc_result_object_handlers; + + return &intern->std; +} + +static zend_function *odbc_result_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct ODBC\\Result, use an appropriate odbc_* function instead"); + return NULL; +} + +static void odbc_result_free(odbc_result *res) +{ + int i; + + if (res->values) { + for(i = 0; i < res->numcols; i++) { + if (res->values[i].value) + efree(res->values[i].value); + } + efree(res->values); + res->values = NULL; + } + /* If aborted via timer expiration, don't try to call any unixODBC function */ + if (res->stmt && !(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) { +#if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) || defined(HAVE_SOLID_35) + SQLTransact(res->conn_ptr->henv, res->conn_ptr->hdbc, + (SQLUSMALLINT) SQL_COMMIT); +#endif + SQLFreeStmt(res->stmt,SQL_DROP); + /* We don't want the connection to be closed after the last statement has been closed + * Connections will be closed on shutdown + * zend_list_delete(res->conn_ptr->id); + */ + } + if (res->param_info) { + efree(res->param_info); + } + efree(res); +} + +static void odbc_result_free_obj(zend_object *obj) { + odbc_result *result = odbc_result_from_obj(obj); + + if (!result->stmt) { + zend_object_std_dtor(&result->std); + return; + } + + odbc_result_free(result); + zend_object_std_dtor(&result->std); +} #define SAFE_SQL_NTS(n) ((SQLSMALLINT) ((n)?(SQL_NTS):0)) @@ -93,44 +217,18 @@ ZEND_TSRMLS_CACHE_DEFINE() ZEND_GET_MODULE(odbc) #endif -/* {{{ _free_odbc_result */ -static void _free_odbc_result(zend_resource *rsrc) -{ - odbc_result *res = (odbc_result *)rsrc->ptr; - int i; +static void close_results_with_connection(const odbc_connection *conn) { + zval *p; - if (res) { - if (res->values) { - for(i = 0; i < res->numcols; i++) { - if (res->values[i].value) - efree(res->values[i].value); - } - efree(res->values); - res->values = NULL; + ZEND_HASH_FOREACH_VAL(&ODBCG(results), p) { + odbc_result *result = Z_ODBC_RESULT_P(p); + if (result->conn_ptr == conn) { + odbc_result_free((odbc_result*) p); } - /* If aborted via timer expiration, don't try to call any unixODBC function */ - if (res->stmt && !(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) { -#if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) || defined(HAVE_SOLID_35) - SQLTransact(res->conn_ptr->henv, res->conn_ptr->hdbc, - (SQLUSMALLINT) SQL_COMMIT); -#endif - SQLFreeStmt(res->stmt,SQL_DROP); - /* We don't want the connection to be closed after the last statement has been closed - * Connections will be closed on shutdown - * zend_list_delete(res->conn_ptr->id); - */ - } - if (res->param_info) { - efree(res->param_info); - } - efree(res); - } + } ZEND_HASH_FOREACH_END(); } -/* }}} */ -/* {{{ safe_odbc_disconnect - * disconnect, and if it fails, then issue a rollback for any pending transaction (lurcher) - */ +/* disconnect, and if it fails, then issue a rollback for any pending transaction (lurcher) */ static void safe_odbc_disconnect( void *handle ) { int ret; @@ -142,51 +240,13 @@ static void safe_odbc_disconnect( void *handle ) SQLDisconnect( handle ); } } -/* }}} */ - -/* {{{ _close_odbc_conn */ -static void _close_odbc_conn(zend_resource *rsrc) -{ - zend_resource *p; - odbc_result *res; - - odbc_connection *conn = (odbc_connection *)rsrc->ptr; - - ZEND_HASH_FOREACH_PTR(&EG(regular_list), p) { - if (p->ptr && (p->type == le_result)) { - res = (odbc_result *)p->ptr; - if (res->conn_ptr == conn) { - zend_list_close(p); - } - } - } ZEND_HASH_FOREACH_END(); - - /* If aborted via timer expiration, don't try to call any unixODBC function */ - if (!(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) { - safe_odbc_disconnect(conn->hdbc); - SQLFreeConnect(conn->hdbc); - SQLFreeEnv(conn->henv); - } - efree(conn); - ODBCG(num_links)--; -} -/* }}} */ /* {{{ void _close_odbc_pconn */ static void _close_odbc_pconn(zend_resource *rsrc) { - zend_resource *p; - odbc_result *res; odbc_connection *conn = (odbc_connection *)rsrc->ptr; - ZEND_HASH_FOREACH_PTR(&EG(regular_list), p) { - if (p->ptr && (p->type == le_result)) { - res = (odbc_result *)p->ptr; - if (res->conn_ptr == conn) { - zend_list_close(p); - } - } - } ZEND_HASH_FOREACH_END(); + close_results_with_connection(conn); /* If aborted via timer expiration, don't try to call any unixODBC function */ if (!(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) { @@ -198,6 +258,7 @@ static void _close_odbc_pconn(zend_resource *rsrc) ODBCG(num_links)--; ODBCG(num_persistent)--; + rsrc->ptr = NULL; } /* }}} */ @@ -378,6 +439,8 @@ static PHP_GINIT_FUNCTION(odbc) ZEND_TSRMLS_CACHE_UPDATE(); #endif odbc_globals->num_persistent = 0; + zend_hash_init(&odbc_globals->results, 0, NULL, NULL, 1); + zend_hash_init(&odbc_globals->connections, 0, NULL, NULL, 1); } /* {{{ PHP_MINIT_FUNCTION */ @@ -389,19 +452,39 @@ PHP_MINIT_FUNCTION(odbc) #endif REGISTER_INI_ENTRIES(); - le_result = zend_register_list_destructors_ex(_free_odbc_result, NULL, "odbc result", module_number); - le_conn = zend_register_list_destructors_ex(_close_odbc_conn, NULL, "odbc link", module_number); le_pconn = zend_register_list_destructors_ex(NULL, _close_odbc_pconn, "odbc link persistent", module_number); odbc_module_entry.type = type; + register_odbc_symbols(module_number); + + odbc_connection_ce = register_class_ODBC_Connection(); + odbc_connection_ce->create_object = odbc_connection_create_object; + odbc_connection_ce->default_object_handlers = &odbc_connection_object_handlers; + + memcpy(&odbc_connection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + odbc_connection_object_handlers.offset = XtOffsetOf(odbc_link, std); + odbc_connection_object_handlers.free_obj = odbc_connection_free_obj; + odbc_connection_object_handlers.get_constructor = odbc_connection_get_constructor; + odbc_connection_object_handlers.clone_obj = NULL; + odbc_connection_object_handlers.compare = zend_objects_not_comparable; + + odbc_result_ce = register_class_ODBC_Result(); + odbc_result_ce->create_object = odbc_result_create_object; + odbc_result_ce->default_object_handlers = &odbc_result_object_handlers; + + memcpy(&odbc_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + odbc_result_object_handlers.offset = XtOffsetOf(odbc_result, std); + odbc_result_object_handlers.free_obj = odbc_result_free_obj; + odbc_result_object_handlers.get_constructor = odbc_result_get_constructor; + odbc_result_object_handlers.clone_obj = NULL; + odbc_result_object_handlers.compare = zend_objects_not_comparable; + #if defined(HAVE_IBMDB2) && defined(_AIX) /* atexit() handler in the DB2/AIX library segfaults in PHP CLI */ /* DB2NOEXITLIST env variable prevents DB2 from invoking atexit() */ putenv("DB2NOEXITLIST=TRUE"); #endif - register_odbc_symbols(module_number); - return SUCCESS; } /* }}} */ @@ -427,6 +510,9 @@ PHP_RSHUTDOWN_FUNCTION(odbc) /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(odbc) { + zend_hash_destroy(&ODBCG(results)); + zend_hash_destroy(&ODBCG(connections)); + UNREGISTER_INI_ENTRIES(); return SUCCESS; } @@ -510,13 +596,12 @@ void php_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAMETERS, int mode) zval *pv_res; zend_long flag; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &pv_res, &flag) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pv_res, odbc_result_ce, &flag) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (mode) { result->longreadlen = flag; @@ -656,13 +741,12 @@ void odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int type) RETCODE rc; zval *pv_conn; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pv_conn) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_conn, odbc_connection_ce) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); rc = SQLTransact(conn->henv, conn->hdbc, (SQLUSMALLINT)((type)?SQL_COMMIT:SQL_ROLLBACK)); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { @@ -674,17 +758,6 @@ void odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int type) } /* }}} */ -/* {{{ _close_pconn_with_res */ -static int _close_pconn_with_res(zend_resource *le, zend_resource *res) -{ - if (le->type == le_pconn && (((odbc_connection *)(le->ptr))->res == res)){ - return 1; - }else{ - return 0; - } -} -/* }}} */ - /* {{{ odbc_column_lengths */ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) { @@ -703,13 +776,12 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) zval *pv_res; zend_long pv_num; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &pv_res, &pv_num) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pv_res, odbc_result_ce, &pv_num) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (pv_num < 1) { zend_argument_value_error(2, "must be greater than 0"); @@ -737,30 +809,26 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ Close all ODBC connections */ PHP_FUNCTION(odbc_close_all) { - zend_resource *p; + zval *p; if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); } /* Loop through list and close all statements */ - ZEND_HASH_FOREACH_PTR(&EG(regular_list), p) { - if (p->ptr && (p->type == le_result)) { - zend_list_close(p); - } + ZEND_HASH_FOREACH_VAL(&ODBCG(results), p) { + odbc_result_free((odbc_result*) p); } ZEND_HASH_FOREACH_END(); - /* Second loop through list, now close all connections */ - ZEND_HASH_FOREACH_PTR(&EG(regular_list), p) { - if (p->ptr) { - if (p->type == le_conn){ - zend_list_close(p); - } else if (p->type == le_pconn){ - zend_list_close(p); - /* Delete the persistent connection */ - zend_hash_apply_with_argument(&EG(persistent_list), - (apply_func_arg_t) _close_pconn_with_res, (void *)p); - } + /* Second loop through list, now close all non-persistent connections */ + ZEND_HASH_FOREACH_VAL(&ODBCG(connections), p) { + odbc_link_free((odbc_link*) p); + } ZEND_HASH_FOREACH_END(); + + /* Third loop through persistent list, now close all persistent connections */ + ZEND_HASH_FOREACH_VAL(&EG(persistent_list), p) { + if (Z_RES_P(p)->type == le_pconn) { + zend_list_close(Z_RES_P(p)); } } ZEND_HASH_FOREACH_END(); } @@ -794,29 +862,29 @@ PHP_FUNCTION(odbc_prepare) SQLUINTEGER scrollopts; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pv_conn, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pv_conn, odbc_connection_ce, &query, &query_len) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); result->numparams = 0; result->param_info = NULL; rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -853,7 +921,7 @@ PHP_FUNCTION(odbc_prepare) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -871,12 +939,10 @@ PHP_FUNCTION(odbc_prepare) odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParameter"); SQLFreeStmt(result->stmt, SQL_RESET_PARAMS); efree(result->param_info); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } - - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ @@ -915,13 +981,12 @@ PHP_FUNCTION(odbc_execute) int i, ne; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|h", &pv_res, &pv_param_ht) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|h", &pv_res, odbc_result_ce, &pv_param_ht) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (result->numparams > 0) { if ((ne = zend_hash_num_elements(pv_param_ht)) < result->numparams) { @@ -1075,13 +1140,12 @@ PHP_FUNCTION(odbc_cursor) odbc_result *result; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pv_res) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); rc = SQLGetInfo(result->conn_ptr->hdbc,SQL_MAX_CURSOR_NAME_LEN, (void *)&max_len,sizeof(max_len),&len); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { @@ -1133,7 +1197,7 @@ PHP_FUNCTION(odbc_data_source) UCHAR server_name[100], desc[200]; SQLSMALLINT len1=0, len2=0, fetch_type; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &zv_conn, &zv_fetch_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &zv_conn, odbc_connection_ce, &zv_fetch_type) == FAILURE) { RETURN_THROWS(); } @@ -1144,9 +1208,8 @@ PHP_FUNCTION(odbc_data_source) RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(zv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(zv_conn); + CHECK_ODBC_CONNECTION(conn); /* now we have the "connection" lets call the DataSource object */ rc = SQLDataSources(conn->henv, @@ -1196,26 +1259,26 @@ PHP_FUNCTION(odbc_exec) SQLUINTEGER scrollopts; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pv_conn, &query, &query_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pv_conn, odbc_connection_ce, &query, &query_len) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -1242,7 +1305,7 @@ PHP_FUNCTION(odbc_exec) */ odbc_sql_error(conn, result->stmt, "SQLExecDirect"); SQLFreeStmt(result->stmt, SQL_DROP); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -1251,7 +1314,7 @@ PHP_FUNCTION(odbc_exec) /* For insert, update etc. cols == 0 */ if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -1260,7 +1323,6 @@ PHP_FUNCTION(odbc_exec) Z_ADDREF_P(pv_conn); result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ @@ -1276,30 +1338,21 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) RETCODE rc; SQLSMALLINT sql_c_type; char *buf = NULL; + zval *pv_res, tmp; + zend_long pv_row = -1; + bool pv_row_is_null = true; #ifdef HAVE_SQL_EXTENDED_FETCH SQLULEN crow; SQLUSMALLINT RowStatus[1]; - SQLLEN rownum; - zval *pv_res, tmp; - zend_long pv_row = -1; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &pv_res, &pv_row) == FAILURE) { - RETURN_THROWS(); - } - - rownum = pv_row; -#else - zval *pv_res, tmp; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pv_res) == FAILURE) { - RETURN_THROWS(); - } #endif - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l!", &pv_res, odbc_result_ce, &pv_row, &pv_row_is_null) == FAILURE) { RETURN_THROWS(); } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); + if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); RETURN_FALSE; @@ -1307,8 +1360,8 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) #ifdef HAVE_SQL_EXTENDED_FETCH if (result->fetch_abs) { - if (rownum > 0) { - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,rownum,&crow,RowStatus); + if (!pv_row_is_null) { + rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,(SQLLEN) pv_row,&crow,RowStatus); } else { rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus); } @@ -1322,12 +1375,11 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) array_init(return_value); -#ifdef HAVE_SQL_EXTENDED_FETCH - if (rownum > 0 && result->fetch_abs) - result->fetched = rownum; - else -#endif + if (!pv_row_is_null && result->fetch_abs) { + result->fetched = (SQLLEN) pv_row; + } else { result->fetched++; + } for(i = 0; i < result->numcols; i++) { sql_c_type = SQL_C_CHAR; @@ -1437,28 +1489,19 @@ PHP_FUNCTION(odbc_fetch_into) SQLSMALLINT sql_c_type; char *buf = NULL; zval *pv_res, *pv_res_arr, tmp; -#ifdef HAVE_SQL_EXTENDED_FETCH zend_long pv_row = 0; + bool pv_row_is_null = true; +#ifdef HAVE_SQL_EXTENDED_FETCH SQLULEN crow; SQLUSMALLINT RowStatus[1]; - SQLLEN rownum = -1; -#endif /* HAVE_SQL_EXTENDED_FETCH */ - -#ifdef HAVE_SQL_EXTENDED_FETCH - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz|l", &pv_res, &pv_res_arr, &pv_row) == FAILURE) { - RETURN_THROWS(); - } +#endif - rownum = pv_row; -#else - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pv_res, &pv_res_arr) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz|l!", &pv_res, odbc_result_ce, &pv_res_arr, &pv_row, &pv_row_is_null) == FAILURE) { RETURN_THROWS(); } -#endif /* HAVE_SQL_EXTENDED_FETCH */ - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); @@ -1472,8 +1515,8 @@ PHP_FUNCTION(odbc_fetch_into) #ifdef HAVE_SQL_EXTENDED_FETCH if (result->fetch_abs) { - if (rownum > 0) { - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,rownum,&crow,RowStatus); + if (!pv_row_is_null) { + rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,(SQLLEN) pv_row,&crow,RowStatus); } else { rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus); } @@ -1485,12 +1528,11 @@ PHP_FUNCTION(odbc_fetch_into) RETURN_FALSE; } -#ifdef HAVE_SQL_EXTENDED_FETCH - if (rownum > 0 && result->fetch_abs) - result->fetched = rownum; - else -#endif + if (!pv_row_is_null && result->fetch_abs) { + result->fetched = (SQLLEN) pv_row; + } else { result->fetched++; + } for(i = 0; i < result->numcols; i++) { sql_c_type = SQL_C_CHAR; @@ -1569,13 +1611,13 @@ PHP_FUNCTION(solid_fetch_prev) RETCODE rc; zval *pv_res; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pv_res) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res; + CHECK_ODBC_RESULT(result); + if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); RETURN_FALSE; @@ -1601,20 +1643,19 @@ PHP_FUNCTION(odbc_fetch_row) odbc_result *result; RETCODE rc; zval *pv_res; - zend_long pv_row; - bool pv_row_is_null = 1; + zend_long pv_row = 0; + bool pv_row_is_null = true; #ifdef HAVE_SQL_EXTENDED_FETCH SQLULEN crow; SQLUSMALLINT RowStatus[1]; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l!", &pv_res, &pv_row, &pv_row_is_null) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l!", &pv_res, odbc_result_ce, &pv_row, &pv_row_is_null) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); @@ -1665,7 +1706,7 @@ PHP_FUNCTION(odbc_result) #endif ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(pv_res) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) Z_PARAM_STR_OR_LONG(pv_field_str, pv_field_long) ZEND_PARSE_PARAMETERS_END(); @@ -1677,9 +1718,8 @@ PHP_FUNCTION(odbc_result) field_ind = (int) pv_field_long - 1; } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); @@ -1873,13 +1913,12 @@ PHP_FUNCTION(odbc_result_all) SQLUSMALLINT RowStatus[1]; #endif - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|s", &pv_res, &pv_format, &pv_format_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s", &pv_res, odbc_result_ce, &pv_format, &pv_format_len) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); @@ -2007,13 +2046,12 @@ PHP_FUNCTION(odbc_free_result) odbc_result *result; int i; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pv_res) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (result->values) { for (i = 0; i < result->numcols; i++) { @@ -2046,18 +2084,23 @@ PHP_FUNCTION(odbc_pconnect) /* }}} */ /* {{{ odbc_sqlconnect */ -int odbc_sqlconnect(odbc_connection **conn, char *db, char *uid, char *pwd, int cur_opt, int persistent) +bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, int persistent, zend_string *hash) { RETCODE rc; + odbc_link *link; + + object_init_ex(zv, odbc_connection_ce); + link = Z_ODBC_LINK_P(zv); + link->connection = (odbc_connection *)pemalloc(sizeof(odbc_connection), persistent); + memset(link->connection, 0, sizeof(odbc_connection)); - *conn = (odbc_connection *)pemalloc(sizeof(odbc_connection), persistent); - memset(*conn, 0, sizeof(odbc_connection)); - (*conn)->persistent = persistent; - SQLAllocEnv(&((*conn)->henv)); - SQLAllocConnect((*conn)->henv, &((*conn)->hdbc)); + link->persistent = persistent; + link->hash = hash; + SQLAllocEnv(link->connection->henv); + SQLAllocConnect(link->connection->henv, link->connection->hdbc); #if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) - SQLSetConnectOption((*conn)->hdbc, SQL_TRANSLATE_OPTION, + SQLSetConnectOption((link->connection->hdbc, SQL_TRANSLATE_OPTION, SQL_SOLID_XLATOPT_NOCNV); #endif #ifdef HAVE_OPENLINK @@ -2065,16 +2108,15 @@ int odbc_sqlconnect(odbc_connection **conn, char *db, char *uid, char *pwd, int char dsnbuf[1024]; short dsnbuflen; - rc = SQLDriverConnect((*conn)->hdbc, NULL, db, SQL_NTS, dsnbuf, sizeof(dsnbuf) - 1, &dsnbuflen, SQL_DRIVER_NOPROMPT); + rc = SQLDriverConnect(link->connection->hdbc, NULL, db, SQL_NTS, dsnbuf, sizeof(dsnbuf) - 1, &dsnbuflen, SQL_DRIVER_NOPROMPT); } #else if (cur_opt != SQL_CUR_DEFAULT) { - rc = SQLSetConnectOption((*conn)->hdbc, SQL_ODBC_CURSORS, cur_opt); + rc = SQLSetConnectOption(link->connection->hdbc, SQL_ODBC_CURSORS, cur_opt); if (rc != SQL_SUCCESS) { /* && rc != SQL_SUCCESS_WITH_INFO ? */ - odbc_sql_error(*conn, SQL_NULL_HSTMT, "SQLSetConnectOption"); - SQLFreeConnect((*conn)->hdbc); - pefree(*conn, persistent); - return FALSE; + odbc_sql_error(link->connection, SQL_NULL_HSTMT, "SQLSetConnectOption"); + SQLFreeConnect(link->connection->hdbc); + return false; } } /* Possible fix for bug #10250 @@ -2132,9 +2174,9 @@ int odbc_sqlconnect(odbc_connection **conn, char *db, char *uid, char *pwd, int } if (direct) { - rc = SQLDriverConnect((*conn)->hdbc, NULL, (SQLCHAR *) ldb, strlen(ldb), dsnbuf, sizeof(dsnbuf) - 1, &dsnbuflen, SQL_DRIVER_NOPROMPT); + rc = SQLDriverConnect(link->connection->hdbc, NULL, (SQLCHAR *) ldb, strlen(ldb), dsnbuf, sizeof(dsnbuf) - 1, &dsnbuflen, SQL_DRIVER_NOPROMPT); } else { - rc = SQLConnect((*conn)->hdbc, (SQLCHAR *) db, SQL_NTS, (SQLCHAR *) uid, SQL_NTS, (SQLCHAR *) pwd, SQL_NTS); + rc = SQLConnect(link->connection->hdbc, (SQLCHAR *) db, SQL_NTS, (SQLCHAR *) uid, SQL_NTS, (SQLCHAR *) pwd, SQL_NTS); } if (ldb) { @@ -2142,17 +2184,15 @@ int odbc_sqlconnect(odbc_connection **conn, char *db, char *uid, char *pwd, int } } #else - rc = SQLConnect((*conn)->hdbc, (SQLCHAR *) db, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS); + rc = SQLConnect(link->connection->hdbc, (SQLCHAR *) db, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS); #endif #endif if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - odbc_sql_error(*conn, SQL_NULL_HSTMT, "SQLConnect"); - SQLFreeConnect((*conn)->hdbc); - pefree((*conn), persistent); - return FALSE; + odbc_sql_error(link->connection, SQL_NULL_HSTMT, "SQLConnect"); + SQLFreeConnect(link->connection->hdbc); + return false; } -/* (*conn)->open = 1;*/ - return TRUE; + return true; } /* }}} */ @@ -2195,42 +2235,43 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) persistent = 0; } + smart_str hashed_details = {0}; + smart_str_append_printf(&hashed_details, "%s_%s_%s_%s_%d", ODBC_TYPE, db, uid, pwd, cur_opt); + try_and_get_another_connection: if (persistent) { - char *hashed_details; - int hashed_len; zend_resource *le; - hashed_len = spprintf(&hashed_details, 0, "%s_%s_%s_%s_%d", ODBC_TYPE, db, uid, pwd, cur_opt); - /* the link is not in the persistent list */ - if ((le = zend_hash_str_find_ptr(&EG(persistent_list), hashed_details, hashed_len)) == NULL) { + if ((le = zend_hash_find_ptr(&EG(persistent_list), hashed_details.s)) == NULL) { if (ODBCG(max_links) != -1 && ODBCG(num_links) >= ODBCG(max_links)) { - php_error_docref(NULL, E_WARNING, "Too many open links (%ld)", ODBCG(num_links)); - efree(hashed_details); + php_error_docref(NULL, E_WARNING, "Too many open links (" ZEND_LONG_FMT ")", ODBCG(num_links)); + smart_str_free(&hashed_details); RETURN_FALSE; } if (ODBCG(max_persistent) != -1 && ODBCG(num_persistent) >= ODBCG(max_persistent)) { - php_error_docref(NULL, E_WARNING,"Too many open persistent links (%ld)", ODBCG(num_persistent)); - efree(hashed_details); + php_error_docref(NULL, E_WARNING,"Too many open persistent links (" ZEND_LONG_FMT ")", ODBCG(num_persistent)); + smart_str_free(&hashed_details); RETURN_FALSE; } - if (!odbc_sqlconnect(&db_conn, db, uid, pwd, cur_opt, 1)) { - efree(hashed_details); + if (!odbc_sqlconnect(return_value, db, uid, pwd, cur_opt, 1, hashed_details.s)) { + smart_str_free(&hashed_details); + zval_ptr_dtor(return_value); RETURN_FALSE; } - if (zend_register_persistent_resource(hashed_details, hashed_len, db_conn, le_pconn) == NULL) { - free(db_conn); - efree(hashed_details); + db_conn = Z_ODBC_CONNECTION_P(return_value); + + if (zend_register_persistent_resource(ZSTR_VAL(hashed_details.s), ZSTR_LEN(hashed_details.s), db_conn, le_pconn) == NULL) { + smart_str_free(&hashed_details); + zval_ptr_dtor(return_value); RETURN_FALSE; } + ODBCG(num_persistent)++; ODBCG(num_links)++; - db_conn->res = zend_register_resource(db_conn, le_pconn); - RETVAL_RES(db_conn->res); } else { /* found connection */ ZEND_ASSERT(le->type == le_pconn); @@ -2253,7 +2294,7 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) &dead, 0, NULL); if (ret == SQL_SUCCESS && dead == SQL_CD_TRUE) { /* Bail early here, since we know it's gone */ - zend_hash_str_del(&EG(persistent_list), hashed_details, hashed_len); + zend_hash_del(&EG(persistent_list), hashed_details.s); goto try_and_get_another_connection; } /* If the driver doesn't support it, or returns @@ -2265,7 +2306,7 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) d_name, sizeof(d_name), &len); if(ret != SQL_SUCCESS || len == 0) { - zend_hash_str_del(&EG(persistent_list), hashed_details, hashed_len); + zend_hash_del(&EG(persistent_list), hashed_details.s); /* Commented out to fix a possible double closure error * when working with persistent connections as submitted by * bug #15758 @@ -2276,23 +2317,29 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) goto try_and_get_another_connection; } } + + object_init_ex(return_value, odbc_connection_ce); + odbc_link *link = Z_ODBC_LINK_P(return_value); + link->connection = db_conn; + link->hash = zend_string_copy(hashed_details.s); + link->persistent = 1; } - efree(hashed_details); - db_conn->res = zend_register_resource(db_conn, le_pconn); - RETVAL_RES(db_conn->res); } else { /* non persistent */ if (ODBCG(max_links) != -1 && ODBCG(num_links) >= ODBCG(max_links)) { - php_error_docref(NULL, E_WARNING,"Too many open connections (%ld)",ODBCG(num_links)); + php_error_docref(NULL, E_WARNING,"Too many open connections (" ZEND_LONG_FMT ")", ODBCG(num_links)); + smart_str_free(&hashed_details); RETURN_FALSE; } - if (!odbc_sqlconnect(&db_conn, db, uid, pwd, cur_opt, 0)) { + if (!odbc_sqlconnect(return_value, db, uid, pwd, cur_opt, 0, hashed_details.s)) { + smart_str_free(&hashed_details); RETURN_FALSE; } - db_conn->res = zend_register_resource(db_conn, le_conn); - RETVAL_RES(db_conn->res); ODBCG(num_links)++; } + + zend_hash_update(&ODBCG(connections), hashed_details.s, return_value); + smart_str_free(&hashed_details); } /* }}} */ @@ -2300,37 +2347,22 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) PHP_FUNCTION(odbc_close) { zval *pv_conn; - zend_resource *p; - odbc_connection *conn; - odbc_result *res; - int is_pconn = 0; + odbc_link *link; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pv_conn) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_conn, odbc_connection_ce) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + link = Z_ODBC_LINK_P(pv_conn); + CHECK_ODBC_CONNECTION(link->connection); - if (Z_RES_P(pv_conn)->type == le_pconn) { - is_pconn = 1; + if (link->persistent) { + zend_hash_del(&EG(persistent_list), link->hash); } - ZEND_HASH_FOREACH_PTR(&EG(regular_list), p) { - if (p->ptr && (p->type == le_result)) { - res = (odbc_result *)p->ptr; - if (res->conn_ptr == conn) { - zend_list_close(p); - } - } - } ZEND_HASH_FOREACH_END(); - - zend_list_close(Z_RES_P(pv_conn)); + close_results_with_connection(link->connection); - if(is_pconn){ - zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) _close_pconn_with_res, (void *) Z_RES_P(pv_conn)); - } + odbc_link_free(link); } /* }}} */ @@ -2341,13 +2373,12 @@ PHP_FUNCTION(odbc_num_rows) SQLLEN rows; zval *pv_res; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pv_res) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); SQLRowCount(result->stmt, &rows); RETURN_LONG(rows); @@ -2362,13 +2393,12 @@ PHP_FUNCTION(odbc_next_result) zval *pv_res; int rc, i; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pv_res) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (result->values) { for(i = 0; i < result->numcols; i++) { @@ -2413,13 +2443,12 @@ PHP_FUNCTION(odbc_num_fields) odbc_result *result; zval *pv_res; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pv_res) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &pv_res, odbc_result_ce) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); RETURN_LONG(result->numcols); } @@ -2432,13 +2461,12 @@ PHP_FUNCTION(odbc_field_name) zval *pv_res; zend_long pv_num; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &pv_res, &pv_num) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pv_res, odbc_result_ce, &pv_num) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (pv_num < 1) { zend_argument_value_error(2, "must be greater than 0"); @@ -2468,13 +2496,12 @@ PHP_FUNCTION(odbc_field_type) zval *pv_res; zend_long pv_num; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &pv_res, &pv_num) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &pv_res, odbc_result_ce, &pv_num) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (pv_num < 1) { zend_argument_value_error(2, "must be greater than 0"); @@ -2518,13 +2545,12 @@ PHP_FUNCTION(odbc_field_num) odbc_result *result; zval *pv_res; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &pv_res, &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pv_res, odbc_result_ce, &fname, &fname_len) == FAILURE) { RETURN_THROWS(); } - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { - RETURN_THROWS(); - } + result = Z_ODBC_RESULT_P(pv_res); + CHECK_ODBC_RESULT(result); if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); @@ -2555,13 +2581,12 @@ PHP_FUNCTION(odbc_autocommit) bool pv_onoff = 0; bool pv_onoff_is_null = true; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b!", &pv_conn, &pv_onoff, &pv_onoff_is_null) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|b!", &pv_conn, odbc_connection_ce, &pv_onoff, &pv_onoff_is_null) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); if (!pv_onoff_is_null) { rc = SQLSetConnectOption(conn->hdbc, SQL_AUTOCOMMIT, pv_onoff ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF); @@ -2604,14 +2629,14 @@ static void php_odbc_lasterror(INTERNAL_FUNCTION_PARAMETERS, int mode) zval *pv_handle = NULL; char *ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &pv_handle) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|O!", &pv_handle, odbc_connection_ce) == FAILURE) { RETURN_THROWS(); } if (pv_handle) { - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_handle), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_handle); + CHECK_ODBC_CONNECTION(conn); + if (mode == 0) { ret = conn->laststate; } else { @@ -2652,36 +2677,42 @@ PHP_FUNCTION(odbc_errormsg) */ PHP_FUNCTION(odbc_setoption) { - odbc_connection *conn; + odbc_link *link; odbc_result *result; RETCODE rc; zval *pv_handle; zend_long pv_which, pv_opt, pv_val; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &pv_handle, &pv_which, &pv_opt, &pv_val) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "olll", &pv_handle, &pv_which, &pv_opt, &pv_val) == FAILURE) { RETURN_THROWS(); } switch (pv_which) { case 1: /* SQLSetConnectOption */ - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_handle), "ODBC-Link", le_conn, le_pconn))) { + if (!instanceof_function(Z_OBJCE_P(pv_handle), odbc_connection_ce)) { + zend_argument_type_error(1, "must be of type ODBC\\Connection for SQLSetConnectOption()"); RETURN_THROWS(); } + link = Z_ODBC_LINK_P(pv_handle); + CHECK_ODBC_CONNECTION(link->connection); - if (conn->persistent) { + if (link->persistent) { php_error_docref(NULL, E_WARNING, "Unable to set option for persistent connection"); RETURN_FALSE; } - rc = SQLSetConnectOption(conn->hdbc, (unsigned short) pv_opt, pv_val); + rc = SQLSetConnectOption(link->connection->hdbc, (unsigned short) pv_opt, pv_val); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - odbc_sql_error(conn, SQL_NULL_HSTMT, "SetConnectOption"); + odbc_sql_error(link->connection, SQL_NULL_HSTMT, "SetConnectOption"); RETURN_FALSE; } break; case 2: /* SQLSetStmtOption */ - if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_handle), "ODBC result", le_result)) == NULL) { + if (!instanceof_function(Z_OBJCE_P(pv_handle), odbc_result_ce)) { + zend_argument_type_error(1, "must be of type ODBC\\Result for SQLSetStmtOption()"); RETURN_THROWS(); } + result = Z_ODBC_RESULT_P(pv_handle); + CHECK_ODBC_RESULT(result); rc = SQLSetStmtOption(result->stmt, (unsigned short) pv_opt, pv_val); @@ -2713,27 +2744,27 @@ PHP_FUNCTION(odbc_tables) size_t cat_len = 0, schema_len = 0, table_len = 0, type_len = 0; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|s!s!s!s!", &pv_conn, &cat, &cat_len, &schema, &schema_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s!s!s!s!", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &table, &table_len, &type, &type_len) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2750,7 +2781,7 @@ PHP_FUNCTION(odbc_tables) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLTables"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2759,7 +2790,7 @@ PHP_FUNCTION(odbc_tables) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -2767,7 +2798,6 @@ PHP_FUNCTION(odbc_tables) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ @@ -2781,27 +2811,27 @@ PHP_FUNCTION(odbc_columns) size_t cat_len = 0, schema_len = 0, table_len = 0, column_len = 0; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|s!s!s!s!", &pv_conn, &cat, &cat_len, &schema, &schema_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s!s!s!s!", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &table, &table_len, &column, &column_len) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2820,7 +2850,7 @@ PHP_FUNCTION(odbc_columns) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLColumns"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2829,7 +2859,7 @@ PHP_FUNCTION(odbc_columns) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -2837,7 +2867,6 @@ PHP_FUNCTION(odbc_columns) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ @@ -2852,27 +2881,27 @@ PHP_FUNCTION(odbc_columnprivileges) size_t cat_len = 0, schema_len, table_len, column_len; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs!sss", &pv_conn, &cat, &cat_len, &schema, &schema_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!sss", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &table, &table_len, &column, &column_len) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2884,7 +2913,7 @@ PHP_FUNCTION(odbc_columnprivileges) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLColumnPrivileges"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2893,7 +2922,7 @@ PHP_FUNCTION(odbc_columnprivileges) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -2901,7 +2930,6 @@ PHP_FUNCTION(odbc_columnprivileges) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ #endif /* HAVE_DBMAKER || HAVE_SOLID*/ @@ -2917,7 +2945,7 @@ PHP_FUNCTION(odbc_foreignkeys) size_t pcat_len = 0, pschema_len, ptable_len, fcat_len, fschema_len, ftable_len; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs!sssss", &pv_conn, &pcat, &pcat_len, &pschema, &pschema_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!sssss", &pv_conn, odbc_connection_ce, &pcat, &pcat_len, &pschema, &pschema_len, &ptable, &ptable_len, &fcat, &fcat_len, &fschema, &fschema_len, &ftable, &ftable_len) == FAILURE) { RETURN_THROWS(); } @@ -2934,22 +2962,22 @@ PHP_FUNCTION(odbc_foreignkeys) EMPTY_TO_NULL(ftable); #endif - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2972,7 +3000,7 @@ PHP_FUNCTION(odbc_foreignkeys) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -2980,7 +3008,6 @@ PHP_FUNCTION(odbc_foreignkeys) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ #endif /* HAVE_SOLID */ @@ -2988,6 +3015,9 @@ PHP_FUNCTION(odbc_foreignkeys) /* {{{ Returns a result identifier containing information about data types supported by the data source */ PHP_FUNCTION(odbc_gettypeinfo) { + zend_value_error("Nope"); + RETURN_THROWS(); + zval *pv_conn; zend_long pv_data_type = SQL_ALL_TYPES; odbc_result *result = NULL; @@ -2995,28 +3025,30 @@ PHP_FUNCTION(odbc_gettypeinfo) RETCODE rc; SQLSMALLINT data_type; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &pv_conn, &pv_data_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l", &pv_conn, odbc_connection_ce, &pv_data_type) == FAILURE) { RETURN_THROWS(); } + printf("Hell noo"); + data_type = (SQLSMALLINT) pv_data_type; - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3024,7 +3056,7 @@ PHP_FUNCTION(odbc_gettypeinfo) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLGetTypeInfo"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3033,7 +3065,7 @@ PHP_FUNCTION(odbc_gettypeinfo) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -3041,7 +3073,6 @@ PHP_FUNCTION(odbc_gettypeinfo) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ @@ -3055,26 +3086,26 @@ PHP_FUNCTION(odbc_primarykeys) size_t cat_len = 0, schema_len, table_len; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs!ss", &pv_conn, &cat, &cat_len, &schema, &schema_len, &table, &table_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!ss", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &table, &table_len) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3085,7 +3116,7 @@ PHP_FUNCTION(odbc_primarykeys) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLPrimaryKeys"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3094,7 +3125,7 @@ PHP_FUNCTION(odbc_primarykeys) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -3102,7 +3133,6 @@ PHP_FUNCTION(odbc_primarykeys) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ @@ -3117,27 +3147,27 @@ PHP_FUNCTION(odbc_procedurecolumns) size_t cat_len = 0, schema_len = 0, proc_len = 0, col_len = 0; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|s!s!s!s!", &pv_conn, &cat, &cat_len, &schema, &schema_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s!s!s!s!", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &proc, &proc_len, &col, &col_len) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3149,7 +3179,7 @@ PHP_FUNCTION(odbc_procedurecolumns) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLProcedureColumns"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3158,7 +3188,7 @@ PHP_FUNCTION(odbc_procedurecolumns) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -3166,7 +3196,6 @@ PHP_FUNCTION(odbc_procedurecolumns) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ #endif /* HAVE_SOLID */ @@ -3182,26 +3211,26 @@ PHP_FUNCTION(odbc_procedures) size_t cat_len = 0, schema_len = 0, proc_len = 0; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|s!s!s!", &pv_conn, &cat, &cat_len, &schema, &schema_len, &proc, &proc_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s!s!s!", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &proc, &proc_len) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3212,7 +3241,7 @@ PHP_FUNCTION(odbc_procedures) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLProcedures"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3221,7 +3250,7 @@ PHP_FUNCTION(odbc_procedures) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -3229,7 +3258,6 @@ PHP_FUNCTION(odbc_procedures) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ #endif /* HAVE_SOLID */ @@ -3246,7 +3274,7 @@ PHP_FUNCTION(odbc_specialcolumns) SQLUSMALLINT type, scope, nullable; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rls!ssll", &pv_conn, &vtype, &cat, &cat_len, &schema, &schema_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ols!ssll", &pv_conn, odbc_connection_ce, &vtype, &cat, &cat_len, &schema, &schema_len, &name, &name_len, &vscope, &vnullable) == FAILURE) { RETURN_THROWS(); } @@ -3255,22 +3283,22 @@ PHP_FUNCTION(odbc_specialcolumns) scope = (SQLUSMALLINT) vscope; nullable = (SQLUSMALLINT) vnullable; - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3283,7 +3311,7 @@ PHP_FUNCTION(odbc_specialcolumns) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLSpecialColumns"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3292,7 +3320,7 @@ PHP_FUNCTION(odbc_specialcolumns) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -3300,7 +3328,6 @@ PHP_FUNCTION(odbc_specialcolumns) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ @@ -3316,7 +3343,7 @@ PHP_FUNCTION(odbc_statistics) SQLUSMALLINT unique, reserved; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs!ssll", &pv_conn, &cat, &cat_len, &schema, &schema_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!ssll", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &name, &name_len, &vunique, &vreserved) == FAILURE) { RETURN_THROWS(); } @@ -3324,22 +3351,22 @@ PHP_FUNCTION(odbc_statistics) unique = (SQLUSMALLINT) vunique; reserved = (SQLUSMALLINT) vreserved; - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3352,7 +3379,7 @@ PHP_FUNCTION(odbc_statistics) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLStatistics"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3361,7 +3388,7 @@ PHP_FUNCTION(odbc_statistics) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -3369,7 +3396,6 @@ PHP_FUNCTION(odbc_statistics) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ @@ -3384,26 +3410,26 @@ PHP_FUNCTION(odbc_tableprivileges) size_t cat_len = 0, schema_len, table_len; RETCODE rc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs!ss", &pv_conn, &cat, &cat_len, &schema, &schema_len, &table, &table_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os!ss", &pv_conn, odbc_connection_ce, &cat, &cat_len, &schema, &schema_len, &table, &table_len) == FAILURE) { RETURN_THROWS(); } - if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(pv_conn), "ODBC-Link", le_conn, le_pconn))) { - RETURN_THROWS(); - } + conn = Z_ODBC_CONNECTION_P(pv_conn); + CHECK_ODBC_CONNECTION(conn); - result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); + object_init_ex(return_value, odbc_result_ce); + result = Z_ODBC_RESULT_P(return_value); rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { - efree(result); php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); + zval_ptr_dtor(return_value); RETURN_FALSE; } if (rc == SQL_ERROR) { odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3414,7 +3440,7 @@ PHP_FUNCTION(odbc_tableprivileges) if (rc == SQL_ERROR) { odbc_sql_error(conn, result->stmt, "SQLTablePrivileges"); - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -3423,7 +3449,7 @@ PHP_FUNCTION(odbc_tableprivileges) if (result->numcols > 0) { if (!odbc_bindcols(result)) { - efree(result); + zval_ptr_dtor(return_value); RETURN_FALSE; } } else { @@ -3431,7 +3457,6 @@ PHP_FUNCTION(odbc_tableprivileges) } result->conn_ptr = conn; result->fetched = 0; - RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ #endif /* HAVE_DBMAKER */ diff --git a/ext/odbc/php_odbc_includes.h b/ext/odbc/php_odbc_includes.h index 21c74d317c68c..383cea5e67557 100644 --- a/ext/odbc/php_odbc_includes.h +++ b/ext/odbc/php_odbc_includes.h @@ -191,10 +191,15 @@ typedef struct odbc_connection { ODBC_SQL_CONN_T hdbc; char laststate[6]; char lasterrormsg[SQL_MAX_MESSAGE_LENGTH]; - zend_resource *res; - int persistent; } odbc_connection; +typedef struct odbc_link { + odbc_connection *connection; + zend_string *hash; + bool persistent; + zend_object std; +} odbc_link; + typedef struct odbc_result_value { char name[256]; char *value; @@ -220,8 +225,9 @@ typedef struct odbc_result { zend_long longreadlen; int binmode; int fetched; - odbc_param_info * param_info; + odbc_param_info *param_info; odbc_connection *conn_ptr; + zend_object std; } odbc_result; ZEND_BEGIN_MODULE_GLOBALS(odbc) @@ -240,8 +246,8 @@ ZEND_BEGIN_MODULE_GLOBALS(odbc) zend_long default_cursortype; char laststate[6]; char lasterrormsg[SQL_MAX_MESSAGE_LENGTH]; - HashTable *resource_list; - HashTable *resource_plist; + HashTable results; + HashTable connections; ZEND_END_MODULE_GLOBALS(odbc) int odbc_add_result(HashTable *list, odbc_result *result); diff --git a/ext/odbc/tests/bug78473.phpt b/ext/odbc/tests/bug78473.phpt index 3903187a36219..bed712e37bd8d 100644 --- a/ext/odbc/tests/bug78473.phpt +++ b/ext/odbc/tests/bug78473.phpt @@ -11,6 +11,6 @@ try { } var_dump(STDIN); ?> ---EXPECTF-- -odbc_close(): supplied resource is not a valid ODBC-Link resource -resource(%d) of type (stream) +--EXPECT-- +odbc_close(): Argument #1 ($odbc) must be of type ODBC\Connection, resource given +resource(1) of type (stream)