Работа с базами данных

Core Framework поддерживает работу с такими базами данных, как MySQL, Oracle, MSsql

Все обращения к базам идут через единый интерфейс, используя файл конфигурации.

При использовании SQL запросов - передача переменных происходит через BINDы. BINDы - это пользовательские переменные, которые могут отличаться при схожих запросах. И тем самым база данных не анализирует схожие запросы, а использует ранее закешированные результаты. Нативно Bindы поддерживает только Oracle, для других баз данных идет эмуляция.

Для Разработчиков использование биндов дает возможность простой защиты от SQL инъекций, а также позволяет в удобном виде передавать разнородные параметры, тем самым не вносится путаница даже при составлении самых больших запросов.

Все подключения к необходимым базам происходят в момент первого обращения. Разработчику не нужно думать о необходимости его осуществления

db

Произвольное подключение к базе

Все подключения к базам идут через ранее настроенную конфигурацию.

Вам не нужно думать о том, был ли осущестлен ранее коннект к конкретной базе, какого типа данная база. Программа сама следит за этим. Если все же помимо настроенной конфигурации вам нужно добавить или переопределить существующий коннектор - можете использовать функцию вида

c\db::setConnect($connect_name,$params);

Выполнить запрос и получить результат в виде полного массива

c\db::e($sql,$bind=array(),$db='');

EXECUTE

Выполняет запрос $sql с передачей массива $bind для базы данных $db

Биндовые переменные должны передаваться в запросе с : в начале, например :USR_ID

При этом в массиве $bind они должны передаваться без :, например $bind=array('USR_ID'=>100500)

Число аргументов $bind должно полностью совпадать с переменными в запросе для базы данных Oracle. Для других баз - аргументов может быть больше, они просто будут игнорироваться

Если не указать $db - для конкретного запроса будет использоваться соединение по-умолчанию, переданное ранее через c\core::$data['db']

 

Результат возвращается в виде двумерного массива с цифровыми и ассоциативными ключами

array(
	array(0=>'Данные колонки A 1й строки','A'=>'Данные колонки A 1й строки',1=>...),
	array(0=>'Данные колонки A 2й строки','A'=>'Данные колонки A 2й строки',1=>...),
	...
);

Данная функция используется в основном для запросов, не требующих ответа, таких, как Insert, Update, Merge.

 

EXECUTE REFERENCE

Выполнение запроса с указанием возвращаемой переменной по ссылке.

Бывают случаи, когда запрос помимо возврата самого результата - также меняет биндовые переменные. Например в Oracle можно получить ID следующей вставленной записи через SEQUENCE при помощи одного запроса

c\db::eRef($sql,$bind,$db);
// example
$bind=array('insert_id'='aaaaaaaaa','data'=>'data');
$sql="INSERT INTO table (ID,DATA) VALUES (SEQ.NEXTVAL,:data) RETURNING :insert_id"
c\db::e_ref($sql,$bind);
echo $bind['insert_id'];

EXECUTE_ASSOC

Полностью аналогичен c\db::e, за за исключением, что выводит результат только в виде ассоциативного массива.

c\db::ea($sql,$bind=array(),$db='');
array(
	array('A'=>'Данные колонки A 1й строки','B'=>...),
	array('A'=>'Данные колонки A 2й строки','B'=>...),
	...
);

Функция используется, чтобы доставать массивы для запросов типа Select, Show, т.к. ассоциативный массив сильно экономит память

 

c\db::ea1($sql,$bind=array(),$db='');

EXECUTE_ASSOC 1 String

Функция полностью аналогична c\db::ea, за исключением возврата одной первой строки в запросе.

array('A'=>'Данные колонки A 1й строки','B'=>...);

Функция облегчает сбор данных из запросов, и используется в запросах, где подразумевается возврат только одной строки, например при обращении по уникальному ключу

 

c\db::ea11($sql,$bind=array(),$db='');

Функция полностью аналогична c\db::ea1 за исключением возврата первого столбца первой колонки.

Если запрос вернет нулевой результат - ответ будет содержать false

Функция подходит для всех групповых запросов, подразумевающих вывод только одного значения

 

c\db::ec($sql,$bind=array(),$db='');

EXECUTE_COLUMN

Функция полностью аналогичная c\db::ea, за исключением вывода результата в виде одномерного массива из первой колонки

array('Данные колонки A 1й стоки','Данные колонки B 1й строки');

Функция применяется в основном для вывода одной колонки. Часто для distinct запросов

 

c\db::last($db='');

Функция возвращает последний вставленный ID последнего успешного запроса в рамках сессии.

 

c\db::rows($db='');

Функция возвращает число измененных строк в последнем запросе в рамках сессии.

Примеси

Для обеспечения одинаковой логики выполнения запросов во всех базах данных - были придуманы специальные примеси. Примеси встраиваются в часть SQL запроса, обеспечивая совместимость между разными базами данных. Примеси применяются внутри запросов, или путем полного преобразования переменной запроса.

Limit. Вывести n записей, начиная с m

c\db::limit($sql,$from=0,$count=0,$db='');

Функция преобразует $sql запрос таким образом, добавляя к нему ограничения по числу выводимых строк, аналогично limit в Mysql. Необходимость использования данной функции заключается в том, что синтаксис ограничение строк в каждой базе разный. С данной функцией разработчикам больше не придется задумываться о синтаксисе написания запросов

 Использование

$sql="SELECT * from USERS";
$sql=c\db::limit($sql,$page*20,$page);

Преобразование даты

Для убоства отображения формата даты при переводе из PHP в базу и обратно - используются функции - преобразователи. Для удобства - Функции используют формат даты, принятый в PHP.

c\db::dateFromDb($value,$format="d.m.Y H:i:s",$db='');
c\db::dateToDb($value,$format="d.m.Y H:i:s",$db='');

Использование

$sql="INSERT INTO DATAS (date_frield) values (".c\db::date_to_db(':bind_date','d.m.Y'.");
c\db::e($sql,array('bind_date'=>date('d.m.Y'));

$sql="SELECT ".c\db::date_from_db('date_field','d.m.Y')." FROM DATAS";
$db=c\db::ea($sql);

Произвольный перечисленный список IN

Для удобства составления запросов с биндами, чтобы обезопасить себя от прямых внесений данных в запрос - существует функция, которая через бинды добавляет произвольный список, который зависит от содержания массива. Обращение сразу наполняет переменную $bind, т.к. построение запроса сильно от нее зависит

c\db::in(&$bind,$value=array(),$variable=null);

Переменная variable - можно оставлять пустой, это лишь кодовое название бинда. Оно будет выбрано само и не отразиться на производительности

использование

$bind=array();
$values=array('val1','val2','val3');
$sql="SELECT * FROM USERS WHERE values in (".c\db::in($bind,$values).")";
$rs=c\db::ea($sql,$bind);

Автобинды

Добавление переменной bind во все последующие запросы на протяжении действия скрипта. Другими словами - вам больше не нужно помнить обозначение повторяющейся переменной, достаточно передать его лишь раз в автобинды.

Добавляется переменная при помощи ссылки на класс core на случай, если подключение к базе вовсе не понадобится первой строкой в скрипте выше.

Автобинды подставляются автоматически во все последующие запросы. При необходимости в конкретном запросе - автобинд можно перекрыть, если принудительно передать тот же параметр в переменной бинд.

2я строка из примера выводит полноценный итоговый $bind массив для запроса $sql и поданого на вход $bind массива.

Не забывайте описывать все случаи применения автобиндов в документации к проекту, чтобы не ввести никого в заблуждение.

c\core::$data['db_autobind']['bind']='value';
c\db::autobind($sql,$bind);

Альтернативные подключения

Если в параметре $db запросов передать массив - система автоматически будет выбирать из альтернативных наиболее предпочтительное подключение.

Такое вариант удобен для написания сервисов и моделей, которые могут использоваться в разных проектах. Например одни и те же данные можно достать используя несколько подключений, но в одном проекте основным является перое, а в другом - второе.

В случае использования альтернативных подключений - программа не будет создавать дополнительное подключение, в случае, когда его можно было бы не задействовать, тем самым экономя ресурсы системы.

c\db::ea1($sql,$bind,array('hr','bw'));

Гидратор. Обработать много данных

При использовании стандартных функций e, ea - программа пытается получить все данные, после чего возвращает массив целиком. Если данных становится слишком много - память выделенная на процесс кончается и возникает ошибка переполнения памяти. Чтобы ее избежать рекомендуется использовать получение данных через гидратор.

То есть данные будут получаться построчно. Получая строку - вы что-то с ней делаете, после чего забываете и получаете следующую строку. Таким образом память экономится очень хорошо. Такой прием применим, когда вам не нужно работать сразу со всем объемом. Например - можно построчно вывести на экран данные, или записать в файл.

Для использования гидратора нужны всего лишь 2 команды - query - подача запра и fa - fetch assoc - достать следующую строчку из запроса query

$fetch=c\db::query($sql,$bind);
while ( $row = c\db::fa($fetch)){
	// $row - одномерный массив каждой вызываемой строчки
}

Вставка/замена данных

c\db::setData($table,$array='',$sequence='',$db='',&$errors=true,$schema='');

Универсальная функция для вставки данных в таблицу

В качестве входных параметров передается

$table - название таблицы

$array - входной массив добавляемых данных

$sequence - имя сиквенса, встречается только в запросах к базе данных Oracle. Для других баз не имеет значение, чем будет заполнено поле

$errors - Выходной массив ошибок. Если не передать переменную - ошибки будут выведены в глобальный массив ошибок errors. При передаче - ошибки возвращаются в переменную

$schema - Название схемы базы данных для возможностей вставки данных в соседнюю схему (при наличии доступа)

Функция проводит вставку insert либо замену update данных в таблице $table в зависимости от совпадений primary key, введенных в $array

В ответ возвращается ID вставленной или редактируемой записи, либо false в случае неуспеха.

 

Для работы с динамическими данными - в функции предусмотрены ключевые слова.

{SYSDATE} - заменяется текущей датой и временем для колонок типа даты.

{+}прибавляет число к уже существующему значению колонки при UPDATE для колонок числового типа.

 

Если в наборе данных $array передается ключевое поле, значение которого уже существует в таблице - происходит UPDATE. Если ключевое поле не передается - функция пытается выполнить INSERT.

Перед выполнением операций - функция проверяет наличие всех необходимых полей для вставки. Если $sequence не передан, а таблица содержит поле с Autoincrement - программа автоматически подбирает следующий свободный ID

Функция работает совместно с классом c\error

При использовании - происходит автоматическая проверка значений длине и типу колонок. В случае несоответствия - функция генерит ошибку в буфер ошибок, или переменную $errors. При наличии ошибок в $errors - итоговый запрос не выполняется

Функция может быть применена к таблицам с любыми ключами. Проверки на уровне ограничений CONSTRAINS не работают.

Вставка множества данных

Вставка множества значений в базу данных методом аналогично SET_DATA

Используется в основном при массовой заливке данных

c\db::setMassData($tablename,$array_in,$parent_array_in,$clearbefore=true,$sequence='',$db='');

Где

$tablename - Имя таблицы

$array_in - входной двумерный массив данных

$parent_array_in - общий массив, который будет слит с каждым из данных входного массива. Перевес на стороне данных входного массива. Здесь могут быть обще параметры - Дата, ID ключевого поля другой таблицы, IP и т.д.

$clearbefore - нужно ли перед загрузкой очистить таблицу. Применяется, если вам надо полностью заменить ранние значения на новые. Записи удаляются по ключам в полях. Не рекомендуется использовать, рекомендуется предварительно самостоятельно очистить данные

$sequence - название сиксвенса в запросах Оракла

История изменений (Устарело, пользуйтесь datawork::difference)

Применяется, если вам нужно получить измененные данные в таблице для истории, а также для ведения логирования. Вы определяете состояние строки таблицы до изменения и после изменения. Всю разницу функция сформирует в один массив

c\dbwork::story($tablename,$keys,$listfields=false);

// example
c\dbwork::story('NEWS',array('ID'=>5);
$sql="UPDATE NEWS SET DATA=now() WHERE ID=5";
c\db::e($sql);
$diff=c\dbwork::story('NEWS',array('ID'=>5);
//result
/* $diff=array(
'DATA изменено с 10.05.2015 на 12.05.2015';
)
*/

Фильтр по диапазонам

Для возможности реализации полей ввода в виде диапазонов и помощи в преобразовании запросов.

Метод позволяет преобразовать введенные пользователем данные

1,3,5,7-10 в массив вида

ID IN (1,3,5) OR ID BETWEEN 7 AND 10

Только с использованием биндов.

c\db::filterDiap($string,$field,&$bind,$bind_prefix=null,$block_delimeter=',',$diap_pelimeter='-');
//example
$string='1,3,5,7-10';
$bind=array();
$where=c\db::filterDiap($string,'ID',$bind);
$sql="SELECT * FROM table WHERE ".$where;
$rs=c\db::ea($sql,$bind);

Создано при помощи сервиса Core CMS