Написание только функции, которая сохраняет данные объекты в sqlite - PullRequest
1 голос
/ 27 августа 2011

Я только начинаю с clojure, и застрял, думая, как реализовать, казалось бы, простую функциональность.

Существует функция generator, которая принимает (среди прочего) функцию saver в качестве аргумента. generator выполняет все виды операций и регулярно генерирует определенные объекты данных, которые необходимо сохранить. Предполагается, что это сохранение обрабатывается функцией saver, поэтому generator вызывает saver с данными, которые необходимо сохранить, каждый раз, когда создаются данные.

Теперь я хочу написать одну функцию сохранения, которая сохраняет данные в базу данных sqlite. Как мне поступить об этом?

  • Одна из стратегий, о которой я подумал, - создать соединение с базой данных sqlite в функции saver. Создавайте новое соединение каждый раз, когда необходимо сохранить данные, сохраняйте данные (только одна строка в одной таблице) и закрывайте соединение. Это казалось немного неэффективным. Особенно учитывая, что данные генерируются каждые 2-5 секунд.

  • Другая идея состоит в том, чтобы сохранить открытое соединение как переменную уровня модуля, которая при запуске имеет значение nil. Соединение открывается при первом вызове функции saver и повторно используется в последующих вызовах. Кажется, это, вероятно, будет более эффективным, но, насколько мне известно, для этого потребуется форма def внутри функции saver. Лично мне это не нравится.

  • Еще одна (сумасшедшая?) Мысль о том, что я должен был использовать агент, который сохраняет объект соединения, изначально установленный на nil. saver будет функцией, которая send передает данные агенту. Агент создает соединение в первый раз, когда ему это нужно, и сохраняет его в связанном объекте данных. Похоже, что это может работать хорошо, но агенты не предназначены для этого, не так ли?

Итак, как вы, люди, решаете проблему? Есть ли какая-то другая парадигма, подходящая именно для этого случая? Или я должен сделать одно из вышеперечисленного?

PS. Я потратил много времени на написание этого, так как очень трудно выразить свою проблему словами. Я не уверен, все ли у меня в порядке. Дайте мне знать, если что-то неясно.

1 Ответ

2 голосов
/ 27 августа 2011

ваше второе решение звучит лучше всего. если вы не хотите использовать изменяемый Var (созданный с помощью def), то вы можете создать соединение в «фабричной» функции как простое неизменяемое значение (поэтому оно просто переносится в замыкании):

(defn sqlite-saver-factory [path]
  (let [db-connection (open-sqlite-connection path)]
    (fn [data]
      (save-to-sqlite db-connection data))))
...
(generator (sqlite-saver-factory path) ...)

Disclaimer: я не большой специалист по clojure - вышеизложенное только то, как я бы сделал это практически на любом функциональном языке. так что, возможно, есть более идиоматический подход укупорки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...