init
This commit is contained in:
		
							
								
								
									
										36
									
								
								ActiveRecord.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								ActiveRecord.php
									
									
									
									
									
										Normal file
									
								
							@@ -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()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								Command.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								Command.php
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								Connection.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								Connection.php
									
									
									
									
									
										Normal file
									
								
							@@ -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();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }*/
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										107
									
								
								Query.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								Query.php
									
									
									
									
									
										Normal file
									
								
							@@ -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();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							@@ -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\\": ""
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user