This commit is contained in:
2021-08-03 18:18:09 +08:00
parent 324db2fa3f
commit 5b28c52a10
43 changed files with 755 additions and 653 deletions
+1
View File
@@ -233,6 +233,7 @@ class ActiveRecord extends BaseActiveRecord
* @return bool
* @throws NotFindClassException
* @throws ReflectionException
* @throws Exception
*/
public static function updateAll(mixed $condition, array $attributes = []): bool
{
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace Database\Affair;
class BeginTransaction
{
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace Database\Affair;
use Exception;
class Commit
{
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace Database\Affair;
class Rollback
{
}
+17 -2
View File
@@ -15,6 +15,8 @@ use Annotation\Inject;
use ArrayAccess;
use Database\ActiveQuery;
use Database\ActiveRecord;
use Database\Affair\BeginTransaction;
use Database\Affair\Rollback;
use Database\Connection;
use Database\HasMany;
use Database\HasOne;
@@ -30,6 +32,7 @@ use Snowflake\Abstracts\Component;
use Snowflake\Abstracts\Config;
use Snowflake\Abstracts\TraitApplication;
use Snowflake\Application;
use Snowflake\Events\EventDispatch;
use Snowflake\Exception\ConfigException;
use Snowflake\Exception\NotFindClassException;
use Snowflake\Snowflake;
@@ -90,7 +93,7 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
protected array $actions = [];
/** @var string */
/** @var string */
private static string $connection = 'db';
@@ -115,6 +118,17 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
return Snowflake::app();
}
/**
* @param EventDispatch $eventDispatch
* @param array $config
* @throws Exception
*/
public function __construct(public EventDispatch $eventDispatch, array $config = [])
{
parent::__construct($config);
}
/**
* @param $data
* @return ActiveRecord
@@ -324,6 +338,7 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
return $first[$field];
}
/**
* @return ActiveQuery
*/
@@ -332,6 +347,7 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
return static::query();
}
/**
* @return ActiveQuery
*/
@@ -523,7 +539,6 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
return false;
}
if ($this->beforeSave($this)) {
static::getDb()->enablingTransactions();
[$change, $condition, $fields] = $this->filtration_and_separation();
if (!$this->isNewExample) {
return $this->updateInternal($fields, $condition, $change);
+4 -2
View File
@@ -133,9 +133,11 @@ class Command extends Component
$this->warning('Mysql:' . Json::encode([$this->sql, $this->params]) . (microtime(true) - $time));
}
$this->prepare?->closeCursor();
return $result;
} catch (\Throwable $exception) {
return $this->addError($this->sql . '. error: ' . $exception->getMessage(), 'mysql');
$result = $this->addError($this->sql . '. error: ' . $exception->getMessage(), 'mysql');
} finally {
$this->db->release();
return $result;
}
}
+39 -28
View File
@@ -11,14 +11,21 @@ declare(strict_types=1);
namespace Database;
use Annotation\Inject;
use Database\Affair\BeginTransaction;
use Database\Affair\Commit;
use Database\Affair\Rollback;
use Database\Mysql\Schema;
use Exception;
use JetBrains\PhpStorm\Pure;
use PDO;
use ReflectionException;
use Server\Events\OnWorkerExit;
use Server\Events\OnWorkerStop;
use Snowflake\Abstracts\Component;
use Snowflake\Abstracts\Config;
use Snowflake\Event;
use Snowflake\Events\EventProvider;
use Snowflake\Exception\NotFindClassException;
use Snowflake\Snowflake;
@@ -28,8 +35,6 @@ use Snowflake\Snowflake;
*/
class Connection extends Component
{
const TRANSACTION_COMMIT = 'transaction::commit';
const TRANSACTION_ROLLBACK = 'transaction::rollback';
public string $id = 'db';
public string $cds = '';
@@ -47,45 +52,46 @@ class Connection extends Component
* enable database cache
*/
public bool $enableCache = false;
/**
* @var string
*/
public string $cacheDriver = 'redis';
/**
* @var array
*
* @example [
* 'cds' => 'mysql:dbname=dbname;host=127.0.0.1',
* 'username' => 'root',
* 'password' => 'root'
* ]
*/
public array $slaveConfig = [];
private ?Schema $_schema = null;
/**
* @var Schema
*/
#[Inject(Schema::class)]
public Schema $_schema;
/**
* @throws Exception
* @var EventProvider
*/
#[Inject(EventProvider::class)]
public EventProvider $eventProvider;
/**
* execute by __construct
*/
public function init()
{
Event::on(Event::SYSTEM_RESOURCE_CLEAN, [$this, 'disconnect']);
Event::on(Event::SYSTEM_RESOURCE_RELEASES, [$this, 'clear_connection']);
$this->eventProvider->on(OnWorkerStop::class, [$this, 'clear_connection'], 0);
$this->eventProvider->on(OnWorkerExit::class, [$this, 'clear_connection'], 0);
$this->eventProvider->on(BeginTransaction::class, [$this, 'beginTransaction'], 0);
$this->eventProvider->on(Rollback::class, [$this, 'rollback'], 0);
$this->eventProvider->on(Commit::class, [$this, 'commit'], 0);
}
/**
* @throws Exception
*/
public function enablingTransactions()
{
if (!Db::transactionsActive()) {
return;
}
$this->beginTransaction();
Event::on(Connection::TRANSACTION_ROLLBACK, [$this, 'rollback'], [], true);
Event::on(Connection::TRANSACTION_COMMIT, [$this, 'commit'], [], true);
}
/**
* @param null $sql
* @return PDO
@@ -233,6 +239,7 @@ class Connection extends Component
public function rollback()
{
$this->connections()->rollback($this->cds);
$this->release();
}
/**
@@ -242,6 +249,7 @@ class Connection extends Component
public function commit()
{
$this->connections()->commit($this->cds);
$this->release();
}
/**
@@ -279,8 +287,11 @@ class Connection extends Component
*/
public function release()
{
if (!Snowflake::isWorker() && !Snowflake::isProcess()) {
$this->clear_connection();
return;
}
$connections = $this->connections();
$connections->release($this->cds, true);
$connections->release($this->slaveConfig['cds'], false);
}
@@ -306,8 +317,8 @@ class Connection extends Component
{
$connections = $this->connections();
$connections->release($this->cds, true);
$connections->release($this->slaveConfig['cds'], false);
$connections->disconnect($this->cds, true);
$connections->disconnect($this->slaveConfig['cds'], false);
}
+84 -81
View File
@@ -4,19 +4,15 @@ declare(strict_types=1);
namespace Database;
use Annotation\IAnnotation;
use Annotation\Inject;
use Exception;
use ReflectionException;
use Server\Constant;
use Server\Events\OnWorkerStart;
use Snowflake\Abstracts\Config;
use Snowflake\Abstracts\Providers;
use Snowflake\Application;
use Snowflake\Event;
use Snowflake\Exception\ComponentException;
use Snowflake\Events\EventProvider;
use Snowflake\Exception\ConfigException;
use Snowflake\Exception\NotFindClassException;
use Snowflake\Exception\NotFindPropertyException;
use Snowflake\Snowflake;
use Snowflake\Abstracts\Config;
/**
* Class DatabasesProviders
@@ -25,89 +21,96 @@ use Snowflake\Abstracts\Config;
class DatabasesProviders extends Providers
{
private array $_pooLength = ['min' => 0, 'max' => 1];
private array $_pooLength = ['min' => 0, 'max' => 1];
/**
* @param Application $application
* @throws Exception
*/
public function onImport(Application $application)
{
$application->set('db', $this);
$this->_pooLength = Config::get('databases.pool', ['min' => 0, 'max' => 1]);
Event::on(Event::SERVER_TASK_START, [$this, 'createPool']);
}
/**
* @var EventProvider
*/
#[Inject(EventProvider::class)]
public EventProvider $eventProvider;
/**
* @param $name
* @return Connection
* @throws ConfigException
* @throws Exception
*/
public function get($name): Connection
{
$application = Snowflake::app();
if (!$application->has('databases.' . $name)) {
$application->set('databases.' . $name, $this->_settings($this->getConfig($name)));
}
return $application->get('databases.' . $name);
}
/**
* @param Application $application
* @throws Exception
*/
public function onImport(Application $application)
{
$application->set('db', $this);
$this->_pooLength = Config::get('databases.pool', ['min' => 0, 'max' => 1]);
$this->eventProvider->on(OnWorkerStart::class, [$this, 'createPool']);
}
/**
* @throws ConfigException
* @throws Exception
*/
public function createPool()
{
$databases = Config::get('databases.connections', []);
if (empty($databases)) {
return;
}
$application = Snowflake::app();
foreach ($databases as $name => $database) {
/** @var Connection $connection */
$application->set('databases.' . $name, $this->_settings($database));
$application->get('databases.' . $name)->fill();
}
}
/**
* @param $name
* @return Connection
* @throws ConfigException
* @throws Exception
*/
public function get($name): Connection
{
$application = Snowflake::app();
if (!$application->has('databases.' . $name)) {
$application->set('databases.' . $name, $this->_settings($this->getConfig($name)));
}
return $application->get('databases.' . $name);
}
/**
* @param $database
* @return array
*/
private function _settings($database): array
{
return [
'class' => Connection::class,
'id' => $database['id'],
'cds' => $database['cds'],
'username' => $database['username'],
'password' => $database['password'],
'tablePrefix' => $database['tablePrefix'],
'database' => $database['database'],
'maxNumber' => $this->_pooLength['max'],
'minNumber' => $this->_pooLength['min'],
'charset' => $database['charset'] ?? 'utf8mb4',
'slaveConfig' => $database['slaveConfig']
];
}
/**
* @throws ConfigException
* @throws Exception
*/
public function createPool(OnWorkerStart $onWorkerStart)
{
$databases = Config::get('databases.connections', []);
if (empty($databases)) {
return;
}
$application = Snowflake::app();
foreach ($databases as $name => $database) {
/** @var Connection $connection */
$application->set('databases.' . $name, $this->_settings($database));
$application->get('databases.' . $name)->fill();
}
}
/**
* @param $name
* @return mixed
* @throws ConfigException
*/
public function getConfig($name): mixed
{
return Config::get('databases.connections.' . $name, null, true);
}
/**
* @param $database
* @return array
*/
private function _settings($database): array
{
return [
'class' => Connection::class,
'id' => $database['id'],
'cds' => $database['cds'],
'username' => $database['username'],
'password' => $database['password'],
'tablePrefix' => $database['tablePrefix'],
'database' => $database['database'],
'maxNumber' => $this->_pooLength['max'],
'minNumber' => $this->_pooLength['min'],
'charset' => $database['charset'] ?? 'utf8mb4',
'slaveConfig' => $database['slaveConfig']
];
}
/**
* @param $name
* @return mixed
* @throws ConfigException
*/
public function getConfig($name): mixed
{
return Config::get('databases.connections.' . $name, null, true);
}
}
+12 -9
View File
@@ -9,10 +9,13 @@ declare(strict_types=1);
namespace Database;
use Database\Affair\BeginTransaction;
use Database\Affair\Commit;
use Database\Affair\Rollback;
use Database\Traits\QueryTrait;
use Exception;
use Snowflake\Abstracts\Config;
use Snowflake\Event;
use Snowflake\Events\EventDispatch;
use Snowflake\Exception\ConfigException;
/**
@@ -39,19 +42,21 @@ class Db implements ISqlBuilder
*/
public static function beginTransaction()
{
if (!static::transactionsActive()) {
di(EventDispatch::class)->dispatch(new BeginTransaction());
}
static::$_inTransaction = true;
}
/**
* @throws Exception
*/
public static function commit()
{
if (!static::transactionsActive()) {
return;
if (static::transactionsActive()) {
di(EventDispatch::class)->dispatch(new Commit());
}
Event::trigger(Connection::TRANSACTION_COMMIT);
Event::offName(Connection::TRANSACTION_COMMIT);
static::$_inTransaction = false;
}
@@ -61,11 +66,9 @@ class Db implements ISqlBuilder
*/
public static function rollback()
{
if (!static::transactionsActive()) {
return;
if (static::transactionsActive()) {
di(EventDispatch::class)->dispatch(new Rollback());
}
Event::trigger(Connection::TRANSACTION_ROLLBACK);
Event::offName(Connection::TRANSACTION_ROLLBACK);
static::$_inTransaction = false;
}