Add handling of simple schemas. Fixes #53.
This commit is contained in:
parent
bae1cfdc77
commit
360f7622e8
6 changed files with 143 additions and 9 deletions
|
@ -713,6 +713,10 @@
|
||||||
Returns a transduced channel of [result err] pairs.
|
Returns a transduced channel of [result err] pairs.
|
||||||
Closes the channel when fully consumed."
|
Closes the channel when fully consumed."
|
||||||
[db find options]
|
[db find options]
|
||||||
|
(let [unexpected (seq (clojure.set/difference (set (keys options)) #{:limit :order-by :inputs}))]
|
||||||
|
(when unexpected
|
||||||
|
(raise "Unexpected options: " unexpected {:bad-options unexpected})))
|
||||||
|
|
||||||
(let [{:keys [limit order-by inputs]} options
|
(let [{:keys [limit order-by inputs]} options
|
||||||
parsed (query/parse find)
|
parsed (query/parse find)
|
||||||
context (-> db
|
context (-> db
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
[datomish.db-factory :as db-factory]
|
[datomish.db-factory :as db-factory]
|
||||||
[datomish.pair-chan]
|
[datomish.pair-chan]
|
||||||
[datomish.sqlite :as sqlite]
|
[datomish.sqlite :as sqlite]
|
||||||
|
[datomish.simple-schema :as simple-schema]
|
||||||
[datomish.js-sqlite :as js-sqlite]
|
[datomish.js-sqlite :as js-sqlite]
|
||||||
[datomish.transact :as transact]))
|
[datomish.transact :as transact]))
|
||||||
|
|
||||||
|
@ -29,6 +30,38 @@
|
||||||
|
|
||||||
;; Public API.
|
;; Public API.
|
||||||
|
|
||||||
|
(defn ^:export db [conn]
|
||||||
|
(transact/db conn))
|
||||||
|
|
||||||
|
(defn ^:export q [db find options]
|
||||||
|
(let [find (cljs.reader/read-string find)
|
||||||
|
options (js->clj options)]
|
||||||
|
(take-pair-as-promise!
|
||||||
|
(db/<?q db find options))))
|
||||||
|
|
||||||
|
(defn ^:export ensure-schema [conn simple-schema]
|
||||||
|
(let [simple-schema (js->clj simple-schema)]
|
||||||
|
(println "simple-schema: " (pr-str simple-schema))
|
||||||
|
(take-pair-as-promise!
|
||||||
|
(transact/<transact!
|
||||||
|
conn
|
||||||
|
(simple-schema/simple-schema->schema simple-schema)))))
|
||||||
|
|
||||||
|
(defn js->tx-data [tx-data]
|
||||||
|
;; Objects to maps.
|
||||||
|
;; Arrays to arrays.
|
||||||
|
;; RHS strings… well, some of them will be richer types.
|
||||||
|
;; TODO
|
||||||
|
(println "Converting" (pr-str tx-data) "to" (pr-str (js->clj tx-data :keywordize-keys true)))
|
||||||
|
(println "Converting" (pr-str tx-data) "to" (pr-str (js->clj tx-data :keywordize-keys true)))
|
||||||
|
(js->clj tx-data))
|
||||||
|
|
||||||
|
(defn ^:export transact [conn tx-data]
|
||||||
|
;; Expects a JS array as input.
|
||||||
|
(let [tx-data (js->tx-data tx-data)]
|
||||||
|
(take-pair-as-promise!
|
||||||
|
(transact/<transact! conn tx-data))))
|
||||||
|
|
||||||
(defn ^:export open [path]
|
(defn ^:export open [path]
|
||||||
;; Eventually, URI. For now, just a plain path (no file://).
|
;; Eventually, URI. For now, just a plain path (no file://).
|
||||||
(take-pair-as-promise!
|
(take-pair-as-promise!
|
||||||
|
@ -38,10 +71,9 @@
|
||||||
(let [c (transact/connection-with-db db)]
|
(let [c (transact/connection-with-db db)]
|
||||||
(clj->js
|
(clj->js
|
||||||
{:conn c
|
{:conn c
|
||||||
|
:ensureSchema (fn [simple-schema] (ensure-schema c simple-schema))
|
||||||
|
:transact (fn [tx-data] (transact c tx-data))
|
||||||
|
:q (fn [find options] (q (transact/db c) find options))
|
||||||
:close (fn [] (db/close-db db))
|
:close (fn [] (db/close-db db))
|
||||||
:toString (fn [] (str "#<DB " path ">"))
|
:toString (fn [] (str "#<DB " path ">"))
|
||||||
:path path}))))))
|
:path path}))))))
|
||||||
|
|
||||||
(defn ^:export q [query & sources]
|
|
||||||
(let [query (cljs.reader/read-string query)]
|
|
||||||
(clj->js query)))
|
|
||||||
|
|
|
@ -208,3 +208,4 @@
|
||||||
{:pre [(or (nil? schema) (map? schema))]}
|
{:pre [(or (nil? schema) (map? schema))]}
|
||||||
(map->Schema {:schema (validate-schema schema)
|
(map->Schema {:schema (validate-schema schema)
|
||||||
:rschema (rschema schema)}))
|
:rschema (rschema schema)}))
|
||||||
|
|
||||||
|
|
66
src/common/datomish/simple_schema.cljc
Normal file
66
src/common/datomish/simple_schema.cljc
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
(ns datomish.simple-schema
|
||||||
|
#?(:cljs
|
||||||
|
(:require-macros
|
||||||
|
[datomish.pair-chan :refer [go-pair <?]]
|
||||||
|
[cljs.core.async.macros :refer [go]]))
|
||||||
|
(:require
|
||||||
|
[clojure.set]
|
||||||
|
[datomish.util :as util
|
||||||
|
#?(:cljs :refer-macros :clj :refer) [raise raise-str cond-let]]
|
||||||
|
[datomish.db :as db]
|
||||||
|
[datomish.schema :as ds]
|
||||||
|
[datomish.sqlite :as s]
|
||||||
|
[datomish.sqlite-schema :as sqlite-schema]
|
||||||
|
#?@(:clj [[datomish.pair-chan :refer [go-pair <?]]
|
||||||
|
[clojure.core.async :as a :refer [chan go <! >!]]])
|
||||||
|
#?@(:cljs [[datomish.pair-chan]
|
||||||
|
[cljs.core.async :as a :refer [chan <! >!]]])))
|
||||||
|
|
||||||
|
(defn- name->ident [name]
|
||||||
|
(when-not (and (string? name)
|
||||||
|
(not (empty? name)))
|
||||||
|
(raise "Invalid name " name {:error :invalid-name :name name}))
|
||||||
|
(keyword name))
|
||||||
|
|
||||||
|
(defn simple-schema-attributes->schema-parts [attrs]
|
||||||
|
(let [{:keys [cardinality type name unique doc fulltext]} attrs
|
||||||
|
value-type (when type (keyword (str "db.type/" type)))]
|
||||||
|
|
||||||
|
(when-not (and value-type
|
||||||
|
(contains? ds/value-type-map value-type))
|
||||||
|
(raise "Invalid type " type {:error :invalid-type :type type}))
|
||||||
|
|
||||||
|
(let [unique
|
||||||
|
(case unique
|
||||||
|
"identity" :db.unique/identity
|
||||||
|
"value" :db.unique/value
|
||||||
|
nil nil
|
||||||
|
(raise "Invalid unique " unique
|
||||||
|
{:error :invalid-unique :unique unique}))
|
||||||
|
|
||||||
|
cardinality
|
||||||
|
(case cardinality
|
||||||
|
"one" :db.cardinality/one
|
||||||
|
"many" :db.cardinality/many
|
||||||
|
nil nil
|
||||||
|
(raise "Invalid cardinality " cardinality
|
||||||
|
{:error :invalid-cardinality :cardinality cardinality}))]
|
||||||
|
|
||||||
|
(util/assoc-if
|
||||||
|
{:db/valueType value-type
|
||||||
|
:db/ident (name->ident name)
|
||||||
|
:db/id (db/id-literal :db.part/user)
|
||||||
|
:db.install/_attribute :db.part/db}
|
||||||
|
:db/doc doc
|
||||||
|
:db/unique unique
|
||||||
|
:db/fulltext fulltext
|
||||||
|
:db/cardinality cardinality))))
|
||||||
|
|
||||||
|
(defn simple-schema->schema [simple-schema]
|
||||||
|
(let [{:keys [name attributes]} simple-schema]
|
||||||
|
(map simple-schema-attributes->schema-parts attributes)))
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
(ns datomish.core
|
(ns datomish.core
|
||||||
(:require [cljs.nodejs :as nodejs]))
|
(:require [cljs.nodejs :as nodejs]))
|
||||||
|
|
||||||
(nodejs/enable-util-print!)
|
(defn -main [& args])
|
||||||
|
|
||||||
(defn -main [& args]
|
|
||||||
(println "Hello world!"))
|
|
||||||
|
|
||||||
(set! *main-cli-fn* -main)
|
(set! *main-cli-fn* -main)
|
||||||
|
(nodejs/enable-util-print!)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
[datomish.db.debug :refer [<datoms-after <transactions-after <shallow-entity <fulltext-values]]
|
[datomish.db.debug :refer [<datoms-after <transactions-after <shallow-entity <fulltext-values]]
|
||||||
[datomish.util :as util #?(:cljs :refer-macros :clj :refer) [raise cond-let]]
|
[datomish.util :as util #?(:cljs :refer-macros :clj :refer) [raise cond-let]]
|
||||||
[datomish.schema :as ds]
|
[datomish.schema :as ds]
|
||||||
|
[datomish.simple-schema]
|
||||||
[datomish.sqlite :as s]
|
[datomish.sqlite :as s]
|
||||||
[datomish.sqlite-schema]
|
[datomish.sqlite-schema]
|
||||||
[datomish.datom]
|
[datomish.datom]
|
||||||
|
@ -816,4 +817,37 @@
|
||||||
(finally
|
(finally
|
||||||
(<? (d/<close conn))))))))
|
(<? (d/<close conn))))))))
|
||||||
|
|
||||||
|
(deftest-db test-simple-schema conn
|
||||||
|
(let [in {:name "mystuff"
|
||||||
|
:attributes [{:name "foo/age"
|
||||||
|
:type "long"
|
||||||
|
:cardinality "one"}
|
||||||
|
{:name "foo/name"
|
||||||
|
:type "string"
|
||||||
|
:cardinality "many"
|
||||||
|
:doc "People can have many names."}
|
||||||
|
{:name "foo/id"
|
||||||
|
:type "string"
|
||||||
|
:cardinality "one"
|
||||||
|
:unique "value"}]}
|
||||||
|
expected [{:db/ident :foo/age
|
||||||
|
:db/valueType :db.type/long
|
||||||
|
:db/cardinality :db.cardinality/one
|
||||||
|
:db.install/_attribute :db.part/db}
|
||||||
|
{:db/ident :foo/name
|
||||||
|
:db/valueType :db.type/string
|
||||||
|
:db/cardinality :db.cardinality/many
|
||||||
|
:db/doc "People can have many names."
|
||||||
|
:db.install/_attribute :db.part/db}
|
||||||
|
{:db/ident :foo/id
|
||||||
|
:db/valueType :db.type/string
|
||||||
|
:db/cardinality :db.cardinality/one
|
||||||
|
:db/unique :db.unique/value
|
||||||
|
:db.install/_attribute :db.part/db}]]
|
||||||
|
|
||||||
|
(testing "Simple schemas are expanded."
|
||||||
|
(is (= (map #(dissoc %1 :db/id) (datomish.simple-schema/simple-schema->schema in))
|
||||||
|
expected)))))
|
||||||
|
|
||||||
|
|
||||||
#_ (time (t/run-tests))
|
#_ (time (t/run-tests))
|
||||||
|
|
Loading…
Reference in a new issue