mentat/tx/fixtures/test_upsert_vector.edn
Nick Alexander 16e9740d8a Implement upsert resolution algorithm. (#186, #283). r=rnewman, f=jsantell
* Pre: Implement batch [a v] pair lookup.

* Pre: Add InternSet for sharing ref-counted handles to large values.

* Pre: Derive more for Entity.

* Pre: Return DB from creating; return TxReport from transact.

I explicitly am not supporting opening existing databases yet, let
alone upgrading databases from earlier versions.  That can follow fast
once basic transactions are supported.

* Pre: Parse string temporary ID entities; remove ValueOrLookupRef.

This adds TempId entities, but we can't disambiguate String temporary
IDs from values without the use of the schema, so there's no new value
branch.  Similarly, we can't disambiguate lookup-ref values from two
element list values without a schema, so we remove this entirely.
We'll handle the ambiguity later in the transactor.

* Persist partitions to SQL store; allocate transaction ID. (#186)

* Post: Test upserting with vectors.

This converts an existing test to EDN:
84a80f40f5/test/datomish/db_test.cljc (L193).

* Implement tempid upsert resolution algorithm. (#184)

* Post: Separate Tx out of DB.

This is very preliminary, since we don't have a real connection type
to manage transactions and their metadata yet.

* Post: Comment on implementation choices in the transactor.

* Review comment: Put long use lists on separate lines.

* Review comment: Accept String: Borrow<S> instead of just String.

* Review comment: Address nits.
2017-02-14 16:50:40 -08:00

122 lines
3.7 KiB
Clojure

[{:test/label ":db.cardinality/one, insert"
:test/assertions
[[:db/add 100 :db/ident :name/Ivan]
[:db/add 101 :db/ident :name/Petr]]
:test/expected-transaction
#{[100 :db/ident :name/Ivan ?tx1 true]
[101 :db/ident :name/Petr ?tx1 true]
[?tx1 :db/txInstant ?ms1 ?tx1 true]}
:test/expected-datoms
#{[100 :db/ident :name/Ivan]
[101 :db/ident :name/Petr]}}
{:test/label "upsert two tempids to same entid"
:test/assertions
[[:db/add "t1" :db/ident :name/Ivan]
[:db/add "t1" :db.schema/attribute 100]
[:db/add "t2" :db/ident :name/Petr]
[:db/add "t2" :db.schema/attribute 101]]
:test/expected-transaction
#{[100 :db.schema/attribute 100 ?tx2 true]
[101 :db.schema/attribute 101 ?tx2 true]
[?tx2 :db/txInstant ?ms2 ?tx2 true]}
:test/expected-datoms
#{[100 :db/ident :name/Ivan]
[101 :db/ident :name/Petr]
[100 :db.schema/attribute 100]
[101 :db.schema/attribute 101]}
:test/expected-tempids
{"t1" 100
"t2" 101}}
{:test/label "upsert with tempid"
:test/assertions
[[:db/add "t1" :db/ident :name/Ivan]
;; Ref doesn't have to exist (at this time). Can't reuse due to :db/unique :db.unique/value.
[:db/add "t1" :db.schema/attribute 102]]
:test/expected-transaction
#{[100 :db.schema/attribute 102 ?tx3 true]
[?tx3 :db/txInstant ?ms3 ?tx3 true]}
:test/expected-datoms
#{[100 :db/ident :name/Ivan]
[101 :db/ident :name/Petr]
[100 :db.schema/attribute 100]
[100 :db.schema/attribute 102]
[101 :db.schema/attribute 101]}
:test/expected-tempids
{"t1" 100}}
;; TODO: don't hard-code allocated entids.
{:test/label "single complex upsert allocates new entid"
:test/assertions
[[:db/add "t1" :db.schema/attribute "t2"]]
:test/expected-transaction
#{[65536 :db.schema/attribute 65537 ?tx4 true]
[?tx4 :db/txInstant ?ms4 ?tx4 true]}
:test/expected-tempids
{"t1" 65536
"t2" 65537}}
{:test/label "conflicting upserts fail"
:test/assertions
[[:db/add "t1" :db/ident :name/Ivan]
[:db/add "t1" :db/ident :name/Petr]]
:test/expected-transaction
nil
:test/expected-error-message
"Conflicting upsert"
;; nil
}
{:test/label "tempids in :db/retract that do upsert are fine"
:test/assertions
[[:db/add "t1" :db/ident :name/Ivan]
;; This ref doesn't exist, so the assertion will be ignored.
[:db/retract "t1" :db.schema/attribute 103]]
:test/expected-transaction
#{[?tx6 :db/txInstant ?ms6 ?tx6 true]}
:test/expected-error-message
""
:test/expected-tempids
{}}
{:test/label "tempids in :db/retract that don't upsert fail"
:test/assertions
[[:db/retract "t1" :db/ident :name/Anonymous]]
:test/expected-transaction
nil
:test/expected-error-message
""}
;; The upsert algorithm will first try to resolve "t1", fail, and then allocate both "t1" and "t2".
{:test/label "multistep, both allocated"
:test/assertions
[[:db/add "t1" :db/ident :name/Josef]
[:db/add "t2" :db.schema/attribute "t1"]]
:test/expected-transaction
#{[65538 :db/ident :name/Josef ?tx8 true]
[65539 :db.schema/attribute 65538 ?tx8 true]
[?tx8 :db/txInstant ?ms8 ?tx8 true]}
:test/expected-error-message
""
:test/expected-tempids
{"t1" 65538
"t2" 65539}}
;; Can't quite test this without more schema elements.
;; ;; This time, we can resolve both, but we have to try "t1", succeed, and then resolve "t2".
;; {:test/label "multistep, upserted allocated"
;; :test/assertions
;; [[:db/add "t1" :db/ident :name/Josef]
;; [:db/add "t2" :db/ident "t1"]]
;; :test/expected-transaction
;; #{[65538 :db/ident :name/Josef]
;; [65538 :db/ident :name/Karl]
;; [?tx8 :db/txInstant ?ms8 ?tx8 true]}
;; :test/expected-error-message
;; ""
;; :test/expected-tempids
;; {"t1" 65538
;; "t2" 65539}}
]