PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/db/CDbConnection.php

https://bitbucket.org/stden/yiiru
PHP | 850 lines | 467 code | 24 blank | 359 comment | 23 complexity | b36d9972a462594ce8a22162a07f7106 MD5 | raw file
  1. <?php
  2. /**
  3. * Файл класса CDbConnection
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright Copyright &copy; 2008-2011 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * Класс CDbConnection представляет подключение БД.
  12. *
  13. * CDbConnection работает вместе с классами {@link CDbCommand}, {@link CDbDataReader}
  14. * и {@link CDbTransaction} для предоставления доступа к данным в разных СУБД с
  15. * использованием общего набора API. Это обертка для расширения PHP {@link http://www.php.net/manual/en/ref.pdo.php PDO}.
  16. *
  17. * Для установки соединения присвойте свойству {@link setActive active} значение true после
  18. * определения свойств {@link connectionString}, {@link username} и {@link password}.
  19. *
  20. * Следующий пример показывает, как создавать экземпляр соединения CDbConnection и устанавливать
  21. * реальное соединения с базой данных:
  22. * <pre>
  23. * $connection=new CDbConnection($dsn,$username,$password);
  24. * $connection->active=true;
  25. * </pre>
  26. *
  27. * После установки соединения БД можно выполнять SQL-выражения следующим образом:
  28. * <pre>
  29. * $command=$connection->createCommand($sqlStatement);
  30. * $command->execute(); // выполнение SQL-выражение без возврата данных (не запрос)
  31. * // выполнение SQL-запроса и получение результирующего набора
  32. * $reader=$command->query();
  33. *
  34. * // $row - это массив, представляющий строку данных
  35. * foreach($reader as $row) ...
  36. * </pre>
  37. *
  38. * Можно подготавливать SQL-выражения и связывать параметры с подготовленным SQL-выражением:
  39. * <pre>
  40. * $command=$connection->createCommand($sqlStatement);
  41. * $command->bindParam($name1,$value1);
  42. * $command->bindParam($name2,$value2);
  43. * $command->execute();
  44. * </pre>
  45. *
  46. * Для использования транзакций используется код, аналогичный следующему:
  47. * <pre>
  48. * $transaction=$connection->beginTransaction();
  49. * try
  50. * {
  51. * $connection->createCommand($sql1)->execute();
  52. * $connection->createCommand($sql2)->execute();
  53. * //.... выполнение других SQL-выражений
  54. * $transaction->commit();
  55. * }
  56. * catch(Exception $e)
  57. * {
  58. * $transaction->rollBack();
  59. * }
  60. * </pre>
  61. *
  62. * Класс CDbConnection также предоставляет набор методов для поддержки установки и запроса
  63. * некоторых атрибутов СУБД, таких как {@link getNullConversion nullConversion}.
  64. *
  65. * Т.к. CDbConnection реализует интерфейс IApplicationComponent, то его можно использовать
  66. * в качестве компонента приложения и настроить в конфигурации приложения как показано ниже:
  67. * <pre>
  68. * array(
  69. * 'components'=>array(
  70. * 'db'=>array(
  71. * 'class'=>'CDbConnection',
  72. * 'connectionString'=>'sqlite:path/to/dbfile',
  73. * ),
  74. * ),
  75. * )
  76. * </pre>
  77. *
  78. * @property boolean $active установлено ли соединение БД
  79. * @property PDO $pdoInstance экземпляр PDO-класса; null, если соединение еще
  80. * не установлено
  81. * @property CDbTransaction $currentTransaction текущая активная транзакция;
  82. * null, если активных транзакций нет
  83. * @property CDbSchema $schema схема БД для данного соединения
  84. * @property CDbCommandBuilder $commandBuilder построитель команд для данного
  85. * соединения
  86. * @property string $lastInsertID идентификатор последней вставленной строки
  87. * или последнего значения, полученного из объекта последовательности
  88. * @property mixed $columnCase регистр имен столбцов
  89. * @property mixed $nullConversion значение того, как конвертируются значения
  90. * null и пустые строки
  91. * @property boolean $autoCommit будут ли запросы на обновление и добавление
  92. * записей БД автоматически подтверждаться
  93. * @property boolean $persistent является ли соединение постоянным или нет
  94. * @property string $driverName имя драйвера БД
  95. * @property string $clientVersion информация о версии драйвера БД
  96. * @property string $connectionStatus статус соединения
  97. * @property boolean $prefetch выполняет ли соединение предварительную выборку
  98. * (prefetching) данных
  99. * @property string $serverInfo информация о сервере СУБД
  100. * @property string $serverVersion информация о версии сервера СУБД
  101. * @property integer $timeout настройки времени ожидания соединения
  102. * @property array $attributes атрибуты (в виде имя => значение), явно
  103. * установленные ранее для соединения БД
  104. * @property array $stats массив, первый элемент которого показывает количество
  105. * выполненных SQL-выражений, а второй - общее затраченное на выполнение
  106. * SQL-выражений время
  107. *
  108. * @author Qiang Xue <qiang.xue@gmail.com>
  109. * @version $Id: CDbConnection.php 3515 2011-12-28 12:29:24Z mdomba $
  110. * @package system.db
  111. * @since 1.0
  112. */
  113. class CDbConnection extends CApplicationComponent
  114. {
  115. /**
  116. * @var string источник данных (Data Source Name, DSN), содержит информацию, требуемую для подключения к БД.
  117. * @see http://www.php.net/manual/en/function.PDO-construct.php
  118. *
  119. * Примечание: если вы используете GBK или BIG5, то настоятельно рекомендуется обновить PHP
  120. * до версии, большей 5.3.6 и определять кодировку через DSN -
  121. * 'mysql:dbname=mydatabase;host=127.0.0.1;charset=GBK;'
  122. */
  123. public $connectionString;
  124. /**
  125. * @var string имя пользователя для установки соединения БД. По умолчанию - пустая строка
  126. */
  127. public $username='';
  128. /**
  129. * @var string пароль для установки соединения БД. По умолчанию - пустая строка
  130. */
  131. public $password='';
  132. /**
  133. * @var integer количество секунд, в течение которыхметаданные таблиц могут оставаться в кэше валидными.
  134. * Для индикации того, что кэширование схемы не используется, устанавливается значение 0 или отрицательное.
  135. * Если значение больше нуля и первичный кэш включен, то метаданные таблиц будут кэшироваться
  136. * @see schemaCachingExclude
  137. */
  138. public $schemaCachingDuration=0;
  139. /**
  140. * @var array список таблиц, метаданные которых НЕ должны кэшироваться. По умолчанию - пустой массив
  141. * @see schemaCachingDuration
  142. */
  143. public $schemaCachingExclude=array();
  144. /**
  145. * @var string идентификатор компонента приложения кэша, используемого для кэширования метаданных таблиц.
  146. * По умолчанию - 'cache' - основной компонент приложения кэша.
  147. * Для отключения кэширования метаданных таблиц необходимо установить данное свойство в значение false
  148. */
  149. public $schemaCacheID='cache';
  150. /**
  151. * @var integer количество секунд, в течение которых результат запроса в кэше остается валидным.
  152. * Для отключения кэширования необходимо установить значение, равным нулю или меньше нуля (поведение по умолчанию).
  153. *
  154. * Для включения кэширования данное свойство должно быть целым положительным числом и
  155. * свойство {@link queryCacheID} должно ссылаться на действительный компонент кэширования.
  156. *
  157. * Метод {@link cache()} предоставлен как простой способ установки данного свойства и
  158. * и свойства {@link queryCachingDependency} на лету
  159. *
  160. * @see cache
  161. * @see queryCachingDependency
  162. * @see queryCacheID
  163. * @since 1.1.7
  164. */
  165. public $queryCachingDuration=0;
  166. /**
  167. * @var CCacheDependency зависимость, используемая при сохранении результата запроса в кэш
  168. * @see queryCachingDuration
  169. * @since 1.1.7
  170. */
  171. public $queryCachingDependency;
  172. /**
  173. * @var integer количество SQL-выражений, которые должны быть кэшированы
  174. * в дальнейшем. Если значение равно 0, то даже если кэширование запросов
  175. * включено, запросы не будут кэшированы. Примечание: каждый раз после
  176. * выполнения SQL-выражения (выполняемом на сервере БД или запрошенном из
  177. * кэша запросов), данное свойство будет уменьшаться на единицу до нуля
  178. * @since 1.1.7
  179. */
  180. public $queryCachingCount=0;
  181. /**
  182. * @var string идентификатор компонента приложения кэша, используемый для
  183. * кэширования запросов. По умолчанию - 'cache' - основной компонент
  184. * приложения кэша. Для отключения кэширования запросов необходимо
  185. * установить данное свойство в значение false
  186. * @since 1.1.7
  187. */
  188. public $queryCacheID='cache';
  189. /**
  190. * @var boolean должно ли автоматически утанавливаться соединение при инициализации
  191. * компонента. По умолчанию - true. Примечание: свойство имеет значение только в случае,
  192. * когда объект класса CDbConnection используется в качестве компонента приложения
  193. */
  194. public $autoConnect=true;
  195. /**
  196. * @var string кодировка, используемая для соединения БД. Свойство
  197. * используется только для СУБД MySQL и PostgreSQL. По умолчанию - null,
  198. * т.е. используется кодировка, определенная в БД по умолчанию.
  199. *
  200. * Примечание: если используется GBK или BIG5, то настоятельно
  201. * рекомендуется обновить PHP до версии 5.3.6+ и установить кодировку через
  202. * DSN, например, так - 'mysql:dbname=mydatabase;host=127.0.0.1;charset=GBK;'
  203. */
  204. public $charset;
  205. /**
  206. * @var boolean включена ли эмуляция подготовки запроса. По умолчанию -
  207. * false, т.е. PDO будет использовать встроенную поддержку подготовки
  208. * запроса, если это возможно. Для некоторых СУБД (например, MySQL), может
  209. * понадобиться установить свойство в значение true, чтобы PDO мог
  210. * эмулировать поддержку подготовки запроса для обхода нестабильной
  211. * встроенной поддержки подготовки запроса. Примечание: свойство имеет
  212. * значение только для PHP версий 5.1.3 или выше. По умолчанию - null, т.е.
  213. * значение параметра ATTR_EMULATE_PREPARES расширения PDO не изменяется
  214. */
  215. public $emulatePrepare;
  216. /**
  217. * @var boolean журналировать ли значения, связываемые с подготовленным
  218. * SQL-выражением. По умолчанию - false. Во время разработки можно
  219. * установить значение true, чтобы журналировать значения параметров в
  220. * целях отладки. Нужно быть внимательным при установке данного свойства,
  221. * т.к. журналирование значений параметров может быть дорогим и оказывать
  222. * значительное влияние на производительность приложения
  223. */
  224. public $enableParamLogging=false;
  225. /**
  226. * @var boolean включено ли профилирование выполняемых SQL-выражений. По
  227. * умолчанию - false. В основном, профилирование включается во время
  228. * разработки для обнаружения узких мест в выполнении SQL-выражений
  229. */
  230. public $enableProfiling=false;
  231. /**
  232. * @var string префикс по умолчанию для имен таблиц. По умолчанию - null,
  233. * т.е. префикс не используется. При установке данного свойства, такая
  234. * метка как '{{tableName}}' в свойстве {@link CDbCommand::text} будет
  235. * заменена на строку 'prefixTableName', где 'prefix' - значение данного
  236. * свойства
  237. * @since 1.1.0
  238. */
  239. public $tablePrefix;
  240. /**
  241. * @var array список SQL-выражений, которые должны выполняться сразу после
  242. * установки соединения БД
  243. * @since 1.1.1
  244. */
  245. public $initSQLs;
  246. /**
  247. * @var array массив соответствий между PDO-драйверами и именами классов
  248. * схемы. Класс схемы БД может быть определен с использованием псевдонимов
  249. * путей
  250. * @since 1.1.6
  251. */
  252. public $driverMap=array(
  253. 'pgsql'=>'CPgsqlSchema', // PostgreSQL
  254. 'mysqli'=>'CMysqlSchema', // MySQL
  255. 'mysql'=>'CMysqlSchema', // MySQL
  256. 'sqlite'=>'CSqliteSchema', // sqlite 3
  257. 'sqlite2'=>'CSqliteSchema', // sqlite 2
  258. 'mssql'=>'CMssqlSchema', // Mssql driver on windows hosts
  259. 'dblib'=>'CMssqlSchema', // dblib drivers on linux (and maybe others os) hosts
  260. 'sqlsrv'=>'CMssqlSchema', // Mssql
  261. 'oci'=>'COciSchema', // Oracle driver
  262. );
  263. /**
  264. * @var string специальный класс-обертка PDO
  265. * @since 1.1.8
  266. */
  267. public $pdoClass = 'PDO';
  268. private $_attributes=array();
  269. private $_active=false;
  270. private $_pdo;
  271. private $_transaction;
  272. private $_schema;
  273. /**
  274. * Конструктор.
  275. * Примечание: соединение БД не устанавливается при создании экземпляра
  276. * соединения. Для установки соединения задайте свойству
  277. * {@link setActive active} значение true
  278. * @param string $dsn источник данных (The Data Source Name, DSN), содержит
  279. * информацию, требуемую для подключения к базе данных
  280. * @param string $username имя пользователя для строки DSN
  281. * @param string $password пароль для строки DSN
  282. * @see http://www.php.net/manual/en/function.PDO-construct.php
  283. */
  284. public function __construct($dsn='',$username='',$password='')
  285. {
  286. $this->connectionString=$dsn;
  287. $this->username=$username;
  288. $this->password=$password;
  289. }
  290. /**
  291. * Закрывать соединение при сериализации
  292. * @return array
  293. */
  294. public function __sleep()
  295. {
  296. $this->close();
  297. return array_keys(get_object_vars($this));
  298. }
  299. /**
  300. * Возвращает список доступных PDO-драйверов
  301. * @return array список доступных PDO-драйверов
  302. * @see http://www.php.net/manual/en/function.PDO-getAvailableDrivers.php
  303. */
  304. public static function getAvailableDrivers()
  305. {
  306. return PDO::getAvailableDrivers();
  307. }
  308. /**
  309. * Инициализирует компонент. Данный метод требуется интерфейсом
  310. * {@link IApplicationComponent} и вызывается приложением при использовании
  311. * CDbConnection в качестве компонента приложения. При переопределении
  312. * данного метода убедитесь, что вызывается родительская реализация, чтобы
  313. * компонент может быть отмечен как инициализированный
  314. */
  315. public function init()
  316. {
  317. parent::init();
  318. if($this->autoConnect)
  319. $this->setActive(true);
  320. }
  321. /**
  322. * Установлено ли соединение БД
  323. * @return boolean установлено ли соединение БД
  324. */
  325. public function getActive()
  326. {
  327. return $this->_active;
  328. }
  329. /**
  330. * Открывает или закрывает соединение БД
  331. * @param boolean $value открыто ли соединение БД
  332. * @throws CException вызывается, если попытка открытия соединение
  333. * завершилась с ошибкой
  334. */
  335. public function setActive($value)
  336. {
  337. if($value!=$this->_active)
  338. {
  339. if($value)
  340. $this->open();
  341. else
  342. $this->close();
  343. }
  344. }
  345. /**
  346. * Устанавливает параметры кэширования запросов. Метод может быть
  347. * использован для включения и отключения кэширования запросов. Установка
  348. * параметра $duration в значение 0 отключает кэширование запросов. В ином
  349. * случае результат запроса нового SQL-выражения, выполняемого далее, будет
  350. * сохранен в кэше и будет оставаться валидным в течение установленного
  351. * срока. При повторном выполнении запроса результат запроса может быть
  352. * получен непосредственно из кэша без реального выполнения SQL-выражения
  353. * @param integer $duration время в секундах, в течение которого результаты
  354. * запросов в кэше могут оставаться валидными. Если установлено в значение
  355. * 0, то кэширование запросов отключено
  356. * @param CCacheDependency $dependency зависимость, используемая при
  357. * сохранении результатов запросов в кэш
  358. * @param integer $queryCount количество SQL-запросов для кэширования после
  359. * выполнения данного метода. По умолчанию - 1, т.е. следующий запрос будет
  360. * кэширован
  361. * @return CDbConnection экземпляр соединения БД
  362. * @since 1.1.7
  363. */
  364. public function cache($duration, $dependency=null, $queryCount=1)
  365. {
  366. $this->queryCachingDuration=$duration;
  367. $this->queryCachingDependency=$dependency;
  368. $this->queryCachingCount=$queryCount;
  369. return $this;
  370. }
  371. /**
  372. * Открывает соединение БД, если оно еще не открыто
  373. * @throws CException вызывается, если попытка открытия соединение
  374. * завершилась с ошибкой
  375. */
  376. protected function open()
  377. {
  378. if($this->_pdo===null)
  379. {
  380. if(empty($this->connectionString))
  381. throw new CDbException(Yii::t('yii','CDbConnection.connectionString cannot be empty.'));
  382. try
  383. {
  384. Yii::trace('Opening DB connection','system.db.CDbConnection');
  385. $this->_pdo=$this->createPdoInstance();
  386. $this->initConnection($this->_pdo);
  387. $this->_active=true;
  388. }
  389. catch(PDOException $e)
  390. {
  391. if(YII_DEBUG)
  392. {
  393. throw new CDbException(Yii::t('yii','CDbConnection failed to open the DB connection: {error}',
  394. array('{error}'=>$e->getMessage())),(int)$e->getCode(),$e->errorInfo);
  395. }
  396. else
  397. {
  398. Yii::log($e->getMessage(),CLogger::LEVEL_ERROR,'exception.CDbException');
  399. throw new CDbException(Yii::t('yii','CDbConnection failed to open the DB connection.'),(int)$e->getCode(),$e->errorInfo);
  400. }
  401. }
  402. }
  403. }
  404. /**
  405. * Закрывает текущее активное соединение БД. Ничего не делает, если
  406. * соединение уже закрыто
  407. */
  408. protected function close()
  409. {
  410. Yii::trace('Closing DB connection','system.db.CDbConnection');
  411. $this->_pdo=null;
  412. $this->_active=false;
  413. $this->_schema=null;
  414. }
  415. /**
  416. * Создает экземпляр PDO-класса. Если в PDO-драйвере нет некоторого
  417. * функционала, можно использовать класс-адаптер для предоставления этого
  418. * функционала
  419. * @return PDO экземпляр PDO-класса
  420. */
  421. protected function createPdoInstance()
  422. {
  423. $pdoClass=$this->pdoClass;
  424. if(($pos=strpos($this->connectionString,':'))!==false)
  425. {
  426. $driver=strtolower(substr($this->connectionString,0,$pos));
  427. if($driver==='mssql' || $driver==='dblib' || $driver==='sqlsrv')
  428. $pdoClass='CMssqlPdoAdapter';
  429. }
  430. return new $pdoClass($this->connectionString,$this->username,
  431. $this->password,$this->_attributes);
  432. }
  433. /**
  434. * Инициализирует открытое соединение БД. Метод вызывает сразу после
  435. * установки соединения. Реализация по умолчанию устанавливает кодировку
  436. * для соединений баз MySQL и PostgreSQL
  437. * @param PDO $pdo экземпляр PDO-класса
  438. */
  439. protected function initConnection($pdo)
  440. {
  441. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  442. if($this->emulatePrepare!==null && constant('PDO::ATTR_EMULATE_PREPARES'))
  443. $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,$this->emulatePrepare);
  444. if($this->charset!==null)
  445. {
  446. $driver=strtolower($pdo->getAttribute(PDO::ATTR_DRIVER_NAME));
  447. if(in_array($driver,array('pgsql','mysql','mysqli')))
  448. $pdo->exec('SET NAMES '.$pdo->quote($this->charset));
  449. }
  450. if($this->initSQLs!==null)
  451. {
  452. foreach($this->initSQLs as $sql)
  453. $pdo->exec($sql);
  454. }
  455. }
  456. /**
  457. * Возвращает экземпляр PDO-класса
  458. * @return PDO экземпляр PDO-класса; null, если соединение еще не
  459. * установлено
  460. */
  461. public function getPdoInstance()
  462. {
  463. return $this->_pdo;
  464. }
  465. /**
  466. * Создает команду для выполнения
  467. * @param mixed $query выполняемый запрос. Может быть строкой,
  468. * представляющей SQL-выражение, или массивом, представляющим разные части
  469. * SQL-выражения. За подробностями о передаче массива в качестве параметра
  470. * обратитесь к описанию метода {@link CDbCommand::__construct}. Если
  471. * данный параметр не передан, необходимо будет вызвать методы создания
  472. * запросов класса {@link CDbCommand}
  473. * @return CDbCommand команда БД
  474. */
  475. public function createCommand($query=null)
  476. {
  477. $this->setActive(true);
  478. return new CDbCommand($this,$query);
  479. }
  480. /**
  481. * Возвращает текущую активную транзакцию
  482. * @return CDbTransaction текущая активная транзакция; null, если активных
  483. * транзакций нет
  484. */
  485. public function getCurrentTransaction()
  486. {
  487. if($this->_transaction!==null)
  488. {
  489. if($this->_transaction->getActive())
  490. return $this->_transaction;
  491. }
  492. return null;
  493. }
  494. /**
  495. * Начинает транзакцию
  496. * @return CDbTransaction инициированная транзакция
  497. */
  498. public function beginTransaction()
  499. {
  500. Yii::trace('Starting transaction','system.db.CDbConnection');
  501. $this->setActive(true);
  502. $this->_pdo->beginTransaction();
  503. return $this->_transaction=new CDbTransaction($this);
  504. }
  505. /**
  506. * Возвращает схему БД для данного соединения
  507. * @return CDbSchema схема БД для данного соединения
  508. */
  509. public function getSchema()
  510. {
  511. if($this->_schema!==null)
  512. return $this->_schema;
  513. else
  514. {
  515. $driver=$this->getDriverName();
  516. if(isset($this->driverMap[$driver]))
  517. return $this->_schema=Yii::createComponent($this->driverMap[$driver], $this);
  518. else
  519. throw new CDbException(Yii::t('yii','CDbConnection does not support reading schema for {driver} database.',
  520. array('{driver}'=>$driver)));
  521. }
  522. }
  523. /**
  524. * Возвращает построитель команд для данного соединения
  525. * @return CDbCommandBuilder построитель команд для данного соединения
  526. */
  527. public function getCommandBuilder()
  528. {
  529. return $this->getSchema()->getCommandBuilder();
  530. }
  531. /**
  532. * Возвращает идентификатор последней вставленной строки или значение
  533. * последовательности
  534. * @param string $sequenceName имя объекта последовательности (требуется
  535. * некоторыми СУБД)
  536. * @return string идентификатор последней вставленной строки или последнего
  537. * значения, полученного из объекта последовательности
  538. * @see http://www.php.net/manual/en/function.PDO-lastInsertId.php
  539. */
  540. public function getLastInsertID($sequenceName='')
  541. {
  542. $this->setActive(true);
  543. return $this->_pdo->lastInsertId($sequenceName);
  544. }
  545. /**
  546. * Заключает в кавычки значение строки для использования в запросе
  547. * @param string $str заключаемая в кавычки строка
  548. * @return string заключённая в кавычки строка
  549. * @see http://www.php.net/manual/en/function.PDO-quote.php
  550. */
  551. public function quoteValue($str)
  552. {
  553. if(is_int($str) || is_float($str))
  554. return $str;
  555. $this->setActive(true);
  556. if(($value=$this->_pdo->quote($str))!==false)
  557. return $value;
  558. else // the driver doesn't support quote (e.g. oci)
  559. return "'" . addcslashes(str_replace("'", "''", $str), "\000\n\r\\\032") . "'";
  560. }
  561. /**
  562. * Заключает в кавычки имя таблицы для использования в запросе. Если имя
  563. * таблицы содержит префикс схемы, то данный префикс также будет заключен в кавычки
  564. * @param string $name имя таблицы
  565. * @return string заключенное в кавычки имя таблицы
  566. */
  567. public function quoteTableName($name)
  568. {
  569. return $this->getSchema()->quoteTableName($name);
  570. }
  571. /**
  572. * Заключает в кавычки имя столбца для использования в запросе. Если имя
  573. * столбца содержит префикс , то данный префикс также будет заключен в кавычки
  574. * @param string $name имя столбца
  575. * @return string заключенное в кавычки имя столбца
  576. */
  577. public function quoteColumnName($name)
  578. {
  579. return $this->getSchema()->quoteColumnName($name);
  580. }
  581. /**
  582. * Определяет тип PDO по переданному типу PHP
  583. * @param string $type тип PHP (полученный вызывом функции gettype())
  584. * @return integer соответствующий тип PDO
  585. */
  586. public function getPdoType($type)
  587. {
  588. static $map=array
  589. (
  590. 'boolean'=>PDO::PARAM_BOOL,
  591. 'integer'=>PDO::PARAM_INT,
  592. 'string'=>PDO::PARAM_STR,
  593. 'NULL'=>PDO::PARAM_NULL,
  594. );
  595. return isset($map[$type]) ? $map[$type] : PDO::PARAM_STR;
  596. }
  597. /**
  598. * Возвращает регистр имен столбцов
  599. * @return mixed регистр имен столбцов
  600. * @see http://www.php.net/manual/en/pdo.setattribute.php
  601. */
  602. public function getColumnCase()
  603. {
  604. return $this->getAttribute(PDO::ATTR_CASE);
  605. }
  606. /**
  607. * Устанавливает регистр имен столбцов
  608. * @param mixed $value регистр имен столбцов
  609. * @see http://www.php.net/manual/en/pdo.setattribute.php
  610. */
  611. public function setColumnCase($value)
  612. {
  613. $this->setAttribute(PDO::ATTR_CASE,$value);
  614. }
  615. /**
  616. * Возвращает значение того, как конвертируются значения null и пустые строки
  617. * @return mixed значение того, как конвертируются значения null и пустые строки
  618. * @see http://www.php.net/manual/en/pdo.setattribute.php
  619. */
  620. public function getNullConversion()
  621. {
  622. return $this->getAttribute(PDO::ATTR_ORACLE_NULLS);
  623. }
  624. /**
  625. * Устанавливает значение того, как конвертируются значения null и пустые строки
  626. * @param mixed $value значение того, как конвертируются значения null и
  627. * пустые строки
  628. * @see http://www.php.net/manual/en/pdo.setattribute.php
  629. */
  630. public function setNullConversion($value)
  631. {
  632. $this->setAttribute(PDO::ATTR_ORACLE_NULLS,$value);
  633. }
  634. /**
  635. * Возвращает флаг, показывающий, будут ли запросы на обновление и
  636. * добавление записей БД автоматически подтверждаться. Некоторые СУБД
  637. * (например, sqlite) могут не поддерживать данную функцию
  638. * @return boolean будут ли запросы на обновление и добавление записей БД
  639. * автоматически подтверждаться
  640. */
  641. public function getAutoCommit()
  642. {
  643. return $this->getAttribute(PDO::ATTR_AUTOCOMMIT);
  644. }
  645. /**
  646. * Устанавливает флаг, показывающий, будут ли запросы на обновление и
  647. * добавление записей БД автоматически подтверждаться. Некоторые СУБД
  648. * (например, sqlite) могут не поддерживать данную функцию
  649. * @param boolean $value будут ли запросы на обновление и добавление
  650. * записей БД автоматически подтверждаться
  651. */
  652. public function setAutoCommit($value)
  653. {
  654. $this->setAttribute(PDO::ATTR_AUTOCOMMIT,$value);
  655. }
  656. /**
  657. * Возвращает флаг, показывающий, является ли соединение постоянным или
  658. * нет. Некоторые СУБД (например, sqlite) могут не поддерживать данную
  659. * функцию
  660. * @return boolean является ли соединение постоянным или нет
  661. */
  662. public function getPersistent()
  663. {
  664. return $this->getAttribute(PDO::ATTR_PERSISTENT);
  665. }
  666. /**
  667. * Устанавливает флаг, показывающий, является ли соединение постоянным или
  668. * нет. Некоторые СУБД (например, sqlite) могут не поддерживать данную
  669. * функцию
  670. * @param boolean $value является ли соединение постоянным или нет
  671. */
  672. public function setPersistent($value)
  673. {
  674. return $this->setAttribute(PDO::ATTR_PERSISTENT,$value);
  675. }
  676. /**
  677. * Возвращает имя драйвера БД
  678. * @return string имя драйвера БД
  679. */
  680. public function getDriverName()
  681. {
  682. if(($pos=strpos($this->connectionString, ':'))!==false)
  683. return strtolower(substr($this->connectionString, 0, $pos));
  684. // return $this->getAttribute(PDO::ATTR_DRIVER_NAME);
  685. }
  686. /**
  687. * Возвращает информацию о версии драйвера БД
  688. * @return string информация о версии драйвера БД
  689. */
  690. public function getClientVersion()
  691. {
  692. return $this->getAttribute(PDO::ATTR_CLIENT_VERSION);
  693. }
  694. /**
  695. * Возвращает статус соединения. Некоторые СУБД (например, sqlite) могут не
  696. * поддерживать данную функцию
  697. * @return string статус соединения
  698. */
  699. public function getConnectionStatus()
  700. {
  701. return $this->getAttribute(PDO::ATTR_CONNECTION_STATUS);
  702. }
  703. /**
  704. * Возвращает флаг, показывающий, выполняет ли соединение предварительную
  705. * выборку (prefetching) данных
  706. * @return boolean выполняет ли соединение предварительную выборку
  707. * (prefetching) данных
  708. */
  709. public function getPrefetch()
  710. {
  711. return $this->getAttribute(PDO::ATTR_PREFETCH);
  712. }
  713. /**
  714. * Возвращает информацию о сервере СУБД
  715. * @return string информация о сервере СУБД
  716. */
  717. public function getServerInfo()
  718. {
  719. return $this->getAttribute(PDO::ATTR_SERVER_INFO);
  720. }
  721. /**
  722. * Возвращает информацию о версии сервера СУБД
  723. * @return string информация о версии сервера СУБД
  724. */
  725. public function getServerVersion()
  726. {
  727. return $this->getAttribute(PDO::ATTR_SERVER_VERSION);
  728. }
  729. /**
  730. * Возвращает настройки времени ожидания соединения
  731. * @return integer настройки времени ожидания соединения
  732. */
  733. public function getTimeout()
  734. {
  735. return $this->getAttribute(PDO::ATTR_TIMEOUT);
  736. }
  737. /**
  738. * Получает информацию о определенном атрибуте соединения БД
  739. * @param integer $name запрашиваемый атрибут
  740. * @return mixed соответствующая информация атрибута
  741. * @see http://www.php.net/manual/en/function.PDO-getAttribute.php
  742. */
  743. public function getAttribute($name)
  744. {
  745. $this->setActive(true);
  746. return $this->_pdo->getAttribute($name);
  747. }
  748. /**
  749. * Устанавливает атрибут соединения БД
  750. * @param integer $name устанавливаемый атрибут
  751. * @param mixed $value значение атрибута
  752. * @see http://www.php.net/manual/en/function.PDO-setAttribute.php
  753. */
  754. public function setAttribute($name,$value)
  755. {
  756. if($this->_pdo instanceof PDO)
  757. $this->_pdo->setAttribute($name,$value);
  758. else
  759. $this->_attributes[$name]=$value;
  760. }
  761. /**
  762. * Возвращает атрибуты, явно установленные ранее для соединения БД
  763. * @return array атрибуты (в виед имя => значение), явно установленные
  764. * ранее для соединения БД
  765. * @see setAttributes
  766. * @since 1.1.7
  767. */
  768. public function getAttributes()
  769. {
  770. return $this->_attributes;
  771. }
  772. /**
  773. * Устанавливает набор атрибутов для соединения БД
  774. * @param array $values устанавливаемые атрибуты (имя => значение)
  775. * @see setAttribute
  776. * @since 1.1.7
  777. */
  778. public function setAttributes($values)
  779. {
  780. foreach($values as $name=>$value)
  781. $this->_attributes[$name]=$value;
  782. }
  783. /**
  784. * Возвращает статистическую информацию о выполнении SQL-выражений.
  785. * Возвращаемые результаты включают количество выполненных SQL-выражений и
  786. * общее затраченное на выполнение время. Для использования данного метода,
  787. * необходимо установить параметр {@link enableProfiling} в значение true
  788. * @return array массив, первый элемент которого показывает количество
  789. * выполненных SQL-выражений, а второй - общее затраченное на выполнение
  790. * SQL-выражений время
  791. */
  792. public function getStats()
  793. {
  794. $logger=Yii::getLogger();
  795. $timings=$logger->getProfilingResults(null,'system.db.CDbCommand.query');
  796. $count=count($timings);
  797. $time=array_sum($timings);
  798. $timings=$logger->getProfilingResults(null,'system.db.CDbCommand.execute');
  799. $count+=count($timings);
  800. $time+=array_sum($timings);
  801. return array($count,$time);
  802. }
  803. }