diff --git a/src/Command.php b/src/Command.php index 122c014..f7fb9ea 100644 --- a/src/Command.php +++ b/src/Command.php @@ -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. diff --git a/src/Connection.php b/src/Connection.php index b77830a..21ea4b3 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -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 */ @@ -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; - } - } } /** diff --git a/src/PdoAdapter.php b/src/PdoAdapter.php index 62e486a..efc34f4 100644 --- a/src/PdoAdapter.php +++ b/src/PdoAdapter.php @@ -48,7 +48,7 @@ public function __construct($dsn, $username, $password, $driver_options = []) * Initiates a transaction * @return bool TRUE on success or FALSE on failure. */ - public function beginTransaction($isolationLevel = null) + public function beginTransaction($isolationLevel = null): bool { $this->setAttribute(PDO::ATTR_AUTOCOMMIT, false); @@ -78,7 +78,7 @@ public function beginTransaction($isolationLevel = null) * Commits a transaction * @return bool TRUE on success or FALSE on failure. */ - public function commit() + public function commit(): bool { $r = $this->exec('COMMIT'); $this->setAttribute(PDO::ATTR_AUTOCOMMIT, true); @@ -93,7 +93,7 @@ public function commit() * Rolls back a transaction * @return bool TRUE on success or FALSE on failure. */ - public function rollBack() + public function rollBack(): bool { $r = $this->exec('ROLLBACK'); $this->setAttribute(PDO::ATTR_AUTOCOMMIT, true); @@ -108,7 +108,7 @@ public function rollBack() * Checks if inside a transaction * @return bool TRUE if a transaction is currently active, and FALSE if not. */ - public function inTransaction() + public function inTransaction(): bool { return $this->_inTransaction; } diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 9acc6b7..fab80b2 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -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'; @@ -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'); } @@ -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 @@ -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;'; @@ -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; } @@ -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'; diff --git a/src/Schema.php b/src/Schema.php index 8fb3cf3..a881bf0 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -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,'; } @@ -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); } @@ -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);