- Sqlite now handles concurrency with transactions

This commit is contained in:
Dave Mc Nicoll 2025-02-25 14:09:41 +00:00
parent 0fd6889c6f
commit e0ec140661
6 changed files with 26 additions and 10 deletions

View File

@ -27,6 +27,7 @@ class SQLite implements AdapterInterface, MigrateInterface, SqlAdapterInterface
public function connect() : PdoObject public function connect() : PdoObject
{ {
try { try {
#$pdo = new PdoObject($this->buildDataSourceName(), null, null);
$pdo = new PdoObject\SqlitePdoObject($this->buildDataSourceName(), null, null); $pdo = new PdoObject\SqlitePdoObject($this->buildDataSourceName(), null, null);
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);

View File

@ -56,7 +56,7 @@ class PdoObject extends PDO {
} }
} }
catch (\Throwable $e) { catch (\Throwable $e) {
throw new \PdoException($e->getMessage() . " `$sql` with data:" . json_encode($parameters)); throw new \PdoException($e->getMessage() . " `$sql` with data:" . json_encode($parameters), (int) $e->getCode(), $e);
} }
return null; return null;
@ -83,7 +83,7 @@ class PdoObject extends PDO {
$this->lastInsertId = null; $this->lastInsertId = null;
try { try {
if ( ! $this->inTransaction() ) { if (! $this->inTransaction()) {
$this->beginTransaction(); $this->beginTransaction();
} }
@ -113,8 +113,6 @@ class PdoObject extends PDO {
catch (\Throwable $e) { catch (\Throwable $e) {
throw $e; throw $e;
} }
return null;
} }
protected function bindVariables(PDOStatement $statement, array &$parameters) : void protected function bindVariables(PDOStatement $statement, array &$parameters) : void

View File

@ -12,7 +12,7 @@ class SqlPdoObject extends \Ulmus\Common\PdoObject
return $this->openTransaction(); return $this->openTransaction();
} }
return $this->exec('SAVEPOINT transaction_'.$this->openedTransaction) !== false; return $this->exec("SAVEPOINT transaction_{$this->openedTransaction}") !== false;
} }
public function commit() : bool public function commit() : bool
@ -21,16 +21,19 @@ class SqlPdoObject extends \Ulmus\Common\PdoObject
return parent::commit(); return parent::commit();
} }
return false; return $this->exec("RELEASE SAVEPOINT transaction_{$this->openedTransaction}") !== false;
} }
public function rollback() : bool public function rollback() : bool
{ {
if (0 !== $this->openedTransaction) { if ($this->openedTransaction > 1) {
return $this->exec('ROLLBACK TO transaction_' . $this->openedTransaction--) !== false; return $this->exec('ROLLBACK TO transaction_' . $this->openedTransaction--) !== false;
} }
elseif ($this->openedTransaction-- === 1) {
return parent::rollback();
}
return parent::rollback(); return false;
} }
protected function openTransaction() : bool protected function openTransaction() : bool

View File

@ -17,6 +17,19 @@ class SqlitePdoObject extends SqlPdoObject
return $this->exec("COMMIT") !== false; return $this->exec("COMMIT") !== false;
} }
return $this->exec("RELEASE SAVEPOINT transaction_{$this->openedTransaction}") !== false;
}
public function rollback() : bool
{
if ($this->openedTransaction > 1) {
return $this->exec('ROLLBACK TO transaction_' . $this->openedTransaction--) !== false;
}
elseif ($this->openedTransaction-- === 1) {
# We must do it manually since opening a transaction manually stucks PDO into thinking we've got no transaction opened
return $this->exec('ROLLBACK') !== false;
}
return false; return false;
} }

View File

@ -20,6 +20,6 @@ abstract class SearchParameter {
public function getParameters() : array public function getParameters() : array
{ {
return array_filter((array) $this->parameter); return array_filter((array) ( $this->parameter ?? [] ));
} }
} }

View File

@ -76,7 +76,8 @@ trait SearchRequestFromRequestTrait
case $attribute instanceof SearchManual: case $attribute instanceof SearchManual:
if ($attribute->toggle) { if ($attribute->toggle) {
$this->$propertyName = !empty($value); $this->$propertyName = !empty($value);
} elseif ($value !== null) { }
elseif ($value !== null) {
foreach ($property->getTypes() as $type) { foreach ($property->getTypes() as $type) {
$enum = $type->type; $enum = $type->type;