2024 年 Clojure 状态调查中分享您的想法!

欢迎!请参阅关于页面以了解有关该操作的信息。

0票数

我搜索了一下,但没有发现明显的答案。但是,我对 Clojure 和 core.logic 相对较新。只想知道是否有简单的方法将逻辑数据库存储到文件中。我想在逻辑数据库中存储/撤消事实,并且偶尔将整个数据库保存用于恢复目的。然后,稍后,可能会将该数据库恢复到内存中。

提前感谢任何帮助。

1 答案

0票数

看起来nippy可以与标准序列化一起使用,因为逻辑事实数据库是用已可序列化的 Clojure 类型实现的。

(ns logos.serial
  (:require [taoensso.nippy :as nippy]
            [clojure.core.logic.pldb :as pldb]
            [clojure.core.logic :as log]
            [clojure.java.io]))

(defn freeze-to! [o target & {:keys [compressor] :or {compressor nippy/lz4hc-compressor}}]
  (with-open [buff (clojure.java.io/output-stream target)
              dos (java.io.DataOutputStream. buff)]
    (nippy/freeze-to-out! dos  o)))

(defn thaw-from! [target & {:keys [compressor] :or {compressor nippy/lz4hc-compressor}}]
  (with-open [fis (clojure.java.io/input-stream target)
              dis (java.io.DataInputStream. fis)]
    (nippy/thaw-from-in! dis )))

(pldb/db-rel man p)
(pldb/db-rel woman p)
(pldb/db-rel likes p1 p2)
(pldb/db-rel fun p)

(def facts0
  (pldb/db
   [man 'Bob]
   [man 'John]
   [man 'Ricky]

   [woman 'Mary]
   [woman 'Martha]
   [woman 'Lucy]

   [likes 'Bob 'Mary]
   [likes 'John 'Martha]
   [likes 'Ricky 'Lucy]))


(def facts1 (-> facts0 (pldb/db-fact fun 'Lucy)))

查询和测试

(defn simple-query [db]
  (pldb/with-db db
    (log/run* [q]
      (log/fresh [x y]
        (fun y)
        (likes x y)
        (log/== q [x y])))))

;;logos.serial>(simple-query facts1)
;;([Ricky Lucy])

(freeze-to! facts1 "facts.lz4")
(def facts-thawed (thaw-from! "facts.lz4"))

;;logos.serial>(= facts1 facts-thawed)
;;logos.serial> (simple-query facts-thawed)
;;([Ricky Lucy])
谢谢。我还未看过那份资料。那应该可行。

我还用 spit/slurp 命令成功地运行了它。  因此,我不知道之前我做了什么。  可能很愚蠢。

再次感谢您的回答。  现在要去检查 nippy...orr...
由于实现细节基于 map/record 并具有可读表示形式,spit/slurp 将会工作。  根据你要序列化的对象的大小、你冻结和解冻的频率,以及诸如压缩等其他问题,nippy 在几乎所有情况下都将成为主导(除了 spit/slurp 已经内置在你的包中之外 :))。  话虽如此,通过 spit/slurp 实现的简化序列化方法出奇地有用。
...