mirror of
https://github.com/php/php-src.git
synced 2024-11-28 04:14:26 +08:00
pdo_dblib: stringify uniqidentifier field
Keep old 5.6 behavior: return Uniqidentifier value as 36-byte hex string (not binary), when PDO::ATTR_STRINGIFY_FETCHES is TRUE pdo_dblib: Stringify uniqidentifier field Keep old 5.6 behavior: return Uniqidentifier value as 36-byte hex string (not binary), when PDO::ATTR_STRINGIFY_FETCHES is TRUE Tests added. pdo_dblib: Stringify uniqidentifier field Keep old 5.6 behavior: return Uniqidentifier value as 36-byte hex string (not binary), when PDO::ATTR_STRINGIFY_FETCHES is TRUE Tests fix. pdo_dblib: Stringify uniqueidentifier field Added separate PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER attribute instead of PDO::ATTR_STRINGIFY_FETCHES. pdo_dblib: Stringify uniqueidentifier field Added `getAttribute` support for PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER. Simplify storage of stringify_uniqueidentifier attribute
This commit is contained in:
parent
433976f931
commit
a000bff2c3
@ -280,16 +280,28 @@ static int dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
|
||||
switch(attr) {
|
||||
case PDO_ATTR_TIMEOUT:
|
||||
return 0;
|
||||
|
||||
case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
|
||||
((pdo_dblib_db_handle *)dbh->driver_data)->stringify_uniqueidentifier = zval_get_long(val);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value)
|
||||
{
|
||||
/* dblib_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; */
|
||||
return 0;
|
||||
switch (attr) {
|
||||
case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
|
||||
ZVAL_BOOL(return_value, ((pdo_dblib_db_handle *)dbh->driver_data)->stringify_uniqueidentifier);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct pdo_dbh_methods dblib_methods = {
|
||||
@ -347,6 +359,15 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
|
||||
|
||||
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars);
|
||||
|
||||
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
|
||||
H->login = dblogin();
|
||||
H->err.sqlstate = dbh->error_code;
|
||||
H->stringify_uniqueidentifier = 0;
|
||||
|
||||
if (!H->login) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (driver_options) {
|
||||
int connect_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT, -1);
|
||||
int query_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_QUERY_TIMEOUT, -1);
|
||||
@ -361,14 +382,8 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
|
||||
|
||||
dbsetlogintime(connect_timeout); /* Connection/Login Timeout */
|
||||
dbsettime(query_timeout); /* Statement Timeout */
|
||||
}
|
||||
|
||||
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
|
||||
H->login = dblogin();
|
||||
H->err.sqlstate = dbh->error_code;
|
||||
|
||||
if (!H->login) {
|
||||
goto cleanup;
|
||||
H->stringify_uniqueidentifier = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, 0);
|
||||
}
|
||||
|
||||
DBERRHANDLE(H->login, (EHANDLEFUNC) pdo_dblib_error_handler);
|
||||
|
@ -120,7 +120,7 @@ static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt)
|
||||
dbcancel(H->link);
|
||||
|
||||
pdo_dblib_err_dtor(&H->err);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno)
|
||||
pdo_dblib_db_handle *H = S->H;
|
||||
struct pdo_column_data *col;
|
||||
char *fname;
|
||||
|
||||
|
||||
if(colno >= stmt->column_count || colno < 0) {
|
||||
return FAILURE;
|
||||
}
|
||||
@ -376,16 +376,28 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef SQLUNIQUE
|
||||
case SQLUNIQUE: {
|
||||
#else
|
||||
case 36: { /* FreeTDS hack */
|
||||
#endif
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRINGL(zv, data, 16); /* uniqueidentifier is a 16-byte binary number */
|
||||
if (H->stringify_uniqueidentifier) { // 36-char hex string representation
|
||||
tmp_data_len = 36;
|
||||
tmp_data = safe_emalloc(tmp_data_len, sizeof(char), 1);
|
||||
data_len = (unsigned int) dbconvert(NULL, SQLUNIQUE, (BYTE*)data, data_len, SQLCHAR, (BYTE*)tmp_data, tmp_data_len);
|
||||
php_strtoupper(tmp_data, data_len);
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRINGL(zv, tmp_data, data_len);
|
||||
efree(tmp_data);
|
||||
|
||||
} else { // a 16-byte binary representation
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRINGL(zv, data, 16);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if (dbwillconvert(coltype, SQLCHAR)) {
|
||||
tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
|
||||
@ -479,4 +491,3 @@ struct pdo_stmt_methods dblib_stmt_methods = {
|
||||
pdo_dblib_stmt_next_rowset, /* nextrow */
|
||||
pdo_dblib_stmt_cursor_closer
|
||||
};
|
||||
|
||||
|
@ -179,6 +179,7 @@ PHP_MINIT_FUNCTION(pdo_dblib)
|
||||
{
|
||||
REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_CONNECTION_TIMEOUT", (long) PDO_DBLIB_ATTR_CONNECTION_TIMEOUT);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_QUERY_TIMEOUT", (long) PDO_DBLIB_ATTR_QUERY_TIMEOUT);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER", (long) PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER);
|
||||
|
||||
if (FAIL == dbinit()) {
|
||||
return FAILURE;
|
||||
|
@ -113,6 +113,7 @@ typedef struct {
|
||||
DBPROCESS *link;
|
||||
|
||||
pdo_dblib_err err;
|
||||
unsigned stringify_uniqueidentifier:1;
|
||||
} pdo_dblib_db_handle;
|
||||
|
||||
typedef struct {
|
||||
@ -142,7 +143,8 @@ ZEND_EXTERN_MODULE_GLOBALS(dblib)
|
||||
|
||||
enum {
|
||||
PDO_DBLIB_ATTR_CONNECTION_TIMEOUT = PDO_ATTR_DRIVER_SPECIFIC,
|
||||
PDO_DBLIB_ATTR_QUERY_TIMEOUT
|
||||
PDO_DBLIB_ATTR_QUERY_TIMEOUT,
|
||||
PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
67
ext/pdo_dblib/tests/stringify_uniqueidentifier.phpt
Normal file
67
ext/pdo_dblib/tests/stringify_uniqueidentifier.phpt
Normal file
@ -0,0 +1,67 @@
|
||||
--TEST--
|
||||
PDO_DBLIB: Uniqueidentifier column data type stringifying
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo_dblib')) die('skip not loaded');
|
||||
require __DIR__ . '/config.inc';
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
|
||||
$testGUID = '82A88958-672B-4C22-842F-216E2B88E72A';
|
||||
$testGUIDBinary = base64_decode('WImogitnIkyELyFuK4jnKg==');
|
||||
|
||||
$sql = "SELECT CAST('$testGUID' as uniqueidentifier) as [guid]";
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// 1. Get and Set the attribute
|
||||
//--------------------------------------------------------------------------------
|
||||
$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true);
|
||||
var_dump(true === $db->getAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER));
|
||||
$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, false);
|
||||
var_dump(false === $db->getAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER));
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// 2. Binary
|
||||
//--------------------------------------------------------------------------------
|
||||
$stmt = $db->query($sql);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
var_dump($row['guid'] === $testGUIDBinary);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// 3. PDO::ATTR_STRINGIFY_FETCHES must not affect `uniqueidentifier` representation
|
||||
//--------------------------------------------------------------------------------
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
$stmt = $db->query($sql);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
|
||||
var_dump($row['guid'] === $testGUIDBinary);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// 4. Stringifying
|
||||
// ! With TDS protocol version <7.0 binary will be returned and the test will fail !
|
||||
// TODO: something from PDO::ATTR_SERVER_VERSION, PDO::ATTR_CLIENT_VERSION or PDO::ATTR_SERVER_INFO should be used
|
||||
// to get TDS version and skip this test in this case.
|
||||
//--------------------------------------------------------------------------------
|
||||
$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true);
|
||||
$stmt = $db->query($sql);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
var_dump($row['guid'] === $testGUID);
|
||||
var_dump($row['guid']);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
string(36) "82A88958-672B-4C22-842F-216E2B88E72A"
|
Loading…
Reference in New Issue
Block a user