dscarpetti / codax Goto Github PK
View Code? Open in Web Editor NEWAn idiomatic transactional embedded database for clojure
License: Eclipse Public License 1.0
An idiomatic transactional embedded database for clojure
License: Eclipse Public License 1.0
Hi @dscarpetti
First off, thanks for this wonderful library!
My request is that could you please add some nippy
exames in the ReadMe ? I'm a beginner in clojure so I'd love to see a couple examples of non-map data being stored via nippy.
I have multiple projects for which I only want to know their ID (keys).
Usually I would simply do this (or the Codax equivalent):
(keys projects-db)
Once I have the keys I could use c/get-at
to only fetch the information I want.
However this is taking way too much time, most probably because Codax is loading the entire map even when I only need the keys.
Is there an alternative approach to obtain the same info without loading everything?
AOT compiling means that this library's dependencies override any other dependencies (https://clojureverse.org/t/deploying-aot-compiled-libraries/2545/6?u=mjmeintjes).
This leads to very hard to debug errors when consumers use a newer version of the clojure.core.cache library.
after upgraded to [codax "1.0.1-SNAPSHOT"]
clojure.lang.Compiler$CompilerException: clojure.lang.ExceptionInfo: Call to clojure.core/let did not conform to spec:
In: [0 0] val: (if (get no-graphs (first path)) (get-in)) fails spec: :clojure.core.specs.alpha/local-name at: [:args :bindings :binding :sym] predicate: simple-symbol?
In: [0 0] val: (if (get no-graphs (first path)) (get-in)) fails spec: :clojure.core.specs.alpha/seq-binding-form at: [:args :bindings :binding :seq] predicate: vector?
In: [0 0 0] val: if fails spec: :clojure.core.specs.alpha/map-binding at: [:args :bindings :binding :map :mb] predicate: vector?
In: [0 0 0] val: if fails spec: :clojure.core.specs.alpha/ns-keys at: [:args :bindings :binding :map :nsk] predicate: vector?
In: [0 0 0] val: if fails spec: :clojure.core.specs.alpha/map-bindings at: [:args :bindings :binding :map :msb] predicate: vector?
In: [0 0 1] val: (get no-graphs (first path)) fails spec: :clojure.core.specs.alpha/map-binding at: [:args :bindings :binding :map :mb] predicate: vector?
In: [0 0 1] val: (get no-graphs (first path)) fails spec: :clojure.core.specs.alpha/ns-keys at: [:args :bindings :binding :map :nsk] predicate: vector?
In: [0 0 1] val: (get no-graphs (first path)) fails spec: :clojure.core.specs.alpha/map-bindings at: [:args :bindings :binding :map :msb] predicate: vector?
In: [0 0 2] val: (get-in) fails spec: :clojure.core.specs.alpha/map-binding at: [:args :bindings :binding :map :mb] predicate: vector?
In: [0 0 2] val: (get-in) fails spec: :clojure.core.specs.alpha/ns-keys at: [:args :bindings :binding :map :nsk] predicate: vector?
In: [0 0 2] val: (get-in) fails spec: :clojure.core.specs.alpha/map-bindings at: [:args :bindings :binding :map :msb] predicate: vector?
In: [0 0] val: (if (get no-graphs (first path)) (get-in)) fails spec: :clojure.core.specs.alpha/map-special-binding at: [:args :bindings :binding :map] predicate: map?
:clojure.spec.alpha/args ([(if (get no-graphs (first path)) (get-in))])
{:clojure.spec.alpha/problems ({:path [:args :bindings :binding :sym], :pred simple-symbol?, :val (if (get no-graphs (first path)) (get-in)), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/local-name], :in [0 0]} {:path [:args :bindings :binding :seq], :pred vector?, :val (if (get no-graphs (first path)) (get-in)), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/seq-binding-form], :in [0 0]} {:path [:args :bindings :binding :map :mb], :pred vector?, :val if, :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings :clojure.core.specs.alpha/map-binding], :in [0 0 0]} {:path [:args :bindings :binding :map :nsk], :pred vector?, :val if, :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings :clojure.core.specs.alpha/ns-keys], :in [0 0 0]} {:path [:args :bindings :binding :map :msb], :pred vector?, :val if, :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings], :in [0 0 0]} {:path [:args :bindings :binding :map :mb], :pred vector?, :val (get no-graphs (first path)), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings :clojure.core.specs.alpha/map-binding], :in [0 0 1]} {:path [:args :bindings :binding :map :nsk], :pred vector?, :val (get no-graphs (first path)), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings :clojure.core.specs.alpha/ns-keys], :in [0 0 1]} {:path [:args :bindings :binding :map :msb], :pred vector?, :val (get no-graphs (first path)), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings], :in [0 0 1]} {:path [:args :bindings :binding :map :mb], :pred vector?, :val (get-in), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings :clojure.core.specs.alpha/map-binding], :in [0 0 2]} {:path [:args :bindings :binding :map :nsk], :pred vector?, :val (get-in), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings :clojure.core.specs.alpha/ns-keys], :in [0 0 2]} {:path [:args :bindings :binding :map :msb], :pred vector?, :val (get-in), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-bindings], :in [0 0 2]} {:path [:args :bindings :binding :map], :pred map?, :val (if (get no-graphs (first path)) (get-in)), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/binding :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/binding-form :clojure.core.specs.alpha/map-binding-form :clojure.core.specs.alpha/map-special-binding], :in [0 0]}), :clojure.spec.alpha/args ([(if (get no-graphs (first path)) (get-in))])}, compiling:(viri/db.clj:157:18)
When using 1.2.0-snapshot and running figwheel, I get this error :
No reader function for tag Inf
986 (js-mod (Math/floor o) 2147483647)
987 (case o
988 ##Inf
^--- No reader function for tag Inf
989 2146435072
990 ##-Inf
991 -1048576
However, re-adding ^:skip-aot
solve this.
I'm doing like this:
(defn init-db [ db ]
(c/with-write-transaction [db tx]
(when-not (c/get-at tx [:counters :user-id])
(c/assoc-at tx [:counters :user-id] 1))))
This is for the one-time DB initialization. As you see, if the DB was already initialized, the body of the when-not will not be evaluated, nothing is written to DB. This leads to NullPointerException clojure.lang.RT.longCast (RT.java:1259)
Any idea how to fix this? I really want to use it. ๐ฐ
clojure.lang.Compiler$CompilerException: clojure.lang.ExceptionInfo: Call to clojure.core/defn did not conform to spec: In: [0] val: codax.pathwise/encode-element fails spec: :clojure.core.specs.alpha/defn-args at: [:args :name] predicate: simple-symbol? :clojure.spec.alpha/args (codax.pathwise/encode-element [el65854] (clojure.core/cond (true? el65854) (clojure.core/str (clojure.core/char 33) ((fn [_] "") el65854) codax.pathwise/+delim+) (date-time? el65854) (clojure.core/str (clojure.core/char 36) (encode-date-time el65854) codax.pathwise/+delim+) (neg-infinity? el65854) (clojure.core/str (clojure.core/char 48) ((fn [_] "") el65854) codax.pathwise/+delim+) (pos-infinity? el65854) (clojure.core/str (clojure.core/char 50) ((fn [_] "") el65854) codax.pathwise/+delim+) (number? el65854) (clojure.core/str (clojure.core/char 49) (encode-number el65854) codax.pathwise/+delim+) (symbol? el65854) (clojure.core/str (clojure.core/char 104) (encode-symbol el65854) codax.pathwise/+delim+) (false? el65854) (clojure.core/str (clojure.core/char 32) ((fn [_] "") el65854) codax.pathwise/+delim+) (string? el65854) (clojure.core/str (clojure.core/char 112) (encode-string el65854) codax.pathwise/+delim+) ((fn* [p1__65853#] (or (vector? p1__65853#) (list? p1__65853#))) el65854) (clojure.core/str (clojure.core/char 160) (encode-vector el65854) codax.pathwise/+delim+) (keyword? el65854) (clojure.core/str (clojure.core/char 105) (encode-keyword el65854) codax.pathwise/+delim+) (nil? el65854) (clojure.core/str (clojure.core/char 16) ((fn [_] "") el65854) codax.pathwise/+delim+) :else (throw (java.lang.Exception. (clojure.core/str "no method for encoding
" el65854 ""))))) {:clojure.spec.alpha/problems [{:path [:args :name], :pred simple-symbol?, :val codax.pathwise/encode-element, :via [:clojure.core.specs.alpha/defn-args :clojure.core.specs.alpha/defn-args], :in [0]}], :clojure.spec.alpha/args (codax.pathwise/encode-element [el65854] (clojure.core/cond (true? el65854) (clojure.core/str (clojure.core/char 33) ((fn [_] "") el65854) codax.pathwise/+delim+) (date-time? el65854) (clojure.core/str (clojure.core/char 36) (encode-date-time el65854) codax.pathwise/+delim+) (neg-infinity? el65854) (clojure.core/str (clojure.core/char 48) ((fn [_] "") el65854) codax.pathwise/+delim+) (pos-infinity? el65854) (clojure.core/str (clojure.core/char 50) ((fn [_] "") el65854) codax.pathwise/+delim+) (number? el65854) (clojure.core/str (clojure.core/char 49) (encode-number el65854) codax.pathwise/+delim+) (symbol? el65854) (clojure.core/str (clojure.core/char 104) (encode-symbol el65854) codax.pathwise/+delim+) (false? el65854) (clojure.core/str (clojure.core/char 32) ((fn [_] "") el65854) codax.pathwise/+delim+) (string? el65854) (clojure.core/str (clojure.core/char 112) (encode-string el65854) codax.pathwise/+delim+) ((fn* [p1__65853#] (or (vector? p1__65853#) (list? p1__65853#))) el65854) (clojure.core/str (clojure.core/char 160) (encode-vector el65854) codax.pathwise/+delim+) (keyword? el65854) (clojure.core/str (clojure.core/char 105) (encode-keyword el65854) codax.pathwise/+delim+) (nil? el65854) (clojure.core/str (clojure.core/char 16) ((fn [_] "") el65854) codax.pathwise/+delim+) :else (throw (java.lang.Exception. (clojure.core/str "no method for encoding
" el65854 "")))))}, compiling:(codax/pathwise.clj:108:1)
Would it be possible to release a non-snapshot version for 1.2.0?
Would it be possible to offer a way to upgrade a read transaction to a write transaction without starting the transaction from scratch?
It would be very helpful when chaining functions where a write might occur. Especially given the superior speed of read transactions.
I have following function
(defn create-user! [ email password db]
(c/with-write-transaction [db tx]
(let [encrypted-password (p/encrypt password)
next-user-id (inc (c/get-at tx [:counters :user-id]))
user {:email email
:password-hash encrypted-password}]
(c/merge-at tx [:users] {next-user-id user})
(c/assoc-at tx [:counters :user-id] next-user-id))))
As you see I have one read and two writes within one transaction. But only the last write occurs. I expect that both writes should occur.
I created an app with lein new luminus myapp
, added codax to project.clj and required it in src/clj/myapp/routes/home.clj.
After running lein run
I get the following error:
Exception in thread "main" java.lang.ExceptionInInitializerError at clojure.main.<clinit>(main.java:20) Caused by: java.lang.IllegalArgumentException: No matching method: repl, compiling:(codax/core.clj:161:3) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6875) at clojure.lang.Compiler.analyze(Compiler.java:6669) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6856) at clojure.lang.Compiler.analyze(Compiler.java:6669) at clojure.lang.Compiler.analyze(Compiler.java:6625) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001) at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5380) at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3972) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6866) at clojure.lang.Compiler.analyze(Compiler.java:6669) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6856) at clojure.lang.Compiler.analyze(Compiler.java:6669) at clojure.lang.Compiler.access$300(Compiler.java:38) at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:589) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6868) at clojure.lang.Compiler.analyze(Compiler.java:6669) at clojure.lang.Compiler.analyze(Compiler.java:6625) at clojure.lang.Compiler.eval(Compiler.java:6931) at clojure.lang.Compiler.load(Compiler.java:7379) at clojure.lang.RT.loadResourceScript(RT.java:372) at clojure.lang.RT.loadResourceScript(RT.java:363) at clojure.lang.RT.load(RT.java:453) at clojure.lang.RT.load(RT.java:419) at clojure.core$load$fn__5677.invoke(core.clj:5893) at clojure.core$load.invokeStatic(core.clj:5892) at clojure.core$load.doInvoke(core.clj:5876) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invokeStatic(core.clj:5697) at clojure.core$load_one.invoke(core.clj:5692) at clojure.core$load_lib$fn__5626.invoke(core.clj:5737) at clojure.core$load_lib.invokeStatic(core.clj:5736) at clojure.core$load_lib.doInvoke(core.clj:5717) at clojure.lang.RestFn.applyTo(RestFn.java:142) at clojure.core$apply.invokeStatic(core.clj:648) at clojure.core$load_libs.invokeStatic(core.clj:5774) at clojure.core$load_libs.doInvoke(core.clj:5758) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.core$apply.invokeStatic(core.clj:648) at clojure.core$require.invokeStatic(core.clj:5796) at clojure.core$require.doInvoke(core.clj:5796) at clojure.lang.RestFn.invoke(RestFn.java:482) at myapp.routes.home$eval5414$loading__5569__auto____5415.invoke(home.clj:1) at myapp.routes.home$eval5414.invokeStatic(home.clj:1) at myapp.routes.home$eval5414.invoke(home.clj:1) at clojure.lang.Compiler.eval(Compiler.java:6927) at clojure.lang.Compiler.eval(Compiler.java:6916) at clojure.lang.Compiler.load(Compiler.java:7379) at clojure.lang.RT.loadResourceScript(RT.java:372) at clojure.lang.RT.loadResourceScript(RT.java:363) at clojure.lang.RT.load(RT.java:453) at clojure.lang.RT.load(RT.java:419) at clojure.core$load$fn__5677.invoke(core.clj:5893) at clojure.core$load.invokeStatic(core.clj:5892) at clojure.core$load.doInvoke(core.clj:5876) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invokeStatic(core.clj:5697) at clojure.core$load_one.invoke(core.clj:5692) at clojure.core$load_lib$fn__5626.invoke(core.clj:5737) at clojure.core$load_lib.invokeStatic(core.clj:5736) at clojure.core$load_lib.doInvoke(core.clj:5717) at clojure.lang.RestFn.applyTo(RestFn.java:142) at clojure.core$apply.invokeStatic(core.clj:648) at clojure.core$load_libs.invokeStatic(core.clj:5774) at clojure.core$load_libs.doInvoke(core.clj:5758) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.core$apply.invokeStatic(core.clj:648) at clojure.core$require.invokeStatic(core.clj:5796) at clojure.core$require.doInvoke(core.clj:5796) at clojure.lang.RestFn.invoke(RestFn.java:551) at myapp.handler$eval288$loading__5569__auto____289.invoke(handler.clj:1) at myapp.handler$eval288.invokeStatic(handler.clj:1) at myapp.handler$eval288.invoke(handler.clj:1) at clojure.lang.Compiler.eval(Compiler.java:6927) at clojure.lang.Compiler.eval(Compiler.java:6916) at clojure.lang.Compiler.load(Compiler.java:7379) at clojure.lang.RT.loadResourceScript(RT.java:372) at clojure.lang.RT.loadResourceScript(RT.java:363) at clojure.lang.RT.load(RT.java:453) at clojure.lang.RT.load(RT.java:419) at clojure.core$load$fn__5677.invoke(core.clj:5893) at clojure.core$load.invokeStatic(core.clj:5892) at clojure.core$load.doInvoke(core.clj:5876) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invokeStatic(core.clj:5697) at clojure.core$load_one.invoke(core.clj:5692) at clojure.core$load_lib$fn__5626.invoke(core.clj:5737) at clojure.core$load_lib.invokeStatic(core.clj:5736) at clojure.core$load_lib.doInvoke(core.clj:5717) at clojure.lang.RestFn.applyTo(RestFn.java:142) at clojure.core$apply.invokeStatic(core.clj:648) at clojure.core$load_libs.invokeStatic(core.clj:5774) at clojure.core$load_libs.doInvoke(core.clj:5758) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.core$apply.invokeStatic(core.clj:648) at clojure.core$require.invokeStatic(core.clj:5796) at clojure.core$require.doInvoke(core.clj:5796) at clojure.lang.RestFn.invoke(RestFn.java:551) at myapp.core$eval282$loading__5569__auto____283.invoke(core.clj:1) at myapp.core$eval282.invokeStatic(core.clj:1) at myapp.core$eval282.invoke(core.clj:1) at clojure.lang.Compiler.eval(Compiler.java:6927) at clojure.lang.Compiler.eval(Compiler.java:6916) at clojure.lang.Compiler.load(Compiler.java:7379) at clojure.lang.RT.loadResourceScript(RT.java:372) at clojure.lang.RT.loadResourceScript(RT.java:363) at clojure.lang.RT.load(RT.java:453) at clojure.lang.RT.load(RT.java:419) at clojure.core$load$fn__5677.invoke(core.clj:5893) at clojure.core$load.invokeStatic(core.clj:5892) at clojure.core$load.doInvoke(core.clj:5876) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invokeStatic(core.clj:5697) at clojure.core$load_one.invoke(core.clj:5692) at clojure.core$load_lib$fn__5626.invoke(core.clj:5737) at clojure.core$load_lib.invokeStatic(core.clj:5736) at clojure.core$load_lib.doInvoke(core.clj:5717) at clojure.lang.RestFn.applyTo(RestFn.java:142) at clojure.core$apply.invokeStatic(core.clj:648) at clojure.core$load_libs.invokeStatic(core.clj:5774) at clojure.core$load_libs.doInvoke(core.clj:5758) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.core$apply.invokeStatic(core.clj:648) at clojure.core$require.invokeStatic(core.clj:5796) at clojure.core$require.doInvoke(core.clj:5796) at clojure.lang.RestFn.invoke(RestFn.java:421) at user$eval3$loading__5569__auto____4.invoke(user.clj:1) at user$eval3.invokeStatic(user.clj:1) at user$eval3.invoke(user.clj:1) at clojure.lang.Compiler.eval(Compiler.java:6927) at clojure.lang.Compiler.eval(Compiler.java:6916) at clojure.lang.Compiler.load(Compiler.java:7379) at clojure.lang.RT.loadResourceScript(RT.java:372) at clojure.lang.RT.loadResourceScript(RT.java:359) at clojure.lang.RT.maybeLoadResourceScript(RT.java:355) at clojure.lang.RT.doInit(RT.java:475) at clojure.lang.RT.<clinit>(RT.java:331) ... 1 more Caused by: java.lang.IllegalArgumentException: No matching method: repl at clojure.lang.Compiler$StaticMethodExpr.<init>(Compiler.java:1642) at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:1011) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6868) ... 136 more
I can comment out the require in home.clj and the project runs fine, uncomment it and everything still works. Any idea why this happens?
I'm a big fan of this library, many thanks!
I just stumbled over the following small issue: a "non-breaking space" in a string-key of a map produces
Execution error (NullPointerException) at codax.pathwise/eval9604$fn$fn$fn$fn (pathwise.clj:136).
Cannot invoke "Object.toString()" because "s" is null
Clojurians are used to be able to use pretty much anything as keys, including maps.
Codax is almost there, but lacks support for maps.
I came up with a simple encoder/decoder that leverages Nippy:
(ns my-ns
(:require [codax.core :as c]
[taoensso.nippy :as nippy])
(:import (java.util Base64)))
;; Simply encoding bytes to strings (String. bytes) causes the data to
;; be corrupted after a round trip in Codax. Encoding in b64 solves
;; this.
(defn bytes-to-base64 [bytes]
(let [encoder (Base64/getEncoder)]
(.encodeToString encoder bytes)))
(defn base64-to-bytes [base64-string]
(let [decoder (Base64/getDecoder)]
(.decode decoder base64-string)))
(c/defpathtype [0x71
clojure.lang.PersistentHashMap
clojure.lang.PersistentArrayMap
clojure.lang.PersistentTreeMap]
(fn map-encoder [m]
(bytes-to-base64 (nippy/freeze m)))
(fn map-decoder [s]
(nippy/thaw (base64-to-bytes s))))
Nippy also automatically handles keys ordering:
(let [encoding1 (:encoding (c/check-path-encoding {{:a 1, :b 2} "map1"}))
encoding2 (:encoding (c/check-path-encoding {{:b 2, :a 1} "map1"}))]
(= encoding1 encoding2))
;=> true
Could something like this be added to Codax?
Could it leverage other types defined for pathwise?
I've noticed that the codax file is increasing in size even when the stored map is small.
It seems related to the number of manipulations.
A small map (~100kb when in a text file) will give a nodes
file bigger than 10Mb after a few dozens of overwrites.
Line 112 in 46fbf34
Are you going to release the 1.1 ?
I'm doing like this:
(defn init-db [ db ]
(c/with-write-transaction [db tx]
(when-not (c/get-at tx [:counters :user-id])
(c/assoc-at tx [:counters :user-id] 1))))
This is for the one-time DB initialization. As you see, if the DB was already initialized, the body of the when-not will not be evaluated, nothing is written to DB. This leads to NullPointerException clojure.lang.RT.longCast (RT.java:1259)
I have following code:
(defn init-db [ _db_ ]
(c/assoc-at! _db_ [:counters :user-id] 1))
(def DB (atom nil))
(defn prepare-all [tests]
(if-not @DB
(reset! DB (c/open-database "db.test")))
(init-db @DB))
(use-fixtures :once prepare-all)
As you see this code prepares database connection for tests. In my normal workflow I recompile this class multiple times and try running tests each time. All goes well but after recompiling the variable DB is redefined and opened connection is lost somewhere.
Your function has all of them stored:
(defn open-database [path & [backup-fn]]
(let [path (to-canonical-path-string path)]
(when (@open-databases path)
(throw (ex-info "Database Already Open" {:cause :database-open
:message "The database at this path is already open."
:path path})))
So while I've lost the connection in my REPL it still physically exists somewhere and I cannot re-open the database again. I don't know how to fix this, maybe you can provide a function like "current-connection" accepting the database name so that I can obtain the existing connection and continue working without re-opening the DB?
Thanks!
The tests relying on parsing dates (Ex: "June 6, 2020 11:01"
) fail because of a 2 hours difference between the expected and actual values.
I suspect this is because the parsed time is assumed to be in the local timezone, but the expected value is in UTC.
A possible alternative would be to leverage the #inst
tag.
Seconds, milliseconds and the timezone can be omitted to reduce the visual noise:
#inst "2023-08-12T01:00"
; => #inst "2023-08-12T01:00:00.000-00:00"
The conversion to Instant is also pretty straightforward:
(.toInstant #inst "2023-08-12T01:00")
;=> #object[java.time.Instant 0x60208ef "2023-08-12T01:00:00Z"]
Before:
(simulate-message! "June 6, 2020 11:01" "Bobby" "Hello")
After:
(simulate-message! #inst "2020-06-06T11:01" "Bobby" "Hello")
Joda-Time
was nice a few years back, but nowadays Clojure users are expected to use java.util.Date
(mostly via #inst
) and java.time.instant
.
Most importantly, clj-time
is deprecated. It's a little annoying to bring those dependencies in new projects.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.