Skip to content

7. Asami API

Paula Gearon edited this page Jun 30, 2021 · 2 revisions

API Introduction

Asami is a simple in-memory graph database. It was initially built as an internal component of Naga, but now exists in its own project. The principal API is in asami.core.

asami.core

The asami.core namespace is where the main APIs for interacting with Asami are found. These attempt to be similar to Datomic, though not identical.

now

Returns the current instant.

instant?

params: t

Tests if a value t is a time instant.

create-database

params: uri

Creates database specified by the uri parameter. Returns true if the database was created, false if it already exists.

connect

params: uri

Connects to the specified database, returning a Connection. In-memory databases get created if they do not exist already.

Currently, only in-memory and on-disk graphs are available. The URI forms for these are:

  • asami:mem://dbname   A standard graph
  • asami:multi://dbname   A multigraph (multiple edges can connect the same nodes together)
  • asami:local://dbname   Durable storage on local disk. Storage occurs in a directory name that matches the dbname, underneath the directory of the process.

db

params: connection

Retrieves the most recent value of the database specified by the connection. Databases are read-only and immutable.

as-of

params: db t

Retrieves the database as of a given moment, inclusive. The t value may be an instant, or a transaction ID. The database returned will be whatever database was the latest at the specified time or transaction.

as-of-t

params: db

Returns the as-of point for a database, or nil if none.

since

params: db t

Returns the value of the database since some point t, exclusive. t can be a transaction number, or instant.

since-t

params: db

Returns the since point for a database, or nil if none.

graph

params: db

Returns the graph object associated with a database. This is needed for some operations that work with the graph directly, like analytics, or the Loom API.

as-connection

params: graph uri

Creates a Database/Connection around an existing Graph.

  • graph: The graph to build a database around.
  • uri: The uri of the database to connect to it with.

transact

params: connection tx-info

Updates a database. This is currently synchronous, but returns a future or delay for compatibility with Datomic.

  • connection: The connection to the database to be updated.
  • tx-info: This is either a seq of items to be transacted, or a map containing a :tx-data value with such a seq. Each item to be transacted is one of:
    • vector of the form: [:db/add entity attribute value] - creates a datom
    • vector of the form: [:db/retract entity attribute value] - removes a datom
    • map: an entity to be inserted/updated.

If the tx-info argument contains a map, then it may contain the following keys:

  • :tx-data A sequence of add or retract operations, or entities to be added (as described above).
  • :tx-triples A sequence of raw triples to be asserted. This is equivalent to :tx-data containign only additions, except the :db/add need not be stipulated.
  • :executor If supplied, then this contains a java.util.concurrent.Executor instance to execute the operation in. (JVM only)
  • :update-fn A function that accepts a graph and a transaction ID, and returns a new graph.

Only one of :update-fn, :tx-triples or :tx-data may be supplied.

Entities and assertions may have attributes that are keywords with a trailing ' character. When these appear an existing attribute without that character will be replaced. This only occurs for the top level entity, and is not applied to attributes appearing in nested structures. Entities can be assigned a :db/id value. If this is a negative number, then it is considered a temporary value and will be mapped to a system-allocated ID. Other entities can reference such an entity in the same transaction using that ID. While :db/id looks like an attribute, it is actually a reference to the node of the entity itself. Entities can be provided a :db/ident value of any type. This will be considered unique, and can be used to identify entities for updates in this and subsequent transactions. The :db/ident attribute is hidden when the object is exported as an entity.

This function returns a future/delay object that will refer to a map containing the following:

Key Description
:db-before database value before the transaction
:db-after database value after the transaction
:tx-data sequence of datoms produced by the transaction
:tempids mapping of the temporary IDs in entities to the allocated nodes

entity

params: db id

Returns an entity based on an identifier, either the :db/id or a :db/ident if this is available. This eagerly retrieves the entity. Objects may be nested, but references to top level objects will be nil in order to avoid loops.

TODO: These objects can be made intelligent and lazy.

q

params: query inputs...

Execute a query against the provided inputs. The query can be a map, a seq, or a string. See the Query documentation for a full description of queries.

The end of the parameters may include a series of key/value pairs for query options. The only recognized option for now is:

:planner :user

This ensures that a query is executed in user-specified order, and not the order calculated by the optimizing planner.

show-plan

params: query inputs...

Return a query plan and do not execute the query. All parameters are identical to the q function.

import-data

params: connection data

Loads a seq of tuples as raw statements. If these include internal identifiers, they will be loaded-as is. This may conflict with existing statements so this operation should usually be executed against an empty store.

data may be a seq of tuples, or an EDN string.

export-data

params: database

Exports the contents of a database as a lazy sequence of statements. These can be converted to an EDN string via the str function.

Caution: Do not use (spit file (export-data db)) as this will create a file with contents like:

clojure.lang.LazySeq@8569ce8c

Instead, use: (spit file (prn-str (export-data db)))

Also, consider using zuko.io/spit as this works in node.js and web pages.

Other

Asami implements graphs using a standard protocol, so the hope is to expand upon this in future, particularly for durable storage implementations. The code in process right now is based on a design that Mulgara was working towards.