mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-12 00:49:04 +01:00
new storage object using a JSON blob to store date not in SQL schema
This commit is contained in:
parent
222c9b1ded
commit
f070e3e82d
234
api/src/Storage/Json.php
Normal file
234
api/src/Storage/Json.php
Normal file
@ -0,0 +1,234 @@
|
||||
<?php
|
||||
/**
|
||||
* EGroupware generalized SQL Storage Object using a JSON blob to store date not in SQL schema
|
||||
*
|
||||
* @license https://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package api
|
||||
* @subpackage storage
|
||||
* @link https://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
* @copyright 2024 by RalfBecker@outdoor-training.de
|
||||
*/
|
||||
|
||||
namespace EGroupware\Api\Storage;
|
||||
|
||||
use EGroupware\Api;
|
||||
|
||||
/**
|
||||
* generalized SQL Storage Object which uses a JSON blob to store all data NOT directly in the schema
|
||||
*
|
||||
* the class can be used in following ways:
|
||||
* 1) by calling the constructor with an app and table-name or
|
||||
* 2) by setting the following documented class-vars in a class derived from this one
|
||||
* Of cause can you derive from the class and call the constructor with params.
|
||||
*
|
||||
* The Json class uses a private $data array and __get and __set methods to set its data.
|
||||
* Please note:
|
||||
* You have to explicitly declare other object-properties of derived classes, which should NOT
|
||||
* be handled by that mechanism!
|
||||
*/
|
||||
class Json extends Base
|
||||
{
|
||||
/**
|
||||
* Private array containing all the object-data
|
||||
*
|
||||
* Collides with the original definition in Storage\Base and I dont want to change it there at the moment.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
//private $data;
|
||||
|
||||
/**
|
||||
* @var string column-name for the JSON blob
|
||||
*/
|
||||
protected $json_column;
|
||||
|
||||
/**
|
||||
* constructor of the class
|
||||
*
|
||||
* NEED to be called from the constructor of the derived class !!!
|
||||
*
|
||||
* @param string $app should be set if table-defs to be read from <app>/setup/tables_current.inc.php
|
||||
* @param string $table should be set if table-defs to be read from <app>/setup/tables_current.inc.php
|
||||
* @param ?Api\Db $db database object, if not the one in $GLOBALS['egw']->db should be used, eg. for an other database
|
||||
* @param string $column_prefix ='' column prefix to automatic remove from the column-name, if the column name starts with it
|
||||
* @param boolean $no_clone =false can we avoid to clone the db-object, default no
|
||||
* new code using appnames and foreach(select(...,$app) can set it to avoid an extra instance of the db object
|
||||
* @param string $timestamp_type =null default null=leave them as is, 'ts'|'integer' use integer unix timestamps,
|
||||
* 'object' use Api\DateTime objects or 'string' use DB timestamp (Y-m-d H:i:s) string
|
||||
*/
|
||||
function __construct($app='', $table='', $json_column='', Api\Db $db=null, $column_prefix='', $no_clone=true, $timestamp_type='object')
|
||||
{
|
||||
parent::__construct($app, $table, $db, $column_prefix, $no_clone, $timestamp_type);
|
||||
|
||||
$this->json_column = $json_column;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the data from the db-format to your work-format
|
||||
*
|
||||
* It un-serializes the JSON blob and copies it into $this->data.
|
||||
*
|
||||
* It gets called everytime when data is read from the db.
|
||||
* This default implementation only converts the timestamps mentioned in $this->timestamps from server to user time.
|
||||
* You can reimplement it in a derived class like this:
|
||||
*
|
||||
* function db2data($data=null)
|
||||
* {
|
||||
* if (($intern = !is_array($data)))
|
||||
* {
|
||||
* $data =& $this->data;
|
||||
* }
|
||||
* // do your own modifications here
|
||||
*
|
||||
* return parent::db2data($intern ? null : $data); // important to use null, if $intern!
|
||||
* }
|
||||
*
|
||||
* @param array $data =null if given works on that array and returns result, else works on internal data-array
|
||||
* @return array
|
||||
*/
|
||||
function db2data($data=null)
|
||||
{
|
||||
if (($intern = !is_array($data)))
|
||||
{
|
||||
$data = &$this->data;
|
||||
}
|
||||
if ($this->json_column && !empty($data[$this->json_column]))
|
||||
{
|
||||
if (is_string($data[$this->json_column]))
|
||||
{
|
||||
$data += (array)json_decode($data[$this->json_column], true);
|
||||
}
|
||||
elseif (is_array($data[$this->json_column]))
|
||||
{
|
||||
$data += $data[$this->json_column];
|
||||
}
|
||||
}
|
||||
unset($data[$this->json_column]);
|
||||
|
||||
return parent::db2data($intern ? null : $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the data from your work-format to the db-format
|
||||
*
|
||||
* It gets called everytime when data gets writen into db or on keys for db-searches.
|
||||
* This default implementation only converts the timestamps mentioned in $this->timestampfs from user to server time.
|
||||
* You can reimplement it in a derived class like this:
|
||||
*
|
||||
* function data2db($data=null)
|
||||
* {
|
||||
* if (($intern = !is_array($data)))
|
||||
* {
|
||||
* $data =& $this->data;
|
||||
* }
|
||||
* // do your own modifications here
|
||||
*
|
||||
* return parent::data2db($intern ? null : $data); // important to use null, if $intern!
|
||||
* }
|
||||
*
|
||||
* @param array $data =null if given works on that array and returns result, else works on internal data-array
|
||||
* @return array
|
||||
*/
|
||||
function data2db($data=null)
|
||||
{
|
||||
if (($intern = !is_array($data)))
|
||||
{
|
||||
$data = &$this->data;
|
||||
}
|
||||
// json-encode non db columns into ths json blob
|
||||
if ($this->json_column && is_array($data) && ($json = array_diff_key($data, array_flip($this->db_cols))))
|
||||
{
|
||||
$data = [
|
||||
$this->json_column => json_encode($json, JSON_UNESCAPED_SLASHES|JSON_THROW_ON_ERROR),
|
||||
] + array_diff_key($data, $json);
|
||||
}
|
||||
return parent::data2db($intern ? null : $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* magic method to read a property from $this->data
|
||||
*
|
||||
* The special property 'id' always refers to the auto-increment id of the object, independent of its name.
|
||||
*
|
||||
* @param string $property
|
||||
* @return mixed
|
||||
*/
|
||||
function __get($property)
|
||||
{
|
||||
switch($property)
|
||||
{
|
||||
case 'id':
|
||||
$property = $this->autoinc_id;
|
||||
break;
|
||||
}
|
||||
return $this->data[$property] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* magic method to set a property in $this->data
|
||||
*
|
||||
* The special property 'id' always refers to the auto-increment id of the object, independent of its name.
|
||||
*
|
||||
* @param string $property
|
||||
* @param mixed $value
|
||||
*/
|
||||
function __set($property, $value)
|
||||
{
|
||||
switch($property)
|
||||
{
|
||||
case 'id':
|
||||
$property = $this->autoinc_id;
|
||||
break;
|
||||
}
|
||||
$this->data[$property] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* magic method to check a property is set in $this->data
|
||||
*
|
||||
* The special property 'id' always refers to the auto-increment id of the object, independent of its name.
|
||||
*
|
||||
* @param string $property
|
||||
* @param mixed $value
|
||||
*/
|
||||
function __isset($property)
|
||||
{
|
||||
switch($property)
|
||||
{
|
||||
case 'id':
|
||||
$property = $this->autoinc_id;
|
||||
break;
|
||||
}
|
||||
return isset($this->data[$property]);
|
||||
}
|
||||
|
||||
/**
|
||||
* magic method to unset a property in $this->data
|
||||
*
|
||||
* The special property 'id' always refers to the auto-increment id of the object, independent of its name.
|
||||
*
|
||||
* @param string $property
|
||||
* @param mixed $value
|
||||
*/
|
||||
function __unset($property)
|
||||
{
|
||||
switch($property)
|
||||
{
|
||||
case 'id':
|
||||
$property = $this->autoinc_id;
|
||||
break;
|
||||
}
|
||||
unset($this->data[$property]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the whole object-data as array, it's a cast of the object to an array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function as_array()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user