Skip to content

Commit

Permalink
feature: allow passing initialisation queries in settings (#354)
Browse files Browse the repository at this point in the history
* feature: allow passing initialisation queries in settings
closes #353

* tweak: explicit int cast
  • Loading branch information
g105b committed Aug 13, 2023
1 parent 5da9c2e commit f9d3562
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 9 deletions.
6 changes: 6 additions & 0 deletions src/Connection/DefaultSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class DefaultSettings implements SettingsInterface {

const DEFAULT_CHARSET = "utf8mb4";
const DEFAULT_COLLATION = "utf8mb4_general_ci";
const DEFAULT_INIT_QUERY = null;

protected string $baseDirectory;
protected string $driver;
Expand All @@ -45,6 +46,7 @@ class DefaultSettings implements SettingsInterface {
protected array $config;
protected string $charset;
protected string $collation;
protected ?string $initQuery;

public function __construct() {
$this->baseDirectory = sys_get_temp_dir();
Expand Down Expand Up @@ -123,4 +125,8 @@ public function getCharset():string {
public function getCollation():string {
return self::DEFAULT_COLLATION;
}

public function getInitQuery():?string {
return self::DEFAULT_INIT_QUERY;
}
}
6 changes: 6 additions & 0 deletions src/Connection/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,11 @@ protected function connect():void {
$this->settings->getPassword(),
$options
);

if($initQuery = $this->settings->getInitQuery()) {
foreach(explode(";", $initQuery) as $q) {
$this->connection->exec($q);
}
}
}
}
10 changes: 10 additions & 0 deletions src/Connection/ImmutableSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,14 @@ public function withCollation(string $collation):SettingsInterface {
$clone->collation = $collation;
return $clone;
}

public function withInitQuery(?string $initQuery):SettingsInterface {
if($this->initQuery === $initQuery) {
return $this;
}

$clone = clone $this;
$clone->initQuery = $initQuery;
return $clone;
}
}
9 changes: 8 additions & 1 deletion src/Connection/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Settings implements SettingsInterface {
protected array $config = [];
protected string $collation;
protected ?string $charset;
protected ?string $initQuery;

public function __construct(
string $baseDirectory,
Expand All @@ -37,7 +38,8 @@ public function __construct(
string $password = DefaultSettings::DEFAULT_PASSWORD,
string $connectionName = DefaultSettings::DEFAULT_NAME,
string $collation = DefaultSettings::DEFAULT_COLLATION,
?string $charset = null
?string $charset = null,
?string $initQuery = null,
) {
$this->baseDirectory = $baseDirectory;
$this->driver = $driver;
Expand All @@ -49,6 +51,7 @@ public function __construct(
$this->connectionName = $connectionName;
$this->collation = $collation;
$this->charset = $charset;
$this->initQuery = $initQuery;
}

/** @param array<string, string> $config */
Expand Down Expand Up @@ -140,6 +143,10 @@ public function getCollation():string {
return $this->collation;
}

public function getInitQuery():?string {
return $this->initQuery;
}

protected function getCharsetFromCollation():string {
return substr(
$this->collation,
Expand Down
2 changes: 2 additions & 0 deletions src/Connection/SettingsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public function getConnectionName():string;
public function getConnectionString():string;
public function getCharset():string;
public function getCollation():string;
public function getInitQuery():?string;

public function withBaseDirectory(string $baseDirectory):SettingsInterface;
public function withDriver(string $driver):SettingsInterface;
Expand All @@ -25,4 +26,5 @@ public function withConnectionName(string $connectionName):SettingsInterface;
public function withoutSchema():SettingsInterface;
public function withCharset(string $charset):SettingsInterface;
public function withCollation(string $collation):SettingsInterface;
public function withInitQuery(?string $initQuery):SettingsInterface;
}
92 changes: 85 additions & 7 deletions test/phpunit/Connection/DriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class DriverTest extends TestCase {
protected $connectionString = "sqlite::memory:";
protected $username = "test-username";
protected $password = "test-password";
protected $initQuery = null;

public function testGetBaseDirectory() {
$settings = $this->getSettingsMock();
Expand All @@ -31,19 +32,96 @@ public function testGetBaseDirectory() {
);
}

protected function getSettingsMock():Settings {
public function testConstruct_initQueryDefaultForeignKeyCheck() {
$settings = $this->getSettingsMock();
$driver = new Driver($settings);
$connection = $driver->getConnection();
$defaultForeignKeysValue = $connection->query("PRAGMA foreign_keys")->fetch()["foreign_keys"];

if($defaultForeignKeysValue) {
$newValue = "OFF";
}
else {
$newValue = "ON";
}
$settings = $this->getSettingsMock(initQuery: "PRAGMA foreign_keys = $newValue");
$driver = new Driver($settings);
$connection = $driver->getConnection();
$actualNewValue = $connection->query("PRAGMA foreign_keys")->fetch()["foreign_keys"];
if($defaultForeignKeysValue) {
self::assertSame(0, $actualNewValue);
}
else {
self::assertSame(1, $actualNewValue);
}
}

public function testConstruct_initQueryMultipleInitQueries() {
$settings = $this->getSettingsMock();
$driver = new Driver($settings);
$connection = $driver->getConnection();
$defaultForeignKeysValue = $connection->query("PRAGMA foreign_keys")->fetch()["foreign_keys"];
$defaultFullSyncValue = $connection->query("PRAGMA fullfsync")->fetch()["fullfsync"];

if($defaultForeignKeysValue) {
$newForeignKeysValue = "OFF";
}
else {
$newForeignKeysValue = "ON";
}
if($defaultFullSyncValue) {
$newFullSyncValue = "OFF";
}
else {
$newFullSyncValue = "ON";
}

$initQuery = implode(";", [
"PRAGMA foreign_keys = $newForeignKeysValue",
"PRAGMA fullfsync = $newFullSyncValue",
]);
$settings = $this->getSettingsMock(initQuery: $initQuery);
$driver = new Driver($settings);
$connection = $driver->getConnection();
$actualNewForeignKeysValue = $connection->query("PRAGMA foreign_keys")->fetch()["foreign_keys"];
$actualNewFullSyncValue = $connection->query("PRAGMA fullfsync")->fetch()["fullfsync"];

if($defaultForeignKeysValue) {
self::assertSame(0, $actualNewForeignKeysValue);
}
else {
self::assertSame(1, $actualNewForeignKeysValue);
}
if($defaultFullSyncValue) {
self::assertSame(0, $actualNewFullSyncValue);
}
else {
self::assertSame(1, $actualNewFullSyncValue);
}
}

protected function getSettingsMock(
string $baseDirectory = null,
string $connectionName = null,
string $connectionString = null,
string $username = null,
string $password = null,
string $initQuery = null,
):Settings {
$settings = $this->createMock(Settings::class);
$settings->method("getBaseDirectory")
->willReturn($this->baseDirectory);
->willReturn($baseDirectory ?? $this->baseDirectory);
$settings->method("getConnectionName")
->willReturn($this->connectionName);
->willReturn($connectionName ?? $this->connectionName);
$settings->method("getConnectionString")
->willReturn($this->connectionString);
->willReturn($connectionString ?? $this->connectionString);
$settings->method("getUsername")
->willReturn($this->username);
->willReturn($username ?? $this->username);
$settings->method("getPassword")
->willReturn($this->password);
->willReturn($password ?? $this->password);
$settings->method("getInitQuery")
->willReturn($initQuery ?? $this->initQuery);

return $settings;
}
}
}
2 changes: 1 addition & 1 deletion test/phpunit/Migration/MigratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ private function generateFileList($missingFiles = false, $duplicateFiles = false
}

if($missingFiles) {
$numToRemove = rand(1, $migLength / 10);
$numToRemove = rand(1, (int)($migLength / 10));
for($i = 0; $i < $numToRemove; $i++) {
$keyToRemove = array_rand($fileList);
unset($fileList[$keyToRemove]);
Expand Down

0 comments on commit f9d3562

Please sign in to comment.