alert("Failed to connect to database after ' . $retryCount . ' retries.")'; return false; // Or handle the failure appropriately } } } //------------------------------------------------------------------------------ // ->query override to handle retries //------------------------------------------------------------------------------ class CustomDatabaseWrapper { private $sqlite; private $maxRetries; private $retryDelay; public function __construct($filename, $flags = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $maxRetries = 3, $retryDelay = 1000, $encryptionKey = null) { $this->sqlite = new SQLite3($filename, $flags, $encryptionKey); $this->maxRetries = $maxRetries; $this->retryDelay = $retryDelay; } public function query(string $query): SQLite3Result|bool { global $DBFILE_LOCKED_FILE; $attempts = 0; while ($attempts < $this->maxRetries) { $result = $this->sqlite->query($query); if ($result !== false) { // Write unlock status to the locked file file_put_contents($DBFILE_LOCKED_FILE, '0'); return $result; } // Write lock status to the locked file file_put_contents($DBFILE_LOCKED_FILE, '1'); $attempts++; usleep($this->retryDelay * 1000); // Retry delay in milliseconds } // If all retries failed, throw an exception or handle the error as needed echo ''; throw new Exception("Query failed after {$this->maxRetries} attempts: " . $this->sqlite->lastErrorMsg()); } // Delegate other SQLite3 methods to the $sqlite instance public function __call($name, $arguments) { return call_user_func_array([$this->sqlite, $name], $arguments); } } //------------------------------------------------------------------------------ // Open DB //------------------------------------------------------------------------------ function OpenDB($DBPath = null) { global $DBFILE; global $db; // Use custom path if supplied if ($DBPath !== null) { $DBFILE = $DBPath; } if (strlen($DBFILE) == 0) { echo ''; die('