Compare commits

...

18 Commits

Author SHA1 Message Date
as2252258 73cb94f657 改名 2021-07-09 14:38:49 +08:00
as2252258 b3ea8978b1 改名 2021-07-09 14:24:23 +08:00
as2252258 008a0914eb 改名 2021-07-09 13:55:52 +08:00
as2252258 01f8e16b38 改名 2021-07-09 13:41:06 +08:00
as2252258 c095b69f67 改名 2021-07-09 10:41:31 +08:00
as2252258 4c8c5ac239 改名 2021-07-09 10:36:45 +08:00
as2252258 cfc847133e 改名 2021-07-09 10:34:27 +08:00
as2252258 30b430f1cf 改名 2021-07-08 19:16:27 +08:00
as2252258 516c7612a5 改名 2021-07-08 18:02:21 +08:00
as2252258 3bb3d5a1d7 改名 2021-07-08 17:36:28 +08:00
as2252258 fb48a0b508 改名 2021-07-07 18:44:29 +08:00
as2252258 a3964faa72 改名 2021-07-07 18:39:03 +08:00
as2252258 0fea7ac770 改名 2021-07-07 18:37:43 +08:00
as2252258 7eccee5d16 改名 2021-07-07 18:36:20 +08:00
as2252258 565943b76f 改名 2021-07-07 17:51:02 +08:00
as2252258 adb95af124 改名 2021-07-07 14:11:17 +08:00
as2252258 b554b53cfd 改名 2021-07-07 14:07:27 +08:00
as2252258 0e0caaf8a9 改名 2021-07-07 14:04:05 +08:00
17 changed files with 1444 additions and 1354 deletions
+310 -290
View File
@@ -11,7 +11,6 @@ namespace Database;
use Database\Traits\QueryTrait; use Database\Traits\QueryTrait;
use Exception; use Exception;
use HttpServer\Http\Context;
use Snowflake\Event; use Snowflake\Event;
use Snowflake\Snowflake; use Snowflake\Snowflake;
@@ -21,309 +20,330 @@ use Snowflake\Snowflake;
*/ */
class Db implements ISqlBuilder class Db implements ISqlBuilder
{ {
use QueryTrait; use QueryTrait;
private static bool $_inTransaction = false; private static bool $_inTransaction = false;
/** /**
* @return bool * @return bool
*/ */
public static function transactionsActive(): bool public static function transactionsActive(): bool
{ {
return static::$_inTransaction === true; return static::$_inTransaction === true;
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public static function beginTransaction() public static function beginTransaction()
{ {
static::$_inTransaction = true; static::$_inTransaction = true;
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public static function commit() public static function commit()
{ {
if (!static::transactionsActive()) { if (!static::transactionsActive()) {
return; return;
} }
Event::trigger(Connection::TRANSACTION_COMMIT); Event::trigger(Connection::TRANSACTION_COMMIT);
Event::offName(Connection::TRANSACTION_COMMIT); Event::offName(Connection::TRANSACTION_COMMIT);
static::$_inTransaction = false; static::$_inTransaction = false;
} }
/** /**
* @throws Exception * @throws Exception
*/ */
public static function rollback() public static function rollback()
{ {
if (!static::transactionsActive()) { if (!static::transactionsActive()) {
return; return;
} }
Event::trigger(Connection::TRANSACTION_ROLLBACK); Event::trigger(Connection::TRANSACTION_ROLLBACK);
Event::offName(Connection::TRANSACTION_ROLLBACK); Event::offName(Connection::TRANSACTION_ROLLBACK);
static::$_inTransaction = false; static::$_inTransaction = false;
} }
/** /**
* @param $table * @param $table
* *
* @return static * @return static
*/ */
public static function table($table): Db|static public static function table($table): Db|static
{ {
$db = new Db(); $db = new Db();
$db->from($table); $db->from($table);
return $db; return $db;
} }
/** /**
* @param string $column * @param string $column
* @param string $alias * @param string $alias
* @return string * @return string
*/ */
public static function any_value(string $column, string $alias = ''): string public static function any_value(string $column, string $alias = ''): string
{ {
if (empty($alias)) { if (empty($alias)) {
$alias = $column . '_any_value'; $alias = $column . '_any_value';
} }
return 'ANY_VALUE(' . $column . ') as ' . $alias; return 'ANY_VALUE(' . $column . ') as ' . $alias;
} }
/**
* @param Connection|null $db
* @return mixed
* @throws Exception
*/
public function get(Connection $db = NULL): mixed
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand(SqlBuilder::builder($this)->one())
->all();
}
/**
* @param $column
* @return string
*/
public static function raw($column): string
{
return '`' . $column . '`';
}
/**
* @param Connection|null $db
* @return mixed
* @throws Exception
*/
public function find(Connection $db = NULL): mixed
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand(SqlBuilder::builder($this)->all())
->one();
}
/**
* @param Connection|NULL $db
* @return bool|int
* @throws Exception
*/
public function count(Connection $db = NULL): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand(SqlBuilder::builder($this)->count())
->exec();
}
/**
* @param Connection|NULL $db
* @return bool|int
* @throws Exception
*/
public function exists(Connection $db = NULL): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand(SqlBuilder::builder($this)->one())
->fetchColumn();
}
/**
* @param string $sql
* @param array $attributes
* @param Connection|null $db
* @return array|bool|int|string|null
* @throws Exception
*/
public static function findAllBySql(string $sql, array $attributes = [], Connection $db = NULL): int|bool|array|string|null
{
return $db->createCommand($sql, $attributes)->all();
}
/**
* @param string $sql
* @param array $attributes
* @param Connection|NULL $db
* @return array|mixed
* @throws Exception
*/
public static function findBySql(string $sql, array $attributes = [], Connection $db = NULL): mixed
{
return $db->createCommand($sql, $attributes)->one();
}
/**
* @param string $field
* @return array|null
* @throws Exception
*/
public function values(string $field): ?array
{
$data = $this->get();
if (empty($data) || empty($field)) {
return NULL;
}
$first = current($data);
if (!isset($first[$field])) {
return NULL;
}
return array_column($data, $field);
}
/**
* @param $field
* @return mixed
* @throws Exception
*/
public function value($field): mixed
{
$data = $this->find();
if (!empty($field) && isset($data[$field])) {
return $data[$field];
}
return $data;
}
/**
* @param null $db
* @return bool|int
* @throws Exception
*/
public function delete($db = null): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
$query = $db->getBuild()->builder($this);
return $db->createCommand($query)->delete();
}
/**
* @param $table
* @param null $db
* @return bool|int
* @throws Exception
*/
public static function drop($table, $db = null): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand('DROP TABLE ' . $table)->delete();
}
/**
* @param $table
* @param null $db
* @return bool|int
* @throws Exception
*/
public static function truncate($table, $db = null): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand('TRUNCATE ' . $table)->exec();
}
/**
* @param $table
* @param Connection|NULL $db
* @return mixed
* @throws Exception
*/
public static function showCreateSql($table, Connection $db = NULL): mixed
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
if (empty($table)) { /**
return null; * @param string $column
} * @return string
*/
return $db->createCommand('SHOW CREATE TABLE ' . $table)->one(); public static function increment(string $column): string
} {
return '+ ' . $column;
/** }
* @param $table
* @param Connection|NULL $db
* @return bool|int|null
* @throws Exception
*/
public static function desc($table, Connection $db = NULL): bool|int|null
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
if (empty($table)) {
return null;
}
return $db->createCommand('SHOW FULL FIELDS FROM ' . $table)->all();
}
/** /**
* @param string $table * @param string $column
* @param Connection|NULL $db * @return string
* @return mixed */
* @throws Exception public static function decrement(string $column): string
*/ {
public static function show(string $table, Connection $db = NULL): mixed return '- ' . $column;
{ }
if (empty($table)) {
return null;
}
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
$table = [' const TABLE = \'select * from %s where REFERENCED_TABLE_NAME=%s\';']; /**
* @param Connection|null $db
* @return mixed
* @throws Exception
*/
public function get(Connection $db = NULL): mixed
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand(SqlBuilder::builder($this)->one())
->all();
}
return $db->createCommand((new Query()) /**
->select('*') * @param $column
->from('INFORMATION_SCHEMA.KEY_COLUMN_USAGE') * @return string
->where(['REFERENCED_TABLE_NAME' => $table]) */
->getSql())->one(); public static function raw($column): string
} {
return '`' . $column . '`';
}
/**
* @param Connection|null $db
* @return mixed
* @throws Exception
*/
public function find(Connection $db = NULL): mixed
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand(SqlBuilder::builder($this)->all())
->one();
}
/**
* @param Connection|NULL $db
* @return bool|int
* @throws Exception
*/
public function count(Connection $db = NULL): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand(SqlBuilder::builder($this)->count())
->exec();
}
/**
* @param Connection|NULL $db
* @return bool|int
* @throws Exception
*/
public function exists(Connection $db = NULL): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand(SqlBuilder::builder($this)->one())
->fetchColumn();
}
/**
* @param string $sql
* @param array $attributes
* @param Connection|null $db
* @return array|bool|int|string|null
* @throws Exception
*/
public static function findAllBySql(string $sql, array $attributes = [], Connection $db = NULL): int|bool|array|string|null
{
return $db->createCommand($sql, $db?->database, $attributes)->all();
}
/**
* @param string $sql
* @param array $attributes
* @param Connection|NULL $db
* @return string|array|bool|int|null
* @throws Exception
*/
public static function findBySql(string $sql, array $attributes = [], Connection $db = NULL): string|array|bool|int|null
{
return $db->createCommand($sql, $db?->database, $attributes)->one();
}
/**
* @param string $field
* @return array|null
* @throws Exception
*/
public function values(string $field): ?array
{
$data = $this->get();
if (empty($data) || empty($field)) {
return NULL;
}
$first = current($data);
if (!isset($first[$field])) {
return NULL;
}
return array_column($data, $field);
}
/**
* @param $field
* @return mixed
* @throws Exception
*/
public function value($field): mixed
{
$data = $this->find();
if (!empty($field) && isset($data[$field])) {
return $data[$field];
}
return $data;
}
/**
* @param null $db
* @return bool|int
* @throws Exception
*/
public function delete($db = null): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
$query = $db->getBuild()->builder($this);
return $db->createCommand($query)->delete();
}
/**
* @param $table
* @param null $db
* @return bool|int
* @throws Exception
*/
public static function drop($table, $db = null): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand('DROP TABLE `' . $db->database . '`.' . $table)->delete();
}
/**
* @param $table
* @param null $db
* @return bool|int
* @throws Exception
*/
public static function truncate($table, $db = null): bool|int
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
return $db->createCommand('TRUNCATE `' . $db->database . '`.' . $table)->exec();
}
/**
* @param $table
* @param Connection|NULL $db
* @return mixed
* @throws Exception
*/
public static function showCreateSql($table, Connection $db = NULL): mixed
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
if (empty($table)) {
return null;
}
return $db->createCommand('SHOW CREATE TABLE `' . $db->database . '`.' . $table)->one();
}
/**
* @param $table
* @param Connection|NULL $db
* @return bool|int|null
* @throws Exception
*/
public static function desc($table, Connection $db = NULL): bool|int|null
{
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
if (empty($table)) {
return null;
}
return $db->createCommand('SHOW FULL FIELDS FROM `' . $db->database . '`.' . $table)->all();
}
/**
* @param string $table
* @param Connection|NULL $db
* @return mixed
* @throws Exception
*/
public static function show(string $table, Connection $db = NULL): mixed
{
if (empty($table)) {
return null;
}
if (empty($db)) {
$db = Snowflake::app()->get('db');
}
$table = [' const TABLE = \'select * from %s where REFERENCED_TABLE_NAME=%s\';'];
return $db->createCommand((new Query())
->select('*')
->from('INFORMATION_SCHEMA.KEY_COLUMN_USAGE')
->where(['REFERENCED_TABLE_NAME' => $table])
->getSql())->one();
}
} }
+16 -17
View File
@@ -52,19 +52,8 @@ class SqlBuilder extends Component
public function update(array $attributes): bool|array public function update(array $attributes): bool|array
{ {
[$string, $array] = $this->builderParams($attributes); [$string, $array] = $this->builderParams($attributes);
if (empty($string) || empty($array)) {
return $this->addError('None data update.');
}
$condition = $this->conditionToString(); return $this->__updateBuilder($string, $array);
if (!empty($condition)) {
$condition = ' WHERE ' . $condition;
}
$update = 'UPDATE ' . $this->tableName() . ' SET ' . implode(',', $string) . $condition;
$update .= $this->builderLimit($this->query);
return [$update, $array];
} }
@@ -76,12 +65,22 @@ class SqlBuilder extends Component
*/ */
public function mathematics(array $attributes, string $opera = '+'): bool|array public function mathematics(array $attributes, string $opera = '+'): bool|array
{ {
$string = $array = []; $string = [];
foreach ($attributes as $attribute => $value) { foreach ($attributes as $attribute => $value) {
$string[] = $attribute . '=' . $attribute . $opera . $value; $string[] = $attribute . '=' . $attribute . $opera . $value;
} }
return $this->__updateBuilder($string, []);
}
/**
* @param array $string
* @param array $params
* @return array|bool
* @throws Exception
*/
private function __updateBuilder(array $string, array $params): array|bool
{
if (empty($string)) { if (empty($string)) {
return $this->addError('None data update.'); return $this->addError('None data update.');
} }
@@ -92,9 +91,9 @@ class SqlBuilder extends Component
} }
$update = 'UPDATE ' . $this->tableName() . ' SET ' . implode(',', $string) . $condition; $update = 'UPDATE ' . $this->tableName() . ' SET ' . implode(',', $string) . $condition;
$update .= $this->builderLimit($this->query); $update .= $this->builderLimit($this->query, false);
return [$update, []]; return [$update, $params];
} }
@@ -185,7 +184,7 @@ class SqlBuilder extends Component
str_starts_with($value, '+ ') || str_starts_with($value, '+ ') ||
str_starts_with($value, '- ') str_starts_with($value, '- ')
) { ) {
$keys[] = $key . '=' . $key . $value; $keys[] = $key . '=' . $key . ' ' . $value;
} else { } else {
$params[$key . $order] = $value; $params[$key . $order] = $value;
$keys[] = $key . '=:' . $key . $order; $keys[] = $key . '=:' . $key . $order;
+3 -2
View File
@@ -104,14 +104,15 @@ trait Builder
/** /**
* @param ActiveQuery|Query $query * @param ActiveQuery|Query $query
* @param bool $hasLimit
* @return string * @return string
*/ */
#[Pure] private function builderLimit(ActiveQuery|Query $query): string #[Pure] private function builderLimit(ActiveQuery|Query $query, bool $hasLimit = true): string
{ {
if (!is_numeric($query->limit) || $query->limit < 1) { if (!is_numeric($query->limit) || $query->limit < 1) {
return ""; return "";
} }
if ($query->offset !== null) { if ($query->offset !== null && $hasLimit) {
return ' LIMIT ' . $query->offset . ',' . $query->limit; return ' LIMIT ' . $query->offset . ',' . $query->limit;
} }
return ' LIMIT ' . $query->limit; return ' LIMIT ' . $query->limit;
+3 -3
View File
@@ -12,9 +12,6 @@ namespace Gii;
use Database\Connection; use Database\Connection;
use Database\Db; use Database\Db;
use Exception; use Exception;
use JetBrains\PhpStorm\ArrayShape;
use Snowflake\Abstracts\Config;
use Snowflake\Abstracts\Input; use Snowflake\Abstracts\Input;
use Snowflake\Exception\ComponentException; use Snowflake\Exception\ComponentException;
use Snowflake\Exception\ConfigException; use Snowflake\Exception\ConfigException;
@@ -42,6 +39,9 @@ class Gii
public string $controllerNamespace = 'App\\Http\\Controllers\\'; public string $controllerNamespace = 'App\\Http\\Controllers\\';
public static array $createSqls = [];
public array $keyword = [ public array $keyword = [
'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'ASENSITIVE', 'BEFORE', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE', 'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'CONDITION', 'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATABASES', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'DUAL', 'EACH', 'ELSE', 'ELSEIF', 'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULLTEXT', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTERVAL', 'INTO', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LABEL', 'LEADING', 'LEAVE', 'LEFT', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'MODIFIES', 'NATURAL', 'NOT', 'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY', 'PROCEDURE', 'PURGE', 'RAID0', 'RANGE', 'READ', 'READS', 'REAL', 'REFERENCES', 'REGEXP', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SCHEMA', 'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR', 'SET', 'SHOW', 'SMALLINT', 'SPATIAL', 'SPECIFIC', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SSL', 'STARTING', 'STRAIGHT_JOIN', 'TABLE', 'TERMINATED', 'THEN', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO', 'TRAILING', 'TRIGGER', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE', 'USAGE', 'USE', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'X509', 'XOR', 'YEAR_MONTH', 'ZEROFILL' 'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'ASENSITIVE', 'BEFORE', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE', 'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'CONDITION', 'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATABASES', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'DUAL', 'EACH', 'ELSE', 'ELSEIF', 'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULLTEXT', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTERVAL', 'INTO', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LABEL', 'LEADING', 'LEAVE', 'LEFT', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'MODIFIES', 'NATURAL', 'NOT', 'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY', 'PROCEDURE', 'PURGE', 'RAID0', 'RANGE', 'READ', 'READS', 'REAL', 'REFERENCES', 'REGEXP', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SCHEMA', 'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR', 'SET', 'SHOW', 'SMALLINT', 'SPATIAL', 'SPECIFIC', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SSL', 'STARTING', 'STRAIGHT_JOIN', 'TABLE', 'TERMINATED', 'THEN', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO', 'TRAILING', 'TRIGGER', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE', 'USAGE', 'USE', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'X509', 'XOR', 'YEAR_MONTH', 'ZEROFILL'
]; ];
+20 -12
View File
@@ -22,12 +22,12 @@ class GiiModel extends GiiBase
public ?array $fields; public ?array $fields;
/** /**
* ModelFile constructor. * GiiModel constructor.
* @param $classFileName * @param string $classFileName
* @param $tableName * @param string $tableName
* @param $visible * @param array $visible
* @param $res * @param array $res
* @param $fields * @param array $fields
*/ */
public function __construct(string $classFileName, string $tableName, array $visible, array $res, array $fields) public function __construct(string $classFileName, string $tableName, array $visible, array $res, array $fields)
{ {
@@ -308,16 +308,20 @@ use Database\ActiveRecord;
if (empty($data)) return ''; if (empty($data)) return '';
$string = []; $string = [];
foreach ($data as $key => $_val) { foreach ($data as $key => $_val) {
if (is_string($key) && str_contains($key, ',')) { if (in_array($_val[0][1], $this->type['float'])) {
$key = '[' . $key . ']'; $e_x = explode(',', $key);
$key = '\'round\' => ' . $e_x[1] . ', \'maxLength\' => ' . ((int)$e_x[0] + 1);
} else if (is_string($key) && str_contains($key, ',')) {
$key = '\'between\' => [' . $key . ']';
} else {
$key = '\'maxLength\' => ' . $key;
} }
if (count($_val) == 1) { if (count($_val) == 1) {
[$typeRule, $type, $rule, $field] = current($_val);
$_tmp = ' $_tmp = '
[\'' . $field . '\', \'' . ($type == 'enum' ? 'enum' : 'maxLength') . '\' => ' . $key . ']'; [\'' . $_val[0][3] . '\', ' . ($_val[0][1] == 'enum' ? '\'enum\' => ' . $key : $key) . ']';
} else { } else {
$_tmp = ' $_tmp = '
[[\'' . implode('\', \'', array_column($_val, 3)) . '\'], \'maxLength\' => ' . $key . ']'; [[\'' . implode('\', \'', array_column($_val, 3)) . '\'], ' . $key . ']';
} }
$string[] = $_tmp; $string[] = $_tmp;
} }
@@ -412,6 +416,10 @@ use Database\ActiveRecord;
*/ */
private function setCreateSql($table): string private function setCreateSql($table): string
{ {
if (isset(Gii::$createSqls[$table])) {
return Gii::$createSqls[$table];
}
$text = Db::showCreateSql($table, $this->db)['Create Table'] ?? ''; $text = Db::showCreateSql($table, $this->db)['Create Table'] ?? '';
$_tmp = []; $_tmp = [];
@@ -419,7 +427,7 @@ use Database\ActiveRecord;
$_tmp[] = '// ' . $val; $_tmp[] = '// ' . $val;
} }
return implode(PHP_EOL, $_tmp); return Gii::$createSqls[$table] = implode(PHP_EOL, $_tmp);
} }
+1 -1
View File
@@ -22,7 +22,7 @@ abstract class HttpService extends Component
* @param string $category * @param string $category
* @throws Exception * @throws Exception
*/ */
protected function write($message, $category = 'app') protected function write($message, string $category = 'app')
{ {
$logger = Snowflake::app()->getLogger(); $logger = Snowflake::app()->getLogger();
$logger->write($message, $category); $logger->write($message, $category);
+2 -2
View File
@@ -150,12 +150,12 @@ class Response extends HttpService
} }
/** /**
* @param string|null $context * @param mixed $context
* @param int $statusCode * @param int $statusCode
* @return bool * @return bool
* @throws Exception * @throws Exception
*/ */
public function send(?string $context = '', int $statusCode = 200): mixed public function send(mixed $context = '', int $statusCode = 200): mixed
{ {
$sendData = $this->parseData($context); $sendData = $this->parseData($context);
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -35,7 +35,6 @@ use function Co\run;
* @package Snowflake * @package Snowflake
* *
* @property-read Config $config * @property-read Config $config
* @property-read WchatProviders $wchat
*/ */
class Application extends BaseApplication class Application extends BaseApplication
{ {
@@ -62,6 +61,9 @@ class Application extends BaseApplication
} }
/** /**
* @param Closure|array $closure * @param Closure|array $closure
* @return $this * @return $this
+23 -23
View File
@@ -39,7 +39,7 @@ class Logger extends Component
/** /**
* @param $message * @param mixed $message
* @param string $method * @param string $method
* @param null $file * @param null $file
* @throws Exception * @throws Exception
@@ -51,18 +51,18 @@ class Logger extends Component
/** /**
* @param $message * @param mixed $message
* @param string $method * @param string $method
* @throws Exception * @throws Exception
*/ */
public function trance($message, $method = 'app') public function trance(mixed $message, string $method = 'app')
{ {
$this->writer($message, $method); $this->writer($message, $method);
} }
/** /**
* @param $message * @param mixed $message
* @param string $method * @param string $method
* @param null $file * @param null $file
* @throws Exception * @throws Exception
@@ -72,13 +72,13 @@ class Logger extends Component
$this->writer($message, $method); $this->writer($message, $method);
} }
/** /**
* @param $message * @param mixed $message
* @param string $method * @param string $method
* @param null $file * @param null $file
* @throws Exception * @throws Exception
*/ */
public function success(mixed $message, $method = 'app', $file = null) public function success(mixed $message, string $method = 'app', $file = null)
{ {
$this->writer($message, $method); $this->writer($message, $method);
} }
@@ -89,7 +89,7 @@ class Logger extends Component
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
private function writer($message, $method = 'app'): string private function writer($message, string $method = 'app'): string
{ {
$this->print_r($message, $method); $this->print_r($message, $method);
if ($message instanceof Throwable) { if ($message instanceof Throwable) {
@@ -114,10 +114,10 @@ class Logger extends Component
/** /**
* @param $message * @param $message
* @param $method * @param string $method
* @throws Exception * @throws Exception
*/ */
public function print_r($message, $method = '') public function print_r($message, string $method = '')
{ {
$debug = Config::get('debug', ['enable' => false]); $debug = Config::get('debug', ['enable' => false]);
if ((bool)$debug['enable'] === true) { if ((bool)$debug['enable'] === true) {
@@ -145,7 +145,7 @@ class Logger extends Component
* @param string $application * @param string $application
* @return mixed * @return mixed
*/ */
public function getLastError($application = 'app'): mixed public function getLastError(string $application = 'app'): mixed
{ {
$filetype = []; $filetype = [];
foreach ($this->logs as $key => $val) { foreach ($this->logs as $key => $val) {
@@ -160,15 +160,15 @@ class Logger extends Component
return end($filetype); return end($filetype);
} }
/** /**
* @param $messages * @param string $messages
* @param string $method * @param string $method
* @throws * @throws Exception
*/ */
public function write(string $messages, $method = 'app') public function write(string $messages, string $method = 'app')
{ {
if (empty($messages)) { return;
return; if (empty($messages)) {
} }
$fileName = 'server-' . date('Y-m-d') . '.log'; $fileName = 'server-' . date('Y-m-d') . '.log';
+386 -366
View File
@@ -5,11 +5,12 @@ namespace Snowflake\Jwt;
use Exception; use Exception;
use HttpServer\Http\HttpHeaders; use HttpServer\Http\HttpHeaders;
use Snowflake\Cache\Redis; use Snowflake\Abstracts\Component;
use Snowflake\Abstracts\Config; use Snowflake\Abstracts\Config;
use Snowflake\Cache\Redis;
use Snowflake\Core\Json;
use Snowflake\Core\Str; use Snowflake\Core\Str;
use Snowflake\Exception\AuthException; use Snowflake\Exception\AuthException;
use Snowflake\Abstracts\Component;
use Snowflake\Exception\ConfigException; use Snowflake\Exception\ConfigException;
use Snowflake\Snowflake; use Snowflake\Snowflake;
@@ -21,20 +22,20 @@ use Snowflake\Snowflake;
class Jwt extends Component class Jwt extends Component
{ {
/** @var int $user */ /** @var int $user */
private int $user; private int $user;
private array $data; private array $data;
private array $source = ['browser', 'android', 'iphone', 'pc', 'mingame']; private array $source = ['browser', 'android', 'iphone', 'pc', 'mingame'];
private array $config = ['token' => '']; private array $config = ['token' => ''];
private ?int $timeout = 7200; private ?int $timeout = 7200;
private string $key = 'www.xshucai.com'; private string $key = 'www.xshucai.com';
private ?string $public = '-----BEGIN PUBLIC KEY----- private ?string $public = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6BuML3gtLGde7QKNuNST MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6BuML3gtLGde7QKNuNST
UCB9gdHC7XIpOc7Wx2I64Esj3UxWHTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6Xad UCB9gdHC7XIpOc7Wx2I64Esj3UxWHTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6Xad
jqfjEWpTy4WwGYsOfH0tFl3wAmse0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5t jqfjEWpTy4WwGYsOfH0tFl3wAmse0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5t
@@ -44,7 +45,7 @@ WlQhpQrA5/wKd76dCzjvqw9M32OiZl2lCKT73cV8GUvt7BNsM1SiPhqfY7nhO6y3
cwIDAQAB cwIDAQAB
-----END PUBLIC KEY-----'; -----END PUBLIC KEY-----';
private ?string $private = '-----BEGIN RSA PRIVATE KEY----- private ?string $private = '-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA6BuML3gtLGde7QKNuNSTUCB9gdHC7XIpOc7Wx2I64Esj3UxW MIIEpQIBAAKCAQEA6BuML3gtLGde7QKNuNSTUCB9gdHC7XIpOc7Wx2I64Esj3UxW
HTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6XadjqfjEWpTy4WwGYsOfH0tFl3wAmse HTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6XadjqfjEWpTy4WwGYsOfH0tFl3wAmse
0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5tWhTMEnpTFDYoDR0KXlLXltQMudBB 0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5tWhTMEnpTFDYoDR0KXlLXltQMudBB
@@ -73,419 +74,438 @@ mlAZUEjsoaT9vjvjGTxl3uCm0TX5KTgtSJIt2kA1tYVjQef+/iZTHxY=
-----END RSA PRIVATE KEY-----'; -----END RSA PRIVATE KEY-----';
/** /**
* @throws ConfigException * @throws ConfigException
*/ */
public function init() public function init()
{ {
if (!Config::has('ssl.public') || !Config::has('ssl.private')) { if (!Config::has('ssl.public') || !Config::has('ssl.private')) {
return; return;
} }
$this->public = Config::get('ssl.public', $this->public); $this->public = Config::get('ssl.public', $this->public);
$this->private = Config::get('ssl.private', $this->private); $this->private = Config::get('ssl.private', $this->private);
$this->timeout = Config::get('ssl.timeout', 7200); $this->timeout = Config::get('ssl.timeout', 7200);
} }
/** /**
* @param string $publicKey * @param string $publicKey
*/ */
public function setPublic(string $publicKey) public function setPublic(string $publicKey)
{ {
$this->public = $publicKey; $this->public = $publicKey;
} }
/** /**
* @param int $timeout * @param int $timeout
*/ */
public function setTimeout(int $timeout) public function setTimeout(int $timeout)
{ {
$this->timeout = $timeout; $this->timeout = $timeout;
} }
/** /**
* @param string $timeout * @param string $timeout
*/ */
public function setKey(string $timeout) public function setKey(string $timeout)
{ {
$this->key = $timeout; $this->key = $timeout;
} }
/** /**
* @param string $privateKey * @param string $privateKey
*/ */
public function setPrivate(string $privateKey) public function setPrivate(string $privateKey)
{ {
$this->private = $privateKey; $this->private = $privateKey;
} }
/** /**
* @param int $unionId * @param int $unionId
* @param array $headers * @param array $headers
* *
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function create(int $unionId, array $headers = []): array public function create(int $unionId, array $headers = []): array
{ {
$this->user = $unionId; $this->user = $unionId;
$this->config['time'] = time(); $this->config['time'] = time();
if (empty($headers)) { if (empty($headers)) {
$headers = request()->headers->getHeaders(); $headers = request()->headers->getHeaders();
} else if ($headers instanceof HttpHeaders) { } else if ($headers instanceof HttpHeaders) {
$headers = $headers->getHeaders(); $headers = $headers->getHeaders();
} }
$this->data = $headers; $this->data = $headers;
if (!isset($this->data['source'])) { if (!isset($this->data['source'])) {
$this->data['source'] = 'browser'; $this->data['source'] = 'browser';
} }
return $this->createEncrypt($unionId); return $this->createEncrypt($unionId);
} }
/** /**
* @param $unionId * @param $unionId
* @return array * @return array
* @throws Exception * @throws Exception
* 对相关信息进行加密 * 对相关信息进行加密
*/ */
private function createEncrypt($unionId): array private function createEncrypt($unionId): array
{ {
$caches = $this->clear($unionId); $caches = $this->clear($unionId);
$param = $this->assembly(array_merge($this->config, [ $param = $this->assembly(array_merge($this->config, [
'user' => $unionId, 'user' => $unionId,
'token' => $this->token($unionId, [ 'token' => $this->token($unionId, [
'device' => Str::rand(128), 'device' => Str::rand(128),
], $this->config['time']), ], $this->config['time']),
]), TRUE); ]), TRUE);
$refresh = array_intersect_key($param, $this->config); $refresh = array_intersect_key($param, $this->config);
$params['user'] = $this->user; $params['user'] = $this->user;
$params['token'] = $refresh['token']; $params['token'] = $refresh['token'];
$json = json_encode($params, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE); $json = json_encode($params, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE);
openssl_private_encrypt($json, $encode, $this->private); openssl_private_encrypt($json, $encode, $this->private);
$refresh['refresh'] = base64_encode($encode); $refresh['refresh'] = base64_encode($encode);
$this->setRefresh($refresh['refresh']); $this->setRefresh($refresh['refresh']);
$redis = $this->getRedis(); $redis = $this->getRedis();
foreach ($caches as $cache) { foreach ($caches as $cache) {
$redis->del($cache); $redis->del($cache);
} }
return $refresh; return $refresh;
} }
/** /**
* @param bool $update * @param bool $update
* @param array $param * @param array $param
* @return array * @return array
* @throws * @throws
*/ */
private function assembly(array $param, bool $update = FALSE): array private function assembly(array $param, bool $update = FALSE): array
{ {
if (isset($param['sign'])) { if (isset($param['sign'])) {
unset($param['sign']); unset($param['sign']);
} }
$param = $this->initialize($param); $param = $this->initialize($param);
asort($param, SORT_STRING); asort($param, SORT_STRING);
$_tmp = []; $_tmp = [];
foreach ($param as $key => $val) { foreach ($param as $key => $val) {
$_tmp[] = trim($key) . '=>' . trim((string)$val); $_tmp[] = trim($key) . '=>' . trim((string)$val);
} }
$param['sign'] = md5(implode(':', $_tmp)); $param['sign'] = md5(implode(':', $_tmp));
if ($update) { if ($update) {
$this->setCache($param); $this->setCache($param);
} }
return $param; return $param;
} }
/** /**
* @param array $headers * @param array $headers
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function refresh(array $headers = []): array public function refresh(array $headers = []): array
{ {
$this->data = $headers; $this->data = $headers;
if (!openssl_public_decrypt(base64_decode($headers['refresh']), $data, $this->public)) { if (!openssl_public_decrypt(base64_decode($headers['refresh']), $data, $this->public)) {
throw new AuthException('信息解码失败.'); throw new AuthException('信息解码失败.');
} }
$this->user = $data['user']; $this->user = $data['user'];
if (!$this->getRedis()->exists('refresh:' . $this->user)) { if (!$this->getRedis()->exists('refresh:' . $this->user)) {
throw new AuthException('refresh data error.'); throw new AuthException('refresh data error.');
} }
$this->getRedis()->del('refresh:' . $this->user); $this->getRedis()->del('refresh:' . $this->user);
return $this->create($this->user, $headers);
}
/**
* @param array $headers
* @return mixed
* @throws AuthException
*/
public function getTokenUser(array $headers = []): int
{
$this->data = $headers;
if (!openssl_public_decrypt(base64_decode($headers['refresh']), $data, $this->public)) {
throw new AuthException('信息解码失败.');
}
$data = Json::decode($data, true);
return (int)$data['user'];
}
return $this->create($this->user, $headers);
}
/** /**
* @param array $param * @param array $param
* *
* @return array * @return array
*/ */
private function initialize(array $param): array private function initialize(array $param): array
{ {
$_param = [ $_param = [
'version' => '1', 'version' => '1',
'source' => $this->getSource(), 'source' => $this->getSource(),
]; ];
if (!isset($param['device'])) { if (!isset($param['device'])) {
$param['device'] = Str::rand(128); $param['device'] = Str::rand(128);
} }
return array_merge($_param, $param); return array_merge($_param, $param);
} }
/** /**
* @param array $data * @param array $data
* @throws Exception * @throws Exception
*/ */
private function setCache(array $data) private function setCache(array $data)
{ {
$redis = $this->getRedis(); $redis = $this->getRedis();
$redis->hMset($this->authKey($this->getSource(), $data['token']), $data); $redis->hMset($this->authKey($this->getSource(), $data['token']), $data);
$redis->expire($this->authKey($this->getSource(), $data['token']), $this->timeout); $redis->expire($this->authKey($this->getSource(), $data['token']), $this->timeout);
} }
/** /**
* @param string $refresh * @param string $refresh
* @throws Exception * @throws Exception
*/ */
private function setRefresh(string $refresh) private function setRefresh(string $refresh)
{ {
$redis = $this->getRedis(); $redis = $this->getRedis();
$redis->set('refresh:' . $this->user, $refresh); $redis->set('refresh:' . $this->user, $refresh);
$redis->expire('refresh:' . $this->user, $this->timeout); $redis->expire('refresh:' . $this->user, $this->timeout);
} }
/** /**
* @param string $_source * @param string $_source
* @param string $token * @param string $token
* *
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
private function authKey(string $_source, string $token): string private function authKey(string $_source, string $token): string
{ {
$source = $this->getSource(); $source = $this->getSource();
if (!empty($_source)) $source = $_source; if (!empty($_source)) $source = $_source;
return 'Tmp_Token:' . strtoupper($source) . ':' . $token; return 'Tmp_Token:' . strtoupper($source) . ':' . $token;
} }
/** /**
* @return string * @return string
*/ */
public function getSource(): string public function getSource(): string
{ {
return $this->data['source'] ?? 'browser'; return $this->data['source'] ?? 'browser';
} }
/** /**
* @param int $user * @param int $user
* @param array $param * @param array $param
* @param null $requestTime * @param null $requestTime
* *
* @return string * @return string
*/ */
private function token(int $user, array $param = [], $requestTime = NULL): string private function token(int $user, array $param = [], $requestTime = NULL): string
{ {
$str = ''; $str = '';
$user = (string)$user; $user = (string)$user;
$_user = str_split(md5($user . md5($user))); $_user = str_split(md5($user . md5($user)));
ksort($_user); ksort($_user);
foreach ($_user as $key => $val) { foreach ($_user as $key => $val) {
$str .= md5(sha1($key . $val . $this->key)); $str .= md5(sha1($key . $val . $this->key));
} }
foreach ($param as $key => $val) { foreach ($param as $key => $val) {
$str .= md5($str . sha1($key . md5($val))); $str .= md5($str . sha1($key . md5($val)));
} }
$str .= sha1(base64_encode((string)$requestTime)); $str .= sha1(base64_encode((string)$requestTime));
return $this->preg(md5($str . $user)); return $this->preg(md5($str . $user));
} }
/** /**
* @param string $str * @param string $str
* *
* @return array|string|null 将字符串替换成指定格式 * @return array|string|null 将字符串替换成指定格式
*/ */
private function preg(string $str): null|array|string private function preg(string $str): null|array|string
{ {
return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $str); return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $str);
} }
/** /**
* @param int $user * @param int $user
* @return string[] * @return string[]
* @throws Exception * @throws Exception
*/ */
public function clear(int $user): array public function clear(int $user): array
{ {
$this->user = $user; $this->user = $user;
$redis = $this->getRedis(); $redis = $this->getRedis();
if (is_bool($refresh = $redis->get('refresh:' . $this->user))) { if (is_bool($refresh = $redis->get('refresh:' . $this->user))) {
return []; return [];
}; };
openssl_public_decrypt(base64_decode($refresh), $info, $this->public); openssl_public_decrypt(base64_decode($refresh), $info, $this->public);
$_tmp = []; $_tmp = [];
if (!empty($info) && $json = json_decode($info, true)) { if (!empty($info) && $json = json_decode($info, true)) {
if (!isset($json['token'])) { if (!isset($json['token'])) {
return []; return [];
} }
foreach ($this->source as $value) { foreach ($this->source as $value) {
$_tmp[] = $this->authKey($value, $json['token']); $_tmp[] = $this->authKey($value, $json['token']);
} }
} }
return $_tmp; return $_tmp;
} }
/** /**
* @param array $data * @param array $data
* @param int $user * @param int $user
* @return bool * @return bool
* @throws AuthException|Exception * @throws AuthException|Exception
*/ */
public function check(array $data, int $user): bool public function check(array $data, int $user): bool
{ {
$this->data = $data; $this->data = $data;
$this->user = $user; $this->user = $user;
if (empty($this->user)) return FALSE; if (empty($this->user)) return FALSE;
$cache = $this->getUserModel(); $cache = $this->getUserModel();
if (empty($cache)) { if (empty($cache)) {
return FALSE; return FALSE;
} }
$merge = $this->assembly(array_merge($cache, [ $merge = $this->assembly(array_merge($cache, [
'token' => $data['token'], 'token' => $data['token'],
])); ]));
$check = array_diff_assoc($this->initialize($cache), $merge); $check = array_diff_assoc($this->initialize($cache), $merge);
return !((bool)count($check)); return !((bool)count($check));
} }
/** /**
* @return mixed * @return mixed
* @throws * @throws
*/ */
public function getCurrentOnlineUser(): int public function getCurrentOnlineUser(): int
{ {
$this->data = request()->headers->getHeaders(); $this->data = request()->headers->getHeaders();
return $this->loadByCache(); return $this->loadByCache();
} }
/** /**
* @param string $token * @param string $token
* @param string $source * @param string $source
* @return mixed * @return mixed
* @throws AuthException * @throws AuthException
*/ */
public function getOnlineUserByToken(string $token, string $source = 'BROWSER'): int public function getOnlineUserByToken(string $token, string $source = 'BROWSER'): int
{ {
$this->data['token'] = $token; $this->data['token'] = $token;
$this->data['source'] = $source; $this->data['source'] = $source;
return $this->loadByCache(); return $this->loadByCache();
} }
/** /**
* @return int * @return int
* @throws AuthException * @throws AuthException
* @throws Exception * @throws Exception
*/ */
private function loadByCache(): int private function loadByCache(): int
{ {
$model = $this->getUserModel(); $model = $this->getUserModel();
if (empty($model)) { if (empty($model)) {
return (int)$this->addError('授权信息已过期!'); return (int)$this->addError('授权信息已过期!');
} }
if (!isset($model['user'])) { if (!isset($model['user'])) {
return (int)$this->addError('授权信息错误!'); return (int)$this->addError('授权信息错误!');
} }
if (!$this->check($this->data, (int)$model['user'])) { if (!$this->check($this->data, (int)$model['user'])) {
return (int)$this->addError('授权信息不合法!'); return (int)$this->addError('授权信息不合法!');
} }
$this->expireRefresh(); $this->expireRefresh();
return (int)$model['user']; return (int)$model['user'];
} }
/** /**
* @param array $header * @param array $header
* @return mixed * @return mixed
* @throws AuthException * @throws AuthException
* @throws Exception * @throws Exception
*/ */
public static function checkAuth(array $header = []): mixed public static function checkAuth(array $header = []): mixed
{ {
$instance = Snowflake::app()->getJwt(); $instance = Snowflake::app()->getJwt();
if (empty($header)) { if (empty($header)) {
$header = request()->headers->getHeaders(); $header = request()->headers->getHeaders();
} }
$instance->data = $header; $instance->data = $header;
$model = $instance->getUserModel(); $model = $instance->getUserModel();
if (empty($model) || !isset($model['user'])) { if (empty($model) || !isset($model['user'])) {
return false; return false;
} }
if (!$instance->check($header, (int)$model['user'])) { if (!$instance->check($header, (int)$model['user'])) {
return false; return false;
} }
$instance->expireRefresh(); $instance->expireRefresh();
return $model['user']; return $model['user'];
} }
/** /**
* @param null $token * @param null $token
* @param null $source * @param null $source
* @throws Exception * @throws Exception
*/ */
public function expireRefresh($token = null, $source = null) public function expireRefresh($token = null, $source = null)
{ {
if (!empty($token)) { if (!empty($token)) {
$this->data['token'] = $token; $this->data['token'] = $token;
} }
if (!empty($source)) { if (!empty($source)) {
$this->data['source'] = $source; $this->data['source'] = $source;
} }
if (!isset($this->data['token'])) { if (!isset($this->data['token'])) {
return; return;
} }
$key = $this->authKey($this->getSource(), $this->data['token']); $key = $this->authKey($this->getSource(), $this->data['token']);
$this->getRedis()->expire($key, $this->timeout); $this->getRedis()->expire($key, $this->timeout);
} }
/** /**
* @return bool|array * @return bool|array
* @throws Exception * @throws Exception
*/ */
private function getUserModel(): bool|array private function getUserModel(): bool|array
{ {
if (!isset($this->data['token'])) { if (!isset($this->data['token'])) {
return $this->addError('暂无访问权限!'); return $this->addError('暂无访问权限!');
} }
$key = $this->authKey($this->getSource(), $this->data['token']); $key = $this->authKey($this->getSource(), $this->data['token']);
return $this->getRedis()->hGetAll($key); return $this->getRedis()->hGetAll($key);
} }
/** /**
* @return Redis|\Redis * @return Redis|\Redis
* @throws * @throws
*/ */
private function getRedis(): Redis|\Redis private function getRedis(): Redis|\Redis
{ {
return Snowflake::app()->getRedis(); return Snowflake::app()->getRedis();
} }
} }
+9 -1
View File
@@ -81,6 +81,11 @@ class ClientsPool extends Component
{ {
if (env('state') == 'exit') { if (env('state') == 'exit') {
Timer::clear($this->creates); Timer::clear($this->creates);
foreach (static::$_connections as $channel) {
$this->flush($channel, 0);
$channel->close();
}
static::$_connections = [];
$this->creates = -1; $this->creates = -1;
} else { } else {
$this->heartbeat_flush(); $this->heartbeat_flush();
@@ -131,7 +136,6 @@ class ClientsPool extends Component
public function flush($channel, $retain_number) public function flush($channel, $retain_number)
{ {
$this->pop($channel, $retain_number); $this->pop($channel, $retain_number);
static::$_connections = [];
} }
@@ -180,12 +184,16 @@ class ClientsPool extends Component
* @param $name * @param $name
* @return Channel * @return Channel
* @throws ConfigException * @throws ConfigException
* @throws Exception
*/ */
private function getChannel($name): Channel private function getChannel($name): Channel
{ {
if (!isset(static::$_connections[$name])) { if (!isset(static::$_connections[$name])) {
static::$_connections[$name] = new Channel(Config::get('databases.pool.max', 10)); static::$_connections[$name] = new Channel(Config::get('databases.pool.max', 10));
} }
if (static::$_connections[$name]->errCode == SWOOLE_CHANNEL_CLOSED){
throw new Exception('Channel is Close.');
}
if ($this->creates === -1) { if ($this->creates === -1) {
$this->creates = Timer::tick(60000, [$this, 'Heartbeat_detection']); $this->creates = Timer::tick(60000, [$this, 'Heartbeat_detection']);
} }
+2 -2
View File
@@ -41,8 +41,8 @@ abstract class Process extends \Swoole\Process implements SProcess
putenv('environmental=' . Snowflake::PROCESS); putenv('environmental=' . Snowflake::PROCESS);
fire(Event::SERVER_WORKER_START); fire(Event::SERVER_WORKER_START);
if (Snowflake::getPlatform()->isLinux()) { if (Snowflake::getPlatform()->isLinux()) {
swoole_set_process_name($this->getProcessName()); name($this->pid, $this->getProcessName());
} }
if (method_exists($this, 'before')) { if (method_exists($this, 'before')) {
$this->before($process); $this->before($process);
+1 -1
View File
@@ -46,7 +46,7 @@ abstract class BaseValidator
* BaseValidator constructor. * BaseValidator constructor.
* @param array $config * @param array $config
*/ */
public function __construct($config = []) public function __construct(array $config = [])
{ {
$this->regConfig($config); $this->regConfig($config);
} }
+5 -8
View File
@@ -37,14 +37,11 @@ class LengthValidator extends BaseValidator
if (is_null($value)) { if (is_null($value)) {
return $this->addError('The param :attribute is null'); return $this->addError('The param :attribute is null');
} }
switch (strtolower($this->method)) { return match (strtolower($this->method)) {
case self::MAX_LENGTH: self::MAX_LENGTH => $this->maxLength($value),
return $this->maxLength($value); self::MIN_LENGTH => $this->minLength($value),
case self::MIN_LENGTH: default => $this->defaultLength($value),
return $this->minLength($value); };
default:
return $this->defaultLength($value);
}
} }
/** /**
+34
View File
@@ -0,0 +1,34 @@
<?php
namespace validator;
use Exception;
/**
* Class RoundValidator
* @package validator
*/
class RoundValidator extends BaseValidator
{
public ?int $value = null;
/**
* @return bool
* @throws Exception
*/
public function trigger(): bool
{
$value = $this->model->getAttribute($this->field);
if ($value == null || round($value, $this->value) != $value) {
return $this->addError('The param :attribute length error');
}
return true;
}
}
+3
View File
@@ -102,6 +102,9 @@ class Validator extends BaseValidator
'class' => 'validator\LengthValidator', 'class' => 'validator\LengthValidator',
'method' => 'default', 'method' => 'default',
], ],
'round' => [
'class' => 'validator\RoundValidator',
],
]; ];
/** /**