С базами данных я не работал уже лет… 10 наверное. Само собой, мой старый опыт это ODBC, C++ обертки над ним и прочие реально страшные штуки. И тут я столкнулся с современными способами взаимодействия с базами данных и не в монстроподобном C++, а в изящной Clojure и обомлел! Все так просто, изящно, правда, потенциально, тормознуто Но про тормознутость это не более чем теория вызванная тяжелым C++ опытом, когда подозреваешь в плохой оптимизации все, что автоматически генерирует какие-либо сущности.
На мой неискушенный взгляд, поддержка баз данных в Clojure замечательная. Я ограничился довольно скромным набором состоящим из ядра org.clojure/java.jdbc, драйвера для SQLite org.xerial/sqlite-jdbc и библиотечки для работы с SQL в Clojure-стиле java-jdbc/dsl.
Мой случай, пока что, совсем уж простой: две таблицы, пара индексов да внешний ключ. Вспоминая об ужасах 10 летней давности, ожидал что даже данный пункт окажется не простым. Внезапно все оказалось сильно иначе.
(jdbc/db-do-commands db
(jdbc/create-table-ddl :authors
[:author_id :integer "primary key"]
[:follow :boolean]
[:follow_date :datetime])
(jdbc/create-table-ddl :images
[:image_id :integer "primary key"]
[:author_id :integer "references authors (author_id)"]
[:commented :boolean]
[:liked :boolean])
"CREATE UNIQUE INDEX image_id ON images(image_id)"
"CREATE UNIQUE INDEX author_id ON authors(author_id)"))
Что не менее восхитительно – так это возможность вынести обработку ошибок из функции с логикой. В данном примере функция
java.lang.Exception
(fn [e & args]
(log/warn "init-db: " e)))
Моя реализация обработки крайне простая и примитивная. При этом ничто не мешает добавить, например, удаление/восстановление базы, создание отсутствующей директории и т.п. в зависимости от перехваченного исключения с последующим перезапуском
Каким образом удобнее писать запросы я как-то не определился. С одной стороны, можно мудрить и написать SQL-запрос на самом SQL. Быстро, просто, понятно.
(jdbc/query db ["select * from images where image_id = ?" id]))
Можно воспользоваться DSL из java-jdbc/dsl. В качестве плюсов видится использование keyword-ов (коллеги, как правильно на русский перевести? Ключевые слова очень не к месту, как мне кажется), что облегчает автоподстановку со стороны IDE, а значит и минимизирует вероятность ошибки. В качестве минусов вылезает более громоздкая конструкция.
(jdbc/query db
(sql/select [:*] :authors
(sql/where {:author_id id})))
)
Прогресс очень далеко шагнул, хотя, не удивлюсь если в мире C++ и баз данных всё тот же ODBC рулит. Проект “поиграться” тут.
Такое ощущение, что если бы ты в 2005 увидел, что позволяет делать ActiveRecord в Ruby-On-Rails, у тебя бы вообще шаблоны разорвало в клочья
PS. По поводу C++ и ODBC. Тут как у кого. Если человек не может пользоваться Google, то да, только хардкор. Если может, то пользуется чем-то вроде OTL или SOCI, на худой конец простейшими обертками вроде Poco::Db. А для SQLite в свое время была очень удобная библиотечка sqlite++, заброшенная авторами, но ее несложно было подкрутить под свои нужды.
PPS. Вместо keywords здесь, возможно, уместно было бы зарезервированные слова.
То был 2002, я думаю. Тогда, вроде бы и гугла не было
А почему ключевые слова? Ты же сам их вводишь… У мен с ключевыми словами скорее if/for ассоциируются.
OTL существует очень давно, даже OTL 4.0 была выпущена в 2001-м: http://otl.sourceforge.net/otl3_hist.htm
В 2002-м был Yahoo, да и Google уже начинался и был, имхо, даже лучше, чем сейчас. Правда, в 2002-м я сам велосипедил свою обертку над ODBS, но в конце-концов забабахался и выбросил ее, перейдя на OTL.
> А почему ключевые слова?
Не ключевые, а зарезервированные слова. Ты же сам написал, что перевод keywords как “ключевые слова” тебе не нравится в данном контексте. Если не “ключевые”, тогда напрашиваются “зарезервированные”.