- Silently skip nils in transaction (was stopping processing without an error before)
- Fixed compatibility with CLJS 1.9.660 (#233, #236)
- Fixed rules ignoring false arguments passed to them (#218)
- Fixed infinite loop in parser on CLJS 1.9.456+ (#210)
- Added
contains?
to built-ins (#211) - Fixed handling of false values in entity cache (PR #198, thx Brandon Bloom)
- Fixed issue when string values were interpreted as lookup refs (#214)
- Speed up rschema calculation (#192, thx Andre R.)
- Optimize generated JS code by declaring fn arities (#197)
- [ BREAKING ] Removed ^:exports from
datascript.core
to enable dead code elimination (#191). This should only affect you if you were using DataScript from JS and were importing datascript.core
directly
- Add
vector
, hash-map
, array-map
, list
and set
to built-in query functions (PR #186, thx Linus Ericsson) - When filtering already filtered DB, filters were applied in the wrong order
- ~30% better performance for predicate and fn calls in queries (see #180)
- JS API now supports lookup refs in index lookups and queries (see #179)
- Lookup refs now work with
:db.unique/value
too (issue #171)
- Compatibility with 1.9 records (issue #176)
- Resolve query functions and predicates on JVM (issue #177, PR #178, thx Luke VanderHart)
- large long entity ids were breaking
init-db
(issue #165)
get-else
throws if nil
is used for default value- JS API: Do not keywordize attribute names in schema (PR #155, issue #153, thx typeetfunc)
init-db
sets correct max-eid
when processing facts about transactions (PR #164, issue #163, thx Nick Alexander)
- Better error messages for upsert conflicts
- Backtracking of tempids when redefining them later with upserts (issue #76)
- Upsert works in vector form too (issue #99, #109)
- Can specify transaction number in
:db/add
- Can put datoms into transaction directly (issue #121: supports both addition and retration datoms, keeps tx number)
- Added all
datascript.core
symbols to externs so they can be called directly from JS (e.g. in combination with mori, issue #139) - Added
reset-conn
, conn-from-datoms
and conn-from-db
(issue #45)
- Unify fn binding results with existing relations (PR #138, issue #141, thx Aaron Brooks)
- [ BREAKING ]
get-some
returns [attr value]
instead of just value
(#143, same as Datomic) - [ BREAKING ] Returning
nil
from query function filters out tuple from result - Throw when calling unbound predicate/function inside a query (#111)
- Added several built-ins, including
count
(#142) and subs
(#111) - Lookups with nil value (
[<attr> nil]
) resolve to nil (#140) - Allow pull-pattern to be specified with a input variable without
?
prefix (#136, #122) - Retract functions do not fail if lookup ref is pointing nowhere (#131)
- Fixed BTSet implementation of IReduceInit (#124)
- Fixed issue #120 with binding of large collections
- Guard
conn?
will check that value is derefable instead of checking for (instance? Atom)
- [ BREAKING ] Main namespace to include is now
datascript.core
, not datascript
- [ BREAKING ] Old
datascript.core
(internal namespace) was renamed to datascript.db
- [ BREAKING ]
datascript.shim
(internal namespace) was renamed to datascript.arrays
Motivations:
- Usage of top-level namespaces is discouraged and even generates a warning in CLJS.
- Better sooner than later.
- 0.13 seems like a great number for this sort of release.
Migration procedure:
- Just change
(require '[datascript :as d])
to (require '[datascript.core :as d])
and you’re good to go.
For the sake of easy migration, there’re no other changes in this release. Just renamings.
- Fix null pointer exception when
contains?
is called with an entity (PR #114, thx Kevin Lynagh)
db-init
respects :db/index
property
[ BREAKING ] Introducing new :db/index
schema attribute:
-
Attributes are not put to AVET by default anymore
-
Following attributes are put to AVET:
:db/index true
:db/unique :db.unique/identity
:db/unique :db.unique/value
:db/valueType :db.type/ref
-
All attributes put to AVET should be comparable. Note: maps and list are not comparable by default, vectors are compared value-by-value
-
[ BREAKING ] Min/max aggregation functions will only work on a comaparable values
Benefits:
- You can finally store any trash easily and reliably in DataScript database: maps, vectors, functions, JS objects. It doesn’t even have to be comparable. Just do not mark it as
:db/index
and do not make it :db.cardinality/many
- Faster transactions. There’s ⅓ less indexes to fill
- Good defaults. Most cases where you’ll probably use AVET (lookup by value)—lookup refs, external ids, references—they are all indexed by default
Caveats:
- Your code may break (see below)
- Queries can do lookup by value event without
:db/index
attribute, but it’ll be slower
Migration procedure:
- Check your code for
datoms
, seek-datoms
calls with :avet
index, and index-range
call - Check your queries to see if they utilize AVET index. It happens when you use this pattern:
[?free-var <constant-attr> <constant-value>]
- Mark necessary attributes with
:db/index true
in the schema
- msec argument to squuid (#95, #97)
- lookup refs in JS API
pull
, pull_many
, entity
(#94, thx Matt Senior) - fix in Pull API for reverse non-component attributes (#91, thx Matt Senior)
- Node.js and Browser repls for dev profile (#93)
- Preconditions to validate db/conn arguments (#101)
- Id allocation bug (#66)
- Ported BTSet to JVM
- BTSet and BTSetIter implement ChunkedSeq
- New benchmark runner
This release brings a significant performance boost for JVM version of DataScript (numbers are in comparison to JS/v8 version):
- queries with single clause, no join: ~5–6 times faster
- queries with joins: ~3–4.5 times faster
transact
: ~3 times fasterinit-db
: ~3–4 times faster- rules: ~3-4 times faster
Experimental support for Clojure on JVM:
sorted-set
instead of BTSet- polymorphic
get
lookup in query - no sorting optimisation for
init-db
Performance numbers so far (raw data):
- queries with single clause, no join: 30–50% faster
- queries with joins: ~50% slower
transact
: ~3.5–4 times fasterinit-db
: ~2–2.5 times slower- rules: ~2–5 times faster
- db
equiv
: ~5 times slower - db
hash
: ~10 times slower
- Fixed UUID constructor warning under CLJS 0.0-3291 and later
- Support reverse attribute refs in combination with wildcards (issue #80)
*.cljc
sources do not conflict with Clojure now. Code compiles under [lein-cljsbuild "1.0.6"]
- Return nil from entity when passed nil eid (issue #75)
- Fixed
init_db
in js (issue #73) - Preliminary work for Clojure port (PR #70, #71)
- [ BREAKING ] DS now requires CLJS 0.0-3196 or later
- New parser for query and rules
- Added a lot of meaningful error messages and validations to query parser
- Support for _ (ignore binding) in
:in
and fn-clause
bindings - Fixed id allocation bug when nested maps are used for referenced entities (issue #59)
- Fixed squuids omitting leading zeros (issue #60)
- Fixed a bug when cross-referencing components caused infinite loop in Pull API (isuue #58, pull request #61)
- Pull API handles recursion more like Datomic does (issue #62)
- Exposed DB filter API to js (pull request #65)
- Added ICounted, ISequable, IEmptyableCollection to
datascript.core/DB
- Force put
Datom
and DB
tag readers to cljs.reader/*tag-table*
, do not rely on data_readers.clj
- Lookup refs can be inlined in query
:where
patterns (issue #53) - Pull API (issue #37, pull request #51) by David Thomas Hume
pull
form in :find
clause
:db/unique
constraints- Upserts
- Lookup refs
entid
function
- Find specifications: collection
:find [?e ...]
, tuple :find [?e ?v]
, and scalar :find ?e .
- Support for
:db/isComponent
(issue #3) - Support for nested maps in
transact!
(also fixes #38) - [ BREAKING ] Custom aggregate fns must be called via special syntax (
aggregate
keyword): (q '[:find (aggregate ?myfn ?e) :in $ ?myfn ...])
. Built-in aggregates work as before: (q '[:find (count ?e) ...]
- Return nil from
entity
when passed nil eid (issue #47) - Transaction data is now validated, with proper error messages (also fixes #48)
- Fixed a bug with function call after function relation was filtered out (issue #44)
- Fixed a bug when emtpy coll in input was not creating empty relation
- BTSet and its slices (returned by
datoms
/seek-datoms
/index-range
calls) now support fast reverse iteration via reverse
. (datascript/datom e a v & [tx added])
call for creating new datoms- Added missing aggregate funs:
avg
, median
, variance
, stddev
and count-distinct
(issue #42, thx @montyxcantsin) min
and max
aggregates use comparator instead of default js <
comparison- Fixed a bug when fn inside a query on empty relation returned non-empty result
- Filtered DB support via
filter
- [ BREAKING ] Entity ids and transaction ids now have to be numbers, attributes can only be keywords (strings if used from JS)
- New method
init-db
for fast creation of DB from existing datoms (useful for e.g. initialization from serialized state) - Improved performance of
transact!
(~20%) and initial database population (init-db
, db-from-reader
, ~800%)
- Externs provided via
deps.cljs
— no need to manually specify externs when using datascript dependency
- Ability to pass inputs (predicates/functions bindings) down to rules (issues #28 #29)
- Javascript version is now packaged as a proper CommonJS/RequireJS module (include via script tag still supported) (issue #39)
- Published to npm: npmjs.org/package/datascript
- [ BREAKING ] Javascript namespace is renamed from
datascript.js
to datascript
- Reference transaction id inside transaction by using
:db/current-tx
instead of entity id (issue #32) - You can get id of transaction from
TxReport
: (get-in tx-report [:tempids :db/current-tx])
- Ability to pass arbitrary metadata along with transaction (third argument to
transact!
) and read it in listener callback (:tx-meta
key of TxReport
) (issue #32)
- Added
:db.fn/cas
transaction function (issue #20, thx @montyxcantsin) - Added
get-some
, get-else
, misssing?
query functions (issue #21, thx @montyxcantsin) - Fixed
touch
breaking entity cache (issue #17) - Added
ground
fn (issue #25) - Fixed query predicate/fn calls without free variables
- Retract incoming entity references on
:db.fn/retractEntity
(issue #18) - You can now use reverse relation name when transacting entity as a map
Cosmetic changes to better mimic Datomic API. Useful for sharing code between Datomic and DataScript:
- Added
tempid
, resolve-tempid
, db
, transact
, transact-async
, index-range
, squuid
, squuid-time-millis
- [ BREAKING ] renamed
transact
to with
, with
to db-with
- Optimized speed of DB’s
equiv
and hash
, Datom’s hash
- Entity’s
touch
call accessible through datascript
namespace - Accept sets in entity maps as values for
:db.cardinality/many
attributes
Proper entities implementation:
- Entities are now lazy and implement usual Map protocols
- [ BREAKING ] When accessing attribute of
:db/valueType :db.type/ref
, its value will be automatically expanded to entites, allowing for recursive exploration of entities graphs (e.g. (-> (d/entity db 42) :parent :parent :children)
) - Entities support backwards navigation (e.g.
(:person/_friends (d/entity db 42))
)
- Externs file now can be referred as
:externs [datascript/externs.js"]
Big performance improvements:
- New B-tree based indexes
- New set-at-a-time, hash-join powered query and rules engine
- Queries now up to 10× times faster
- You can specify DB for rule call (like
($db follows ?e1 ?e2)
) - Datoms are required to have integer id and keyword attributes, but no restriction on types of values
- Clojure reader support (pr/read) for DB and Datom
datoms
and seek-datoms
API calls- referencing other entities’ tempids in transaction data (issue #10)
- Transactor functions via
:db.fn/call
(thx @thegeez) - Vanilla JS API bindings
- [ BREAKING ] Schema keywords namespaced on a par with Datomic schema