Added support for extra database fields.
This commit is contained in:
parent
572b46580a
commit
8a563ba73b
2 changed files with 110 additions and 27 deletions
102
src/DbConfig.php
102
src/DbConfig.php
|
@ -24,13 +24,29 @@ class DbConfig implements IConfig {
|
|||
/** @var array<string, DbConfigValueInfo> */
|
||||
private array $values = [];
|
||||
|
||||
/** @var string[] */
|
||||
private array $extraFieldNames;
|
||||
|
||||
/** @var mixed[] */
|
||||
private array $extraFieldValues;
|
||||
|
||||
/**
|
||||
* @param IDbConnection $dbConn
|
||||
* @param string $tableName
|
||||
* @param string $nameField
|
||||
* @param string $valueField
|
||||
* @param array<string, mixed> $extraFields
|
||||
*/
|
||||
public function __construct(
|
||||
IDbConnection $dbConn,
|
||||
private string $tableName,
|
||||
private string $nameField = 'config_name',
|
||||
private string $valueField = 'config_value'
|
||||
private string $valueField = 'config_value',
|
||||
array $extraFields = [],
|
||||
) {
|
||||
$this->cache = new DbStatementCache($dbConn);
|
||||
$this->extraFieldNames = array_keys($extraFields);
|
||||
$this->extraFieldValues = array_values($extraFields);
|
||||
}
|
||||
|
||||
public static function validateName(string $name): bool {
|
||||
|
@ -90,15 +106,23 @@ class DbConfig implements IConfig {
|
|||
$names = array_values($names);
|
||||
$nameCount = count($names);
|
||||
|
||||
$stmt = $this->cache->get(sprintf(
|
||||
$query = sprintf(
|
||||
'SELECT COUNT(*) FROM %s WHERE %s IN (%s)',
|
||||
$this->tableName, $this->nameField,
|
||||
DbTools::prepareListString($nameCount)
|
||||
));
|
||||
for($i = 0; $i < $nameCount; ++$i)
|
||||
$stmt->addParameter($i + 1, $names[$i]);
|
||||
$stmt->execute();
|
||||
);
|
||||
foreach($this->extraFieldNames as $extraFieldName)
|
||||
$query .= sprintf(' AND %s = ?', $extraFieldName);
|
||||
|
||||
$stmt = $this->cache->get($query);
|
||||
|
||||
$args = 0;
|
||||
foreach($names as $name)
|
||||
$stmt->addParameter(++$args, $name);
|
||||
foreach($this->extraFieldValues as $extraFieldValue)
|
||||
$stmt->addParameter(++$args, $extraFieldValue);
|
||||
|
||||
$stmt->execute();
|
||||
$result = $stmt->getResult();
|
||||
if($result->next())
|
||||
return $result->getInteger(0) >= $nameCount;
|
||||
|
@ -117,14 +141,21 @@ class DbConfig implements IConfig {
|
|||
unset($this->values[$name]);
|
||||
|
||||
$nameCount = count($names);
|
||||
$stmt = $this->cache->get(sprintf(
|
||||
$query = sprintf(
|
||||
'DELETE FROM %s WHERE %s IN (%s)',
|
||||
$this->tableName, $this->nameField,
|
||||
DbTools::prepareListString($nameCount)
|
||||
));
|
||||
);
|
||||
foreach($this->extraFieldNames as $extraFieldName)
|
||||
$query .= sprintf(' AND %s = ?', $extraFieldName);
|
||||
|
||||
for($i = 0; $i < $nameCount; ++$i)
|
||||
$stmt->addParameter($i + 1, $names[$i]);
|
||||
$stmt = $this->cache->get($query);
|
||||
|
||||
$args = 0;
|
||||
foreach($names as $name)
|
||||
$stmt->addParameter(++$args, $name);
|
||||
foreach($this->extraFieldValues as $extraFieldValue)
|
||||
$stmt->addParameter(++$args, $extraFieldValue);
|
||||
|
||||
$stmt->execute();
|
||||
}
|
||||
|
@ -136,6 +167,8 @@ class DbConfig implements IConfig {
|
|||
$hasRange = $range !== 0;
|
||||
|
||||
$query = sprintf('SELECT %s, %s FROM %s', $this->nameField, $this->valueField, $this->tableName);
|
||||
foreach($this->extraFieldNames as $i => $extraFieldName)
|
||||
$query .= sprintf(' %s %s = ?', $i < 1 ? 'WHERE' : 'AND', $extraFieldName);
|
||||
if($hasRange) {
|
||||
if($range < 0)
|
||||
throw new InvalidArgumentException('$range must be a positive integer.');
|
||||
|
@ -146,10 +179,15 @@ class DbConfig implements IConfig {
|
|||
}
|
||||
|
||||
$stmt = $this->cache->get($query);
|
||||
|
||||
$args = 0;
|
||||
foreach($this->extraFieldValues as $extraFieldValue)
|
||||
$stmt->addParameter(++$args, $extraFieldValue);
|
||||
if($hasRange) {
|
||||
$stmt->addParameter(1, $range);
|
||||
$stmt->addParameter(2, $offset);
|
||||
$stmt->addParameter(++$args, $range);
|
||||
$stmt->addParameter(++$args, $offset);
|
||||
}
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->getResult();
|
||||
|
@ -184,13 +222,22 @@ class DbConfig implements IConfig {
|
|||
$names = array_values($names);
|
||||
$nameCount = count($names);
|
||||
|
||||
$stmt = $this->cache->get(sprintf(
|
||||
'SELECT %s, %s FROM %s WHERE config_name IN (%s)',
|
||||
$this->nameField, $this->valueField, $this->tableName,
|
||||
$query = sprintf(
|
||||
'SELECT %s, %s FROM %s WHERE %s IN (%s)',
|
||||
$this->nameField, $this->valueField, $this->tableName, $this->nameField,
|
||||
DbTools::prepareListString($nameCount)
|
||||
));
|
||||
for($i = 0; $i < $nameCount; ++$i)
|
||||
$stmt->addParameter($i + 1, $names[$i]);
|
||||
);
|
||||
foreach($this->extraFieldNames as $extraFieldName)
|
||||
$query .= sprintf(' AND %s = ?', $extraFieldName);
|
||||
|
||||
$stmt = $this->cache->get($query);
|
||||
|
||||
$args = 0;
|
||||
foreach($names as $name)
|
||||
$stmt->addParameter(++$args, $name);
|
||||
foreach($this->extraFieldValues as $extraFieldValue)
|
||||
$stmt->addParameter(++$args, $extraFieldValue);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->getResult();
|
||||
|
@ -207,9 +254,16 @@ class DbConfig implements IConfig {
|
|||
if(empty($values))
|
||||
return;
|
||||
|
||||
$fields = [$this->nameField, $this->valueField];
|
||||
if(count($this->extraFieldNames) > 0)
|
||||
$fields = array_merge($fields, $this->extraFieldNames);
|
||||
$fieldCount = count($fields);
|
||||
$fields = implode(', ', $fields);
|
||||
|
||||
$stmt = $this->cache->get(sprintf(
|
||||
'INSERT INTO %s (%s, %s) VALUES (?, ?)',
|
||||
$this->tableName, $this->nameField, $this->valueField
|
||||
'INSERT INTO %s (%s) VALUES (%s)',
|
||||
$this->tableName, $fields,
|
||||
DbTools::prepareListString($fieldCount)
|
||||
));
|
||||
|
||||
foreach($values as $name => $value) {
|
||||
|
@ -225,8 +279,12 @@ class DbConfig implements IConfig {
|
|||
|
||||
$this->removeValues($name);
|
||||
|
||||
$stmt->addParameter(1, $name);
|
||||
$stmt->addParameter(2, serialize($value));
|
||||
$args = 0;
|
||||
$stmt->addParameter(++$args, $name);
|
||||
$stmt->addParameter(++$args, serialize($value));
|
||||
foreach($this->extraFieldValues as $extraFieldValue)
|
||||
$stmt->addParameter(++$args, $extraFieldValue);
|
||||
|
||||
$stmt->execute();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase;
|
|||
* @covers \Syokuhou\GetValuesTrait
|
||||
*/
|
||||
final class DbConfigTest extends TestCase {
|
||||
private \Index\Data\IDbConnection $dbConn;
|
||||
private \Syokuhou\DbConfig $config;
|
||||
|
||||
private const VALUES = [
|
||||
|
@ -34,18 +35,33 @@ final class DbConfigTest extends TestCase {
|
|||
'test.int' => 'i:243230;',
|
||||
];
|
||||
|
||||
protected function setUp(): void {
|
||||
$dbConn = \Index\Data\DbTools::create('sqlite::memory:');
|
||||
$dbConn->execute('CREATE TABLE skh_config (config_name TEXT NOT NULL COLLATE NOCASE, config_value BLOB NOT NULL, PRIMARY KEY (config_name))');
|
||||
private const USER_VALUES = [
|
||||
'mobile.left_handed' => ['b:0;', 'b:1;'],
|
||||
'profile.allow_indexing' => ['b:1;', 'b:0;'],
|
||||
];
|
||||
|
||||
$stmt = $dbConn->prepare('INSERT INTO skh_config (config_name, config_value) VALUES (?, ?)');
|
||||
protected function setUp(): void {
|
||||
$this->dbConn = \Index\Data\DbTools::create('sqlite::memory:');
|
||||
$this->dbConn->execute('CREATE TABLE skh_config (config_name TEXT NOT NULL COLLATE NOCASE, config_value BLOB NOT NULL, PRIMARY KEY (config_name))');
|
||||
$this->dbConn->execute('CREATE TABLE skh_user_settings (user_id INTEGER NOT NULL, setting_name TEXT NOT NULL COLLATE NOCASE, setting_value BLOB NOT NULL, PRIMARY KEY (user_id, setting_name))');
|
||||
|
||||
$stmt = $this->dbConn->prepare('INSERT INTO skh_config (config_name, config_value) VALUES (?, ?)');
|
||||
foreach(self::VALUES as $name => $value) {
|
||||
$stmt->addParameter(1, $name);
|
||||
$stmt->addParameter(2, $value);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$this->config = new \Syokuhou\DbConfig($dbConn, 'skh_config');
|
||||
$stmt = $this->dbConn->prepare('INSERT INTO skh_user_settings (user_id, setting_name, setting_value) VALUES (?, ?, ?)');
|
||||
for($i = 1; $i <= 10; ++$i)
|
||||
foreach(self::USER_VALUES as $name => $value) {
|
||||
$stmt->addParameter(1, $i);
|
||||
$stmt->addParameter(2, $name);
|
||||
$stmt->addParameter(3, $value[$i % 2]);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$this->config = new \Syokuhou\DbConfig($this->dbConn, 'skh_config');
|
||||
}
|
||||
|
||||
public function testScoping(): void {
|
||||
|
@ -152,4 +168,13 @@ final class DbConfigTest extends TestCase {
|
|||
$this->assertFalse(\Syokuhou\DbConfig::validateName('this..is.not.valid'));
|
||||
$this->assertFalse(\Syokuhou\DbConfig::validateName('First.may.Not.be.uppercase'));
|
||||
}
|
||||
|
||||
public function testUserSettings(): void {
|
||||
for($i = 1; $i <= 10; ++$i) {
|
||||
$config = new \Syokuhou\DbConfig($this->dbConn, 'skh_user_settings', 'setting_name', 'setting_value', ['user_id' => $i]);
|
||||
|
||||
foreach(self::USER_VALUES as $name => $value)
|
||||
$this->assertEquals(unserialize($value[$i % 2]), $config->getBoolean($name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue