Эволюция DBAPI

Эволюция DBAPI

Agel Nash

В новых версиях MODX Evolution ожидается существенная переделка ядра. Ключевым улучшением станет полноценное внедрение паттерна Dependency Injection. Ну, а как этим пользоваться, я покажу на примере DBAPI. Но для начала расскажу с чего все начиналось, чтобы было понятно зачем…

Начало

Один из двух самых значимых классов для MODX Evolution это DBAPI. Для тех, кто в танке, этот класс нужен для работы с базой данных. Так вот, этот самый класс DBAPI немного хардкорного синтаксического сахара для mysqli. В нем определены методы, как select/update/insert/save/delete/etc… Видя подобные названия знающие люди сразу начинают думать в сторону ORM или ActiveRecord. Но не тут то было. Эти методы не имеют ничего общего с вышеназванными паттернами. Более того, методы работают с параметрами насколько по разному, что зачастую не совсем понятно какой же в итоге SQL запрос получится.

Давайте на примере

->select('id', 'site_content', array('id > 10', 'pagetitle = "test"'));
//SELECT id FROM site_content WHERE id > 10 pagetitle = "test"


По логике, тут не хватает AND. Но нет, параметр where делает просто implode массива с пробелом. Хорошо. Запомнили. Смотрим следующий метод — update

->update(array('pagetitle' => 'new'), 'site_content', array('id > 10', 'AND pagetitle = "test"'));


А тут уже нельзя использовать массив в аргументе where. НО! У нас есть метод save который так же может принимать параметр where и пробрасывать его в select запрос или update в зависимости от результатов. 

->save(array('pagetitle' => 'new'), 'site_content', array('id > 10', 'AND pagetitle = "test"'));


Если в базе не окажется документов с ID > 10 и pagetitle = «test», то будет вызван метод insert и как следствие, добавится новая запись у которой pagetitle будет установлен в значение new. В противном случае мы получим ошибку

trim() expects parameter 1 to be string, array given in


Помимо этого мы имеем кучу старевшего кода, в стиле _getFromStringFromArray, который ничем не отличается от

implode(' ', $tables)


Эксперимент

Исходя из вышеперечисленного захотелось попробовать немного причесать код и проверить — получился ли в результате сохранить обратную совместимость. Я взял класс DBAPIразрезал на части. После чего привел вызовы к единому стилю и тут стало очевидно, что завязка на mysqli не такая уж и жесткая. А это значит, что мы можем теоретически использовать pdo драйвер и скрестить MODX с любой базой данных.

Так, получилось самодостаточное решение, которое идеально подойдет для тех, кто не умеет работать с базой вне MODX. Покрыв код тестами почти на 90% пришла в голову мысль не изобретать велосипед, а прокинуть Illuminate\Database от Laravel в качестве альтернативы для mysqli драйвера. Вы не поверите, но получилось добиться почти полной совместимости (за исключением метода dataSeek, но ни в ядре, ни в компонентах этот метод не используется).

Что получилось

— Полная совместимость пакета со стандартным DBAPI классом

— Возможность использовать привычный синтаксис DBAPI вне MODX

— Поддержка полноценной ORM Eloquent для плавного переноса сайта на Laravel. Либо, как альтернатива поделке MODxAPI, которая входит в состав DocLister

Автор

https://agel-nash.ru 

Telegram: @agel_nash 

Email: modx@agel-nash.ru



Report Page