Issue #1889328 by gielfeldt, gumanist: Fixed Not all objects respect the query option throw_exception.

8.0.x
catch 2013-04-03 11:55:27 +01:00
parent 31bd200679
commit ee96cf6b96
4 changed files with 103 additions and 34 deletions

View File

@ -403,42 +403,57 @@ class Merge extends Query implements ConditionInterface {
}
public function execute() {
if (!count($this->condition)) {
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
}
$select = $this->connection->select($this->conditionTable)
->condition($this->condition);
$select->addExpression('1');
if (!$select->execute()->fetchField()) {
try {
$insert = $this->connection->insert($this->table)->fields($this->insertFields);
if ($this->defaultFields) {
$insert->useDefaults($this->defaultFields);
}
$insert->execute();
return self::STATUS_INSERT;
// Default options for merge queries.
$this->queryOptions += array(
'throw_exception' => TRUE,
);
try {
if (!count($this->condition)) {
throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
}
catch (IntegrityConstraintViolationException $e) {
// The insert query failed, maybe it's because a racing insert query
// beat us in inserting the same row. Retry the select query, if it
// returns a row, ignore the error and continue with the update
// query below.
if (!$select->execute()->fetchField()) {
throw $e;
}
}
}
if ($this->needsUpdate) {
$update = $this->connection->update($this->table)
->fields($this->updateFields)
$select = $this->connection->select($this->conditionTable)
->condition($this->condition);
if ($this->expressionFields) {
foreach ($this->expressionFields as $field => $data) {
$update->expression($field, $data['expression'], $data['arguments']);
$select->addExpression('1');
if (!$select->execute()->fetchField()) {
try {
$insert = $this->connection->insert($this->table)->fields($this->insertFields);
if ($this->defaultFields) {
$insert->useDefaults($this->defaultFields);
}
$insert->execute();
return self::STATUS_INSERT;
}
catch (IntegrityConstraintViolationException $e) {
// The insert query failed, maybe it's because a racing insert query
// beat us in inserting the same row. Retry the select query, if it
// returns a row, ignore the error and continue with the update
// query below.
if (!$select->execute()->fetchField()) {
throw $e;
}
}
}
$update->execute();
return self::STATUS_UPDATE;
if ($this->needsUpdate) {
$update = $this->connection->update($this->table)
->fields($this->updateFields)
->condition($this->condition);
if ($this->expressionFields) {
foreach ($this->expressionFields as $field => $data) {
$update->expression($field, $data['expression'], $data['arguments']);
}
}
$update->execute();
return self::STATUS_UPDATE;
}
}
catch (\Exception $e) {
if ($this->queryOptions['throw_exception']) {
throw $e;
}
else {
return NULL;
}
}
}
}

View File

@ -589,7 +589,7 @@ class Select extends Query implements SelectInterface {
public function countQuery() {
$count = $this->prepareCountQuery();
$query = $this->connection->select($count);
$query = $this->connection->select($count, NULL, $this->queryOptions);
$query->addExpression('COUNT(*)');
return $query;

View File

@ -208,7 +208,25 @@ class MergeTest extends DatabaseTestBase {
*/
function testInvalidMerge() {
try {
// This query should die because there is no key field specified.
// This query will fail because there is no key field specified.
// Normally it would throw an exception but we are supressing it with
// the throw_exception option.
$options['throw_exception'] = FALSE;
db_merge('test_people', $options)
->fields(array(
'age' => 31,
'name' => 'Tiffany',
))
->execute();
$this->pass('$options[\'throw_exception\'] is FALSE, no InvalidMergeQueryException thrown.');
}
catch (InvalidMergeQueryException $e) {
$this->fail('$options[\'throw_exception\'] is FALSE, but InvalidMergeQueryException thrown for invalid query.');
return;
}
try {
// This query will fail because there is no key field specified.
db_merge('test_people')
->fields(array(
'age' => 31,

View File

@ -376,4 +376,40 @@ class SelectTest extends DatabaseTestBase {
$alias2 = $query->addField('t', 'age', 'the_alias');
$this->assertNotIdentical($alias1, $alias2, 'Duplicate aliases are renamed.');
}
/**
* Tests that an invalid merge query throws an exception.
*/
function testInvalidSelectCount() {
try {
// This query will fail because the table does not exist.
// Normally it would throw an exception but we are supressing
// it with the throw_exception option.
$options['throw_exception'] = FALSE;
db_select('some_table_that_doesnt_exist', 't', $options)
->fields('t')
->countQuery()
->execute();
$this->pass('$options[\'throw_exception\'] is FALSE, no Exception thrown.');
}
catch (\Exception $e) {
$this->fail('$options[\'throw_exception\'] is FALSE, but Exception thrown for invalid query.');
return;
}
try {
// This query will fail because the table does not exist.
db_select('some_table_that_doesnt_exist', 't')
->fields('t')
->countQuery()
->execute();
}
catch (\Exception $e) {
$this->pass('Exception thrown for invalid query.');
return;
}
$this->fail('No Exception thrown.');
}
}