Как стать автором
Обновить

Комментарии 5

Наработки интересные и однозначно заслуживают внимания. За ORM я бы порекомендовал поизучать принципы работы ORM на других языках. Я сам питонщик, и у нас напитоне много всяких разных ORM: от попсовой DjangoORM (однозадачная хр%нь) до гибкой SQLAlchemy (которая меня очень порадовала гибкой и расширяемой поддержкой SQL)

И касательно "без счастливого конца" -- недавно сам грустил -- не знаю, как тестировать написанный код

Очень сложно проводить аналогии между ORM для Питона и плюсов. В том смысле, что расширение функционала сортировкой-фильтрами - is not a rocket science - дело чисто техническое. Решается через стек объектов-команд и усложнённый генератор запросов. А вот с наращиванием производительности - большая беда.

На плюсах красивая рефлексия на данный момент практически отсутствует - и её было ещё меньше в начале-середине 2018 года, когда этот код писался. Поэтому любая попытка сделать ORM обречена либо на значительное изменение кода и использование кучи меток, либо на внешний препроцессор. В Qt метасистема пошла по обоим путям: с одной стороны, необходимо описывать структуру класса, оставляя макросы Q_OBJECT Q_GADGET и тп. С другой, поверх этого кода проходится moc, который для всех помеченных классов создаёт весьма уродливый код: там и касты в void*, и магические числа, и прочее прочее. Был даже цикл статей о том, как это работает - и почему. И, в общем-то, ничего сверхъестественного под капотом нет. Уродливое, не самое гибкое, порой, весьма неэффективное решение - но не сверхъестественное. И, главное, рабочее.

Проблема ещё и в том, что и сам moc, и сгенерированный им код вообще не дружат с шаблонами. Автор moc даже сделал версию, поддерживающую шаблоны, потом написал "не, фигня какая-то получается" - и забросил её. Не могу его осуждать (но осуждаю). И constexpr в метасистеме не сказать, чтобы часто встречается. Поэтому, в оригинальном qt не получится перенести генерацию кода запросов на этап компиляции. Можно было бы, если бы да кабы. Но нельзя. А, значит, всё будет делаться на этапе исполнения, самым обобщённым (читай, медленным) способом. Отсюда и сумасшедшие показатели времени запроса select по сравнению с явным созданием структур. Правда, я не смотрел, что там подвезли в самые свежие версии. Быть может, теперь всё не так плохо.

А по поводу вашей задачи, я не очень понял, в чём, собсно, проблема. Если у вас есть зоопарк, вы отдельно тестируете каждый вольер, отдельно - каждое животное. А потом тестируете их вместе, как единое целое. Или вы чисто технически не понимаете, как встроить тесты в ваши миксины? Начните с того, что тесты - это тоже миксины, которые чередуются с обычными миксинами и проверяют текущее состояние вашего приложения против известного нормального. Например, при рестарте последний завершающийся тестирующий миксин выключает свет и оставляет записку с PID'ом на пороге, а первый запускающийся тестовый проверяет, что этого PID'а с записки уже нет в живых. Или после каждого миксина каждого модуля ставится миксин тестов этого модуля против нужной версии и набора функций. И тд и тп.

Очень сложно проводить аналогии между ORM для Питона и плюсов

Аналогии -- интересный нюанс. Если вы про воспроизведение аналогичного API -- то это идея гиблая и ненужная. Я предлагаю смотреть, как решения устроены под капотом, и по мере необходимости эти решения в подходящем виде переносить себе. По сути я предлагаю обратить внимание на компилятор запросов, на предлагаемые клиентские подходы (см. bindparam), на кэшируемость объектов запросов, и так далее -- на низкоуровневые нюансы. На рефлексию, наконец -- это уберфича концепции ORM

Поэтому, в оригинальном qt не получится перенести генерацию кода запросов на этап компиляции.

Это не нужно. Нигде так не делают, это абсурдно. При необходимости подключиться вместо мускуля к постгресу вы на серьёзных щах предлагаете перекомпилировать клиентское приложение? Вместо этого сделайте такое API, чтобы объекты запросов (ВНИМАНИЕ -- это не только строки, это ещё и метаданые, во имя рефлексии) можно было кэшировать. Ни одно реальное приложение не обладает неограниченным списком запросов к БД, а CGI в далёком прошлом, чтобы переживать за единичное проседание производительности на первом запросе

А по поводу вашей задачи, я не очень понял, в чём, собсно, проблема

Кстати вообще не поняли. Как тестировать работу REPL? Как тестировать поведение REPL с учётом отправки команд и анализа результата? Как протестировать, не сломался ли REPL? Сейчас приходит понимание, что похожий с этой точки зрения инструмент уже есть, только он о другом и вообще из другого мира -- это selenium. Естественно, он не подходит для моей задачи. Значит, всё же надо городить огород с expect и его аналогами типа pexpect. И начинать с написания фреймворка для тестирования поведения терминала. Блин, оно мне надо?

По сути я предлагаю обратить внимание на компилятор запросов, на предлагаемые клиентские подходы (см. bindparam), на кэшируемость объектов запросов, и так далее -- на низкоуровневые нюансы.

Учитывая поставленную задачу? Основные накладные расходы происходят внутри Qt при использовании сеттеров. Без изменения самого Qt любой выигрыш на кешированиях будет теряться в долях процентов. А без Qt нет рефлексии.

Это не нужно. Нигде так не делают, это абсурдно. При необходимости подключиться вместо мускуля к постгресу вы на серьёзных щах предлагаете перекомпилировать клиентское приложение?

Во-первых, я имел в виду прежде всего код оптимального обхода структур. Во-вторых, разве мускул и постгря так далеко разошлись от ANSI SQL, чтобы универсальные запросы не работали? Ну и в-третьих, а почему нет? Это плюсы, детка!

Вместо этого сделайте такое API, чтобы объекты запросов (ВНИМАНИЕ -- это не только строки, это ещё и метаданые, во имя рефлексии) можно было кэшировать. 

Плюсы - не Питон, они работают немного не так. Что толку кешировать типы, если передача всё равно будет по значению - с многократным копированием в процессе?

Кстати вообще не поняли. Как тестировать работу REPL? Как тестировать поведение REPL с учётом отправки команд и анализа результата? Как протестировать, не сломался ли REPL?

stdin + stdout? Терминал - и REPL - это обмен сообщений по стандартным пайпам. Весь REPL - это read_stdin->eval->write_stdout. А все вставки текста, автодополнения, цветные символы и прочие перделки - это управляющие последовательности и спецсимволы. Поэтому ваших страданий по тестированию зоопарка целиком я вдвойне не понял. Делайте прокси для пайп, записывайте тестовую сессию, воспроизводите её в режиме "без терминала".

stdin + stdout? Терминал - и REPL - это обмен сообщений по стандартным пайпам.

Очень внимательно читаем. Сути всё равно не уловили.

Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации