Merge branch 'PHP-7.4'

This commit is contained in:
Nikita Popov 2019-07-02 13:03:45 +02:00
commit 80fc31c887
7 changed files with 211 additions and 21 deletions

View File

@ -76,6 +76,7 @@ PHP_MINIT_FUNCTION(pdo_sqlite)
REGISTER_PDO_CLASS_CONST_LONG("SQLITE_OPEN_READWRITE", (zend_long)SQLITE_OPEN_READWRITE);
REGISTER_PDO_CLASS_CONST_LONG("SQLITE_OPEN_CREATE", (zend_long)SQLITE_OPEN_CREATE);
REGISTER_PDO_CLASS_CONST_LONG("SQLITE_ATTR_READONLY_STATEMENT", (zend_long)PDO_SQLITE_ATTR_READONLY_STATEMENT);
REGISTER_PDO_CLASS_CONST_LONG("SQLITE_ATTR_EXTENDED_RESULT_CODES", (zend_long)PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES);
return php_pdo_register_driver(&pdo_sqlite_driver);
}

View File

@ -76,7 +76,8 @@ extern const struct pdo_stmt_methods sqlite_stmt_methods;
enum {
PDO_SQLITE_ATTR_OPEN_FLAGS = PDO_ATTR_DRIVER_SPECIFIC,
PDO_SQLITE_ATTR_READONLY_STATEMENT
PDO_SQLITE_ATTR_READONLY_STATEMENT,
PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES
};
#endif

View File

@ -305,6 +305,9 @@ static int pdo_sqlite_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
case PDO_ATTR_TIMEOUT:
sqlite3_busy_timeout(H->db, zval_get_long(val) * 1000);
return 1;
case PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES:
sqlite3_extended_result_codes(H->db, zval_get_long(val));
return 1;
}
return 0;
}

View File

@ -0,0 +1,50 @@
--TEST--
PDO_sqlite: Testing PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES
--SKIPIF--
<?php if (!extension_loaded('pdo_sqlite')) print 'skip not loaded'; ?>
--FILE--
<?php
echo "Creating new PDO" . PHP_EOL;
$db = new PDO('sqlite::memory:');
$db->exec("CREATE TABLE dog ( id INTEGER PRIMARY KEY, name TEXT, annoying INTEGER )");
echo "Inserting first time which should succeed" . PHP_EOL;
$db->exec("INSERT INTO dog VALUES (1, 'Annoying Dog', 1)");
$errorInfo = $db->errorInfo();
echo sprintf("First Error Info: SQLSTATE Error Code: (%s), Driver Specific Error Code: (%s)", $errorInfo[0], $errorInfo[1]) . PHP_EOL;
echo "Inserting second time which should fail" . PHP_EOL;
$result = $db->exec("INSERT INTO dog VALUES (1, 'Annoying Dog', 1)");
$errorInfo = $db->errorInfo();
echo sprintf("Second Error Info: SQLSTATE Error Code: (%s), Driver Specific Error Code: (%s)", $errorInfo[0], $errorInfo[1]) . PHP_EOL;
echo "Creating new PDO with Extended Result Codes turned on" . PHP_EOL;
$db = new PDO('sqlite::memory:', '', '', [PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES => TRUE]);
$db->exec("CREATE TABLE dog ( id INTEGER PRIMARY KEY, name TEXT, annoying INTEGER )");
echo "Inserting first time which should succeed" . PHP_EOL;
$result = $db->exec("INSERT INTO dog VALUES (1, 'Annoying Dog', 1)");
$errorInfo = $db->errorInfo();
echo sprintf("First (Extended) Error Info: SQLSTATE Error Code: (%s), Driver Specific Error Code: (%s)", $errorInfo[0], $errorInfo[1]) . PHP_EOL;
echo "Inserting second time which should fail" . PHP_EOL;
$result = $db->exec("INSERT INTO dog VALUES (1, 'Annoying Dog', 1)");
$errorInfo = $db->errorInfo();
echo sprintf("Second (Extended) Error Info: SQLSTATE Error Code: (%s), Driver Specific Error Code: (%s)", $errorInfo[0], $errorInfo[1]) . PHP_EOL;
?>
--EXPECT--
Creating new PDO
Inserting first time which should succeed
First Error Info: SQLSTATE Error Code: (00000), Driver Specific Error Code: ()
Inserting second time which should fail
Second Error Info: SQLSTATE Error Code: (23000), Driver Specific Error Code: (19)
Creating new PDO with Extended Result Codes turned on
Inserting first time which should succeed
First (Extended) Error Info: SQLSTATE Error Code: (00000), Driver Specific Error Code: ()
Inserting second time which should fail
Second (Extended) Error Info: SQLSTATE Error Code: (HY000), Driver Specific Error Code: (1555)

View File

@ -289,6 +289,56 @@ PHP_METHOD(sqlite3, lastErrorCode)
}
/* }}} */
/* {{{ proto int SQLite3::lastExtendedErrorCode()
Returns the numeric extended result code of the most recent failed sqlite API call for the database connection. */
PHP_METHOD(sqlite3, lastExtendedErrorCode)
{
php_sqlite3_db_object *db_obj;
zval *object = ZEND_THIS;
db_obj = Z_SQLITE3_DB_P(object);
SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (db_obj->initialised) {
RETURN_LONG(sqlite3_extended_errcode(db_obj->db));
} else {
RETURN_LONG(0);
}
}
/* }}} */
/* {{{ proto bool SQLite3::enableExtendedResultCodes([bool enable = true])
Turns on or off the extended result codes feature of SQLite. */
PHP_METHOD(sqlite3, enableExtendedResultCodes)
{
php_sqlite3_db_object *db_obj;
zval *object = ZEND_THIS;
zend_bool enable = 1;
db_obj = Z_SQLITE3_DB_P(object);
int ret;
SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &enable) == FAILURE) {
return;
}
if (db_obj->initialised) {
ret = sqlite3_extended_result_codes(db_obj->db, enable ? 1 : 0);
if (ret == SQLITE_OK)
{
RETURN_TRUE;
}
}
RETURN_FALSE;
}
/* }}} */
/* {{{ proto string SQLite3::lastErrorMsg()
Returns english text describing the most recent failed sqlite API call for the database connection. */
PHP_METHOD(sqlite3, lastErrorMsg)
@ -2157,35 +2207,41 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3result_fetcharray, 0, 0, 0)
ZEND_ARG_INFO(0, mode)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_sqlite3_enableextended, 0, 0, 1)
ZEND_ARG_INFO(0, enable)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_sqlite3_void, 0)
ZEND_END_ARG_INFO()
/* }}} */
/* {{{ php_sqlite3_class_methods */
static const zend_function_entry php_sqlite3_class_methods[] = {
PHP_ME(sqlite3, open, arginfo_sqlite3_open, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, close, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, exec, arginfo_sqlite3_query, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, version, arginfo_sqlite3_void, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(sqlite3, lastInsertRowID, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, lastErrorCode, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, lastErrorMsg, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, busyTimeout, arginfo_sqlite3_busytimeout, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, open, arginfo_sqlite3_open, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, close, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, exec, arginfo_sqlite3_query, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, version, arginfo_sqlite3_void, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(sqlite3, lastInsertRowID, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, lastErrorCode, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, lastExtendedErrorCode, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, enableExtendedResultCodes, arginfo_sqlite3_enableextended, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, lastErrorMsg, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, busyTimeout, arginfo_sqlite3_busytimeout, ZEND_ACC_PUBLIC)
#ifndef SQLITE_OMIT_LOAD_EXTENSION
PHP_ME(sqlite3, loadExtension, arginfo_sqlite3_loadextension, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, loadExtension, arginfo_sqlite3_loadextension, ZEND_ACC_PUBLIC)
#endif
PHP_ME(sqlite3, changes, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, escapeString, arginfo_sqlite3_escapestring, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(sqlite3, prepare, arginfo_sqlite3_query, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, query, arginfo_sqlite3_query, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, querySingle, arginfo_sqlite3_querysingle, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, createFunction, arginfo_sqlite3_createfunction, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, createAggregate, arginfo_sqlite3_createaggregate, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, createCollation, arginfo_sqlite3_createcollation, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, openBlob, arginfo_sqlite3_openblob, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, enableExceptions, arginfo_sqlite3_enableexceptions, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, changes, arginfo_sqlite3_void, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, escapeString, arginfo_sqlite3_escapestring, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(sqlite3, prepare, arginfo_sqlite3_query, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, query, arginfo_sqlite3_query, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, querySingle, arginfo_sqlite3_querysingle, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, createFunction, arginfo_sqlite3_createfunction, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, createAggregate, arginfo_sqlite3_createaggregate, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, createCollation, arginfo_sqlite3_createcollation, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, openBlob, arginfo_sqlite3_openblob, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, enableExceptions, arginfo_sqlite3_enableexceptions, ZEND_ACC_PUBLIC)
#if SQLITE_VERSION_NUMBER >= 3006011
PHP_ME(sqlite3, backup, arginfo_sqlite3_backup, ZEND_ACC_PUBLIC)
PHP_ME(sqlite3, backup, arginfo_sqlite3_backup, ZEND_ACC_PUBLIC)
#endif
/* Aliases */
PHP_MALIAS(sqlite3, __construct, open, arginfo_sqlite3_open, ZEND_ACC_PUBLIC)

View File

@ -0,0 +1,36 @@
--TEST--
SQLite3 extended error code Function
--SKIPIF--
<?php require_once(__DIR__ . '/skipif.inc'); ?>
--FILE--
<?php
require_once(__DIR__ . '/new_db.inc');
$db->query("CREATE TABLE dog ( id INTEGER PRIMARY KEY, name TEXT, annoying INTEGER )");
echo "Inserting first time which should succeed" . PHP_EOL;
$result = $db->query("INSERT INTO dog VALUES (1, 'Annoying Dog', 1)");
echo "First Error Code: " . $db->lastErrorCode() . PHP_EOL;
echo "Inserting second time which should fail" . PHP_EOL;
$result = $db->query("INSERT INTO dog VALUES (1, 'Annoying Dog', 1)");
echo "Second Error Code: " . $db->lastErrorCode() . PHP_EOL;
echo "Second Extended Error Code: " . $db->lastExtendedErrorCode() . PHP_EOL;
echo "Closing database\n";
var_dump($db->close());
echo "Done" . PHP_EOL;
?>
--EXPECTF--
Inserting first time which should succeed
First Error Code: 0
Inserting second time which should fail
Warning: SQLite3::query(): Unable to execute statement: UNIQUE constraint failed: dog.id in %s on line %d
Second Error Code: 19
Second Extended Error Code: 1555
Closing database
bool(true)
Done

View File

@ -0,0 +1,43 @@
--TEST--
SQLite3 enable Extended Error Result Codes
--SKIPIF--
<?php require_once(__DIR__ . '/skipif.inc'); ?>
--FILE--
<?php
require_once(__DIR__ . '/new_db.inc');
$db->query("CREATE TABLE dog ( id INTEGER PRIMARY KEY, name TEXT, annoying INTEGER )");
echo "Inserting first time which should succeed" . PHP_EOL;
$result = $db->query("INSERT INTO dog VALUES (1, 'Annoying Dog', 1)");
echo "First Error Code: " . $db->lastErrorCode() . PHP_EOL;
echo "Inserting second time which should fail" . PHP_EOL;
$result = $db->query("INSERT INTO dog VALUES (1, 'Annoying Dog', 1)");
echo "Second Error Code: " . $db->lastErrorCode() . PHP_EOL;
echo "Toggling extended error codes and re-inserting a third time" . PHP_EOL;
$db->enableExtendedResultCodes(true);
$result = $db->query("INSERT INTO DOG VALUES (1, 'Annoying Dog', 1)");
echo "Third (Extended) Error Code: " . $db->lastErrorCode() . PHP_EOL;
echo "Closing database\n";
var_dump($db->close());
echo "Done" . PHP_EOL;
?>
--EXPECTF--
Inserting first time which should succeed
First Error Code: 0
Inserting second time which should fail
Warning: SQLite3::query(): Unable to execute statement: UNIQUE constraint failed: dog.id in %s on line %d
Second Error Code: 19
Toggling extended error codes and re-inserting a third time
Warning: SQLite3::query(): Unable to execute statement: UNIQUE constraint failed: dog.id in %s on line %d
Third (Extended) Error Code: 1555
Closing database
bool(true)
Done