Skip to content

Commit

Permalink
Merge pull request #22 from codeigniter4/multiple-writes
Browse files Browse the repository at this point in the history
Multiple Write Handlers
  • Loading branch information
MGatner authored Nov 22, 2021
2 parents 04a3044 + 9f65521 commit 0c3fbd5
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 52 deletions.
6 changes: 4 additions & 2 deletions src/Handlers/BaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ abstract public function get(string $class, string $property, ?string $context =
* If the Handler supports saving values, it
* MUST override this method to provide that functionality.
* Not all Handlers will support writing values.
* Must throw RuntimeException for any failures.
*
* @param mixed $value
*
* @throws RuntimeException
*
* @return mixed
* @return void
*/
public function set(string $class, string $property, $value = null, ?string $context = null)
{
Expand All @@ -38,10 +39,11 @@ public function set(string $class, string $property, $value = null, ?string $con
* If the Handler supports forgetting values, it
* MUST override this method to provide that functionality.
* Not all Handlers will support writing values.
* Must throw RuntimeException for any failures.
*
* @throws RuntimeException
*
* @return mixed
* @return void
*/
public function forget(string $class, string $property, ?string $context = null)
{
Expand Down
12 changes: 5 additions & 7 deletions src/Handlers/DatabaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function get(string $class, string $property, ?string $context = null)
*
* @throws RuntimeException For database failures
*
* @return mixed|void
* @return void
*/
public function set(string $class, string $property, $value = null, ?string $context = null)
{
Expand Down Expand Up @@ -103,13 +103,13 @@ public function set(string $class, string $property, $value = null, ?string $con

// Update storage
$this->setStored($class, $property, $value, $context);

return $result;
}

/**
* Deletes the record from persistent storage, if found,
* and from the local cache.
*
* @return void
*/
public function forget(string $class, string $property, ?string $context = null)
{
Expand All @@ -123,13 +123,11 @@ public function forget(string $class, string $property, ?string $context = null)
->delete();

if (! $result) {
return $result;
throw new RuntimeException(db_connect()->error()['message'] ?? 'Error writing to the database.');
}

// Delete from local storage
$this->forgetStored($class, $property, $context);

return $result;
}

/**
Expand All @@ -139,7 +137,7 @@ public function forget(string $class, string $property, ?string $context = null)
*
* @throws RuntimeException For database failures
*/
private function hydrate(?string $context)
private function hydrate(?string $context): void
{
// Check for completion
if (in_array($context, $this->hydrated, true)) {
Expand Down
47 changes: 28 additions & 19 deletions src/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace CodeIgniter\Settings;

use CodeIgniter\Settings\Config\Settings as SettingsConfig;
use CodeIgniter\Settings\Handlers\BaseHandler;
use InvalidArgumentException;
use RuntimeException;

Expand All @@ -14,19 +15,18 @@
class Settings
{
/**
* An array of Setting Stores that handle
* the actual act of getting/setting the values.
* An array of handlers for getting/setting the values.
*
* @var array
* @var BaseHandler[]
*/
private $handlers = [];

/**
* The name of the handler that handles writes.
* An array of the config options for each handler.
*
* @var string
* @var array<string,array<string,mixed>>
*/
private $writeHandler;
private $options;

/**
* Grabs instances of our handlers.
Expand All @@ -41,12 +41,7 @@ public function __construct(SettingsConfig $config)
}

$this->handlers[$handler] = new $class();

$writeable = $config->{$handler}['writeable'] ?? null;

if ($writeable) {
$this->writeHandler = $handler;
}
$this->options[$handler] = $config->{$handler};
}
}

Expand Down Expand Up @@ -79,41 +74,55 @@ public function get(string $key, ?string $context = null)
*
* @param mixed $value
*
* @return void|null
* @return void
*/
public function set(string $key, $value = null, ?string $context = null)
{
[$class, $property] = $this->prepareClassAndProperty($key);

return $this->getWriteHandler()->set($class, $property, $value, $context);
foreach ($this->getWriteHandlers() as $handler) {
$handler->set($class, $property, $value, $context);
}
}

/**
* Removes a setting from the persistent storage,
* effectively returning the value to the default value
* found in the config file, if any.
*
* @return void
*/
public function forget(string $key, ?string $context = null)
{
[$class, $property] = $this->prepareClassAndProperty($key);

return $this->getWriteHandler()->forget($class, $property, $context);
foreach ($this->getWriteHandlers() as $handler) {
$handler->forget($class, $property, $context);
}
}

/**
* Returns the handler that is set to store values.
*
* @throws RuntimeException
*
* @return mixed
* @return BaseHandler[]
*/
private function getWriteHandler()
private function getWriteHandlers()
{
if (empty($this->writeHandler) || ! isset($this->handlers[$this->writeHandler])) {
$handlers = [];

foreach ($this->options as $handler => $options) {
if (! empty($options['writeable'])) {
$handlers[] = $this->handlers[$handler];
}
}

if ($handlers === []) {
throw new RuntimeException('Unable to find a Settings handler that can store values.');
}

return $this->handlers[$this->writeHandler];
return $handlers;
}

/**
Expand Down
41 changes: 17 additions & 24 deletions tests/DatabaseHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ protected function setUp(): void

public function testSetInsertsNewRows()
{
$results = $this->settings->set('Test.siteName', 'Foo');
$this->settings->set('Test.siteName', 'Foo');

$this->assertTrue($results);
$this->seeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
Expand All @@ -51,9 +50,8 @@ public function testSetInsertsNewRows()

public function testSetInsertsBoolTrue()
{
$results = $this->settings->set('Test.siteName', true);
$this->settings->set('Test.siteName', true);

$this->assertTrue($results);
$this->seeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
Expand All @@ -66,9 +64,8 @@ public function testSetInsertsBoolTrue()

public function testSetInsertsBoolFalse()
{
$results = $this->settings->set('Test.siteName', false);
$this->settings->set('Test.siteName', false);

$this->assertTrue($results);
$this->seeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
Expand All @@ -81,9 +78,8 @@ public function testSetInsertsBoolFalse()

public function testSetInsertsNull()
{
$results = $this->settings->set('Test.siteName', null);
$this->settings->set('Test.siteName', null);

$this->assertTrue($results);
$this->seeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
Expand All @@ -96,10 +92,9 @@ public function testSetInsertsNull()

public function testSetInsertsArray()
{
$data = ['foo' => 'bar'];
$results = $this->settings->set('Test.siteName', $data);
$data = ['foo' => 'bar'];
$this->settings->set('Test.siteName', $data);

$this->assertTrue($results);
$this->seeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
Expand All @@ -112,10 +107,9 @@ public function testSetInsertsArray()

public function testSetInsertsObject()
{
$data = (object) ['foo' => 'bar'];
$results = $this->settings->set('Test.siteName', $data);
$data = (object) ['foo' => 'bar'];
$this->settings->set('Test.siteName', $data);

$this->assertTrue($results);
$this->seeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
Expand All @@ -136,9 +130,8 @@ public function testSetUpdatesExistingRows()
'updated_at' => Time::now()->toDateTimeString(),
]);

$results = $this->settings->set('Test.siteName', 'Bar');
$this->settings->set('Test.siteName', 'Bar');

$this->assertTrue($results);
$this->seeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
Expand All @@ -148,9 +141,8 @@ public function testSetUpdatesExistingRows()

public function testWorksWithoutConfigClass()
{
$results = $this->settings->set('Nada.siteName', 'Bar');
$this->settings->set('Nada.siteName', 'Bar');

$this->assertTrue($results);
$this->seeInDatabase($this->table, [
'class' => 'Nada',
'key' => 'siteName',
Expand All @@ -170,9 +162,8 @@ public function testForgetSuccess()
'updated_at' => Time::now()->toDateTimeString(),
]);

$results = $this->settings->forget('Test.siteName');
$this->settings->forget('Test.siteName');

$this->assertTrue($results);
$this->dontSeeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
Expand All @@ -181,16 +172,18 @@ public function testForgetSuccess()

public function testForgetWithNoStoredRecord()
{
$results = $this->settings->forget('Test.siteName');
$this->settings->forget('Test.siteName');

$this->assertTrue($results);
$this->dontSeeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
]);
}

public function testSetWithContext()
{
$results = $this->settings->set('Test.siteName', 'Banana', 'environment:test');
$this->settings->set('Test.siteName', 'Banana', 'environment:test');

$this->assertTrue($results);
$this->seeInDatabase($this->table, [
'class' => 'Tests\Support\Config\Test',
'key' => 'siteName',
Expand Down

0 comments on commit 0c3fbd5

Please sign in to comment.