Update database engine

This commit is contained in:
Fred Tempez 2022-03-27 18:13:43 +02:00
parent 10c79f6247
commit 01bc932fe3
2 changed files with 50 additions and 228 deletions

View File

@ -10,7 +10,7 @@ use ArrayAccess;
* This class provides dot notation access to arrays, so it's easy to handle * This class provides dot notation access to arrays, so it's easy to handle
* multidimensional data in a clean way. * multidimensional data in a clean way.
*/ */
class Dot implements \ArrayAccess, \Iterator, \Countable class Dot implements ArrayAccess
{ {
/** @var array Data */ /** @var array Data */
@ -94,14 +94,9 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
*/ */
public static function addValue(&$array, $key, $value = null, $pop = false) public static function addValue(&$array, $key, $value = null, $pop = false)
{ {
if (is_array($key)) { if (is_string($key)) {
// Iterate array of paths and values
foreach ($key as $k => $v) {
self::addValue($array, $k, $v);
}
} else {
// Iterate path // Iterate path
$keys = explode('.', (string)$key); $keys = explode('.', $key);
if ($pop === true) { if ($pop === true) {
array_pop($keys); array_pop($keys);
} }
@ -113,6 +108,11 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
} }
// Add value to path // Add value to path
$array[] = $value; $array[] = $value;
} elseif (is_array($key)) {
// Iterate array of paths and values
foreach ($key as $k => $v) {
self::addValue($array, $k, $v);
}
} }
} }
@ -154,14 +154,9 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
* @param mixed|null $default Default value * @param mixed|null $default Default value
* @return mixed Value of path * @return mixed Value of path
*/ */
public function get($key, $default = null, $asObject = false) public function get($key = null, $default = null)
{ {
$value = self::getValue($this->data, $key, $default); return self::getValue($this->data, $key, $default);
if ($asObject && is_array($value)) {
return new self($value);
}
return $value;
} }
/** /**
@ -169,12 +164,10 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
* *
* @param mixed $key Path or array of paths and values * @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array * @param mixed|null $value Value to set if path is not an array
* @return $this
*/ */
public function set($key, $value = null) public function set($key, $value = null)
{ {
self::setValue($this->data, $key, $value); return self::setValue($this->data, $key, $value);
return $this;
} }
/** /**
@ -183,12 +176,10 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
* @param mixed $key Path or array of paths and values * @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array * @param mixed|null $value Value to set if path is not an array
* @param boolean $pop Helper to pop out last key if value is an array * @param boolean $pop Helper to pop out last key if value is an array
* @return $this
*/ */
public function add($key, $value = null, $pop = false) public function add($key, $value = null, $pop = false)
{ {
self::addValue($this->data, $key, $value); return self::addValue($this->data, $key, $value, $pop);
return $this;
} }
/** /**
@ -215,42 +206,10 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
* Delete path or array of paths * Delete path or array of paths
* *
* @param mixed $key Path or array of paths to delete * @param mixed $key Path or array of paths to delete
* @return $this
*/ */
public function delete($key) public function delete($key)
{ {
self::deleteValue($this->data, $key); return self::deleteValue($this->data, $key);
return $this;
}
/**
* Increase numeric value
*
* @param string $key
* @param float $number
* @return float
*/
public function plus(string $key, float $number): float
{
$newAmount = $this->get($key, 0) + $number;
$this->set($key, $newAmount);
return $newAmount;
}
/**
* Reduce numeric value
*
* @param string $key
* @param float $number
* @return float
*/
public function minus(string $key, float $number): float
{
$newAmount = $this->get($key, 0) - $number;
$this->set($key, $newAmount);
return $newAmount;
} }
/** /**
@ -354,115 +313,4 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
{ {
$this->delete($key); $this->delete($key);
} }
/**
* Check for emptiness
*
* @return bool
*/
public function isEmpty(): bool
{
return !(bool)count($this->data);
}
/**
* Return all data as array
*
* @return array
*/
public function toArray()
{
return $this->data;
}
/**
* Return as json string
*
* @return false|string
*/
public function toJson()
{
return json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
}
/**
* @return string
*/
public function __toString()
{
return $this->toJson();
}
/**
* @return array
*/
public function __toArray()
{
return $this->toArray();
}
/**
* Return the current element
* @link https://php.net/manual/en/iterator.current.php
* @return mixed Can return any type.
* @since 5.0.0
*/
public function current()
{
return current($this->data);
}
/**
* Move forward to next element
* @link https://php.net/manual/en/iterator.next.php
* @return void Any returned value is ignored.
* @since 5.0.0
*/
public function next()
{
return next($this->data);
}
/**
* Return the key of the current element
* @link https://php.net/manual/en/iterator.key.php
* @return mixed scalar on success, or null on failure.
* @since 5.0.0
*/
public function key()
{
return key($this->data);
}
/**
* Checks if current position is valid
* @link https://php.net/manual/en/iterator.valid.php
* @return bool The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
* @since 5.0.0
*/
public function valid()
{
$key = key($this->data);
return ($key !== NULL && $key !== FALSE);
}
/**
* Rewind the Iterator to the first element
* @link https://php.net/manual/en/iterator.rewind.php
* @return void Any returned value is ignored.
* @since 5.0.0
*/
public function rewind()
{
return reset($this->data);
}
/**
* @inheritDoc
*/
public function count()
{
return count($this->data);
}
} }

View File

@ -23,30 +23,20 @@ class JsonDb extends \Prowebcraft\Dot
{ {
$this->config = array_merge([ $this->config = array_merge([
'name' => 'data.json', 'name' => 'data.json',
'backup' => false, 'backup' => 5,
'dir' => getcwd() 'dir' => getcwd(),
//'template' => getcwd() . DIRECTORY_SEPARATOR . 'data.template.json' 'template' => getcwd() . DIRECTORY_SEPARATOR . 'data.template.json'
], $config); ], $config);
$this->loadData(); $this->loadData();
parent::__construct(); parent::__construct();
} }
/**
* Reload data from file
* @return $this
*/
public function reload()
{
$this->loadData(true);
return $this;
}
/** /**
* Set value or array of values to path * Set value or array of values to path
* *
* @param mixed $key Path or array of paths and values * @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array * @param mixed|null $value Value to set if path is not an array
* @param bool $save Save data to database * @param bool $save Сохранить данные в базу
* @return $this * @return $this
*/ */
public function set($key, $value = null, $save = true) public function set($key, $value = null, $save = true)
@ -59,10 +49,10 @@ class JsonDb extends \Prowebcraft\Dot
/** /**
* Add value or array of values to path * Add value or array of values to path
* *
* @param mixed $key Path or array of paths and values * @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array * @param mixed|null $value Value to set if path is not an array
* @param boolean $pop Helper to pop out last key if value is an array * @param boolean $pop Helper to pop out last key if value is an array
* @param bool $save Save data to database * @param bool $save Сохранить данные в базу
* @return $this * @return $this
*/ */
public function add($key, $value = null, $pop = false, $save = true) public function add($key, $value = null, $pop = false, $save = true)
@ -75,8 +65,8 @@ class JsonDb extends \Prowebcraft\Dot
/** /**
* Delete path or array of paths * Delete path or array of paths
* *
* @param mixed $key Path or array of paths to delete * @param mixed $key Path or array of paths to delete
* @param bool $save Save data to database * @param bool $save Сохранить данные в базу
* @return $this * @return $this
*/ */
public function delete($key, $save = true) public function delete($key, $save = true)
@ -91,8 +81,8 @@ class JsonDb extends \Prowebcraft\Dot
* optionally format path if it doesn't exist * optionally format path if it doesn't exist
* *
* @param mixed|null $key Path or array of paths to clean * @param mixed|null $key Path or array of paths to clean
* @param boolean $format Format option * @param boolean $format Format option
* @param bool $save Save data to database * @param bool $save Сохранить данные в базу
* @return $this * @return $this
*/ */
public function clear($key = null, $format = false, $save = true) public function clear($key = null, $format = false, $save = true)
@ -104,62 +94,46 @@ class JsonDb extends \Prowebcraft\Dot
/** /**
* Local database upload * Загрузка локальной базы данных
* @param bool $reload Reboot data? * @param bool $reload
* Перезагрузить данные?
* @return array|mixed|null * @return array|mixed|null
*/ */
protected function loadData($reload = false) { protected function loadData($reload = false) {
if ($this->data === null || $reload) { if ($this->data === null || $reload) {
// $this->db = $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name']; $this->db = $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'];
$this->db = $this->config['dir'] . $this->config['name'];
if (!file_exists($this->db)) { if (!file_exists($this->db)) {
return null; $templateFile = $this->config['template'];
if (file_exists($templateFile)) {
copy($templateFile, $this->db);
} else {
//file_put_contents($this->db, '{}');
return null; // Rebuild database manage by CMS
}
} else { } else {
// 3 essais if ($this->config['backup']) {
for($i = 0; $i <3; $i++) { try {
if ($this->data = json_decode(@file_get_contents($this->db), true) ) { //todo make backup of database
break; } catch (\Exception $e) {
}
// Pause de 10 millisecondes }
usleep(10000);
}
// Gestion de l'erreur
if (!$this->data === null) {
exit ('JsonDB : Erreur de lecture du fichier de données ' . $this->db .'. Aucune donnée lisible, essayez dans quelques instants ou vérifiez le système de fichiers.');
} }
} }
$this->data = json_decode(file_get_contents($this->db), true);
if (!$this->data === null) {
throw new \InvalidArgumentException('Database file ' . $this->db
. ' contains invalid json object. Please validate or remove file');
}
} }
return $this->data; return $this->data;
} }
/** /**
* Saving to local database * Сохранение в локальную базу
*/ */
public function save() { public function save() {
// Fichier inexistant, le créer file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)); // Multi user get a locker
if ( !file_exists($this->db) ) {
touch($this->db);
}
// Backup file
if ($this->config['backup'] === true) {
copy ($this->db, str_replace('json' , 'backup.json', $this->db));
}
if ( is_writable($this->db) ) {
// 3 essais
for($i = 0; $i < 3; $i++) {
if( @file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)) !== false) {
break;
}
// Pause de 10 millisecondes
usleep(10000);
}
if ($i === 2) {
exit ('Jsondb : Erreur d\'écriture dans le fichier de données ' . $this->db . '. Vérifiez le système de fichiers.' );
}
} else {
exit ('Jsondb : Écriture interdite dans le fichier de données ' . $this->db .'. Vérifiez les permissions.' );
}
} }
} }