Skip to content

Commit

Permalink
Merge pull request yiisoft#7868 from nineinchnick/7757-oci-schema-cas…
Browse files Browse the repository at this point in the history
…e-sensitivity

fixes yiisoft#7757: in oci schema fix query results row keys case
  • Loading branch information
samdark committed Mar 30, 2015
2 parents 3abc07d + 18b107d commit 62a35cd
Show file tree
Hide file tree
Showing 18 changed files with 838 additions and 130 deletions.
7 changes: 7 additions & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ Yii Framework 2 Change Log
- Bug #6871: Fixed the bug that using defaults and hostnames in URL rules may cause an out-of-range index issue (qiangxue)
- Bug #7529: Fixed `yii\web\Response::sendContentAsFile()` that was broken in 2.0.3 (samdark)
- Bug #7603: Fixed escape characters in `FormatConverter` to work with unicode characters (maddoger, cebe)
- Bug #7757: Fix fetching tables schema for oci and mysql when PDO::ATTR_CASE is set (nineinchnick)
- Bug #7775: Added more strict check on controller IDs when they are being used to create controller instances on Windows (Bhoft, qiangxue)
- Bug: Fixed fetching columns definition and composite foreign keys for oci (nineinchnick)
- Bug: Removed column's autoIncrement detection from oci (nineinchnick)
- Bug: Fixed creating raw sql (for logging) by skipping object and resource params (nineinchnick)
- Bug: Fixed Schema::getLastInsertID() by quoting sequence name (nineinchnick)
- Enh #6895: Added `ignoreCategories` config option for message command to ignore categories specified (samdark)
- Enh #6975: Pressing arrows while focused in inputs of Active Form with `validateOnType` enabled no longer triggers validation (slinstj)
- Enh #7488: Added `StringHelper::explode` to perform explode with trimming and skipping of empty elements (SilverFire, nineinchnick, creocoder, samdark)
Expand All @@ -18,6 +23,8 @@ Yii Framework 2 Change Log
- Enh #7636: `yii\web\Session::getHasSessionId()` uses a more lenient way to check if session ID is provided in URL (robsch)
- Enh #7850: Added `yii\filters\PageCache::cacheCookies` and `cacheHeaders` to allow selectively caching cookies and HTTP headers (qiangxue)
- Enh: Added `yii\helper\Console::wrapText()` method to wrap indented text by console window width and used it in `yii help` command (cebe)
- Enh: Implement batchInsert for oci (nineinchnick)
- Enh: Detecting IntegrityException for oci (nineinchnick)
- Chg: Updated dependency to `cebe/markdown` to version `1.1.x` (cebe)


Expand Down
38 changes: 18 additions & 20 deletions framework/db/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,28 +157,26 @@ public function getRawSql()
{
if (empty($this->params)) {
return $this->_sql;
} else {
$params = [];
foreach ($this->params as $name => $value) {
if (is_string($value)) {
$params[$name] = $this->db->quoteValue($value);
} elseif ($value === null) {
$params[$name] = 'NULL';
} else {
$params[$name] = $value;
}
}
if (isset($params[1])) {
$sql = '';
foreach (explode('?', $this->_sql) as $i => $part) {
$sql .= (isset($params[$i]) ? $params[$i] : '') . $part;
}

return $sql;
} else {
return strtr($this->_sql, $params);
}
$params = [];
foreach ($this->params as $name => $value) {
if (is_string($value)) {
$params[$name] = $this->db->quoteValue($value);
} elseif ($value === null) {
$params[$name] = 'NULL';
} elseif (!is_object($value) && !is_resource($value)) {
$params[$name] = $value;
}
}
if (!isset($params[1])) {
return strtr($this->_sql, $params);
}
$sql = '';
foreach (explode('?', $this->_sql) as $i => $part) {
$sql .= (isset($params[$i]) ? $params[$i] : '') . $part;
}

return $sql;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion framework/db/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ public function findUniqueIndexes($table)
public function getLastInsertID($sequenceName = '')
{
if ($this->db->isActive) {
return $this->db->pdo->lastInsertId($sequenceName === '' ? null : $sequenceName);
return $this->db->pdo->lastInsertId($sequenceName === '' ? null : $this->quoteSimpleTableName($sequenceName));
} else {
throw new InvalidCallException('DB Connection is not active.');
}
Expand Down
21 changes: 12 additions & 9 deletions framework/db/mysql/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,13 @@ protected function loadColumnSchema($info)
{
$column = $this->createColumnSchema();

$column->name = $info['Field'];
$column->allowNull = $info['Null'] === 'YES';
$column->isPrimaryKey = strpos($info['Key'], 'PRI') !== false;
$column->autoIncrement = stripos($info['Extra'], 'auto_increment') !== false;
$column->comment = $info['Comment'];
$column->name = $info['field'];
$column->allowNull = $info['null'] === 'YES';
$column->isPrimaryKey = strpos($info['key'], 'PRI') !== false;
$column->autoIncrement = stripos($info['extra'], 'auto_increment') !== false;
$column->comment = $info['comment'];

$column->dbType = $info['Type'];
$column->dbType = $info['type'];
$column->unsigned = stripos($column->dbType, 'unsigned') !== false;

$column->type = self::TYPE_STRING;
Expand Down Expand Up @@ -173,12 +173,12 @@ protected function loadColumnSchema($info)
$column->phpType = $this->getColumnPhpType($column);

if (!$column->isPrimaryKey) {
if ($column->type === 'timestamp' && $info['Default'] === 'CURRENT_TIMESTAMP') {
if ($column->type === 'timestamp' && $info['default'] === 'CURRENT_TIMESTAMP') {
$column->defaultValue = new Expression('CURRENT_TIMESTAMP');
} elseif (isset($type) && $type === 'bit') {
$column->defaultValue = bindec(trim($info['Default'],'b\''));
$column->defaultValue = bindec(trim($info['default'],'b\''));
} else {
$column->defaultValue = $column->phpTypecast($info['Default']);
$column->defaultValue = $column->phpTypecast($info['default']);
}
}

Expand Down Expand Up @@ -206,6 +206,9 @@ protected function findColumns($table)
throw $e;
}
foreach ($columns as $info) {
if ($this->db->slavePdo->getAttribute(\PDO::ATTR_CASE) !== \PDO::CASE_LOWER) {
$info = array_change_key_case($info, CASE_LOWER);
}
$column = $this->loadColumnSchema($info);
$table->columns[$column->name] = $column;
if ($column->isPrimaryKey) {
Expand Down
57 changes: 57 additions & 0 deletions framework/db/oci/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,61 @@ public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $

return $sql;
}

/**
* Generates a batch INSERT SQL statement.
* For example,
*
* ~~~
* $sql = $queryBuilder->batchInsert('user', ['name', 'age'], [
* ['Tom', 30],
* ['Jane', 20],
* ['Linda', 25],
* ]);
* ~~~
*
* Note that the values in each row must match the corresponding column names.
*
* @param string $table the table that new rows will be inserted into.
* @param array $columns the column names
* @param array $rows the rows to be batch inserted into the table
* @return string the batch INSERT SQL statement
*/
public function batchInsert($table, $columns, $rows)
{
$schema = $this->db->getSchema();
if (($tableSchema = $schema->getTableSchema($table)) !== null) {
$columnSchemas = $tableSchema->columns;
} else {
$columnSchemas = [];
}

$values = [];
foreach ($rows as $row) {
$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 ($value === false) {
$value = 0;
} elseif ($value === null) {
$value = 'NULL';
}
$vs[] = $value;
}
$values[] = '(' . implode(', ', $vs) . ')';
}

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

$tableAndColumns = ' INTO ' . $schema->quoteTableName($table)
. ' (' . implode(', ', $columns) . ') VALUES ';

return 'INSERT ALL ' . $tableAndColumns . implode($tableAndColumns, $values) . ' SELECT 1 FROM SYS.DUAL';
}
}
Loading

0 comments on commit 62a35cd

Please sign in to comment.