Skip to content

Commit 08a9459

Browse files
committed
add Storage::clearValue()
1 parent 8ea7fda commit 08a9459

8 files changed

+181
-54
lines changed

src/Storage.php

+8
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,12 @@ abstract public function get(): array;
3030
* @return bool success.
3131
*/
3232
abstract public function clear(): bool;
33+
34+
/**
35+
* Clear saved value for the specified item.
36+
*
37+
* @param string|int $key the key of the item to be cleared.
38+
* @return bool success.
39+
*/
40+
abstract public function clearValue($key): bool;
3341
}

src/StorageArray.php

+10
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,14 @@ public function clear(): bool
4444

4545
return true;
4646
}
47+
48+
/**
49+
* {@inheritDoc}
50+
*/
51+
public function clearValue($key): bool
52+
{
53+
unset($this->data[$key]);
54+
55+
return true;
56+
}
4757
}

src/StorageDb.php

+58-17
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace yii1tech\config;
44

5+
use CDbCriteria;
56
use Yii;
67

78
/**
@@ -24,7 +25,8 @@
2425
* @author Paul Klimov <[email protected]>
2526
* @since 1.0
2627
*/
27-
class StorageDb extends Storage {
28+
class StorageDb extends Storage
29+
{
2830
/**
2931
* @var string id of the database connection application component.
3032
*/
@@ -33,6 +35,14 @@ class StorageDb extends Storage {
3335
* @var string name of the table, which should store values.
3436
*/
3537
public $table = 'app_config';
38+
/**
39+
* @var string name of the column, which should store config item key.
40+
*/
41+
public $keyColumn = 'id';
42+
/**
43+
* @var string name of the column, which should store config item value.
44+
*/
45+
public $valueColumn = 'value';
3646

3747
/**
3848
* @return \CDbConnection database connection application component.
@@ -47,22 +57,36 @@ public function getDbConnection()
4757
*/
4858
public function save(array $values): bool
4959
{
50-
$this->clear();
51-
52-
$data = [];
53-
foreach ($values as $id => $value) {
54-
$data[] = array(
55-
'id' => $id,
56-
'value' => $value,
57-
);
58-
}
60+
$existingValues = $this->get();
5961

60-
$insertedRowsCount = $this->getDbConnection()
61-
->getCommandBuilder()
62-
->createMultipleInsertCommand($this->table, $data)
63-
->execute();
62+
foreach ($values as $key => $value) {
63+
if (array_key_exists($key, $existingValues)) {
64+
if ($value === $existingValues[$key]) {
65+
continue;
66+
}
67+
68+
$criteria = new CDbCriteria();
69+
$criteria->addColumnCondition([$this->keyColumn => $key]);
70+
$data = [$this->valueColumn => $value];
71+
72+
$this->getDbConnection()
73+
->getCommandBuilder()
74+
->createUpdateCommand($this->table, $data, $criteria)
75+
->execute();
76+
} else {
77+
$data = [
78+
$this->keyColumn => $key,
79+
$this->valueColumn => $value,
80+
];
81+
82+
$this->getDbConnection()
83+
->getCommandBuilder()
84+
->createInsertCommand($this->table, $data)
85+
->execute();
86+
}
87+
}
6488

65-
return (count($values) == $insertedRowsCount);
89+
return true;
6690
}
6791

6892
/**
@@ -76,7 +100,7 @@ public function get(): array
76100

77101
$values = [];
78102
foreach ($rows as $row) {
79-
$values[$row['id']] = $row['value'];
103+
$values[$row[$this->keyColumn]] = $row[$this->valueColumn];
80104
}
81105

82106
return $values;
@@ -87,7 +111,24 @@ public function get(): array
87111
*/
88112
public function clear(): bool
89113
{
90-
$this->getDbConnection()->createCommand()->delete($this->table);
114+
$this->getDbConnection()
115+
->createCommand()
116+
->delete($this->table);
117+
118+
return true;
119+
}
120+
121+
/**
122+
* {@inheritDoc}
123+
*/
124+
public function clearValue($key): bool
125+
{
126+
$criteria = new CDbCriteria();
127+
$criteria->addColumnCondition([$this->keyColumn => $key]);
128+
129+
$this->getDbConnection()
130+
->createCommand()
131+
->delete($this->table, $criteria->condition, $criteria->params);
91132

92133
return true;
93134
}

src/StoragePhp.php

+41-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
* @author Paul Klimov <[email protected]>
1313
* @since 1.0
1414
*/
15-
class StoragePhp extends Storage {
15+
class StoragePhp extends Storage
16+
{
1617
/**
1718
* @var string name of the file, which should be used to store values.
1819
*/
@@ -55,17 +56,9 @@ protected function defaultFileName(): string
5556
*/
5657
public function save(array $values): bool
5758
{
58-
$this->clear();
59+
$values = array_merge($this->get(), $values);
5960

60-
$fileName = $this->getFileName();
61-
62-
$dirName = dirname($fileName);
63-
if (!file_exists($dirName)) {
64-
mkdir($dirName, 0777, true);
65-
}
66-
67-
$bytesWritten = file_put_contents($fileName, $this->composeFileContent($values));
68-
$this->invalidateScriptCache($fileName);
61+
$bytesWritten = $this->saveToFile($values);
6962

7063
return ($bytesWritten > 0);
7164
}
@@ -98,6 +91,43 @@ public function clear(): bool
9891
return true;
9992
}
10093

94+
/**
95+
* {@inheritdoc}
96+
*/
97+
public function clearValue($key): bool
98+
{
99+
$values = $this->get();
100+
if (empty($values)) {
101+
return true;
102+
}
103+
104+
unset($values[$key]);
105+
106+
$bytesWritten = $this->saveToFile($values);
107+
108+
return ($bytesWritten > 0);
109+
}
110+
111+
/**
112+
* Saves given values to the file.
113+
* @param array $values values to be saved.
114+
* @return int number of bytes written.
115+
*/
116+
protected function saveToFile(array $values)
117+
{
118+
$fileName = $this->getFileName();
119+
120+
$dirName = dirname($fileName);
121+
if (!file_exists($dirName)) {
122+
mkdir($dirName, 0777, true);
123+
}
124+
125+
$bytesWritten = file_put_contents($fileName, $this->composeFileContent($values));
126+
$this->invalidateScriptCache($fileName);
127+
128+
return $bytesWritten;
129+
}
130+
101131
/**
102132
* Composes file content for the given values.
103133
* @param array $values values to be saved.

tests/ManagerTest.php

+3-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Yii;
66
use yii1tech\config\Item;
77
use yii1tech\config\Manager;
8-
use yii1tech\config\StoragePhp;
8+
use yii1tech\config\StorageArray;
99

1010
class ManagerTest extends TestCase
1111
{
@@ -52,8 +52,7 @@ protected function createTestManager(): Manager
5252
$config = [
5353
'class' => Manager::class,
5454
'storage' => [
55-
'class' => StoragePhp::class,
56-
'fileName' => $this->getTestFileName(),
55+
'class' => StorageArray::class,
5756
],
5857
];
5958

@@ -73,7 +72,7 @@ public function testSetGet(): void
7372
$manager->setItems($items);
7473
$this->assertEquals($items, $manager->getItems(), 'Unable to setup items!');
7574

76-
$storage = new StoragePhp();
75+
$storage = new StorageArray();
7776
$manager->setStorage($storage);
7877
$this->assertEquals($storage, $manager->getStorage(), 'Unable to setup storage!');
7978
}

tests/StorageArrayTest.php

+19
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,23 @@ public function testClear()
7272

7373
$this->assertEmpty($this->storage->get());
7474
}
75+
76+
/**
77+
* @depends testSave
78+
*/
79+
public function testClearValue()
80+
{
81+
$values = [
82+
'test.name' => 'Test name',
83+
'test.title' => 'Test title',
84+
];
85+
86+
$this->storage->save($values);
87+
$this->storage->clearValue('test.name');
88+
89+
$returnedValues = $this->storage->get();
90+
91+
$this->assertFalse(array_key_exists('test.name', $returnedValues));
92+
$this->assertTrue(array_key_exists('test.title', $returnedValues));
93+
}
7594
}

tests/StorageDbTest.php

+25-14
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ protected function setUp(): void
1414
{
1515
parent::setUp();
1616

17-
$this->createTestConfigTable();
17+
$this->createTestDbSchema();
1818
}
1919

2020
/**
2121
* @return string test table name
2222
*/
2323
protected function getTestTableName(): string
2424
{
25-
return '_test_config';
25+
return 'test_config';
2626
}
2727

2828
/**
2929
* Creates test config table.
3030
*/
31-
protected function createTestConfigTable(): void
31+
protected function createTestDbSchema(): void
3232
{
3333
$dbConnection = Yii::app()->db;
3434
$columns = [
@@ -41,12 +41,13 @@ protected function createTestConfigTable(): void
4141
/**
4242
* @return \yii1tech\config\StorageDb test storage instance.
4343
*/
44-
protected function createTestStorage() {
45-
$config = array(
44+
protected function createTestStorage(): StorageDb
45+
{
46+
$config = [
4647
'class' => StorageDb::class,
4748
'db' => 'db',
4849
'table' => $this->getTestTableName(),
49-
);
50+
];
5051

5152
return Yii::createComponent($config);
5253
}
@@ -61,35 +62,45 @@ public function testSave(): void
6162
'name2' => 'value2',
6263
];
6364
$this->assertTrue($storage->save($values), 'Unable to save values!');
65+
66+
$returnedValues = $storage->get();
67+
68+
$this->assertEquals($values, $returnedValues, 'Unable to get values!');
6469
}
6570

6671
/**
6772
* @depends testSave
6873
*/
69-
public function testGet(): void
74+
public function testClear(): void
7075
{
7176
$storage = $this->createTestStorage();
7277
$values = [
7378
'name1' => 'value1',
7479
'name2' => 'value2',
7580
];
7681
$storage->save($values);
77-
$this->assertEquals($values, $storage->get(), 'Unable to get values!');
82+
83+
$this->assertTrue($storage->clear(), 'Unable to clear values!');
84+
$this->assertEmpty($storage->get(), 'Values are not cleared!');
7885
}
7986

8087
/**
81-
* @depends testGet
88+
* @depends testSave
8289
*/
83-
public function testClear(): void
90+
public function testClearValue()
8491
{
8592
$storage = $this->createTestStorage();
8693
$values = [
87-
'name1' => 'value1',
88-
'name2' => 'value2',
94+
'test.name' => 'Test name',
95+
'test.title' => 'Test title',
8996
];
97+
9098
$storage->save($values);
99+
$storage->clearValue('test.name');
91100

92-
$this->assertTrue($storage->clear(), 'Unable to clear values!');
93-
$this->assertEquals([], $storage->get(), 'Values are not cleared!');
101+
$returnedValues = $storage->get();
102+
103+
$this->assertFalse(array_key_exists('test.name', $returnedValues));
104+
$this->assertTrue(array_key_exists('test.title', $returnedValues));
94105
}
95106
}

0 commit comments

Comments
 (0)