This is necessary for the timelines work ahead. When schema is being
moved off of a main timeline, we need to be able to retract it cleanly.
Retractions are only processed if the whole defining attribute set
is being retracted at once (:db/ident, :db/valueType, :db/cardinality).
Timelines work starts to perform modifications on the partitions
that go beyond simple allocations. This change pre-emptively protects
partition integrity by asserting that index modifications are legal.
Generally, I think that Mentat is using too many small traits rather
than wrapping types into newtypes. Wrapping into newtypes is cheap in
Rust, and it makes it easier to reason about the code.
* Add a top-level "syncable" feature.
Tested with:
cargo test --all
cargo test --all --no-default-features
cargo build --manifest-path tools/cli/Cargo.toml --no-default-features
cargo run --manifest-path tools/cli/Cargo.toml --no-default-features debugcli
Co-authored-by: Nick Alexander <nalexander@mozilla.com>
* Add 'syncable' feature to 'db' crate to conditionally derive serialization for Partition*
This is leading up to syncing with partition support.
* Part 3: Parameterize Entity by value type.
This isn't quite right, because after parsing, we shouldn't care
about` `edn::ValueAndSpan`, we should care only about edn::Value.
However, I think we can drop `ValueAndSpan` entirely if we just use
`rust-peg` (and its simpler error messages) rather than a mix of
`rust-peg` and `combine`.
In any case, this paves the way to transacting `Entity<TypedValue>`,
which is a nice step towards building general entities.
* Part 1: Add AttributePlace.
* Part 2: Name other places EntityPlace and ValuePlace.
Now we're consistent and closer to self-documenting. Both matter more
as we expose `Entity` as the thing to build for programmatic usage.
* Part 4: Allow Ident and TempId in ValuePlace.
The parser will never produce these, since determining whether an
integer/keyword or string is an ident or a tempid, respectively, in
the value place requires the schema.
But a builder that produces `Entity` instances directly will want to
produce these.
Simplify.
This has a watcher collect txid -> AttributeSet mappings each time a
transact occurs. On commit we retrieve those mappings and hand them over
to the observer service, which filters them and packages them up for
dispatch.
Tidy up
Pre: export AttributeBuilder from mentat_db.
Pre: fix module-level comment for tx/src/entities.rs.
Pre: rename some `to_` conversions to `into_`.
Pre: make AttributeBuilder::unique less verbose.
Pre: split out a HasSchema trait to abstract over Schema.
Pre: rename SchemaMap/schema_map to AttributeMap/attribute_map.
Pre: TypedValue/NamespacedKeyword conversions.
Pre: turn Unique and ValueType into TypedValue::Keyword.
Pre: export IntoResult.
Pre: export NamespacedKeyword from mentat_core.
Pre: use intern_set in tx.
Pre: add InternSet::len.
Pre: comment gardening.
Pre: remove inaccurate TODO from TxReport comment.
* Update some dependencies.
* Update rusqlite to 0.12.
* Update error-chain to a forked version that implements Sync.
* Fix some compiler warnings.
* Remove unused imports in tests.
* Parse errors no longer naturally print with the expected symbol.
This commit adds a check to the partition map that a provided entity ID
has been mentioned (i.e., is present in the start:index range of one of
our partitions).
We introduce a newtype for known entity IDs, using this internally in
the tx expander to track user-provided entids that have passed the above
check (and IDs that we allocate as part of tempid processing). This
newtype is stripped prior to tx assertion.
In order that DB tests can continue to write
[:db/add 111 :foo/bar 222]
we add an additional fake partition to our test connections, ranging
from 100 to 1000.
* Pre: unused import in translate.rs.
* Part 2: take a dependency on rusqlite for query arguments.
* Part 1: flatten V2 schema into V1. Add UUID and URI.
Bump expected ident and bootstrap datom count in tests.
* Part 5: parse edn::Value::Uuid.
* Part 3: extend ValueType and TypedValue to include Uuid.
* Part 4: add Uuid to query arguments.
* Part 6: extend db to support Uuid.
* Part 8: add a tx-parser test for #f NaN and #uuid.
* Part 7: parse and algebrize UUIDs in queries.
* Part 1: parse #inst in EDN and throughout query engine.
* Part 3: handle instants in db.
* Part 2: instants never matches integers in queries.
* Part 4: use DateTime for tx_instants.
* Add a test for adding and querying UUIDs and instants.
* Review comments.
* Test collecting tempids after upsert resolution. Fixes#299.
I just didn't finish and expose the tempid collection when I
implemented upsert resolution. Here it is!
* Review comment: Take ownership of temp_id_map; avoid contains_key().
* 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.
* Move Schema from mentat_db to mentat_core.
* Define SchemaMap in terms of Entid, not i64.
* Add Schema::{is_attribute,identifies_attribute}.
* Add pointer to #291.
* Don't pass around 64-bit pointers to 64-bit integers.
* Start installing the SQLite store and bootstrapping the datom store.
* Review comment: Decomplect V2_IDENTS.
* Review comment: Decomplect V2_PARTS.
* Review comment: Pre: Expose Clojure's merge on Value instances.
* Review comment: Decomplect V2_SYMBOLIC_SCHEMA.
* Review comment: Decomplect V1_STATEMENTS.
* Review comment: Prefer ? to try!.
* Review comment: Fix typos; format; add TODOs.
* Review comment: Assert that Mentat `Schema` is valid upon creation.
* Review comment: Improve conversion to and from SQL values.
This patch factors the fundamental SQL conversion maps
between (rusqlite::Value, value_type_tag) and (edn::Value, ValueType)
through a new Mentat TypedValue. (A future patch might rename this
fundamental type mentat::Value.)
To make certain conversion functions infallible, I removed
placeholders for :db.type/{instant,uuid,uri}. (We could panic
instead, but there's no need to do that right now.)
* Review comment: Always uses bundled SQLite in rusqlite.
This avoids (runtime) failures in Travis CI due to old SQLite
versions. See 432966ac77.
* Review comment: Move semantics in `from_sql_value_pair`.
* Review comment: DB_EXCISE_BEFORE_T instead of ...BEFORET (no underscore).
* Review comment: Move overview notes to the Wiki.