init
This commit is contained in:
commit
12b888a674
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace dominion\db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ActiveRecord extends \yii\db\ActiveRecord
|
||||||
|
{
|
||||||
|
protected static $tableSchemaCache = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* этот класс позволяет ускорить работу за счет хранения структуры бд
|
||||||
|
*/
|
||||||
|
public static function getTableSchema()
|
||||||
|
{
|
||||||
|
if(!isset(self::$tableSchemaCache[static::tableName()]))
|
||||||
|
{
|
||||||
|
self::$tableSchemaCache[static::tableName()] = parent::getTableSchema();
|
||||||
|
}
|
||||||
|
return self::$tableSchemaCache[static::tableName()];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* этот класс позволяет ускорить работу за счет отказа от получения списка атрибутов из схемы бд
|
||||||
|
* /
|
||||||
|
public function attributes()
|
||||||
|
{
|
||||||
|
return array_keys($this->attributeLabels());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace dominion\db;
|
||||||
|
|
||||||
|
use \Yii;
|
||||||
|
use \Exception;
|
||||||
|
use dominion\amqp\AmqpLoger;
|
||||||
|
/**
|
||||||
|
* Description of Command
|
||||||
|
*
|
||||||
|
* @author noname
|
||||||
|
*/
|
||||||
|
class Command extends \yii\db\Command
|
||||||
|
{
|
||||||
|
|
||||||
|
public function prepare($forRead = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
parent::prepare($forRead);
|
||||||
|
}
|
||||||
|
catch (Exception $ex)
|
||||||
|
{
|
||||||
|
if(isset($ex->errorInfo, $ex->errorInfo[1]) && $ex->errorInfo[1] >= 2000 && $ex->errorInfo[1] < 3000)
|
||||||
|
{
|
||||||
|
AmqpLoger::log('reconnectDB', $ex->errorInfo);
|
||||||
|
$this->db->close();
|
||||||
|
$this->db->open();
|
||||||
|
parent::prepare($forRead);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function internalExecute($rawSql)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
parent::internalExecute($rawSql);
|
||||||
|
}
|
||||||
|
catch (Exception $ex)
|
||||||
|
{
|
||||||
|
if(isset($ex->errorInfo, $ex->errorInfo[1]) && $ex->errorInfo[1] >= 2000 && $ex->errorInfo[1] < 3000)
|
||||||
|
{
|
||||||
|
AmqpLoger::log('reconnectDB', $ex->errorInfo);
|
||||||
|
$this->db->close();
|
||||||
|
$this->db->open();
|
||||||
|
$this->pdoStatement = $this->db->pdo->prepare($rawSql);
|
||||||
|
parent::internalExecute($rawSql);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace dominion\db;
|
||||||
|
use dominion\amqp\AmqpLoger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of Connection
|
||||||
|
*
|
||||||
|
* @author noname
|
||||||
|
*/
|
||||||
|
class Connection extends \yii\db\Connection
|
||||||
|
{
|
||||||
|
public $commandClass = 'dominion\db\Command';
|
||||||
|
|
||||||
|
public $commandMap = [
|
||||||
|
'pgsql' => 'dominion\db\Command', // PostgreSQL
|
||||||
|
'mysqli' => 'dominion\db\Command', // MySQL
|
||||||
|
'mysql' => 'dominion\db\Command', // MySQL
|
||||||
|
'sqlite' => 'yii\db\sqlite\Command', // sqlite 3
|
||||||
|
'sqlite2' => 'yii\db\sqlite\Command', // sqlite 2
|
||||||
|
'sqlsrv' => 'dominion\db\Command', // newer MSSQL driver on MS Windows hosts
|
||||||
|
'oci' => 'yii\db\oci\Command', // Oracle driver
|
||||||
|
'mssql' => 'dominion\db\Command', // older MSSQL driver on MS Windows hosts
|
||||||
|
'dblib' => 'dominion\db\Command', // dblib drivers on GNU/Linux (and maybe other OSes) hosts
|
||||||
|
'cubrid' => 'dominion\db\Command', // CUBRID
|
||||||
|
];
|
||||||
|
|
||||||
|
/* public function open()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return parent::open();
|
||||||
|
}
|
||||||
|
catch (\Exception $ex)
|
||||||
|
{
|
||||||
|
AmqpLoger::log('reconnectDB', $ex->errorInfo);
|
||||||
|
return parent::open();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace dominion\db;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обертка над стандартным классом \yii\db\Query
|
||||||
|
* Описывает общие методы для работы, которые могут понадобиться при запросах
|
||||||
|
*/
|
||||||
|
class Query extends \yii\db\Query
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Множественное обновление записей в таблице по первичному ключу id
|
||||||
|
* @param string $table Название таблицы бд
|
||||||
|
* @param array $data Массив данных для обновления
|
||||||
|
* Например:
|
||||||
|
* [
|
||||||
|
* 23 => ['name' => 'обновленное название 23', 'description' => 'обновленное описание 23'],
|
||||||
|
* 24 => ['name' => 'обновленное название 24', 'description' => 'обновленное описание 24'],
|
||||||
|
* ]
|
||||||
|
* Обновит поля name и description у полей с id=23 и id=24 одним запросом
|
||||||
|
* @return int Количество обновленных записей
|
||||||
|
*/
|
||||||
|
public function batchUpdate($table, $data)
|
||||||
|
{
|
||||||
|
$fields = [];
|
||||||
|
$columns = [];
|
||||||
|
$rows = [];
|
||||||
|
foreach ($data as $id => $values)
|
||||||
|
{
|
||||||
|
if (empty($columns))
|
||||||
|
{
|
||||||
|
$fields = array_keys($values);
|
||||||
|
$columns = array_merge(['id'], $fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = [$id];
|
||||||
|
foreach ($values as $value)
|
||||||
|
{
|
||||||
|
$row[] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = Yii::$app->db->getQueryBuilder()->batchInsert($table, $columns, $rows);
|
||||||
|
$update = [];
|
||||||
|
foreach ($fields as $field)
|
||||||
|
{
|
||||||
|
$field = Yii::$app->db->quoteColumnName($field);
|
||||||
|
$update[] = $field . ' = VALUES(' . $field . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($update))
|
||||||
|
{
|
||||||
|
$sql .= ' ON DUPLICATE KEY UPDATE ' . implode(',', $update);
|
||||||
|
}
|
||||||
|
\Yii::beginProfile('batchUpdate_' . $table);
|
||||||
|
$result = Yii::$app->db->createCommand($sql)->execute();
|
||||||
|
\Yii::endProfile('batchUpdate_' . $table);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Множественное добавление записей в таблицу
|
||||||
|
* @param string $table Название таблицы бд
|
||||||
|
* @param array $data Массив данных для добавления
|
||||||
|
* Например:
|
||||||
|
* [
|
||||||
|
* ['name' => 'Название 1', 'description' => 'Описание 1'],
|
||||||
|
* ['name' => 'Название 2', 'description' => 'Описание 2'],
|
||||||
|
* ]
|
||||||
|
* Добавит две записи с заполненными полями name и description одним запросом
|
||||||
|
* Если в массиве больще 5000 элементов, то будет несколько запросов с добавлением по 5000 элементов в одном запросе
|
||||||
|
*/
|
||||||
|
public function batchInsert($table, $data)
|
||||||
|
{
|
||||||
|
$columns = [];
|
||||||
|
$rows = [];
|
||||||
|
foreach ($data as $values)
|
||||||
|
{
|
||||||
|
if (empty($columns))
|
||||||
|
{
|
||||||
|
$columns = array_keys($values);
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = [];
|
||||||
|
foreach ($values as $value)
|
||||||
|
{
|
||||||
|
$row[] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$limit = 5000;
|
||||||
|
$count = (int) floor(count($rows) / $limit);
|
||||||
|
for ($i = 0; $i <= $count; $i++)
|
||||||
|
{
|
||||||
|
$partRows = array_slice($rows, $i * $limit, $limit);
|
||||||
|
Yii::$app->db->createCommand()->batchInsert($table, $columns, $partRows)->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "dominion/db",
|
||||||
|
"description": "Функционал для работы с db",
|
||||||
|
"type": "yii2-extension",
|
||||||
|
"keywords": ["yii2","extension"],
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Rybkin Sasha",
|
||||||
|
"email": "ribkin@dominion.ru"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"yiisoft/yii2": "~2.0.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"dominion\\db\\": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue