Commit graph

226 commits

Author SHA1 Message Date
Richard Newman 8e6f8399ae Add <??, a null-safe variant of <?. 2016-11-16 21:04:13 -08:00
Richard Newman 7e50528788 Add repeated-keys utility. 2016-11-16 21:04:13 -08:00
Richard Newman 30023dd939 Move test helpers so they're not included in the built output. 2016-11-16 21:04:12 -08:00
Richard Newman 8ad434574e Remove dependency on Tufte. Fixes #109. 2016-11-16 21:03:59 -08:00
Richard Newman 9d361055d3 Implement schema alteration. Fixes #78.
Altering uniqueness and cardinality attributes works, with the exception
of enabling uniqueness from nothing.

:db/noHistory and :db/isComponent changes are implemented but untested,
and aren't really supported by Datomish anyway.
2016-10-24 20:01:44 -07:00
Richard Newman 46269fe720 Add db.alter/attribute to the bootstrap schema. 2016-10-24 20:01:44 -07:00
Richard Newman 9d81abace5 Implement ident renaming. Fixes #103. 2016-10-24 20:01:44 -07:00
Richard Newman 3cfccc4b81 Implement ground. Fixes #99. 2016-10-19 12:54:05 -07:00
Nick Alexander 3670c5cce7 Review comment: save allocations when evolving. 2016-10-14 10:20:43 -07:00
Nick Alexander 679ab8cf7d Review comment: explain why upserts between generational steps don't conflict. 2016-10-14 10:20:43 -07:00
Nick Alexander caa9d2d7cb Review comment: prefer dissoc and update to destructuring. 2016-10-14 10:20:43 -07:00
Nick Alexander 00c72f9188 Review comment: fix "Like {...}" map examples. 2016-10-14 10:20:43 -07:00
Nick Alexander 885a816812 Review comment: style nits. 2016-10-14 10:20:43 -07:00
Nick Alexander 39c909ec32 Rewrite resolve-id-literals to use bulk <avs. (#88)
The metaphor we use is that of "evolution", where each "evolutionary
step" contains a number of different "generations".  Entities in the
process of being resolved are increasingly "evolved" into simpler
generations, until no further evolution is possible.
2016-10-14 10:20:43 -07:00
Nick Alexander 1c83287fcf Pre: Make <avs handle fulltext datoms correctly.
The test would fail because we would have an [a v] pair with a string
value, but we were looking for the fulltext rowid in <avs.  Using
all_datoms correctly looks up the string value, at the cost of crippling
the speed of <avs.
2016-10-14 10:20:43 -07:00
Nick Alexander 60c7db4301 Pre: Make testing consistent by sorting fulltext values before inserting.
This sorts fulltext values inserted in a single transaction, not across
transactions.  This makes the rowids assigned in the fulltext_values
table internally consistent, even as the order of entities and datoms
changes (as the transaction applying algorithm evolves over time).  The
test changes simply make the fulltext values sort easily.

In theory, these fulltext values could be very large, and sorting might
be very expensive.  In practice, we expect values to differ in their
first few characters, so that this is efficient (i.e., proportional to
the number of fulltext values inserted and not their size).
2016-10-14 10:20:43 -07:00
Nick Alexander bc011bbf43 Pre: Add util/group-by-kv. 2016-10-14 10:20:43 -07:00
Richard Newman feebfd09da Generate known type for the entity in a fulltext expression, and add a test. Fixes #85. 2016-10-13 18:19:29 -07:00
Nick Alexander a4dd7e4e9c Review comment: make a large-ish dropping buffer for JS listen! consumers. 2016-10-13 16:11:22 -07:00
Nick Alexander 032bfafec2 Review comment: fail pending transactions after closing connection.
This is pretty difficult to test robustly, but here's a stab at it.
2016-10-13 16:11:22 -07:00
Nick Alexander f02d508370 Review comment: ensure <transact! after <close is rejected. 2016-10-13 16:11:22 -07:00
Nick Alexander b20c70fc2a Review comment: ensure report is non-nil after in-transaction!. 2016-10-13 16:11:22 -07:00
Nick Alexander cea0e3d60f Review comment: return pair-chan; accept a result chan and close? flag. 2016-10-13 16:11:22 -07:00
Nick Alexander e5917406b4 Add {un}listen{-chan}! to connection. (#61) 2016-10-13 16:11:16 -07:00
Nick Alexander a8ad79d0e6 Make <transact! run in a critical section. (#80) 2016-10-11 20:32:35 -07:00
Nick Alexander 2081ca4563 Pre: Add unlimited-buffer and unblocking-chan?. 2016-10-11 20:32:35 -07:00
Nick Alexander e1b1abe2de Pre: clarify comments. 2016-10-11 20:32:35 -07:00
Richard Newman c36be57018 Expose a 'tempid' function on transaction results, because JS object lookup doesn't work for TempIds. 2016-10-07 20:12:17 -07:00
Richard Newman 5b6000003d Support order-by query option from JS. 2016-10-07 20:12:17 -07:00
Richard Newman e89544beba Implement all four find specs. Fixes #38. r=nalexander 2016-10-07 11:02:35 -07:00
Richard Newman 021f2be620 Review comment: add comment about cljify. 2016-10-05 14:07:07 -07:00
Richard Newman 61757e271c Review comment: use datomish.api where possible. 2016-10-05 14:06:36 -07:00
Richard Newman c7d0a8596b Part 2: extend 'cljify' implementation to round-trip records like TempId. 2016-10-05 12:54:26 -07:00
Richard Newman 0b6ac81ed5 Part 1: extend 'db' JS object with more useful methods. 2016-10-05 12:53:57 -07:00
Richard Newman b777445ebf Sort variable sets to make tests consistent across platforms. 2016-10-04 11:38:14 -07:00
Nick Alexander 3cd64fb4d8 Review comments. 2016-09-30 17:00:27 -07:00
Nick Alexander 611d44fcce Process lookup-refs in batches. Fixes #25.
This uses a common table expression and multiple SQL calls rather than a
temporary table, since transactions with huge numbers of distinct
lookup-refs are likely to be very rare.

We mark lookup-refs with `lookup-ref`, which is a little awkward because
binding `(let [[a v] lookup-ref] ...)` doesn't directly work, but avoids
some ambiguity present in Datomic and DataScript around interpreting
lookup-refs as multiple value lists.  (Which bit the tests in an earlier
version of this patch!)
2016-09-30 16:47:04 -07:00
Nick Alexander 20531c1789 Pre: Don't insert nil tx where it should not be. 2016-09-30 16:47:04 -07:00
Nick Alexander c46f0eb8ae Part 2: Get rid of {0, 1} -> {2, 3} mapping for added/added0. Fixes #28.
Now that we copying from tx_lookup_before -> tx_lookup_after, we don't
need to avoid duplicating rows.
2016-09-30 16:47:04 -07:00
Nick Alexander da1250d210 Part 1: Separate tx_lookup into tx_lookup_before and tx_lookup_after. 2016-09-30 16:47:04 -07:00
Richard Newman a7d6a37cfc Update comment in cc.cljc. 2016-09-29 15:49:30 -07:00
Richard Newman 6ab93208cb Part 2: implement complex 'or' translation. Fixes #57. r=nalexander
We implement sql-projection-for-simple-variable-list to allow us to add
a projection to subqueries.
2016-09-29 15:46:15 -07:00
Richard Newman b9b9c37dfa Part 1: pass in :select when creating a partial subquery from a CC. 2016-09-29 15:44:16 -07:00
Richard Newman 1296b8090f Allow sets of attributes in fulltext expressions. Fixes #54. r=nalexander 2016-09-26 16:34:37 -07:00
Richard Newman 9587311412 Include deps.cljs giving externs for Node.js consumers; normalize build output.
cljsbuild using leiningen projects that depend on Datomish will
automatically include the externs.
2016-09-22 16:24:37 -07:00
Richard Newman d0a04a5e56 Review comment: extracted shared go-promise. 2016-09-22 16:24:37 -07:00
Richard Newman 17d7eaec7b Add a babelified test file, Webpack the add-on, and make the JS API work.
We concatenate a simple setTimeout monkeypatch onto the add-on itself.
2016-09-22 15:59:15 -07:00
Richard Newman 360f7622e8 Add handling of simple schemas. Fixes #53. 2016-09-22 15:59:15 -07:00
Richard Newman 4f37a86039 Use cljify in promise-sqlite. 2016-09-22 15:59:15 -07:00
Richard Newman ea027e8cea Implement cljify. 2016-09-22 15:59:15 -07:00
Richard Newman 1d53d547b8 Externs. 2016-09-22 12:43:36 -07:00
Richard Newman 330433a45c Add externs file for Node's use of promise_sqlite. 2016-09-22 12:43:35 -07:00
Nick Alexander 1a30306314 Move datomish.api into exported namespace. 2016-09-19 12:03:09 -07:00
Richard Newman b5aec2e890 Move src-node and src-browser into subdirectories of src. 2016-09-09 12:07:03 -07:00
Richard Newman 418bb34d57 Add is-node?. 2016-09-08 19:11:44 -07:00
Richard Newman 5ccc725b56 Flesh out JS API. 2016-09-08 19:11:44 -07:00
Richard Newman 9e4e95ce51 Default SQLite's user_version to zero.
I saw nil here with Sqlite.jsm.
2016-09-08 19:11:44 -07:00
Richard Newman cc25ce33e2 Move platform-specific code into src-node. 2016-09-08 19:11:44 -07:00
Richard Newman 9dbda3d9d8 Pre: remove exec_repl.cljc. 2016-09-08 19:04:15 -07:00
Richard Newman 53322d8389 Pre: @arg -> @param to quiet cljsbuild warnings. 2016-09-08 19:04:15 -07:00
Nick Alexander 659c26339c Serialize and de-serialize non-keyword schema values correctly. Fixes #52. 2016-09-07 17:31:30 -07:00
Nick Alexander 362bdb2028 Add :db.fn/retractAttribute and :db.fn/retractEntity. Fixes #46.
There's no distinction made for fulltext attributes, since the values
found by the retractAttributes SELECT are already rowids into the
fulltext_values table and therefore need no additional mapping.
2016-09-06 13:13:20 -07:00
Nick Alexander 94bac9704b Pre: Use SQLite temp files in deftest-db.
These temp files will almost certainly live in memory only, speeding our
test suite evaluation significantly.  Before this patch, in a warmed
REPL environment I get:

Testing datomish.db-test

Ran 19 tests containing 97 assertions.
0 failures, 0 errors.
"Elapsed time: 1408.720681 msecs"
"Elapsed time: 1343.986464 msecs"
"Elapsed time: 1338.660762 msecs"

After this patch, in a warmed REPL environment I get:

Testing datomish.db-test

Ran 19 tests containing 97 assertions.
0 failures, 0 errors.
"Elapsed time: 587.605168 msecs"
"Elapsed time: 569.522333 msecs"
"Elapsed time: 589.080282 msecs"
2016-09-06 13:13:20 -07:00
Nick Alexander cfdce12c1a Pre: Use deftest-db in tests. 2016-09-06 13:13:20 -07:00
Richard Newman 5424e61be4 Review comment: args -> inputs. 2016-09-02 16:23:30 -07:00
Richard Newman 1197764949 Implement :limit and :order-by-vars. Fixes #37.
We'd like this to be part of the query syntax itself, but doing so
requires extending DataScript's parser.

Instead we generalize our `args` to `options`, and take `:limit`
and `:order-by-vars`. The former must be an integer or nil, and the
latter is an array of `[var direction]` pairs.

This commit includes descriptive error messages and tests for success
and failure.
2016-09-02 08:32:45 -07:00
Nick Alexander d92016166a Cache partition map and update materialized partition view once. Fixes #47.
This caches a partition map per DB, which is helpful because it exposes
what the point in time DB partition state is, but is unhelpful because
the partition state can advance underneath the DB cache.  This is
generally true of the approach -- this can happen to the ident/entid
maps, and the datoms themselves -- so we'll roll with it for now.

This reduces the number of SQL UPDATE operations from linear in the
number of id-literals used to constant in the number of known
partitions.
2016-09-01 14:46:04 -07:00
Nick Alexander d419554361 Revert "Add Datomic, for testing."
This reverts commit 1b1cc6f18e.

This should never have escaped the lab; Datomic is not a dependency of
Datomish.
2016-08-31 16:17:08 -07:00
Richard Newman 7486c2a8ba Hacking on exec-repl. 2016-08-30 18:22:23 -07:00
Richard Newman ae65ba14fb Review comment: move assoc-if to utils. 2016-08-30 18:22:22 -07:00
Richard Newman 6fbd63fed2 Review comment: clarity. 2016-08-30 18:22:22 -07:00
Richard Newman 495e5a737e Review comment: check that Datalog vars don't have a namespace.
And fix the only test that uses syntax-quote, which namespace-qualifies bare symbols.
2016-08-30 18:22:22 -07:00
Richard Newman 0f399eafb0 Review comment: better UUID support. 2016-08-30 18:22:22 -07:00
Richard Newman 7d684216f0 Extension: allow non-constant attributes in fulltext expressions. Fixes #42.
This change breaks compatibility with Datomic, but is useful when we simply want
to find entities linked somehow to matching content.
2016-08-30 18:22:22 -07:00
Richard Newman 31e354ae61 Correctly distinguish between fulltext-values and fulltext-datoms. 2016-08-30 18:22:22 -07:00
Richard Newman a9b26f154a Add (currently unused) ability to generate CTEs. 2016-08-30 18:22:22 -07:00
Richard Newman f225dbe734 Implement get-else. 2016-08-30 18:22:22 -07:00
Richard Newman 38cd30a895 Implement aggregation. Fixes #39. 2016-08-30 18:22:22 -07:00
Richard Newman 1e04425287 Dates in and out. 2016-08-30 18:22:21 -07:00
Richard Newman 0cd6da1039 Add :db/doc as a default attribute. 2016-08-30 18:22:21 -07:00
Richard Newman 893f944596 Error out when an attribute could not be interned when transacting. 2016-08-30 18:22:11 -07:00
Richard Newman bdac50e03c Define deftest-db to do async testing with an open DB. 2016-08-30 18:22:11 -07:00
Richard Newman 479a7fd583 Project real values. Fixes #30. 2016-08-30 18:22:11 -07:00
Richard Newman 1c6244db5b Implement type-aware querying. Fixes #14.
* Alter how clauses are concatenated. They now preserve order more accurately.
* Track mappings between vars and extracted type columns.
* Generate type code constraints.
* Push known types down into :not.
* Push known types down into :or.
* Tests and test fixes.
2016-08-30 18:22:11 -07:00
Richard Newman 2529378725 Rewrite <resolve-lookup-refs to work for lookup refs.
Note that `go` (and `go-pair`) don't descend into `for` comprehensions
and other situations in which a fn is created. This commit rewrites to
use nested `loop`s, and also improves use of `<av`.
2016-08-30 18:22:11 -07:00
Richard Newman 86b5a8ea8a Rework <apply-entities to be 40% faster and not blow the stack in CLJS.
* Batch up datoms into a smaller number of queries, improving transact speed by about 50%.
* Restore transacting FTS attributes.
* Implement retraction of freetext datoms.
2016-08-30 18:22:11 -07:00
Richard Newman 587959d1ff Simplify id-literal?, avoid some consing. 2016-08-30 18:22:11 -07:00
Richard Newman b4112bbe52 Symbolicating is not expensive. 2016-08-30 18:22:10 -07:00
Richard Newman 43a96efd32 Memoize and simplify parts of insertion. 2016-08-30 18:22:10 -07:00
Richard Newman 6b480a700d Minor perf improvement: use UNION ALL to populate tx_lookup in a single INSERT. 2016-08-30 18:22:10 -07:00
Richard Newman f53869ba6f Minor perf improvement: create idx_tx_lookup_added after populating tx_lookup. 2016-08-30 18:22:10 -07:00
Richard Newman 2a55b138f6 Limit number of imported places, not number of imported rows. Default to 1000. 2016-08-30 18:22:10 -07:00
Richard Newman 5836b1867e Don't attempt to add a places visit list of (nil). 2016-08-30 18:22:10 -07:00
Richard Newman db8d043b27 Places import: add a title import function to exercise lookup refs. 2016-08-30 18:22:10 -07:00
Richard Newman 5ec79f6be3 Places import: LEFT JOIN correctly to pick up unvisited pages. 2016-08-30 18:22:10 -07:00
Richard Newman f85968de88 Places import: title is the same for each returned row. Don't filter. 2016-08-30 18:22:10 -07:00
Richard Newman d7018aedaa Remove dependency on test code from places importer. 2016-08-30 18:22:10 -07:00
Nick Alexander 3775c7c773 Start importing places. This is just about profiling for now. 2016-08-30 18:22:10 -07:00
Nick Alexander 71446a3af5 Completely rewrite main transaction logic to be faster.
This is almost complete; it passes the test suite save for retracting
fulltext datoms correctly.

There's a lot to say about this approach, but I don't have time to give
too many details.  The broad outline is as follows.  We collect datoms
to add and retract in a tx_lookup table.  Depending on flags ("search
value" sv and "search value type tag" svalue_type_tag) we "complete" the
tx_lookup table by joining matching datoms.  This allows us to find
datoms that are present (and should not be added as part of the
transaction, or should be retracted as part of the transaction, or
should be replaced as part of the transaction.  We complete the
tx_lookup (in place!) in two separate INSERTs to avoid a quadratic
two-table walk (explain the queries to observe that both INSERTs walk
the lookup table once and then use the datoms indexes to complete the
matching values).

We could simplify the code by using multiple lookup tables, both for the
two cases of search parameters (eav vs. ea) and for the incomplete and
completed rows.  Right now we differentiate the former with NULL checks,
and the latter by incrementing the added0 column.  It performs well
enough, so I haven't tried to understand the performance of separating
these things.

After the tx_lookup table is completed, we build the transaction from
it; and update the datoms materialized view table as well.  Observe the
careful handling of the "search value" sv parameters to handle replacing
:db.cardinality/one datoms.

Finally, we read the processed transaction back to produce to the API.
This is strictly to match the Datomic API; we might make allow to skip
this, since many consumers will not want to stream this over the wire.

Rough timings show the transactor processing a single >50k datom
transaction in about 3.5s, of which less than 0.5s is spent in the
expensive joins.  Further, repeating the processing of the same
transaction is only about 3.5s again!  That's the worst possible for the
joins, since every single inserted datom will already be present in the
database, making the most expensive join match every row.
2016-08-30 18:22:10 -07:00
Nick Alexander b59c71cb00 Extract datomish.db.debug from test code, in order to use it during development. 2016-08-30 18:22:10 -07:00