Initial DB Wrapper

This commit is contained in:
Philipp Holzer 2019-02-28 13:38:25 +01:00
parent a65a30b303
commit bfc4615440
No known key found for this signature in database
GPG Key ID: 517BE60E2CE5C8A5
6 changed files with 330 additions and 8 deletions

View File

@ -14,6 +14,7 @@ use Friendica\Core\Config\Configuration;
use Friendica\Core\Hook;
use Friendica\Core\Theme;
use Friendica\Database\DBA;
use Friendica\Database\IDatabase;
use Friendica\Model\Profile;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Util\Config\ConfigFileLoader;
@ -235,7 +236,7 @@ class App
*
* @throws Exception if the Basepath is not usable
*/
public function __construct(Configuration $config, App\Mode $mode, App\Router $router, LoggerInterface $logger, Profiler $profiler, $isBackend = true)
public function __construct(Configuration $config, App\Mode $mode, App\Router $router, LoggerInterface $logger, Profiler $profiler, IDatabase $database, $isBackend = true)
{
BaseObject::setApp($this);

185
src/Database/IDatabase.php Normal file
View File

@ -0,0 +1,185 @@
<?php
namespace Friendica\Database;
interface IDatabase
{
/**
* Returns if the database is connected
* @return bool
*/
function isConnected();
/**
* Disconnects the current database connection
*/
function disconnect();
/**
* Perform a reconnect of an existing database connection
*/
function reconnect();
/**
* Return the database object.
* @return mixed
*/
function getConnection();
/**
* Returns the server version string
* @return string
*/
function serverInfo();
/**
* Returns the selected database name
* @return string
*/
function databaseName();
/**
* Check if data exists
*
* @param string $table The table name
* @param array $condition An array of fields for condition
*
* @return bool Are there rows for that condition?
*/
function exists($table, array $condition);
/**
* Counts the rows from a table satisfying the provided condition
*
* Example:
* $table = 'item';
*
* $condition = ['uid' => 1, 'network' => 'dspr'];
* or:
* $condition = ['`uid` = ? AND `network` IN (?, ?)', 1, 'dfrn', 'dspr'];
*
* $count = IDatabase->count($table, $condition);
*
* @param string $table The table name
* @param array $condition An array of fields for condition
*
* @return int The counted rows
*/
function count($table, array $condition = []);
/**
* Fetch a single row
* @param mixed $stmt A statement object
*
* @return array The current row
*/
function fetch($stmt);
/**
* Starts a transaction
*
* @return bool Was the command executed successfully?
*/
function transaction();
/**
* Does a commit
*
* @return bool Was the command executed successfully?
*/
function commit();
/**
* Does a rollback
*
* @return bool Was the command executed successfully?
*/
function rollback();
/**
* Insert a row into a table
*
* @param string $table The table name
* @param array $param An array of fields for inserting
* @param bool $on_duplicate_update Do an update on a duplicate entry
*
* @return bool Was the insert successful?
*/
function insert($table, array $param, $on_duplicate_update = false);
/**
* Delete a row from a table
*
* @param string $table The table name
* @param array $conditions An array of fields for condition
* @param bool $cascade If true we delete records in other tables that depend on the one we're deleting through
* relations (default: true)
*
* @return bool Was the delete successful?
*/
function delete($table, array $conditions, $cascade = false);
/**
* Updates rows in the database.
*
* When $old_fields is set to an array, the system will only do an update if the fields in that array changed.
*
* Attention:
* Only the values in $old_fields are compared. This is intentional behaviour.
*
* Example:
* We include the timestamp field in $fields but not in $old_fields.
* Then the row will only get the new timestamp when the other fields had changed.
*
* When $old_fields is set to a boolean value, the system will do this compare itself.
* When $old_fields is set to "true", the system will do an insert if the row doesn't exist.
*
* Attention:
* Only set $old_fields to a boolean value when you are sure that you will update a single row.
* When you set $old_fields to "true", then $fields must contain all relevant fields!
*
* @param string $table The table name
* @param array $fields An array of fields for updating
* @param array $condition An array of fields for condition
* @param array|bool $old_fields An array of old fields that are about to be replaced (true = update on duplicate)
*
* @return bool Was the update successful?
*/
function update($table, array $fields, array $condition, $old_fields = []);
/**
* Select rows from a table.
*
* Example:
* $table = "item";
* $fields = ['id', 'uri', 'uid', 'network'];
*
* $condition = ['uid' => 1, 'network' => 'dspr'];
* or:
* $condition = ['`uid` = ? AND `network` IN (?, ?)', 1, 'dfrn', 'dspr');
*
* $params = ['order' => ['id', 'received' => true), 'limit' => 10];
*
* $data = IDatabase->select($table, $fields, $condition, $params);
*
* @param string $table The table name
* @param array $fields An array of fields for selecting, empty for all
* @param array $condition An array of fields for condition
* @param array $params An array of fields of several parameters
*
* @return bool|object The result object or "false" if nothing was found.
*/
function select($table, array $fields = [], array $condition = [], array $params = []);
/**
* Retrieve a single record from a table and returns it in an associative array
*
* @param string $table The table name
* @param array $fields An array of fields for selecting, empty for all
* @param array $condition An array of fields for condition
* @param array $params An array of fields of several parameters
*
* @return bool|array The result array or "false" if nothing was found.
*/
function selectFirst($table, array $fields = [], array $condition = [], array $params = []);
}

View File

@ -0,0 +1,22 @@
<?php
namespace Friendica\Database;
interface IDatabaseLock
{
/**
* Locks a table for exclusive write access
*
* @param string $table The table name
*
* @return bool Was the lock successful?
*/
function lock($table);
/**
* Unlocks all locked tables
*
* @return bool Was the unlock successful?
*/
function unlock();
}

View File

@ -0,0 +1,112 @@
<?php
namespace Friendica\Database;
use Friendica\Core\Config\Cache\IConfigCache;
use Friendica\Util\Profiler;
class MysqlDatabase implements IDatabase, IDatabaseLock
{
private $connected;
public function __construct(IConfigCache $configCache, Profiler $profiler, $serveraddr, $user, $pass, $db, $charset = null)
{
$this->connected = DBA::connect($configCache, $profiler, $serveraddr, $user, $pass, $db, $charset);
}
function isConnected()
{
return $this->connected;
}
function disconnect()
{
DBA::disconnect();
}
function reconnect()
{
DBA::reconnect();
$this->connected = DBA::connected();
}
function getConnection()
{
return DBA::getConnection();
}
function serverInfo()
{
return DBA::serverInfo();
}
function databaseName()
{
return DBA::databaseName();
}
function exists($table, array $condition)
{
return DBA::exists($table, $condition);
}
function count($table, array $condition = [])
{
return DBA::count($table, $condition);
}
function fetch($stmt)
{
return DBA::fetch($stmt);
}
function transaction()
{
return DBA::transaction();
}
function commit()
{
return DBA::commit();
}
function rollback()
{
return DBA::rollback();
}
function insert($table, array $param, $on_duplicate_update = false)
{
return DBA::insert($table, $param, $on_duplicate_update);
}
function delete($table, array $conditions, $cascade = true)
{
return DBA::delete($table, $conditions, [$cascade]);
}
function update($table, array $fields, array $condition, array $old_fields = [])
{
return DBA::delete($table, $fields, $condition, $old_fields);
}
function select($table, array $fields = [], array $condition = [], array $params = [])
{
return DBA::select($table, $fields, $condition, $params);
}
function selectFirst($table, array $fields = [], array $condition = [], $params = [])
{
return DBA::selectFirst($table, $fields, $condition, $params);
}
function lock($table)
{
return DBA::lock($table);
}
function unlock()
{
return DBA::unlock();
}
}

View File

@ -16,16 +16,14 @@ class DBFactory
* @param Profiler $profiler The profiler
* @param array $server The $_SERVER variables
*
* @return Database\IDatabase
*
* @throws \Exception if connection went bad
*
* @todo refactor basedir during https://github.com/friendica/friendica/issues/6720
*/
public static function init($basePath, Cache\IConfigCache $configCache, Profiler $profiler, array $server)
{
if (Database\DBA::connected()) {
return;
}
$db_host = $configCache->get('database', 'hostname');
$db_user = $configCache->get('database', 'username');
$db_pass = $configCache->get('database', 'password');
@ -51,11 +49,15 @@ class DBFactory
$db_data = $server['MYSQL_DATABASE'];
}
if (Database\DBA::connect($basePath, $configCache, $profiler, $db_host, $db_user, $db_pass, $db_data, $charset)) {
$database = new Database\MysqlDatabase($basePath, $configCache, $profiler, $db_host, $db_user, $db_pass, $db_data, $charset);
if ($database->isConnected()) {
// Loads DB_UPDATE_VERSION constant
Database\DBStructure::definition($basePath, false);
}
unset($db_host, $db_user, $db_pass, $db_data, $charset);
return $database;
}
}

View File

@ -28,13 +28,13 @@ class DependencyFactory
$configLoader = new Config\ConfigFileLoader($basePath, $mode);
$configCache = Factory\ConfigFactory::createCache($configLoader);
$profiler = Factory\ProfilerFactory::create($configCache);
Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
$database = Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
$config = Factory\ConfigFactory::createConfig($configCache);
// needed to call PConfig::init()
Factory\ConfigFactory::createPConfig($configCache);
$logger = Factory\LoggerFactory::create($channel, $config, $profiler);
Factory\LoggerFactory::createDev($channel, $config, $profiler);
return new App($config, $mode, $router, $logger, $profiler, $isBackend);
return new App($config, $mode, $router, $logger, $profiler, $database, $isBackend);
}
}