GreenPig (далее GP) – это небольшая DAO библиотека для работы с базами данных Oracle или mySql.
Как и любой инструмент GP заточен под решение определенных задач. Он будет вам полезен, если вы предпочитаете писать запросы к БД на чистом sql и не используете Active record и прочие подобные технологии.
GP позволяет решать следующие задачи:
Вы можете установить GreenPig (далее именуемый GP) двумя способами:
Сначала необходимо настроить параметры соединения с БД в «единой точке входа» приложения
(в принципе можно настроить в любом месте). Настраивается с помощью функции
GP::config($settings)
. Если у вас одно соединение с БД, то достаточно просто
описать настройки подключений в массиве настроек:
GP::config([ // настройки подключения ]);
Данный набор настроек автоматически будет назван default
и получить объект
для работы с GP можно так: GP::instance()
(полный синтаксис: GP::instance('default')
).
Вся работа с БД осуществляется через объект, полученный с помощью функции GP::instance()
.
Можно настроить несколько подключений к разным БД. В таком случае необходимо написать ассоциативный
массив настроек, где ключами будут названия соединений. В таком случае необходимо явно указать ключ
default
, т.к. дефолтное соединения должно быть обязательно.
GP::config([ 'default' => [ /* настройки подключения */], 'oracle' => [ /* настройки подключения */], 'mysql' => [ /* настройки подключения */], ........ ]); $gp = GP::instance(); $gpOracle = GP::instance('oracle'); $gpMysql = GP::instance('mysql');
GP::config([ 'RDBMS' => 'Oracle', 'db' => [ 'username' => 'my_app', 'password' => 'secret', 'connection_string' => '8.8.8.8:3306/XE', 'character_set' => 'AL32UTF8', 'session_mode' => null, ], 'date' => [ 'php' => 'd.m.Y H:i:s', 'sql' => 'dd.mm.yyyy hh24:mi:ss' ], 'debugQuery' => 100 ]);
RDBMS
- название БД (может быть либо Oracle, либо MySQL).
db
- настройки подключения к БД. Для подключения к БД Oracle используется
oci_connect()
и все значения настройки, это параметры данной функции.
username
- Имя пользователя Oraclepassword
- Пароль usernameconnection_string
- Содержит экземпляр Oracle для подключения.character_set
- Определяет кодировку, используемую клиентскими библиотеками Oracle.session_mode
- Данный параметр можно не писать, он служит для настройки привилегированного соединенияdate
- Настройка формата даты для Where части запросов.
Данная настройка не обязательна, по умолчанию для Oracle значения выставляются так:
'date' => [ 'php' => 'd.m.Y H:i:s', 'sql' => 'dd.mm.yyyy hh24:mi:ss' ]
php
- формат даты для экземпляров рнр класса DateTime
.
Т.е. нам достаточно передать в where условие переменную, которая является экземпляром
класса DateTime
без дополнительных действий.
sql
- формат для преобразования в дату с помощью sql функции Oracle TO_DATE()
.
['date', '>', new DateTime()] // Преобразует в: // sql: date > TO_DATE(:greenpig_alias_where_1, 'dd.mm.yyyy hh24:mi:ss') // bind: ['greenpig_alias_where_1' => '31.05.2021 14:35:32']Подробнее в разделе Where.
debugQuery
- Настройка для дебага. Советуем не указывать эту настройку, оставить значения по умолчанию.GP::config([ 'RDBMS' => 'MySql', 'db' => [ 'dsn' => 'mysql:host=localhost;dbname=my_app;charset=utf8', 'username' => 'my_app', 'password' => 'secret', 'options' => null ], 'date' => [ 'php' => 'd.m.Y H:i:s', 'sql' => '%d.%m.%Y %H:%i:%s' ], 'debugQuery' => 100 ]);
RDBMS
- название БД (может быть либо Oracle, либо MySQL).
db
- настройки подключения к БД. Для подключения к БД MySQL используется
PDO::__construct()
и все значения настройки, это параметры данного конструктора.
dsn
- Имя источника данных или DSNusername
- Имя пользователя для строки DSNpassword
- Пароль для строки DSNoptions
- Данный параметр можно не писать, он служит для специфичных настроек подключения.date
- Настройка формата даты для Where части запросов.
Данная настройка не обязательна, по умолчанию для mySql значения выставляются так:
'date' => [ 'php' => 'd.m.Y H:i:s', 'sql' => '%d.%m.%Y %H:%i:%s' ]
php
- формат даты для экземпляров рнр класса DateTime
.
Т.е. нам достаточно передать в where условие переменную, которая является экземпляром
класса DateTime
без дополнительных действий.
sql
- формат для преобразования в дату с помощью sql функции mySql STR_TO_DATE()
.
['date', '>', new DateTime()] // Преобразует в: // sql: date > STR_TO_DATE(:greenpig_alias_where_1, '%d.%m.%Y %H:%i:%s') // bind: ['greenpig_alias_where_1' => '31.05.2021 14:35:32']Подробнее в разделе Where.
debugQuery
- Настройка для дебага. Советуем не указывать эту настройку, оставить значения по умолчанию.GP::config([ 'default' => [ 'RDBMS' => 'MySql', 'db' => [ 'dsn' => 'mysql:host=localhost;dbname=my_app;charset=utf8', 'username' => 'my_app', 'password' => 'secret', 'options' => null ] ], 'oracle' => [ 'RDBMS' => 'Oracle', 'db' => [ 'username' => 'my_app', 'password' => 'secret', 'connection_string' => '8.8.8.8:3306/XE', 'character_set' => 'AL32UTF8', 'session_mode' => null, ] ] ]); $gp = GP::instance(); $gpOracle = GP::instance('oracle');или
GP::config([ 'RDBMS' => 'MySql', 'db' => [ 'dsn' => 'mysql:host=localhost;dbname=my_app;charset=utf8', 'username' => 'my_app', 'password' => 'secret', 'options' => null ] ]); GP::config([ 'oracle' => [ 'RDBMS' => 'Oracle', 'db' => [ 'username' => 'my_app', 'password' => 'secret', 'connection_string' => '8.8.8.8:3306/XE', 'character_set' => 'AL32UTF8', 'session_mode' => null, ] ] ]); $gp = GP::instance(); $gpOracle = GP::instance('oracle');Дополнительные функции для работы с соединениями:
GP::getNamesActiveInstances()
- возвращает массив имен всех активных подключений к БД.
GP::disconnect($nameConnection)
- закрывает $nameConnection соединение
с БД. Возвращает true, если соединение с БД было открыто и оно успешно закрылось,
во всех остальных случаях - false. При этом настройки данного соединения остануться и
можно будет заново открыть соединение с помошью функции
GP::instance($nameConnection)
. Под копотом используется синглтон, так что с БД
всегда будет только одно соединение для конкретного $nameConnection.
GP::disconnectAll()
- закрывает все активные соединение с БД.
Возвращает количество закрытых соединений.
GP::clearConfig()
- закрывает все активные соединение с БД. Возвращает количество
закрытых соединений. При этом весь массив настроек так же очищается и теперь невозможно снова
открыть соединение с БД, необходимо будет сначала передать параметры подключения с
помощью функции GP::config($settings)
.
GP::configDate($formatDatePhp, $formatDateSql, $nameConnection = 'default')
- меняет формат
преобразования даты в конфиге для конкретного $nameConnection
.
GP::configDebugQuery($numberQuery, $nameConnection = 'default')
- указываем для
скольких запросов храним отладочную информацию (sql текст, бинды и время выполнения)
для конкретного $nameConnection
. Чтобы отключить сбор информации для отладки,
необходимо выставить значение 0.
подготовка запроса - Функции из данной группы должны предшествовать функциям из остальных групп, причем внутри зеленой группы порядок вызова функций не имеет значения.
получение данных - Функции в данной группе выполняют запрос на получение данных, подготовленный функциями зеленой группы.
результат запроса и/или его обработка - Функции в синей группе работают с данными, полученными из базы.
изменение данных - Функции из данной группы изменяют данные в базе.
Функция | Описание | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
sql($baseSQL, $binds = null) |
Задаем шаблон базового sql запроса. sql('SELECT * FROM dual')
Вторым необязательным параметром является массив биндов, эквивалентно функции
|
||||||||||||||||||||||||||
sqlPart($alias, $sql) |
Задаем часть sql запроса, которая будет вставлена в базовый запрос вместо $alias .
sqlPart('/*_select_*/', 'round(dbms_random.value(:a, :b)) as val')Пример: $x = $gp->sql('SELECT /*_select_*/ FROM dual') ->sqlPart('/*_select_*/', 'round(dbms_random.value(:a, :b)) as val') ->binds(['a'=>1, 'b'=>100]) ->first('val'); // В результате получим такой sql: // SELECT round(dbms_random.value(:a, :b)) as val FROM dual // В переменную $x записывается число, к примеру 67ВАЖНО: Вы должны задавать уникальные $alias .
Псевдонимы должны быть заключены в /* */ .
|
||||||||||||||||||||||||||
Бинды
ПРИМЕЧАНИЕ
Inout параметры работают только с Oracle.
ПРИМЕЧАНИЕ
Само имя вашего бинда не должно превышать 30 символов.
ПРИМЕЧАНИЕ
Если мы передали биндов больше, чем используем в нашем sql запросе, то PDO выдаст ошибку: "Invalid parameter number: number of bound variables does not match number of tokens". GP позволяет избежать этой ошибки и использует только актуальные бинды, но не стоит этим злоупотреблять. |
|||||||||||||||||||||||||||
binds($binds) |
Задаем массив биндов. Причем если вы до этого устанавливали бинды
с помощью функций Общий случай $gp->binds([ 'nameBind' => 123, ...... ]) Для Oracle $gp->binds([ 'nameBind1' => 123, 'nameBind2 [12]' => &$str, 'nameBind3 [int]' => 123, 'nameBind4 [int 11]' => &$val, 'nameBind5 [clob]' => &$bigText, 'nameBind6 [bool]' => true, 'nameBind7 [array(SQLT_INT)]' => $arr ]);
GreenPig для работы с Oracle использует библиотеку OCI8. Для
связывания биндов с sql используется функция
(документация):
oci_bind_by_name ( resource $statement , string $bv_name ,
mixed &$variable , int $maxlength = -1 , int $type = SQLT_CHR )
Поэтому ['nameBind [int 11]' => &$val] будет представлена как
oci_bind_by_name ($stmt , 'nameBind', $val , 11, OCI_B_INT)
Пример: // У нас есть переменная $bigTxt и нам надо записать ее в колонку типа clob, что-то с текстом // сделать и записать данные обратно в переменную (GreenPig позволяет сделать это очень просто). $bigTxt = 'bla bla bla'; print_r($bigTxt); // bla bla bla $gp = GP::instance(); $gp->sql("INSERT INTO TEST (big_text) VALUES (:big_txt) returning TO_CLOB('guf guf guf') into :big_txt") ->binds(['big_txt [clob]' => &$bigTxt]) ->execute(); print_r($bigTxt); // guf guf guf Для MySQL binds([ 'nameBind1' => $val, 'nameBind2 [int]' => 123, 'nameBind3 [bool]' => $val, 'nameBind4 [null]' => $val ])
GreenPig для работы с MySQL использует PDO. Для связывания биндов с sql используется функция (
документация):
bindParam(string|int $param, mixed &$var, int $type = PDO::PARAM_STR, int $maxLength = 0, mixed $driverOptions = null) Поэтому ['nameBind [int]' => $val] будет представлена как
$sth->bindParam(":nameBind", $val, PDO::PARAM_INT)
Не смотря на то, что в документации написано о возможности использовать inout переменные, на практике насколько я понял, такой возможности нет. Нашел разные примеры для других БД, например для Db2, а для MySQL на разных форумах пишут, что этот функционал не работает. Также в официальной документации библиотеки MySQLi написано, что inout параметров нет. Возможно PDO и MySQLi используют один и тот же драйвер (не удалось найти информацию). Как бы там ни было inout параметры использовать не получится. Можно применять решение, которое предлагают на форумах для PDO (и в официальной документации по MySQLi). $dbMySQL = GP::instance(); $dbMySQL->sql("set @number = 5")->execute(); // test_fun_inout(@var) - sql процедура, получает число @var прибовляет // к нему 10 и записывает результат в эту же переменную $dbMySQL->sql("call test_fun_inout(@number)")->execute(); $number = $dbMySQL->sql("select @number num")->first('num'); var_dump($number); // 15 |
||||||||||||||||||||||||||
addBinds($binds) |
К массиву биндов добавляем новый массив биндов.
addBinds([ 'name' => 'Вася', 'old' => $old, ..... ]) Причем можно добавлять и по ссылке (для inout параметров у Oracle): addBinds(['nameBind' => &$val]) |
||||||||||||||||||||||||||
bind($alias, $value) |
Добавляем одно значение в массив биндов, причем, если псевдоним не уникальный,
то произойдет перезапись значения.
bind('number', 123); bind('text_article', $txt); Использовать переменную по ссылке тут нельзя, но можно получить измененное значение с
помощью функции $qaz = -1; $gp->binds(['id' => 21, 'rating' => 20]) ->bind('qaz [13]', $qaz) ->sql("insert into table_name (id, rating) values (:id, :rating) returning 'xxx' into :qaz") ->execute(); print_r($qaz); // -1 print_r( $gp->getBind('qaz') ); // xxx |
||||||||||||||||||||||||||
linkBind($alias, &$value) |
Добавляем одно значение в массив биндов по ссылке
(причем, если псевдоним не уникальный, то произойдет перезапись значения).
$qaz = -1; $gp->binds(['id' => 21, 'rating' => 20]) ->linkBind('qaz [13]', $qaz) ->sql("insert into table_name (id, rating) values (:id, :rating) returning 'xxx' into :qaz") ->execute(); print_r($qaz); // xxx |
||||||||||||||||||||||||||
where($alias, $where, $beginKeyword = ‘where’) |
В базовом шаблоне вместо $alias подставляется sql, который генерируется
из массива $where (подробнее в разделе Where).
where('/*where*/', ['id', '=', 344]) $beginKeyword - ключевое слово, которое будет вставлено перед
сгенерированным sql. Может принимать значения: where, and, or
или пустоту .
$gp->sql("select * from product /*_whrere_*/") ->where('/*_whrere_*/', ['id', '=', 2]) ->all(); // Сгенерируется sql: select * from product where id = :greenpig_alias_where_1 $gp->sql("select * from product where id = 2 /*_whrere_*/") ->where('/*_whrere_*/', ['status', '=', 'delete'], 'and') ->all(); // Сгенерируется sql: select * from product where id = 2 and status = :greenpig_alias_where_1УПРОЩЕННАЯ ЗАПИСЬ Возможна упрощенная запись, когда вместо условия передается просто число, оно будет интерпретировано как id. where('/*wh*/', 2) // или where('/*wh*/', ['id', '=', 2]) // sql: where id = 2 Также можно передать простой массив (с числовыми индексами), значения которого обязательно должны быть целыми числами. В этом случае данный массив будет интерпретирован как набор id: where('/*wh*/', [4,8,16,32]) // или where('/*wh*/', ['id', 'in', [4,8,16,32]]) // sql: where id in (4,8,16,32) Упрощенная запись также поддерживается для where части функций
|
||||||||||||||||||||||||||
whereJoin($aliasJoin, $nameTable, $aliasTable, $conditionJoin, $aliasWhere, $where, $beginKeywordWhere = 'where') |
При запросе на выборку функция генерирует sql как для where
части, так и для join части. Подробно принцип работы функции описан
в пункте whereJoin().(подробнее на хабр) |
||||||||||||||||||||||||||
sort($nameColumn) |
$nameColumn может быть строкой, и тогда сортируем
только по одному указанному столбцу.
$gp->sql("select * from product")->sort('name')->all(); $gp->sql("select * from product")->sort('name desc')->all(); $nameColumn может быть массивом, и тогда сортируем по
нескольким столбцам.
$gp->sql("select * from product")->sort(['name desc', 'date'])->all(); // Формируется sql: select * from (select * from product) order by name desc, dateВАЖНО: указываем только название столбцов, без указания таблицы. ВАЖНО: в случае агрегированного запроса сортировка возможна только по верхнему уровню.
ПРИМЕЧАНИЕ
Ваш запрос оборачивается в следующий sql: |
||||||||||||||||||||||||||
pagination($currentPage, $numberRowOnPage) |
При выборке из БД получаем $numberRowOnPage записей, находящихся на
$currentPage странице.
$gp->sql("select * from product")->pagination(1, 10);ВАЖНО: пагинация с агрегированным запросом считает только верхние, самые основные данные. |
||||||||||||||||||||||||||
all($options = null, $isKeyPK = false) |
Возвращает все строки запроса.
// Возвращает все записи $gp->sql("select * from product")->all(); // Возвращает первые 10 записей $gp->sql("select * from product")->pagination(1, 10)->all();Если нужна агрегация, то $options должен быть массивом правил, которые
описывают как именно должна происходить группировка.
Массив $option строится по следующим правилам:
[ 'pk' => 'name_column_1', 'name_column_2', ...... 'courseworks' => [ 'pk' => 'name_column_n', 'name_column_n1' ] ] Если необходимо чтобы ключами массивов были значения первичных ключей из БД,
то параметру
$gp = GP::instance(); $gp->sql("SELECT s.id, s.name, c.id title_id, c.title FROM student s INNER JOIN coursework c ON c.student_id = s.id"); $studentsSimple = $gp->all(); // В обычном случае получим плоский результат: // [ // 0 => [ // 'id' => 3, // 'name' => 'Паша', // 'title_id' => 6, // 'title' => '«Азы» программирования и обучающие программы', // ], // 1=> [ // 'id' => 3, // 'name' => 'Паша', // 'title_id' => 7, // 'title' => 'История возникновения Интернет' // ] // ] $studentsTreeData = $gp->all(['pk' => 'id', 'name', 'courseworks' => ['pk' => 'title_id', 'title']]); // Получаем ответ с вложенными значениями: // [ // 0 => [ // 'id' => 3, // 'name' => 'Паша', // 'courseworks' => [ // 0 => ['title_id' => 6, 'title' => '«Азы» программирования и обучающие программы'], // 1 => ['title_id' => 7, 'title' => 'История возникновения Интернет'] // ] // ] // ] $studentsTreeDataPK = $gp->all(['pk' => 'id', 'name', 'courseworks' => ['pk' => 'title_id', 'title']], true); // Получаем ответ с вложенными значениями (ключи массива - значения первичного ключа): // [ // 3 => [ // 'id' => 3, // 'name' => 'Паша', // 'courseworks' => [ // 6 => ['title_id' => 6, 'title' => '«Азы» программирования и обучающие программы'], // 7 => ['title_id' => 7, 'title' => 'История возникновения Интернет'] // ] // ] // ]
ПРИМЕЧАНИЕ
В случае агрегации названия столбцов всегда будут в нижнем регистре, если
необходимо получить в верхнем - используйте функцию
ПРИМЕЧАНИЕ
Пагинация с агрегированным запросом считает только верхние, самые основные данные. В приведенном выше примере для пагинации будет только 1 строчка.
ПРИМЕЧАНИЕ
В случае пагинации с БД Oracle в выборку добавляется служебная колонка
ПРИМЕЧАНИЕ
В случае агрегированного запроса сортировка возможна только по верхнему уровню. Если мы хоти получить вложенный массив, где на верхнем уровне будут студенты, на втором уровне будут статусы курсовых работ для этих студентов, а на третьем уровне список названий курсовых, относящихся к данному статусу курсовых работ, то можно написать так: $gp = GP::instance(); $gp->sql("SELECT s.id, s.name, c.id title_id, c.title, c.status FROM student s INNER JOIN coursework c ON c.student_id = s.id) ->all([ 'pk' => 'id', 'name', 'courseworks' => [ 'pk' => 'status', 'titles' => [ 'pk' => 'title_id', 'title' ] ] ], true); // [ // 3 => [ // 'id' => 3, // 'name' => 'Паша', // 'courseworks' => [ // 'work' => [ // 'status' => 'work', // 'titles' => [ // 6 => ['title_id' => 6, 'title' => '«Азы» программирования и обучающие программы'], // 7 => ['title_id' => 7, 'title' => 'История возникновения Интернет'] // ] // ] // ] // ] // ] Данный сформированный вложенный массив можно без дополнительной оброботки отправлять на фронтенд и там уже удобно с ним работать. |
||||||||||||||||||||||||||
oneOrError($nameColumn = null) |
Возвращает одну строку запроса. В случае если в результате запроса получаем
больше одной строки - вызывается ошибка. Данную функцию необходимо использовать,
когда критически важно, чтобы из БД была получена только одна строка. Если указать
название колонки – $nameColumn , то получим содержимое конкретной ячейки.
$name = $gp->sql("select * from product /*where*/") ->where('/*where*/', ['id', '=', 777]) ->oneOrError('name'); |
||||||||||||||||||||||||||
first($nameColumn = null) |
Возвращает первую строку запроса. Если указать название колонки –
nameColumn , то получим содержимое конкретной ячейки.
$name = $gp->sql("select * from product") ->first('name'); |
||||||||||||||||||||||||||
count($nameColumn = '*') |
Возвращает количество записей (строк) запроса.
// $countProduct - количество записей (строк) запроса // select count(*) from (select * from product) $countProduct = $gp->sql("select * from product")->count(); // select count(name) from (select * from product) $countProduct = $gp->sql("select id, name from product")->count('name'); // select count(distinct name) from (select * from product) $countProduct = $gp->sql("select id, name from product")->count('distinct name');
ПРИМЕЧАНИЕ
Параметр
|
||||||||||||||||||||||||||
execute() |
Особая функция, которая может выполнить любой sql запрос и возвращает результат выполнения. Если запрос - это выборка из БД, то Если запрос на изменения данных в БД (или в случае с Oracle - PL/SQL конструкция),
то функция $gp->sql("INSERT INTO product(id, basket_id) VALUES(nameSequence.NEXTVAL, :basket_id) RETURNING id INTO :id_val") ->binds(['basket_id' => $basketId, 'id_val[11]' => &$this->id]) ->execute(); $data = $gp->sql("select id, basket_id, name from product") ->sort('name') ->pagination(1, 10) ->execute(); $gp->sql("BEGIN drovosek.update_basket(p_basket_id => :basket_id, p_mode => :mode); END;") ->binds(['basket_id' => 234, 'mode' => 'normal']) ->execute(); |
||||||||||||||||||||||||||
insert($table, $parameters) |
Вставляем в таблицу $table данные $parameters .
Структура массива $parameters :
[ 'название_колонки' => 'значение', 'название_колонки' => ["LOWER('AAAAA')"], ...... ]Пример: // sql: INSERT INTO table_name (column_name) VALUES (:greenpig_alias_insert_1) insert('table_name', ['column_name' => $val])Значение автоматически оборачивается псевдонимом и добавляется в массив биндов. Если вам необходимо добавить sql, то значение обрамляется квадратными скобками (объявляем массив). В таком случае данные вставляются в sql запрос напрямую и вам нужно будет значение добавить через функцию binds(). // sql: INSERT INTO product (title, status_product) VALUES (:greenpig_alias_insert_1, LOWER(:status)) $idProduct = $gp->binds(['status' => $status]) ->insert('product', [ 'title' => $title, 'status_product' => ['LOWER(:status)'] ]); Для MySQL Функция возвращает значение первичного ключа с автоинкрементом для новой вставленной записи. Грубо говоря возвращает "id" новой строки (под капотом просто вызывается функция PDO::lastInsertId()). $idProduct = $gp->insert('product', ['title' => $title]); Для Oracle Функция возвращает полностью всю новую вставленную строку. Если третьем параметром указать название колонки, то получим значение конкретной ячейки. $newRow = $gp->insert('product', ['title' => $title]); $idProduct = $gp->insert('product', ['title' => $title], 'id'); |
||||||||||||||||||||||||||
inserts($table, $parameters) |
Вставляем в таблицу $table несколько строк.
$gp->inserts('product', [['title' => $title1, 'age' => $val1], ['title' => $title2, 'age' => $val2], ['title' => $title3, 'age' => $val3]]);Функция возвращает количество вставленых записей. |
||||||||||||||||||||||||||
update($table, $parameters, $where) |
Обновление данных в таблице
// sql: UPDATE table_name SET column_name = :greenpig_alias_update_1 WHERE id = :greenpig_alias_update_2 update('table_name', ['column_name' => $val], ['id', '=', 1]) // sql: UPDATE product SET title = :greenpig_alias_update_1, status_product = LOWER(:status) // WHERE id = :greenpig_alias_update_2 $gp->bind('status', $status) ->update('product', ['title' => $title, 'status_product' => ['LOWER(:status)']], ['id', '=', $id]);Функция возвращает количество изменных строк. |
||||||||||||||||||||||||||
insertUpdate($table, $paramInsert, $paramUpdate) |
Пытаемся вставить новую запись из Если в таблице есть первичный ключ с автоинкрементом, то использование данной функции не имеет смысла. Если же у таблицы есть колонки с уникальными значениями (в том числе это может быть и первичный ключ) и у вас есть эти данные, но вы не знаете существует ли запись в таблице или нет и в случае отсутствия записи - вставить новую, а если уже есть, то обновить. Для второго варианта функция подходит идеально. Под капотом для mySql реализована такая конструкция: INSERT INTO name_table (a, b, c) VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE b = 4 Для Oracle реализован аналог. ПРИМЕР: Допустим у нас есть пустая таблица student с двумя колонками email и name, причем значения в колонке email должны быть уникальными. $gp->insertUpdate('student', ['email' => 't@test.ru', 'name' => 'Паша'], ['name' => 'Маша']); После выполнения функции в таблице будет так:
Попробуем еще раз выполнить тот же код: $gp->insertUpdate('student', ['email' => 't@test.ru', 'name' => 'Паша'], ['name' => 'Маша']); Теперь таблица выглядит следующим образом:
|
||||||||||||||||||||||||||
delete($table, $where) |
Удаляет данные в таблице
// sql: DELETE FROM product WHERE id in (1, 2, 56, 777, 19000) $countDelRow = $gp->delete('product', ['id', 'in', [1, 2, 56, 777, 19000]]); // или можно записать по упрощенному варианту $countDelRow = $gp->delete('product', [1, 2, 56, 777, 19000]); Функция возвращает количество удаленных строк.
Если функции передать вторым параметром именно true (===), то удаляются все записи
из таблицы. |
||||||||||||||||||||||||||
beginTransaction() |
Начало транзакции, отключение автоматической фиксации.
try { $gp->beginTransaction(); // начало транзакции ..... $gp->update('product', ['status' => 'delete'], ['title', 'like' => 'iPhone*']); ..... $gp->commit(); // записываем изменения } catch ( Exception $e ) { $gp->rollBack(); // откатываем транзакцию } |
||||||||||||||||||||||||||
commit() |
Фиксирует транзакцию.
try { $gp->beginTransaction(); // начало транзакции ..... $gp->update('product', ['status' => 'delete'], ['title', 'like' => 'iPhone*']); ..... $gp->commit(); // записываем изменения } catch ( Exception $e ) { $gp->rollBack(); // откатываем транзакцию } |
||||||||||||||||||||||||||
rollBack() |
Откат транзакции.
try { $gp->beginTransaction(); // начало транзакции ..... $gp->update('product', ['status' => 'delete'], ['title', 'like' => 'iPhone*']); ..... $gp->commit(); // записываем изменения } catch ( Exception $e ) { $gp->rollBack(); // откатываем транзакцию } |
||||||||||||||||||||||||||
getData($formatting = false) |
Функции из голубой и красной группы получают данные из БД. Функция
|
||||||||||||||||||||||||||
getPagination() |
Если была применина пагинация при выборке данных, то информацию о пагинации можно
получить с помошью этой функции.
$gp->getPagination(); // Пример результата: [ 'currentPage' => 1, // текущая страница 'numberRowOnPage' => 10, // количество строк запроса на странице 'numberAllRow' => 100, // сколько всего строк запроса 'numberAllPage' => 10 // сколько всего страниц ] |
||||||||||||||||||||||||||
getBind($alias = false) |
Функция возвращает бинды, используемые в последнем выполненном запросе.
Если передать Может быть полезен для получения inout биндов. Или для получения технических биндов, добавленных библиотекой. $gp->binds(['id' => 21, 'rating' => 20]) ->bind('qaz [13]', -1) ->sql("insert into table_name (id, rating) values (:id, :rating) returning 'xxx' into :qaz") ->execute(); print_r( $gp->getBind('qaz') ); // xxx |
||||||||||||||||||||||||||
column($nameColumn) |
Если в исходных данных (смотри функцию getData() ) было множество строк,
то данная функция формирует и возвращает обычный одномерный массив. Элементами
сгенерированного массива являются данные из колонки $nameColumn .
// Результат запроса: // [ // 0 => [ // 'id' => 3, // 'name' => 'Паша', // 'title_id' => 6, // 'title' => '«Азы» программирования и обучающие программы', // ], // 1=> [ // 'id' => 3, // 'name' => 'Паша', // 'title_id' => 7, // 'title' => 'История возникновения Интернет' // ] // ] $titles = $gp->column('title'); // $titles содержит массив: // ['«Азы» программирования и обучающие программы', 'История возникновения Интернет'] |
||||||||||||||||||||||||||
map($pk, $columns = []) |
Функция из исходного массива выборки формирует и возвращает ассоциативный массив,
ключами которого будут данные из колонки $pk . Если параметр
$columns не указывать, то данные из всех колонок сохраняться,
но можно задать массив из названий колонок и тогда, в результате, будут данные
только из перечисленных колонок. Пример:
// исходный массив выборки // [ // 0 => [ 'inn' => 111111222222, // 'name_org' => 'Красный буржуй', // 'address' => 'ул.Ленина д.3' ], // 1 => [ 'inn' => 333333444444, // 'name_org' => 'MakeGreatAgain', // 'address' => 'ул.Трампа д.666' ], // 2 => [ 'inn' => 555555666666, // 'name_org' => 'Собчак', // 'address' => 'ул.Лошадиная д.40' ] // ] map('inn'); // результат // [ // 111111222222 => [ 'inn' => 111111222222, // 'name_org' => 'Красный буржуй', // 'address' => 'ул.Ленина д.3' ], // 333333444444 => [ 'inn' => 333333444444, // 'name_org' => 'MakeGreatAgain', // 'address' => 'ул.Трампа д.666' ], // 555555666666 => [ 'inn' => 555555666666, // 'name_org' => 'Собчак', // 'address' => 'ул.Лошадиная д.40' ] // ] map('inn', ['name_org']); // результат // [ // 111111222222 => ['name_org' => 'Красный буржуй'], // 333333444444 => ['name_org' => 'MakeGreatAgain'], // 555555666666 => ['name_org' => 'Собчак'] // ] |
||||||||||||||||||||||||||
debugInfo() |
Пока существует экземпляр класса (переменная), все запросы к БД логируются и данная
функция возвращает массив информации для отладки, пример:
$gp->debugInfo(); // Пример результата: [ // Массив запросов, сделанных пользователем, пока существует экземпляр класса. 0 => [ 'numberQuery' => 999 // порядковый номер запроса // В рамках одного запроса под копотом может быть выполненно несколько технических // запросов, поэтому они группируются в массив. 'querys' => [ 0 => [ 'sql' => 'SELECT * FROM table WHERE id = :id', // выполняемый sql 'sqlWithBinds' => 'SELECT * FROM table WHERE id = 1', // выполняемый sql с подставленными биндами (для отладки) 'binds' => ['id' => 1], // массив биндов 'timeQuery' => 0.012 // время выполнения запроса ], ......... ] 'allTime' => 0.356 // общее время ], ........ ] |
['nameColumn', 'like' => '*tEsT'] // sql: nameColumn like :greenpig_alias_where_1 ['nameColumn', 'notLike' => '*tEsT'] // sql: nameColumn not like :greenpig_alias_where_2 ['nameColumn', 'flex' => 'tEsT*'] // sql: LOWER(nameColumn) like LOWER(:greenpig_alias_where_3) ['nameColumn', 'notFlex' => '*tEsT'] // sql: LOWER(nameColumn) not like LOWER(:greenpig_alias_where_4) ['nameColumn', 'fullFlex' => 'tEsT'] // sql: LOWER(nameColumn) like LOWER(:greenpig_alias_where_5) значение 'tEsT' => '*tEsT*' ['nameColumn', '=', 2] // sql: nameColumn = :greenpig_alias_where_6 ['nameColumn', '>', new \DateTime()] // sql: nameColumn > TO_DATE(:greenpig_alias_where_7, 'dd.mm.yyyy hh24:mi:ss') ['nameColumn', 'in', [1,2, 'ggg']] // sql: nameColumn in (:greenpig_alias_where_8, :greenpig_alias_where_9, :greenpig_alias_where_10) ['nameColumn', '=', 'sql'=>'7'] // sql: nameColumn = 7 ['nameColumn', '=', 'date' => '12.12.2020'] // sql: nameColumn = TO_DATE(:greenpig_alias_where_11, 'dd.mm.yyyy hh24:mi:ss') ['nameColumn', '=', 'date' => ['2020.12.12', 'yyyy.mm.dd']] ['nameColumn', 'between', 2, 4] // sql: nameColumn between :greenpig_alias_where_12 and :greenpig_alias_where_13 ['nameColumn', 'between', new \DateTime(), new \DateTime()] // sql: nameColumn between TO_DATE(:greenpig_alias_where_14, 'dd.mm.yyyy hh24:mi:ss') and TO_DATE(:greenpig_alias_where_15, 'dd.mm.yyyy hh24:mi:ss') ['nameColumn', 'between', 'date1'=>'12:12:12', 'date2'=>'12:12:12'] // sql: nameColumn between TO_DATE(:greenpig_alias_where_16, 'dd.mm.yyyy hh24:mi:ss') and TO_DATE(:greenpig_alias_where_17, 'dd.mm.yyyy hh24:mi:ss') ['nameColumn', 'between', 'date1'=>['2020.12.12', 'yyyy.mm.dd'], 'date2'=>'12:12:12'] ['nameColumn', 'between', 'date1'=>'12:12:12', 'date2'=>['2020.12.12', 'yyyy.mm.dd']] ['nameColumn', 'between', 'date1'=>['2020.12.12', 'yyyy.mm.dd'], 'date2'=>['2020.12.12', 'yyyy.mm.dd']]
GreenPigException
- общая ошибка GP, от этого класса наследуются все остальныеGreenPigDatabaseException
- ошибка связанная с БДGreenPigWhereException
- ошибка связанная с генерацией Where части sql запросаGreenPigQueryException
- ошибка связанная с основным классом QueryФункция | Описание |
---|---|
Т.к. все исключения наследуются от стандартного класса Exception , то доступны все базовые функции:
|
|
getNameException() |
Получаем “заголовок” ошибки, который строится так:
название_класса_ошибки (путь_к_файлу_где_была_ошибка : номер_строки) Пример: Исключение GreenPig\Exception\GreenPigWhereException (\pr-test\GP2\Where.php:125)
|
getErrorObject() | При возникновении ошибки, как правило в Exception передается объект в котором возникла ошибка. Данная функция позволяет получить этот объект. |
getErrorData($nameParameter = false) |
Если в у функции не указывать параметр, то получим массив, содержащий всю информацию связанную с ошибкой:
Array ( [nameException] => Исключение GreenPig\Exception\GreenPigWhereException (\pr-test\GP2\Where.php:125) [messageException] => Если логическая операция состоит из 2 элементов, то второй элемент всегда имеет строковый или числовой тип и у него ключ должен быть следующим: like, notLike, flex, notFlex или fullFlex. [moreParamForDebug] => Array ( [0] => Array ( [0] => Логическое выражение where: [1] => Array ( [0] => dat [1] => 31.05.2021 ) ) ) [errorObject] => Array ( [0] => dat [1] => 31.05.2021 ) [trace] => #0 /var/www/html/pr-test/GP2/Where.php(107): GreenPig\Where->identifyType() #1 /var/www/html/pr-test/GP2/Where.php(60): GreenPig\Where->genSql() #2 /var/www/html/pr-test/GP2/Query.php(171): GreenPig\Where->where() #3 /var/www/html/pr-test/GP2/t.php(98): GreenPig\Query->where() #4 {main} )В качестве параметра функция может принимать слудующие значения: nameException, messageException, errorObject, trace, moreParamForDebug .
Передав значение, мы получим не весь массив, а только интерисующую нас часть.
|
drawHtmlDebug() |
Для отладки можно использовать данную функцию, которая отрисовывает на экране в удобном
виде содержимое функции getErrorData()
Пример: Исключение GreenPig\Exception\GreenPigWhereException (\pr-test\GP2\Where.php:125)
Если логическая операция состоит из 2 элементов, то второй элемент всегда имеет строковый или числовой тип и у него ключ должен быть следующим: like, notLike, flex, notFlex или fullFlex.
Логическое выражение where: Array ( [0] => dat [1] => 31.05.2021 ) Значение объекта ошибки: Array ( [0] => dat [1] => 31.05.2021 ) Трассировка ошибок: #0 /var/www/html/pr-test/GP2/Where.php(107): GreenPig\Where->identifyType() #1 /var/www/html/pr-test/GP2/Where.php(60): GreenPig\Where->genSql() #2 /var/www/html/pr-test/GP2/Query.php(171): GreenPig\Where->where() #3 /var/www/html/pr-test/GP2/t.php(98): GreenPig\Query->where() #4 {main} |
Для того чтобы поймать исключения от GreenPig
, достаточно ловить только исключения
GreenPigException
.
try { ............ } catch (\GreenPig\Exception\GreenPigException $gpE) { $gpE->drawHtmlDebug(); } catch (\Exception $e) { GP::varDump($e, 'Exception'); }