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

欢迎!请查看 关于 页面获取更多关于如何使用本站的信息。

0

我在周围看了看,没有看到任何明显的办法。不过,我对 Clojure 和 core.logic 还比较新手。只是想看看是否有简单的办法将逻辑数据库保存到文件中。我想要在逻辑数据库中存储/检索事实,并偶尔将整个数据库保存起来,以防万一需要恢复。然后,后期可能还需要将数据库恢复到内存中。

提前感谢任何帮助。

1 答案

0

看起来nippy 可以与标准序列化一起工作,因为 prolog 事实数据库是用 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了...
by
由于实现细节基于map/record并且它们具有可读的表示,spit/slurp将有效。根据你序列化的事物的尺寸、你冷冻/解冻的频率以及压缩等其它问题,我认为nippy在几乎所有情况下都会胜出(除了spit/slurp早已捆绑在内的情况)。话虽如此,通过spit/slurp进行糟糕的序列化竟然出奇地有用。
...