Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions src/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,6 @@ public function setSql($sql)

return parent::setSql($sql);
}

public function getSql() {
$sql = parent::getSql();
if (is_string($sql)) {
// Unquote the {{@table@}} to {{table}} for insert
$sql = preg_replace('/(\{\{)@(%?[\w\-\. ]+%?)@(\}\})/', '\1\2\3', $sql);
}
return $sql;
}

/**
* Binds a value to a parameter.
Expand Down
37 changes: 0 additions & 37 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,6 @@ class Connection extends \yii\db\Connection
*/
public $firebird_version = null;

/**
* @see https://www.firebirdsql.org/file/documentation/release_notes/html/en/3_0/rnfb30-ddl-enhance.html#rnfb30-ddl-identity
* @var boolean|null
*/
public $supportColumnIdentity = null;

/**
* @see https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-insert.html#fblangref25-dml-insert-select-unstable
* @var boolean|null
*/
public $supportStableCursor = null;

/**
* @see https://bugs.php.net/bug.php?id=72931
* @var boolean|null
*/
public $supportReturningInsert = null;

/**
* @see https://bugs.php.net/bug.php?id=61183
* @var boolean|null
*/
public $supportBlobDataType = null;

/**
* @inheritdoc
*/
Expand Down Expand Up @@ -117,19 +93,6 @@ public function init()
}
} catch (\Exception $ex) {
}

$supports = [
'supportColumnIdentity' => version_compare($this->firebird_version, '3.0.0', '>='),
'supportStableCursor' => version_compare($this->firebird_version, '3.0.0', '>='),
'supportReturningInsert' => version_compare($this->firebird_version, '3.0.0', '<') || version_compare(phpversion('pdo_firebird'), '7.0.15', '>='),
'supportBlobDataType' => version_compare(phpversion('pdo_firebird'), '7.0.13', '>'),
];

foreach ($supports as $key => $value) {
if ($this->{$key} === null) {
$this->{$key} = $value;
}
}
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/PdoAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function __construct($dsn, $username, $password, $driver_options = [])
* Initiates a transaction
* @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
*/
public function beginTransaction($isolationLevel = null)
public function beginTransaction($isolationLevel = null): bool
{
$this->setAttribute(PDO::ATTR_AUTOCOMMIT, false);

Expand Down Expand Up @@ -78,7 +78,7 @@ public function beginTransaction($isolationLevel = null)
* Commits a transaction
* @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
*/
public function commit()
public function commit(): bool
{
$r = $this->exec('COMMIT');
$this->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
Expand All @@ -93,7 +93,7 @@ public function commit()
* Rolls back a transaction
* @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
*/
public function rollBack()
public function rollBack(): bool
{
$r = $this->exec('ROLLBACK');
$this->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
Expand All @@ -108,7 +108,7 @@ public function rollBack()
* Checks if inside a transaction
* @return bool <b>TRUE</b> if a transaction is currently active, and <b>FALSE</b> if not.
*/
public function inTransaction()
public function inTransaction(): bool
{
return $this->_inTransaction;
}
Expand Down
79 changes: 29 additions & 50 deletions src/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class QueryBuilder extends \yii\db\QueryBuilder

public function init()
{
if ($this->db->supportColumnIdentity) {
if (version_compare($this->db->firebird_version, '3.0.0', '>=')) {
$this->typeMap[Schema::TYPE_PK] = 'integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY';
$this->typeMap[Schema::TYPE_UPK] = 'integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY';
$this->typeMap[Schema::TYPE_BIGPK] = 'bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY';
Expand Down Expand Up @@ -249,7 +249,7 @@ protected function prepareInsertSelectSubQuery($columns, $schema, $params = [])
/**
* @see https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-insert.html#fblangref25-dml-insert-select-unstable
*/
if (!$this->db->supportStableCursor) {
if (version_compare($this->db->firebird_version, '3.0.0', '<')) {
throw new NotSupportedException('Firebird < 3.0.0 has the "Unstable Cursor" problem');
}

Expand Down Expand Up @@ -278,51 +278,6 @@ public function prepareUpdateSets($table, $columns, $params = [])
}
return parent::prepareUpdateSets($table, $columns, $params);
}

public function rawInsert($table, $columns, $values, &$params)
{
$schema = $this->db->getSchema();
if (($tableSchema = $schema->getTableSchema($table)) !== null) {
$columnSchemas = $tableSchema->columns;
} else {
$columnSchemas = [];
}

$cs = [];
$vs = [];
foreach ($values as $i => $value) {
if (isset($columns[$i], $columnSchemas[$columns[$i]]) && !is_array($value)) {
$value = $columnSchemas[$columns[$i]]->dbTypecast($value);
}
if (is_string($value)) {
// Quote the {{table}} to {{@table@}} for insert
$value = preg_replace('/(\{\{)(%?[\w\-\. ]+%?)(\}\})/', '\1@\2@\3', $value);
$value = $schema->quoteValue($value);
} elseif (is_float($value)) {
// ensure type cast always has . as decimal separator in all locales
$value = \yii\helpers\StringHelper::floatToString($value);
} elseif ($value === false) {
$value = 0;
} elseif ($value === null) {
$value = 'NULL';
} elseif ($value instanceof ExpressionInterface) {
$value = $this->buildExpression($value, $params);
}

if (isset($columns[$i])) {
$cs[] = $schema->quoteColumnName($columns[$i]);
}
$vs[] = $value;
}

if (empty($vs)) {
return 'INSERT INTO ' . $schema->quoteTableName($table)
. ' DEFAULT VALUES';
}

return 'INSERT INTO ' . $schema->quoteTableName($table)
. ' (' . implode(', ', $cs) . ') VALUES (' . implode(', ', $vs) . ')';
}

/**
* @inheritdoc
Expand All @@ -342,7 +297,31 @@ public function batchInsert($table, $columns, $rows, &$params = [])

$values = [];
foreach ($rows as $row) {
$values[] = $this->rawInsert($table, $columns, $row, $params) . ';';
$vs = [];
foreach ($row as $i => $value) {
if (isset($columns[$i], $columnSchemas[$columns[$i]]) && !is_array($value)) {
$value = $columnSchemas[$columns[$i]]->dbTypecast($value);
}
if (is_string($value)) {
$value = $schema->quoteValue($value);
} elseif (is_float($value)) {
// ensure type cast always has . as decimal separator in all locales
$value = \yii\helpers\StringHelper::floatToString($value);
} elseif ($value === false) {
$value = 0;
} elseif ($value === null) {
$value = 'NULL';
} elseif ($value instanceof ExpressionInterface) {
$value = $this->buildExpression($value, $params);
}
$vs[] = $value;
}
$values[] = 'INSERT INTO ' . $schema->quoteTableName($table)
. ' (' . implode(', ', $columns) . ') VALUES (' . implode(', ', $vs) . ');';
}

foreach ($columns as $i => $name) {
$columns[$i] = $schema->quoteColumnName($name);
}

return 'EXECUTE block AS BEGIN ' . implode(' ', $values) . ' END;';
Expand Down Expand Up @@ -605,7 +584,7 @@ public function createTable($table, $columns, $options = null)
{
$sql = parent::createTable($table, $columns, $options);

if ($this->db->supportColumnIdentity) {
if (version_compare($this->db->firebird_version, '3.0.0', '>=')) {
return $sql;
}

Expand Down Expand Up @@ -655,7 +634,7 @@ public function dropTable($table)
/**
* Not drop sequence for sequence "GENERATED BY DEFAULT AS IDENTITY"
*/
if ($this->db->supportColumnIdentity) {
if (version_compare($this->db->firebird_version, '3.0.0', '>=')) {
$sqlUserSquence = 'SELECT 1 FROM RDB$GENERATORS
WHERE RDB$SYSTEM_FLAG = 0 AND RDB$GENERATOR_NAME = :name';

Expand Down
35 changes: 9 additions & 26 deletions src/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ protected function findColumns($table)
rel.rdb$description AS fcomment,
fld.rdb$default_value AS fdefault_value,';

if ($this->db->supportColumnIdentity) {
if (version_compare($this->db->firebird_version, '3.0.0', '>=')) {
$sql .= '
rel.rdb$generator_name AS fgenerator_name,';
}
Expand Down Expand Up @@ -427,6 +427,9 @@ protected function findColumns($table)
$pkeys = array_map('rtrim', $pkeys);
$pkeys = array_map('strtolower', $pkeys);
foreach ($columns as $key => $column) {
$column = array_filter($column, function($item){
return is_string($item);
});
$column = array_map('strtolower', $column);
$columns[$key]['fprimary'] = in_array(rtrim($column['fname']), $pkeys);
}
Expand Down Expand Up @@ -716,34 +719,14 @@ public function insert($table, $columns)
{
$this->_lastInsertID = false;
$params = [];
$sql = "";
$sql = $this->db->getQueryBuilder()->insert($table, $columns, $params);
$returnColumns = $this->getTableSchema($table)->primaryKey;
if (!empty($returnColumns)) {
if (!$this->db->supportReturningInsert) {
$returs = [];
$returning = [];
$columnSchemas = $this->getTableSchema($table)->columns;
foreach ((array) $returnColumns as $name) {
$returs[] = $this->quoteColumnName($name) . ' ' . $columnSchemas[$name]->dbType;
$returning[] = $this->quoteColumnName($name);
}

$sql = $this->db->getQueryBuilder()->rawInsert($table, array_keys($columns), array_values($columns), $params);

$sql = "EXECUTE block RETURNS ("
. implode(', ',$returs)
. ") AS BEGIN\n"
. $sql . ' RETURNING ' . implode(', ', $returning)
. ' INTO ' . implode(', ', $returning)
. ";\nSUSPEND;\nEND;";
} else {
$sql = $this->db->getQueryBuilder()->insert($table, $columns, $params);
$returning = [];
foreach ((array) $returnColumns as $name) {
$returning[] = $this->quoteColumnName($name);
}
$sql .= ' RETURNING ' . implode(', ', $returning);
$returning = [];
foreach ((array) $returnColumns as $name) {
$returning[] = $this->quoteColumnName($name);
}
$sql .= ' RETURNING ' . implode(', ', $returning);
}

$command = $this->db->createCommand($sql, $params);
Expand Down