Source for file DBA.class.php
Documentation is available at DBA.class.php
* @copyright Energine 2006
//require_once('core/framework/SystemConfig.class.php');
* Database Abstraction Layer.
* @var PDO экземпляр класса PDO (PHP Data Objects)
* @var string последний запрос к БД
* @var mixed результат последнего запроса к БД
* Число с плавающей точкой
* Типы строк только для внутреннего использования. Без комментариев :)
* @param string $dsn Data Source Name для подключения к БД
* @param string $username имя пользователя
* @param string $password пароль
* @param array $driverOptions специфические параметры драйвера БД
public function __construct($dsn, $username, $password, array $driverOptions, $charset = 'utf8') {
$this->pdo = new PDO($dsn, $username, $password, $driverOptions);
catch (PDOException $e) {
$this->pdo->query('SET NAMES '. $charset);
* Выполняет SELECT-запрос к БД.
* Если количество аргументов метода больше 1, тогда $query трактуется
* как строка формата подобно функции printf, а дополнительные аргументы
* экранируются и помещаются на место меток (placeholder) строки $query.
* Возвращает в результате:
* rowID => array(fieldName => fieldValue, ...)
* если запрос исполнился успешно и вернул какие-либо строки;
* 2. true, если запрос исполнился успешно, но не вернул ни одной строки;
* 3. false, если при выполнении запроса произошла ошибка.
* @param string $query SELECT-запрос к БД
$res = $this->pdo->query($query);
if (!($res instanceof PDOStatement)) {
$errorInfo = $this->pdo->errorInfo();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
foreach ($row as $fieldName => $fieldValue) {
$fieldMeta = @$res->getColumnMeta($fieldNum);
if (isset ($fieldMeta['native_type'])) {
if ($fieldMeta['native_type'] == self::COLTYPE_DATETIME ||
$fieldMeta['native_type'] == self::COLTYPE_DATE) {
elseif (in_array($fieldMeta['native_type'], array(self::COLTYPE_STRING1, self::COLTYPE_STRING2))) {
if ($fieldMeta['len'] == 1) {
$fieldValue = (intval($fieldValue) == 0 ? false : true);
$result[$rowCount][$fieldName] = $fieldValue;
* Выполняет модифицирующую (INSERT, UPDATE, DELETE) операцию в БД.
* Если количество аргументов метода больше 1, тогда $query трактуется
* как строка формата подобно функции printf, а дополнительные аргументы
* экранируются и помещаются на место меток (placeholder) строки $query.
* Возвращает в результате:
* 1. Последний сгенерированный ID для поля типа AUTO_INCREMENT, или
* 2. true, если запрос выполнен успешно;
* 2. false, в случае неудачи.
$res = $this->pdo->query($query);
if (!($res instanceof PDOStatement)) {
$errorInfo = $this->pdo->errorInfo();
$result = intval($this->pdo->lastInsertId());
* Ставит кавычки вокруг входной строки (если необходимо) и экранирует
* специальные символы внутри входной строки.
public function quote($string) {
* Возвращает последний запрос к БД.
* Возвращает результат последнего запроса к БД.
* Возвращает последнюю ошибку
return $this->pdo->errorInfo();
* Выполняет (commit) транзакцию.
return $this->pdo->rollBack();
* Возвращает информацию о колонках таблицы $tableName в виде массива:
* 'nullable' => принимает ли значение NULL?,
* 'key' => описание ключа колонки (если есть),
* 'default' => значение по-умолчанию,
* @param string $tableName
* @staticvar $columnsInfo - кеш полей таблицы
if(!isset ($columnsInfo[$tableName])){
$nullable = (strtolower($row['Null']) == 'yes' ? true : false);
$default = (empty($row['Default']))? false: $row['Default'];
// получаем тип и размер поля
preg_match('/([A-Z]+)(\(([0-9]+)(,[0-9]+)?\))?/', $type, $matches);
if (count($matches) >= 2) {
if (isset ($matches[3])) {
$length = intval($matches[3]);
// получаем информацию о ключе поля
$key = ($fk == false ? true : $fk);
$columnsInfo[$tableName][$name] = compact('length', 'nullable', 'default', 'key', 'type' , 'tableName', 'index');
return $columnsInfo[$tableName];
* Возвращает информацию о внешнем ключе поля $fieldName таблицы $tableName
* 'tableName' => имя таблицы,
* 'fieldName' => имя поля
* или false, если $tableName.$fieldName не является первичным ключем.
* @param string $tableName имя таблицы
* @param string $fieldName имя поля
* @staticvar $foreignKeyInfo кеш результатов
if(!isset ($foreignKeyInfo[$tableName][$fieldName])){
$res = preg_match_all("/FOREIGN KEY \(`([_a-z0-9]+)`\) REFERENCES `([^`]+)` \(`([^`]+)`\)/m", $res[0]['Create Table'], $matches, PREG_SET_ORDER);
foreach($matches as $row){
$foreignKeyInfo[$tableName][$row[1]] = array('tableName' => $row[2], 'fieldName' => $row[3]);
if(!isset ($foreignKeyInfo[$tableName][$fieldName])){
$foreignKeyInfo[$tableName][$fieldName] = false;
return $foreignKeyInfo[$tableName][$fieldName];
* Конвертирует тип данных из описания БД (MySQL) в наш, системный тип.
* @param string $mysqlType
$result = self::COLTYPE_INTEGER;
$result = self::COLTYPE_FLOAT;
$result = self::COLTYPE_DATE;
$result = self::COLTYPE_TIME;
$result = self::COLTYPE_TIMESTAMP;
$result = self::COLTYPE_DATETIME;
$result = self::COLTYPE_STRING;
$result = self::COLTYPE_TEXT;
$result = self::COLTYPE_BLOB;
default: // не используется
* Возвращает для таблицы $tableName имя таблицы с переводами,
* если такая существует. В противном случае возвращает false.
* @param string $tableName
static $translationTables;
if(!isset ($translationTables[$tableName])){
$translationTableName = $tableName. '_translation';
$res = $this->selectRequest('SHOW TABLES LIKE \''. $translationTableName. '\'');
$translationTables[$tableName] = (empty($res) || $res === true) ? false : $translationTableName;
return $translationTables[$tableName];
* Формирует строку запроса к БД.
* @param array $args массив аргументов, переданных в методы selectRequest и modifyRequest
* @see DBA::selectRequest()
* @see DBA::modifyRequest()
$query = array_shift($args); // отбрасываем первый аргумент $query
foreach ($args as &$arg) {
|