Current Path : /var/www/html/clients/nkpgkx11.e-nk.ru/bitrix/modules/main/lib/db/ |
Current File : /var/www/html/clients/nkpgkx11.e-nk.ru/bitrix/modules/main/lib/db/dbconnection.php |
<?php namespace Bitrix\Main\DB; abstract class DbConnection extends \Bitrix\Main\Data\Connection { /**@var SqlHelper */ protected $sqlHelper; /** @var \Bitrix\Main\Diag\SqlTracker */ protected $sqlTracker; protected $trackSql = false; protected $version; protected $versionExpress; protected $dbHost; protected $dbName; protected $dbLogin; protected $dbPassword; protected $dbInitCommand = 0; protected $dbOptions = 0; protected $tableColumnsCache = array(); protected $lastQueryResult; const PERSISTENT = 1; const DEFERRED = 2; public function __construct($configuration) { parent::__construct($configuration); if (!is_string($configuration['database']) || $configuration['database'] == "") throw new \Bitrix\Main\Config\ConfigurationException("Empty database name"); if (!is_string($configuration['login']) || $configuration['login'] == "") throw new \Bitrix\Main\Config\ConfigurationException("Empty database user login"); $this->dbHost = $configuration['host']; $this->dbName = $configuration['database']; $this->dbLogin = $configuration['login']; $this->dbPassword = $configuration['password']; $this->dbInitCommand = $configuration['initCommand']; $this->dbOptions = intval($configuration['options']); if ($this->dbOptions < 0) $this->dbOptions = self::PERSISTENT | self::DEFERRED; } /********************************************************** * SqlHelper **********************************************************/ /** * @return SqlHelper */ public function getSqlHelper() { if ($this->sqlHelper == null) $this->sqlHelper = $this->createSqlHelper(); return $this->sqlHelper; } /** * @return SqlHelper */ abstract protected function createSqlHelper(); /*********************************************************** * Connection and disconnection ***********************************************************/ public function connect() { if (($this->dbOptions & self::DEFERRED) != 0) return; parent::connect(); } public function disconnect() { if (($this->dbOptions & self::PERSISTENT) != 0) return; parent::disconnect(); } /********************************************************* * Query *********************************************************/ abstract protected function queryInternal($sql, array $arBinds = null, $offset = 0, $limit = 0, \Bitrix\Main\Diag\SqlTrackerQuery $trackerQuery = null); /** * @param $result * @param \Bitrix\Main\Diag\SqlTrackerQuery $trackerQuery * @return DbResult */ abstract protected function createDbResult($result, \Bitrix\Main\Diag\SqlTrackerQuery $trackerQuery = null); /** * Executes a query to database * query($sql) * query($sql, $limit) * query($sql, $offset, $limit) * query($sql, $arBinds) * query($sql, $arBinds, $limit) * query($sql, $arBinds, $offset, $limit) * * @param string $sql Sql query * @param array $arBinds Array of binds * @param int $offset Offset * @param int $limit Limit * @return DbResult */ public function query($sql) { list($sql, $arBinds, $offset, $limit) = self::parseQueryFunctionArgs(func_get_args()); $trackerQuery = null; if ($this->trackSql) $trackerQuery = $this->sqlTracker->getNewTrackerQuery(); $result = $this->queryInternal($sql, $arBinds, $offset, $limit, $trackerQuery); return $this->createDbResult($result, $trackerQuery); } /** * Executes a query, fetches a row and returns single field value * * @param string $sql * @param array $arBinds * @return string|null */ public function queryScalar($sql, array $arBinds = null) { $trackerQuery = null; if ($this->trackSql) $trackerQuery = $this->sqlTracker->getNewTrackerQuery(); $result = $this->queryInternal($sql, $arBinds, 0, 1, $trackerQuery); $dbResult = $this->createDbResult($result, $trackerQuery); $return = null; if ($ar = $dbResult->fetch()) $return = array_shift($ar); return $return; } /** * Executes a query without returning result, i.e. INSERT, UPDATE, DELETE * * @param string $sql * @param array $arBinds */ public function queryExecute($sql, array $arBinds = null) { $trackerQuery = null; if ($this->trackSql) $trackerQuery = $this->sqlTracker->getNewTrackerQuery(); $this->queryInternal($sql, $arBinds, 0, 0, $trackerQuery); } protected static function parseQueryFunctionArgs($args) { /* * query($sql) * query($sql, $limit) * query($sql, $offset, $limit) * query($sql, $arBinds) * query($sql, $arBinds, $limit) * query($sql, $arBinds, $offset, $limit) */ $numArgs = count($args); if ($numArgs < 1) throw new \Bitrix\Main\ArgumentNullException("Empty sql statement", "sql"); $arBinds = array(); $offset = 0; $limit = 0; if ($numArgs == 1) { $sql = $args[0]; } elseif ($numArgs == 2) { if (is_array($args[1])) list($sql, $arBinds) = $args; else list($sql, $limit) = $args; } elseif ($numArgs == 3) { if (is_array($args[1])) list($sql, $arBinds, $limit) = $args; else list($sql, $offset, $limit) = $args; } else { list($sql, $arBinds, $offset, $limit) = $args; } return array($sql, $arBinds, $offset, $limit); } /** * Adds row to table and returns ID of added row * * @param string $tableName * @param array $data * @param string $identity For Oracle only * @return integer */ public function add($tableName, array $data, $identity = "ID") { $insert = $this->getSqlHelper()->prepareInsert($tableName, $data); $sql = "INSERT INTO ".$tableName."(".$insert[0].") ". "VALUES (".$insert[1].")"; $this->queryExecute($sql); return $this->getIdentity(); } abstract public function getIdentity($name = ""); public function executeSqlBatch($sqlBatch, $stopOnError = false) { $delimiter = $this->getSqlHelper()->getQueryDelimiter(); $sqlBatch = trim($sqlBatch); $arSqlBatch = array(); $sql = ""; do { if (preg_match("%^(.*?)(['\"`#]|--|".$delimiter.")%is", $sqlBatch, $match)) { //Found string start if ($match[2] == "\"" || $match[2] == "'" || $match[2] == "`") { $sqlBatch = substr($sqlBatch, strlen($match[0])); $sql .= $match[0]; //find a qoute not preceeded by \ if (preg_match("%^(.*?)(?<!\\\\)".$match[2]."%s", $sqlBatch, $string_match)) { $sqlBatch = substr($sqlBatch, strlen($string_match[0])); $sql .= $string_match[0]; } else { //String falled beyong end of file $sql .= $sqlBatch; $sqlBatch = ""; } } //Comment found elseif ($match[2] == "#" || $match[2] == "--") { //Take that was before comment as part of sql $sqlBatch = substr($sqlBatch, strlen($match[1])); $sql .= $match[1]; //And cut the rest $p = strpos($sqlBatch, "\n"); if ($p === false) { $p1 = strpos($sqlBatch, "\r"); if ($p1 === false) $sqlBatch = ""; elseif ($p < $p1) $sqlBatch = substr($sqlBatch, $p); else $sqlBatch = substr($sqlBatch, $p1); } else $sqlBatch = substr($sqlBatch, $p); } //Delimiter! else { //Take that was before delimiter as part of sql $sqlBatch = substr($sqlBatch, strlen($match[0])); $sql .= $match[1]; //Delimiter must be followed by whitespace if (preg_match("%^[\n\r\t ]%", $sqlBatch)) { $sql = trim($sql); if (!empty($sql)) { $arSqlBatch[] = str_replace("\r\n", "\n", $sql); $sql = ""; } } //It was not delimiter! elseif (!empty($sqlBatch)) { $sql .= $match[2]; } } } else //End of file is our delimiter { $sql .= $sqlBatch; $sqlBatch = ""; } } while (!empty($sqlBatch)); $sql = trim($sql); if (!empty($sql)) $arSqlBatch[] = str_replace("\r\n", "\n", $sql); $result = array(); foreach ($arSqlBatch as $sql) { try { $this->queryExecute($sql); } catch (SqlException $ex) { $result[] = $ex->getMessage(); if ($stopOnError) return $result[0]; } } return $result; } /** * Returns affected rows count from last executed query * * @return int */ abstract public function getAffectedRowsCount(); /********************************************************* * DDL *********************************************************/ abstract public function isTableExists($tableName); abstract public function isIndexExists($tableName, array $arColumns); abstract public function getIndexName($tableName, array $arColumns, $strict = false); abstract public function getTableFields($tableName); /********************************************************* * Transaction *********************************************************/ abstract public function startTransaction(); abstract public function commitTransaction(); abstract public function rollbackTransaction(); /********************************************************* * Tracker *********************************************************/ public function startTracker($reset = false) { if ($this->sqlTracker == null) $this->sqlTracker = new \Bitrix\Main\Diag\SqlTracker(); if ($reset) $this->sqlTracker->reset(); $this->trackSql = true; } public function stopTracker() { $this->trackSql = false; } public function getTracker() { return $this->sqlTracker; } /********************************************************* * Type, version, cache, etc. *********************************************************/ abstract public function getType(); abstract public function getVersion(); abstract protected function getErrorMessage(); public function clearCaches() { $this->tableColumnsCache = array(); } }