Skip to content

Commit

Permalink
Update the TursoConnection inheritance parent class to be Illuminate\…
Browse files Browse the repository at this point in the history
…Database\Connection
  • Loading branch information
richan-fongdasen committed Apr 17, 2024
1 parent 6b4478e commit a2da98c
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 41 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
"@php vendor/bin/testbench serve --host=0.0.0.0"
],
"analyse": "vendor/bin/phpstan analyse",
"test": "vendor/bin/pest",
"test-coverage": "vendor/bin/pest --coverage",
"test": "vendor/bin/pest --stop-on-failure --stop-on-error",
"test-coverage": "vendor/bin/pest --coverage --stop-on-failure --stop-on-error",
"format": "vendor/bin/pint"
},
"config": {
Expand Down
78 changes: 46 additions & 32 deletions src/Database/TursoConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

namespace RichanFongdasen\Turso\Database;

use Illuminate\Database\SQLiteConnection;
use Exception;
use Illuminate\Database\Connection;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Str;
use PDO;

class TursoConnection extends SQLiteConnection
class TursoConnection extends Connection
{
protected bool $hasUpdated = false;

Expand Down Expand Up @@ -44,14 +46,33 @@ public function affectingStatement($query, $bindings = [])
return parent::affectingStatement($query, $bindings);
}

protected function queryIsUpdatingRemoteDB(string $query): bool
public function createReadPdo(array $config = []): ?PDO
{
return Str::startsWith(trim(strtolower($query)), self::$updatingStatements);
$replicaPath = (string) data_get($config, 'db_replica');

if (($replicaPath === '') || ! file_exists($replicaPath)) {
return null;
}

$pdo = new PDO('sqlite:' . $replicaPath);

$this->setReadPdo($pdo);

return $pdo;
}

protected function escapeBinary(mixed $value): string
{
$hex = bin2hex($value);

return "x'{$hex}'";
}

protected function getDefaultPostProcessor(): TursoQueryProcessor
{
return new TursoQueryProcessor();
}

/**
* Get the default query grammar instance.
*/
protected function getDefaultQueryGrammar(): TursoQueryGrammar
{
$grammar = new TursoQueryGrammar();
Expand All @@ -62,21 +83,6 @@ protected function getDefaultQueryGrammar(): TursoQueryGrammar
return $grammar;
}

/**
* Get a schema builder instance for the connection.
*/
public function getSchemaBuilder(): TursoSchemaBuilder
{
if (is_null($this->schemaGrammar)) {
$this->useDefaultSchemaGrammar();
}

return new TursoSchemaBuilder($this);
}

/**
* Get the default schema grammar instance.
*/
protected function getDefaultSchemaGrammar(): TursoSchemaGrammar
{
$grammar = new TursoSchemaGrammar();
Expand All @@ -87,27 +93,35 @@ protected function getDefaultSchemaGrammar(): TursoSchemaGrammar
return $grammar;
}

/**
* Get the schema state for the connection.
*/
public function getSchemaState(?Filesystem $files = null, ?callable $processFactory = null): TursoSchemaState
public function getSchemaBuilder(): TursoSchemaBuilder
{
return new TursoSchemaState($this, $files, $processFactory);
if (is_null($this->schemaGrammar)) {
$this->useDefaultSchemaGrammar();
}

return new TursoSchemaBuilder($this);
}

/**
* Get the default post processor instance.
*/
protected function getDefaultPostProcessor(): TursoQueryProcessor
public function getSchemaState(?Filesystem $files = null, ?callable $processFactory = null): TursoSchemaState
{
return new TursoQueryProcessor();
return new TursoSchemaState($this, $files, $processFactory);
}

public function hasUpdated(): bool
{
return $this->hasUpdated;
}

protected function isUniqueConstraintError(Exception $exception): bool
{
return boolval(preg_match('#(column(s)? .* (is|are) not unique|UNIQUE constraint failed: .*)#i', $exception->getMessage()));
}

protected function queryIsUpdatingRemoteDB(string $query): bool
{
return Str::startsWith(trim(strtolower($query)), self::$updatingStatements);
}

/**
* Execute an SQL statement and return the boolean result.
*
Expand Down
8 changes: 1 addition & 7 deletions src/TursoLaravelServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Illuminate\Database\Connection;
use Illuminate\Database\DatabaseManager;
use Illuminate\Support\Facades\Event;
use PDO;
use RichanFongdasen\Turso\Commands\TursoSyncCommand;
use RichanFongdasen\Turso\Database\TursoConnection;
use RichanFongdasen\Turso\Database\TursoConnector;
Expand Down Expand Up @@ -46,7 +45,6 @@ public function boot(): void
(app('running-artisan-command') === data_get($event, 'command'))
) {
Turso::sync();
Turso::enableReadReplica();
}
});
}
Expand Down Expand Up @@ -84,11 +82,7 @@ public function register(): void
$connection = new TursoConnection($pdo, $database ?? 'turso', $prefix, $config);
app()->instance(TursoConnection::class, $connection);

$replicaPath = (string) data_get($config, 'db_replica');

if (($replicaPath !== '') && file_exists($replicaPath)) {
$connection->setReadPdo(new PDO('sqlite:' . $replicaPath));
}
$connection->createReadPdo($config);

return $connection;
});
Expand Down
2 changes: 2 additions & 0 deletions src/TursoManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public function sync(): void
}

Artisan::call('turso:sync');

$this->enableReadReplica();
}

public function __call(string $method, array $arguments = []): mixed
Expand Down
29 changes: 29 additions & 0 deletions tests/Unit/TursoConnectionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use Illuminate\Support\Facades\DB;
use RichanFongdasen\Turso\Database\TursoPDO;

beforeEach(function () {
$this->connection = DB::connection('turso');
});

test('it can create a PDO object for read replica database connection', function () {
expect($this->connection->getReadPdo())->toBeInstanceOf(TursoPDO::class);

$pdo = $this->connection->createReadPdo([
'db_replica' => '/dev/null',
]);

expect($pdo)->toBeInstanceOf(\PDO::class)
->and($this->connection->getReadPdo())->toBe($pdo);
})->group('TursoConnectionTest', 'UnitTest');

test('it will return null when trying to create read PDO with no replica database path configured', function () {
expect($this->connection->createReadPdo())->toBeNull();
})->group('TursoConnectionTest', 'UnitTest');

test('it can escape binary data and convert it into string type', function () {
$actual = $this->connection->escape('Hello world!', true);

expect($actual)->toBe("x'48656c6c6f20776f726c6421'");
})->group('TursoConnectionTest', 'UnitTest');

0 comments on commit a2da98c

Please sign in to comment.