package util
- Alphabetic
- By Inheritance
- util
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Molecule library - a Scala meta-DSL for the Datomic database.
Molecule library - a Scala meta-DSL for the Datomic database.
See api package for various api imports to start using Molecule.
api | Molecule API. | |
ast | Internal Molecule ASTs. | |
boilerplate | Internal interfaces for auto-generated DSL boilerplate code. | |
composition | Builder methods to compose molecules. | |
exceptions | Exceptions thrown by Molecule. | |
expression | Attribute expressions and operations. | |
facade | Molecule facades to Datomic. | |
factory | Implicit macro methods `m` to instantiate molecules from custom DSL molecule constructs. | |
input | Input molecules awaiting input. | |
macros | Internal macros generating molecule code from custom DSL molecule constructs. | |
generic | Interfaces to generic information about datoms and Datomic database. | |
ops | Internal operational helpers for transforming DSL to molecule. | |
schema | Schema definition DSL. | |
transform | Internal transformers from DSL to Model/Query/Transaction. | |
util | Internal Java database functions for Datomic. |
Public interface to be imported to use Molecule.
Public interface to be imported to use Molecule.
To make the Molecule macro materializations as fast as possible we try to import as few macro implicits as possible. If your application code build molecules with at the most 10 attributes, then you can do the following import to start using Molecule:
import molecule.api.out10._
out
means "output molecule" , and 10
the maximum arity or number of attributes
of your molecules.
If you use input molecules awaiting an input then you can add inX
where X is
how many inputs (1, 2 or 3) you will use, for instance:
import molecule.api.in2_out10._
This way we keep the implicit macro def lookups to a minimum and compilation speed as fast as possible.
Arities can be changed anytime you like. But not to a lower arity than that of the molecules you use in scope of the import.
Internal Molecule ASTs.
Internal Molecule ASTs.
Internal interfaces for auto-generated DSL boilerplate code.
Internal interfaces for auto-generated DSL boilerplate code.
Interfaces to the generated schema-defined DSL boilerplate code that the sbt-plugin generates when doing a sbt-compile
.
Molecule macros can then type-safely deduct the type structure of composed molecules.
Methods to build transaction, composite and nested molecules.
Methods to build transaction, composite and nested molecules.
Exceptions thrown by Molecule.
Exceptions thrown by Molecule.
Attribute expressions and operations.
Attribute expressions and operations.
Refine attribute matches with various attribute expressions:
Person.age(42) // equality Person.name.contains("John") // fulltext search Person.age.!=(42) // negation (or `not`) Person.age.<(42) // comparison (< > <= >=) Person.name("John" or "Jonas") // OR-logic Person.age() // apply empty value to retract value(s) in updates Person.hobbies.assert("golf") // add value(s) to card-many attributes Person.hobbies.retract("golf") // retract value(s) of card-many attributes Person.hobbies.replace("golf", "diving") // replace value(s) of card-many attributes Person.tags.k("en") // match values of map attributes by key Person.age(Nil) // match non-asserted datoms (null) Person.name(?) // initiate input molecules awaiting input at runtime Person.name(unify) // Unify attributes in self-joins
Apply aggregate keywords to aggregate attribute value(s):
// Aggregates on any attribute type Person.age(count).get.head === 3 // count of asserted `age` attribute values Person.age(countDistinct).get.head === 3 // count of asserted distinct `age` attribute values Person.age(max).get.head === 38 // maximum `age` value (using `compare`) Person.age(min).get.head === 5 // maximum `age` value (using `compare`) Person.age(rand).get.head === 25 // single random `age` value Person.age(sample).get.head === 27 // single sample `age` value (when single value, same as random) // Aggregates on any attribute type, returning multiple values Person.age(distinct).get.head === Vector(5, 7, 38) // distinct `age` values Person.age(max(2)).get.head === Vector(38, 7) // 2 maximum `age` values Person.age(min(2)).get.head === Vector(5, 7) // 2 minimum `age` values Person.age(rand(2)).get.head === Stream(5, ?) // 2 random `age` values (values can re-occur) Person.age(sample(2)).get.head === Vector(7, 38) // 2 sample `age` values // Aggregates on number attributes Person.age(sum).get.head === 50 // sum of all `age` numbers Person.age(avg).get.head === 16.66666667 // average of all `age` numbers Person.age(median).get.head === 7 // median of all `age` numbers Person.age(stddev).get.head === 15.107025591499 // standard deviation of all `age` numbers Person.age(variance).get.head === 228.2222222222 // variance of all `age` numbers
Manual: expressions | aggregates | input molecules
Tests: expressions
Molecule facades to Datomic.
Molecule facades to Datomic.
Facades are not trying to cover all Datomic methods but rather
only interfaces relevant to Molecule.
Factory methods m
to instantiate molecules from custom DSL molecule constructs.
Factory methods m
to instantiate molecules from custom DSL molecule constructs.
Interfaces to get generic information about data and schema.
Interfaces to get generic information about data and schema.
Input molecules awaiting input.
Input molecules awaiting input.
Input molecules are molecules that awaits one or more inputs at runtime. When input value is applied,
the input molecule is resolved and a standard molecule is returned that we can then call actions on.
Input molecule queries are cached by Datomic. So there is a runtime performance gain in using input molecules. Furthermore,
input molecules are a good fit for re-use for queries where only a few parameters change.
Input molecules can await 1, 2 or 3 inputs and are constructed by applying the ? marker
to attributes. If one marker is applied, we get a InputMolecule_1, 2 inputs creates
an InputMolecule_2 and 3 an InputMolecule_3.
The three input molecule interfaces come in arity-versions corresponding to the number of non-?-marked attributes
in the input molecule. Let's see a simple example:
// Sample data Person.name.age insert List(("Ben", 42), ("Liz", 34)) // Input molecule created at compile time. Awaits a name of type String val ageOfPersons: InputMolecule_1.InputMolecule_1_01[String, Int] = m(Person.name_(?).age) // Resolved molecule. "Ben" input is matched against name attribute val ageOfPersonsNamedBen: Molecule.Molecule01[Int] = ageOfPersons.apply("Ben") // Calling action on resolved molecule. // (Only age is returned since name was marked as tacit with the underscore notation) ageOfPersonsNamedBen.get === List(42) // Or we can re-use the input molecule straight away ageOfPersons("Liz").get === List(34)
Internal macros generating molecule code from custom DSL molecule constructs.
Internal macros generating molecule code from custom DSL molecule constructs.
Internal operational helpers for transforming DSL to molecules.
Internal operational helpers for transforming DSL to molecules.
Schema definition DSL and API.
Schema definition DSL and API.
Internal transformers from DSL to Model/Query/Transaction/Datomic.
Internal transformers from DSL to Model/Query/Transaction/Datomic.
Molecule transforms custom boilerplate DSL constructs to Datomic queries in 3 steps:
Custom DSL molecule --> Model --> Query --> Datomic query string
Internal database functions for Datomic.
Internal database functions for Datomic.
Documentation/API for the Molecule library - a meta DSL for the Datomic database.
Manual | scalamolecule.org | Github | Forum