Skip to content

Commit

Permalink
fix(Queries): rollback transactions before throwing exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
cooldogedev committed Oct 20, 2023
1 parent 3c26b47 commit 8cc4a75
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public function onRun(mysqli $connection): void
$checkQuery->close();

if ($checkResult->num_rows > 0) {
$connection->rollback();
throw new RecordAlreadyExistsException(
_message: "Account already exists for xuid " . $this->xuid . " or username " . $this->username
);
Expand All @@ -85,6 +86,6 @@ public function onRun(mysqli $connection): void
$checkResult->free();
$insertionResult->free();

$this->setResult(true);
$this->setResult($connection->affected_rows > 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,6 @@ public function onRun(mysqli $connection): void
$targetUpdateResult->free();
$sourceUpdateResult->free();

$this->setResult(true);
$this->setResult($connection->affected_rows > 0 );
}
}
7 changes: 5 additions & 2 deletions src/cooldogedev/BedrockEconomy/database/mysql/UpdateQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public function onRun(mysqli $connection): void
$checkQuery->close();

if ($checkResult->num_rows === 0) {
$connection->rollback();
throw new RecordNotFoundException(
_message: "Account not found for xuid " . $this->xuid . " or username " . $this->username
);
Expand Down Expand Up @@ -93,22 +94,24 @@ public function onRun(mysqli $connection): void
$updateQuery->close();

if ($updateResult->num_rows === 0 && $this->mode === UpdateMode::SUBTRACT) {
$connection->rollback();
throw new InsufficientFundsException(
_message: "Insufficient funds for xuid " . $this->xuid . " or username " . $this->username
);
}

if ($updateResult->num_rows === 0) {
$connection->rollback();
throw new RecordNotFoundException(
_message: "Account not found for xuid " . $this->xuid . " or username " . $this->username
);
}

$this->setResult($connection->affected_rows > 0);
$connection->commit();

$checkResult->free();
$updateResult->free();

$connection->commit();
$this->setResult($connection->affected_rows > 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public function onRun(SQLite3 $connection): void
$checkResult = $checkQuery->execute();

if ($checkResult->fetchArray(SQLITE3_ASSOC) !== false) {
$connection->exec("ROLLBACK");
throw new RecordAlreadyExistsException(
_message: "Account already exists for xuid " . $this->xuid . " or username " . $this->username
);
Expand All @@ -70,6 +71,7 @@ public function onRun(SQLite3 $connection): void
$insertionQuery->execute();

if ($connection->changes() === 0) {
$connection->exec("ROLLBACK");
throw new RecordAlreadyExistsException(
_message: "Account already exists for xuid " . $this->xuid . " or username " . $this->username
);
Expand All @@ -82,6 +84,6 @@ public function onRun(SQLite3 $connection): void
$checkQuery->close();
$insertionQuery->close();

$this->setResult(true);
$this->setResult($connection->changes() > 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ public function onRun(SQLite3 $connection): void

$connection->exec("COMMIT");

$this->setResult($connection->changes() > 0);

$targetResult->finalize();
$sourceResult->finalize();
$targetUpdateResult->finalize();
Expand All @@ -127,5 +125,7 @@ public function onRun(SQLite3 $connection): void
$targetQuery->close();
$sourceUpdateQuery->close();
$targetUpdateQuery->close();

$this->setResult($connection->changes() > 0);
}
}
23 changes: 16 additions & 7 deletions src/cooldogedev/BedrockEconomy/database/sqlite/UpdateQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,17 @@ public function __construct(protected int $mode, protected int $amount, protecte
*/
public function onRun(SQLite3 $connection): void
{
$connection->exec("BEGIN TRANSACTION");

// check if account exists
$checkQuery = $connection->prepare("SELECT * FROM " . $this->table . " WHERE xuid = ? OR username = ?");
$checkQuery->bindValue(1, $this->xuid);
$checkQuery->bindValue(2, $this->username);

$checkResult = $checkQuery->execute();

if ($checkResult->fetchArray(SQLITE3_ASSOC) === false) {
$connection->exec("ROLLBACK");
throw new RecordNotFoundException(
_message: "Account not found for xuid " . $this->xuid . " or username " . $this->username
);
Expand All @@ -72,6 +76,7 @@ public function onRun(SQLite3 $connection): void
default => throw new InvalidArgumentException("Invalid mode " . $this->mode)
};

// update account
$updateQuery = $connection->prepare($updateQuery);
$updateQuery->bindValue(1, $this->amount, SQLITE3_INTEGER);
$updateQuery->bindValue(2, $this->decimals, SQLITE3_INTEGER);
Expand All @@ -85,24 +90,28 @@ public function onRun(SQLite3 $connection): void

$updateResult = $updateQuery->execute();

if ($connection->changes() === 0) {
if ($this->mode === UpdateMode::SUBTRACT) {
throw new InsufficientFundsException(
_message: "Insufficient funds for xuid " . $this->xuid . " or username " . $this->username
);
}
if ($connection->changes() === 0 && $this->mode === UpdateMode::SUBTRACT) {
$connection->exec("ROLLBACK");
throw new InsufficientFundsException(
_message: "Insufficient funds for xuid " . $this->xuid . " or username " . $this->username
);
}

if ($connection->changes() === 0) {
$connection->exec("ROLLBACK");
throw new RecordNotFoundException(
_message: "Account not found for xuid " . $this->xuid . " or username " . $this->username
);
}

$this->setResult($connection->changes() > 0);
$connection->exec("COMMIT");

$checkResult->finalize();
$updateResult->finalize();

$checkQuery->close();
$updateQuery->close();

$this->setResult($connection->changes() > 0);
}
}

0 comments on commit 8cc4a75

Please sign in to comment.