datomic_gen_server v1.1.0 DatomicGenServer
DatomicGenServer is an Elixir GenServer that communicates with a Clojure Datomic peer running in the JVM, using clojure-erlastic.
The interface functions in this module communicate with Datomic using edn
strings. To use Elixir data structures, see the accompanying DatomicGenServer.db
module.
Examples
DatomicGenServer.start(
"datomic:mem://test",
true,
[{:timeout, 20_000}, {:default_message_timeout, 20_000}, {:name, DatomicGenServer}]
)
query = "[:find ?c :where [?c :db/doc \"Some docstring that isn't in the database\"]]"
DatomicGenServer.q(DatomicGenServer, query)
# => {:ok, "#{}\n"}
data_to_add = """
[ { :db/id #db/id[:db.part/db]
:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc \"A person's name\"
:db.install/_attribute :db.part/db}]
"""
DatomicGenServer.transact(DatomicGenServer, data_to_add)
# => {:ok, "{:db-before {:basis-t 1000}, :db-after {:basis-t 1000},
:tx-data [{:a 50, :e 13194139534313, :v #inst \"2016-02-14T02:10:54.580-00:00\",
:tx 13194139534313, :added true} {:a 10, :e 64, :v :person/name, :tx 13194139534313,
:added true} {:a 40, :e 64, :v 23, :tx 13194139534313, :added true} {:a 41,
:e 64, :v 35, :tx 13194139534313, :added true} {:a 62, :e 64,
:v \"A person's name\", :tx 13194139534313, :added true} {:a 13,
:e 0, :v 64, :tx 13194139534313, :added true}], :tempids {-9223367638809264705 64}}"}
Summary
Functions
Issues an entity
call that is passed to the Datomic entity
API function
Issues a call to net.phobot.datomic/migrator to migrate a database using database migration files in edn format
Queries a DatomicGenServer using a query formulated as an edn string.
This query is passed to the Datomic q
API function
Issues a call to net.phobot.datomic/seed to seed a database using database migration files and seed data files in edn format. The database is not dropped or recreated before migrating and seeding
Starts the GenServer
Starts the GenServer in a linked process
Issues a transaction against a DatomicGenServer using a transaction
formulated as an edn string. This transaction is passed to the Datomic transact
API function
Types
datomic_call :: {datomic_message, message_timeout :: non_neg_integer}
datomic_message ::
{:q, integer, String.t} |
{:transact, integer, String.t} |
{:entity, integer, String.t, [atom] | :all}
datomic_result :: {:ok, String.t} | {:error, term}
send_option ::
{:message_timeout, non_neg_integer} |
{:client_timeout, non_neg_integer}
start_option ::
GenServer.option |
{:default_message_timeout, non_neg_integer}
Functions
Specs
entity(GenServer.server, String.t, [atom] | :all, [send_option]) :: datomic_result
Issues an entity
call that is passed to the Datomic entity
API function.
The first parameter to this function is the pid or alias of the GenServer process;
the second is an edn string representing the parameter that is to be passed to
entity
: either an entity id, an ident, or a lookup ref. The third parameter
is a list of atoms that represent the keys of the attributes you wish to fetch,
or :all
if you want all the entity’s attributes.
The options keyword list may include a :client_timeout
option that specifies
the milliseconds timeout passed to GenServer.call, and a :message_timeout
option that specifies how long the GenServer should wait for a response before
crashing (overriding the default value set in start
or start_link
). Note
that if the :client_timeout
is shorter than the :message_timeout
value,
the call will return an error but the server will not crash even if the message
is never returned from the Clojure peer.
Example
DatomicGenServer.entity(DatomicGenServer, ":person/email", [:"db/valueType", :"db/doc"])
=> {:ok, "{:db/valueType :db.type/string, :db/doc \"A person's email\"}\n"}
Specs
migrate(GenServer.server, String.t, [send_option]) :: datomic_result
Issues a call to net.phobot.datomic/migrator to migrate a database using database migration files in edn format.
The first parameter to this function is the pid or alias of the GenServer process; the second is the path to the directory containing the migration files. Files will be processed in sort order. The Clojure Conformity library is used to keep the migrations idempotent.
The options keyword list may include a :client_timeout
option that specifies
the milliseconds timeout passed to GenServer.call, and a :message_timeout
option that specifies how long the GenServer should wait for a response before
crashing (overriding the default value set in start
or start_link
). Note
that if the :client_timeout
is shorter than the :message_timeout
value,
the call will return an error but the server will not crash even if the message
is never returned from the Clojure peer.
Example
DatomicGenServer.migrate(DatomicGenServer, Path.join [System.cwd(), "migrations"])
=> {:ok, :migrated}
Specs
q(GenServer.server, String.t, [send_option]) :: datomic_result
Queries a DatomicGenServer using a query formulated as an edn string.
This query is passed to the Datomic q
API function.
The first parameter to this function is the pid or alias of the GenServer process;
the second is the query. The options keyword list may include a :client_timeout
option that specifies the milliseconds timeout passed to GenServer.call, and a
:message_timeout
option that specifies how long the GenServer should wait
for a response before crashing (overriding the default value set in start
or
start_link
). Note that if the :client_timeout
is shorter than the
:message_timeout
value, the call will return an error but the server will
not crash even if the response message is never returned from the Clojure peer.
Example
query = "[:find ?c :where [?c :db/doc \"Some docstring that isn't in the database\"]]"
DatomicGenServer.q(DatomicGenServer, query)
=> {:ok, "#{}\n"}
Specs
seed(GenServer.server, String.t, String.t, [send_option]) :: datomic_result
Issues a call to net.phobot.datomic/seed to seed a database using database migration files and seed data files in edn format. The database is not dropped or recreated before migrating and seeding.
The first parameter to this function is the pid or alias of the GenServer process; the second is the path to the directory containing the migration files. The third parameter is the path to a (different) directory containing the seed data files. The migration files will be processed in the sort order of their directory, and then the seed data files in the sort order of their directory.
Seed data is loaded in a single transaction. The return value of the function
is the result of the Datomic transact
API function call that executed the
transaction. If you want this result in a struct, call the wrapper seed
function
in the DatomicGenServer.Db
module.
The Clojure Conformity library is used to keep the migrations idempotent, but the loading of seed data is not idempotent.
The options keyword list may include a :client_timeout
option that specifies
the milliseconds timeout passed to GenServer.call, and a :message_timeout
option that specifies how long the GenServer should wait for a response before
crashing (overriding the default value set in start
or start_link
). Note
that if the :client_timeout
is shorter than the :message_timeout
value,
the call will return an error but the server will not crash even if the message
is never returned from the Clojure peer.
Example
migration_dir = Path.join [System.cwd(), "migrations"]
seed_data_dir = Path.join [System.cwd(), "seed-data"]
DatomicGenServer.seed(DatomicGenServer, migration_dir, seed_data_dir)
=> {:ok, "{:db-before {:basis-t 1000}, :db-after {:basis-t 1000}, ...
Specs
start(String.t, boolean, [start_option]) :: GenServer.on_start
Starts the GenServer.
This function is basically a pass-through to GenServer.start
, but with some
additional parameters: The first is the URL of the Datomic transactor to which
to connect, and the second a boolean parameter indicating whether or not to
create the database if it does not yet exist.
The options keyword list may include the normal options accepted by GenServer.start
,
as well as a :default_message_timeout
option that controls the default time in
milliseconds that the server will wait for a message before crashing. Note that
if the :timeout
option is provided, the GenServer will crash if that timeout
is exceeded.
Example
DatomicGenServer.start(
"datomic:mem://test",
true,
[{:timeout, 20_000}, {:default_message_timeout, 20_000}, {:name, DatomicGenServer}]
)
Specs
start_link(String.t, boolean, [start_option]) :: GenServer.on_start
Starts the GenServer in a linked process.
This function is basically a pass-through to GenServer.start_link
, but with
some additional parameters: The first is the URL of the Datomic transactor to
which to connect, and the second a boolean parameter indicating whether or not
to create the database if it does not yet exist.
The options keyword list may include the normal options accepted by GenServer.start_link
,
as well as a :default_message_timeout
option that controls the default time in
milliseconds that the server will wait for a message before crashing. Note that
if the :timeout
option is provided, the GenServer will crash if that timeout
is exceeded.
Example
DatomicGenServer.start_link(
"datomic:mem://test",
true,
[{:timeout, 20_000}, {:default_message_timeout, 20_000}, {:name, DatomicGenServer}]
)
Specs
transact(GenServer.server, String.t, [send_option]) :: datomic_result
Issues a transaction against a DatomicGenServer using a transaction
formulated as an edn string. This transaction is passed to the Datomic transact
API function.
The first parameter to this function is the pid or alias of the GenServer process;
the second is the transaction data in edn format. The options keyword list may
include a :client_timeout
option that specifies the milliseconds timeout passed
to GenServer.call, and a :message_timeout
option that specifies how long the
GenServer should wait for a response before crashing (overriding the default
value set in start
or start_link
). Note that if the :client_timeout
is
shorter than the :message_timeout
value, the call will return an error but
the server will not crash even if the response message is never returned from
the Clojure peer.
Example
data_to_add = """
[ { :db/id #db/id[:db.part/db]
:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc \"A person's name\"
:db.install/_attribute :db.part/db}]
"""
DatomicGenServer.transact(DatomicGenServer, data_to_add)
=> {:ok, "{:db-before {:basis-t 1000}, :db-after {:basis-t 1000},
:tx-data [{:a 50, :e 13194139534313, :v #inst \"2016-02-14T02:10:54.580-00:00\",
:tx 13194139534313, :added true} {:a 10, :e 64, :v :person/name, :tx 13194139534313,
:added true} {:a 40, :e 64, :v 23, :tx 13194139534313, :added true} {:a 41,
:e 64, :v 35, :tx 13194139534313, :added true} {:a 62, :e 64,
:v \"A person's name\", :tx 13194139534313, :added true} {:a 13,
:e 0, :v 64, :tx 13194139534313, :added true}], :tempids {-9223367638809264705 64}}"}