Define <-tagged-SQLite and tagged-SQLite-to-JS to do tag-aware value transforms.
This commit is contained in:
parent
ff9a75ae09
commit
22fc2ce201
1 changed files with 61 additions and 16 deletions
|
@ -17,21 +17,6 @@
|
||||||
|
|
||||||
(def current-version 1)
|
(def current-version 1)
|
||||||
|
|
||||||
;; Datomish rows are tagged with a numeric representation of :db/valueType:
|
|
||||||
;; The tag is used to limit queries, and therefore is placed carefully in the relevant indices to
|
|
||||||
;; allow searching numeric longs and doubles quickly. The tag is also used to convert SQLite values
|
|
||||||
;; to the correct Datomish value type on query egress.
|
|
||||||
(def value-type-tag-map
|
|
||||||
{:db.type/ref 0
|
|
||||||
:db.type/boolean 1
|
|
||||||
:db.type/instant 4
|
|
||||||
:db.type/long 5 ;; SQLite distinguishes integral from decimal types, allowing long and double to share a tag.
|
|
||||||
:db.type/double 5 ;; SQLite distinguishes integral from decimal types, allowing long and double to share a tag.
|
|
||||||
:db.type/string 10
|
|
||||||
:db.type/uuid 11
|
|
||||||
:db.type/uri 12
|
|
||||||
:db.type/keyword 13})
|
|
||||||
|
|
||||||
(def v1-statements
|
(def v1-statements
|
||||||
["CREATE TABLE datoms (e INTEGER NOT NULL, a SMALLINT NOT NULL, v BLOB NOT NULL, tx INTEGER NOT NULL,
|
["CREATE TABLE datoms (e INTEGER NOT NULL, a SMALLINT NOT NULL, v BLOB NOT NULL, tx INTEGER NOT NULL,
|
||||||
value_type_tag SMALLINT NOT NULL,
|
value_type_tag SMALLINT NOT NULL,
|
||||||
|
@ -176,7 +161,8 @@
|
||||||
number
|
number
|
||||||
(->SQLite [x] x)]))
|
(->SQLite [x] x)]))
|
||||||
|
|
||||||
(defn <-SQLite "Transforms SQLite values to Clojure{Script}."
|
(defn <-SQLite
|
||||||
|
"Transforms SQLite values to Clojure{Script}."
|
||||||
[valueType value]
|
[valueType value]
|
||||||
(case valueType
|
(case valueType
|
||||||
:db.type/ref value
|
:db.type/ref value
|
||||||
|
@ -186,8 +172,67 @@
|
||||||
:db.type/long value
|
:db.type/long value
|
||||||
:db.type/double value))
|
:db.type/double value))
|
||||||
|
|
||||||
|
;; Datomish rows are tagged with a numeric representation of :db/valueType:
|
||||||
|
;; The tag is used to limit queries, and therefore is placed carefully in the relevant indices to
|
||||||
|
;; allow searching numeric longs and doubles quickly. The tag is also used to convert SQLite values
|
||||||
|
;; to the correct Datomish value type on query egress.
|
||||||
|
(def value-type-tag-map
|
||||||
|
{:db.type/ref 0
|
||||||
|
:db.type/boolean 1
|
||||||
|
:db.type/instant 4
|
||||||
|
:db.type/long 5 ;; SQLite distinguishes integral from decimal types, allowing long and double to share a tag.
|
||||||
|
:db.type/double 5 ;; SQLite distinguishes integral from decimal types, allowing long and double to share a tag.
|
||||||
|
:db.type/string 10
|
||||||
|
:db.type/uuid 11
|
||||||
|
:db.type/uri 12
|
||||||
|
:db.type/keyword 13})
|
||||||
|
|
||||||
(defn ->tag [valueType]
|
(defn ->tag [valueType]
|
||||||
(or
|
(or
|
||||||
(valueType value-type-tag-map)
|
(valueType value-type-tag-map)
|
||||||
(raise "Unknown valueType " valueType ", expected one of " (sorted-set (keys value-type-tag-map))
|
(raise "Unknown valueType " valueType ", expected one of " (sorted-set (keys value-type-tag-map))
|
||||||
{:error :SQLite/tag, :valueType valueType})))
|
{:error :SQLite/tag, :valueType valueType})))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(defn <-tagged-SQLite
|
||||||
|
"Transforms SQLite values to Clojure with tag awareness."
|
||||||
|
[tag value]
|
||||||
|
(case tag
|
||||||
|
;; In approximate commonality order.
|
||||||
|
0 value ; ref.
|
||||||
|
1 (= value 1) ; boolean
|
||||||
|
4 (java.util.Date. value) ; instant
|
||||||
|
13 (keyword (subs value 1)) ; keyword
|
||||||
|
12 (java.net.URI. value) ; URI
|
||||||
|
11 (java.util.UUID/fromString value) ; UUID
|
||||||
|
; 5 value ; numeric
|
||||||
|
; 10 value ; string
|
||||||
|
value
|
||||||
|
)))
|
||||||
|
|
||||||
|
#?(:cljs
|
||||||
|
(defn <-tagged-SQLite
|
||||||
|
"Transforms SQLite values to ClojureScript with tag awareness."
|
||||||
|
[tag value]
|
||||||
|
;; In approximate commonality order.
|
||||||
|
(case tag
|
||||||
|
0 value ; ref.
|
||||||
|
1 (= value 1) ; boolean
|
||||||
|
4 (new Date value) ; instant
|
||||||
|
13 (keyword (subs value 1)) ; keyword
|
||||||
|
; 12 value ; URI
|
||||||
|
; 11 value ; UUID
|
||||||
|
; 5 value ; numeric
|
||||||
|
; 10 value ; string
|
||||||
|
value
|
||||||
|
)))
|
||||||
|
|
||||||
|
(defn tagged-SQLite-to-JS
|
||||||
|
"Transforms SQLite values to JavaScript-compatible values."
|
||||||
|
[tag value]
|
||||||
|
(case tag
|
||||||
|
1 (= value 1) ; boolean.
|
||||||
|
; 0 value ; No point trying to ident.
|
||||||
|
; 4 value ; JS doesn't have a Date representation.
|
||||||
|
; 13 value ; Return the keyword string from the DB: ":foobar".
|
||||||
|
value))
|
||||||
|
|
Loading…
Reference in a new issue