Внес изменения в свою реализацию класса для генерации SQL запросов по сравнению с прошлой версией. Однако прежде чем писать о них, хотелось сразу прояснить некоторые вопросы которые в первом посте остались, на мой взгляд, не раскрыты:
- Это не очередной QueryBuilder. Хотя синтаксис и выглядит похоже, но по сути работает это по-другому. QueryBuilder обычно выполняется в Runtime. Мой же код предварительно нужно компилировать и на выполнение запускать уже откомпилированную версию. В частности код с картинки будет скомпилирован в следующий код PHP
if (!isset($__query58)) { $__query58 = new MLSQLQuery( '0cfd84f430c39bb567ef7cd28bf36054', array( 'server' => '***', 'database' => '***', 'user' => '***', 'pass' => '***', 'prefix' => 'ms-', 'codepage' => 'utf8' ) ); } $__query58->sql = ' SELECT `profile`.`iduser` AS `profile.iduser`,`user`.`name` AS `user.name` FROM `ms-Users-Profile` AS `profile`LEFT OUTER JOIN `ms-Users-User` AS `user` ON `user`.`id`=`profile`.`iduser` WHERE (`profile`.`net`='VK' OR `profile`.`net`='OK') AND `user`.`sex`='M''; $rows = $__query58->rows();
При использовании переменных в качестве имен полей или значений они будут вставлены в запрос через вызовы специальных функций, которые исключат SQL-инъекцию
- Для чего это нужно: я планирую сделать свой ORM (само собой с блекджеком и шлюхами) и PHPSQL будет являться абстрактным слоем для работы с БД. Планируется писать запросы в виде
select(id)->from(UsersUser)->where(sex == 'M');
который затем будет компилировать в PHP код с промежуточной компиляцией в PHPSQL.
- Нет, такой подход с компиляцией файлов не будет тормозить работу. Достаточно сделать это один раз при первом обращении к файлу, а затем закешировать скомпилированный вариант и в дальнейшем работать уже с ним. Также это можно делать один раз при установке/обновлении движка через консоль. В этом случае нам вообще неважно сколько времени займет компиляция, главное чтобы итоговый файл работал быстро.
- Да, такой подход действительно может создавать проблемы в отладке. Потому что из-за сгенерированного кода при ошибке в коде номер строки ошибки будет соответствовать новому скомпилированному файлу, а не тому, в котором вы этот код набирали.На текущий момент я пока не придумал как это обойти. Если есть какие-то идеи — озвучьте их.
- Да, я в курсе что «вместо изобретения своего велосипеда лучше бы использовал что-то крутое, типа Doctrine|Eloquent|другой вариант». Но я пошел своим путем потому что 1) мне это интересно 2)мне это нравится
- Почему не выложил на гибхаб: потому что данный класс использует функции из других моих библиотек, которые в свою очередь требуют еще библиотек и в общем это все занимает 17 мб исходных текстов, по которым нет справки. При этом из некоторых библиотек используется одна/две простенькие функции. На текущий момент пока не вижу смысла делать рефакторинг чтобы вынести этот функционал в отдельную небольшую папку для общего доступа. Будет интерес — выложу.
Ну а теперь перейдем к изменениям:
- Самое основное нововведение — в новой редакции все константные строки интерпретируются как имена полей. Т.е. теперь вместо field(net) == 'VK' можно писать net == 'VK'. Для имен полей с символом тире в имени можно использовать оператор исполнения в обратных ковычках: `net-soc`== 'VK'. Функция field осталась, её можно использовать если имя поля, к примеру, находится в переменной: field($fieldname).
- Исчезли функции вида _And, _Or. Теперь в условии нужно использовать вместо них операторы && и ||. Т.е. раньше было _Or(field(net)==value('VK'),field(net)==value('OK')), в новой редакции net=='VK' || net=='OK'
- Добавилась поддержка JOIN запросов (на стартовой картинке как раз пример с ним)
- Добавлен низкоуровневый метод Query, который позволяет создавать любые запросы,
которые нельзя сделать с помощью специализированных функций. По сути это просто обычное формирование запроса с помощью конкатенации строк. Однако в методе можно использовать специальные функции, которые позволяют исключить SQL-инъекции. - Расширилась функция field. Теперь можно написать в виде field([<имя псевдонима таблицы>,]<имя поля>)[->as(<имя псевдонима поля>)]
- Поддержка сортировки, группировки, условий агрегации
Для тех, кому интересно, тестовый полигон для компиляции кода находится по тому же адресу. Если найдете какую-то ошибку, пишите в комментариях. Пока это версия 0.2 так что ошибки весьма вероятны.
Автор: Шабанов Валерий