Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP added db insert ignore support #1868

Merged
merged 10 commits into from
Dec 10, 2019
Merged
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
2 changes: 1 addition & 1 deletion system/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ function force_https(int $duration = 31536000, RequestInterface $request = null,
$response->setHeader('Strict-Transport-Security', 'max-age=' . $duration);
$response->redirect($uri);
$response->sendHeaders();

exit();
}
}
Expand Down
84 changes: 77 additions & 7 deletions system/Database/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,15 @@ class BaseBuilder
*/
protected $QBWhereGroupCount = 0;

/**
* Ignore data that cause certain
* exceptions, for example in case of
* duplicate keys.
*
* @var boolean
*/
protected $QBIgnore = false;

/**
* A reference to the database connection.
*
Expand Down Expand Up @@ -218,6 +227,14 @@ class BaseBuilder
*/
protected $canLimitWhereUpdates = true;

/**
* Specifies which sql statements
* support the ignore option.
*
* @var array
*/
protected $supportedIgnoreStatements = [];

//--------------------------------------------------------------------

/**
Expand Down Expand Up @@ -266,6 +283,25 @@ public function getBinds(): array

//--------------------------------------------------------------------

/**
* Ignore
*
* Set ignore Flag for next insert,
* update or delete query.
*
* @param boolean $ignore
*
* @return BaseBuilder
*/
public function ignore(bool $ignore = true)
{
$this->QBIgnore = $ignore;

return $this;
}

//--------------------------------------------------------------------

/**
* Select
*
Expand Down Expand Up @@ -1705,7 +1741,7 @@ public function insertBatch(array $set = null, bool $escape = null, int $batchSi
*/
protected function _insertBatch(string $table, array $keys, array $values): string
{
return 'INSERT INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES ' . implode(', ', $values);
return 'INSERT ' . $this->compileIgnore('insert') . 'INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES ' . implode(', ', $values);
}

//--------------------------------------------------------------------
Expand Down Expand Up @@ -1774,6 +1810,8 @@ public function setInsertBatch($key, string $value = '', bool $escape = null)
*
* @param boolean $reset TRUE: reset QB values; FALSE: leave QB values alone
*
* @throws DatabaseException
*
* @return string
*/
public function getCompiledInsert(bool $reset = true): string
Expand Down Expand Up @@ -1808,6 +1846,8 @@ public function getCompiledInsert(bool $reset = true): string
* @param boolean $escape Whether to escape values and identifiers
* @param boolean $test Used when running tests
*
* @throws DatabaseException
*
* @return BaseResult|Query|false
*/
public function insert(array $set = null, bool $escape = null, bool $test = false)
Expand Down Expand Up @@ -1885,7 +1925,7 @@ protected function validateInsert(): bool
*/
protected function _insert(string $table, array $keys, array $unescapedKeys): string
{
return 'INSERT INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES (' . implode(', ', $unescapedKeys) . ')';
return 'INSERT ' . $this->compileIgnore('insert') . 'INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES (' . implode(', ', $unescapedKeys) . ')';
}

//--------------------------------------------------------------------
Expand Down Expand Up @@ -2001,6 +2041,8 @@ public function getCompiledUpdate(bool $reset = true): string
* @param integer $limit
* @param boolean $test Are we testing the code?
*
* @throws DatabaseException
*
* @return boolean TRUE on success, FALSE on failure
*/
public function update(array $set = null, $where = null, int $limit = null, bool $test = false): bool
Expand Down Expand Up @@ -2064,14 +2106,14 @@ public function update(array $set = null, $where = null, int $limit = null, bool
*/
protected function _update(string $table, array $values): string
{
$valstr = [];
$valStr = [];

foreach ($values as $key => $val)
{
$valstr[] = $key . ' = ' . $val;
$valStr[] = $key . ' = ' . $val;
}

return 'UPDATE ' . $table . ' SET ' . implode(', ', $valstr)
return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . implode(', ', $valStr)
. $this->compileWhereHaving('QBWhere')
. $this->compileOrderBy()
. ($this->QBLimit ? $this->_limit(' ') : '');
Expand Down Expand Up @@ -2201,6 +2243,7 @@ protected function _updateBatch(string $table, array $values, string $index): st
{
$ids = [];
$final = [];

foreach ($values as $key => $val)
{
$ids[] = $val[$index];
Expand All @@ -2224,7 +2267,7 @@ protected function _updateBatch(string $table, array $values, string $index): st

$this->where($index . ' IN(' . implode(',', $ids) . ')', null, false);

return 'UPDATE ' . $table . ' SET ' . substr($cases, 0, -2) . $this->compileWhereHaving('QBWhere');
return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . substr($cases, 0, -2) . $this->compileWhereHaving('QBWhere');
}

//--------------------------------------------------------------------
Expand Down Expand Up @@ -2481,7 +2524,7 @@ public function decrement(string $column, int $value = 1)
*/
protected function _delete(string $table): string
{
return 'DELETE FROM ' . $table . $this->compileWhereHaving('QBWhere')
return 'DELETE ' . $this->compileIgnore('delete') . 'FROM ' . $table . $this->compileWhereHaving('QBWhere')
. ($this->QBLimit ? ' LIMIT ' . $this->QBLimit : '');
}

Expand Down Expand Up @@ -2597,6 +2640,32 @@ protected function compileSelect($select_override = false): string

//--------------------------------------------------------------------

/**
* Compile Ignore Statement
*
* Checks if the ignore option is supported by
* the Database Driver for the specific statement.
*
* @param string $statement
*
* @return string
*/
protected function compileIgnore(string $statement)
{
$sql = '';

if ($this->QBIgnore &&
isset($this->supportedIgnoreStatements[$statement])
)
{
$sql = trim($this->supportedIgnoreStatements[$statement]) . ' ';
}

return $sql;
}

//--------------------------------------------------------------------

/**
* Compile WHERE, HAVING statements
*
Expand Down Expand Up @@ -2918,6 +2987,7 @@ protected function resetWrite()
'QBOrderBy' => [],
'QBKeys' => [],
'QBLimit' => false,
'QBIgnore' => false,
]);
}

Expand Down
12 changes: 12 additions & 0 deletions system/Database/MySQLi/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,16 @@ class Builder extends BaseBuilder
*/
protected $escapeChar = '`';

/**
* Specifies which sql statements
* support the ignore option.
*
* @var array
*/
protected $supportedIgnoreStatements = [
'update' => 'IGNORE',
'insert' => 'IGNORE',
'delete' => 'IGNORE',
];

}
75 changes: 75 additions & 0 deletions system/Database/Postgre/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Database\Exceptions\DatabaseException;
use http\Encoding\Stream\Inflate;

/**
* Builder for Postgre
Expand All @@ -55,6 +56,40 @@ class Builder extends BaseBuilder
'RANDOM()',
];

/**
* Specifies which sql statements
* support the ignore option.
*
* @var array
*/
protected $supportedIgnoreStatements = [
'insert' => 'ON CONFLICT DO NOTHING',
];

//--------------------------------------------------------------------

/**
* Compile Ignore Statement
*
* Checks if the ignore option is supported by
* the Database Driver for the specific statement.
*
* @param string $statement
*
* @return string
*/
protected function compileIgnore(string $statement)
{
$sql = parent::compileIgnore($statement);

if (! empty($sql))
{
$sql = ' ' . trim($sql);
}

return $sql;
}

//--------------------------------------------------------------------

/**
Expand Down Expand Up @@ -97,6 +132,8 @@ public function orderBy(string $orderBy, string $direction = '', bool $escape =
* @param string $column
* @param integer $value
*
* @throws DatabaseException
*
* @return mixed
*/
public function increment(string $column, int $value = 1)
Expand All @@ -116,6 +153,8 @@ public function increment(string $column, int $value = 1)
* @param string $column
* @param integer $value
*
* @throws DatabaseException
*
* @return mixed
*/
public function decrement(string $column, int $value = 1)
Expand All @@ -129,6 +168,42 @@ public function decrement(string $column, int $value = 1)

//--------------------------------------------------------------------

/**
* Insert batch statement
*
* Generates a platform-specific insert string from the supplied data.
*
* @param string $table Table name
* @param array $keys INSERT keys
* @param array $values INSERT values
*
* @return string
*/
protected function _insertBatch(string $table, array $keys, array $values) : string
{
return 'INSERT INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES ' . implode(', ', $values) . $this->compileIgnore('insert');
}

//--------------------------------------------------------------------

/**
* Insert statement
*
* Generates a platform-specific insert string from the supplied data
*
* @param string $table The table name
* @param array $keys The insert keys
* @param array $unescapedKeys The insert values
*
* @return string
*/
protected function _insert(string $table, array $keys, array $unescapedKeys) : string
{
return 'INSERT INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES (' . implode(', ', $unescapedKeys) . ')' . $this->compileIgnore('insert');
}

//--------------------------------------------------------------------

/**
* Replace
*
Expand Down
9 changes: 7 additions & 2 deletions system/Database/SQLite3/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ class Builder extends BaseBuilder
*/
protected $canLimitWhereUpdates = false;

/**
* @var array
*/
protected $supportedIgnoreStatements = [
'insert' => 'OR IGNORE',
];

//--------------------------------------------------------------------

/**
Expand Down Expand Up @@ -105,6 +112,4 @@ protected function _truncate(string $table): string
return 'DELETE FROM ' . $table;
}

//--------------------------------------------------------------------

}
4 changes: 2 additions & 2 deletions system/Debug/Toolbar/Views/toolbarloader.js.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ function loadDoc(time) {

// Track all AJAX requests
if (window.ActiveXObject) {
var oldXHR = new ActiveXObject('Microsoft.XMLHTTP');
var oldXHR = new ActiveXObject('Microsoft.XMLHTTP');
} else {
var oldXHR = window.XMLHttpRequest;
var oldXHR = window.XMLHttpRequest;
}

function newXHR() {
Expand Down
2 changes: 1 addition & 1 deletion system/Language/en/Entity.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@

return
[
'tryingToAccessNonExistentProperty' => 'Trying to access non existent property {0} of {1}'
'tryingToAccessNonExistentProperty' => 'Trying to access non existent property {0} of {1}',
];
3 changes: 2 additions & 1 deletion system/Router/Exceptions/RedirectException.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
/**
* Redirect exception
*/

class RedirectException extends \Exception
{
public static function forUnableToRedirect(string $route, string $code)
{
return new static(lang('Redirect.forUnableToRedirect', [$route, $code]));
}
}
}
4 changes: 2 additions & 2 deletions tests/_support/Database/MockConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public function getVersion(): string
/**
* Executes the query against the database.
*
* @param string $sql
* @param string $sql
*
* @return mixed
*/
Expand All @@ -155,7 +155,7 @@ protected function execute(string $sql)
/**
* Returns the total number of rows affected by this query.
*
* @return int
* @return integer
*/
public function affectedRows(): int
{
Expand Down
Loading