Packages

  • package root

    Documentation/API for the Molecule library - a meta DSL for the Datomic database.

    Manual | scalamolecule.org | Github | Forum

    Definition Classes
    root
  • package molecule

    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.

    Sub-packages

    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.

    Definition Classes
    root
  • package generic

    Interfaces to get generic information about data and schema.

    Interfaces to get generic information about data and schema.

    • Datom - Datom attributes in molecules
    • Log - Datoms sorted by transaction/time
    • EAVT - Datoms sorted by Entity-Attribute-Value-Transaction
    • AVET - Datoms sorted by Attribute-Value-Entity-Transaction
    • AEVT - Datoms sorted by Attribute-Entity-Value-Transaction
    • VAET - "Reverse index" for reverse lookup of ref types
    • Schema - Meta information about the current database schema.
    Definition Classes
    molecule
  • package datom

    Generic Datom attribute interfaces of all arities.

    Generic Datom attribute interfaces of all arities.

    "Generic attributes" are special pre-defined attributes that can be combined with custom attributes in molecules to return meta data:

    // Get id of Ben entity with `e`
    Person.e.name.get.head === (benEntityId, "Ben")
    
    // When was Ben's age updated? Using `txInstant`
    Person(benEntityId).age.txInstant.get.head === (42, <April 4, 2019>) // (Date)
    
    // With a history db we can access the transaction number `t` and
    // assertion/retraction statusses with `op`
    Person(benEntityId).age.t.op.getHistory === List(
      (41, t1, true),  // age 41 asserted in transaction t1
      (41, t2, false), // age 41 retracted in transaction t2
      (42, t2, true)   // age 42 asserted in transaction t2
    )

    Available generic attributes:

    • e - Entity id (Long)
    • a - Full attribute name like ":Person/name" (String)
    • v - Value of Datoms (Any)
    • t - Transaction pointer (Long/Int)
    • tx - Transaction entity id (Long)
    • txInstant - Transaction wall clock time (java.util.Date)
    • op - Operation status: assertion (true) / retraction (false)
    Definition Classes
    generic
    See also

    Tests for more generic attribute query examples.

  • package index

    Datomic Index APIs in Molecule.

    Datomic Index APIs in Molecule.

    Datomic maintains four indexes that contain ordered sets of datoms. Each of these indexes is named based on the sort order used:

    • EAVT - Datoms sorted by Entity-Attribute-Value-Transaction
    • AVET - Datoms sorted by Attribute-Value-Entity-Transaction
    • AEVT - Datoms sorted by Attribute-Entity-Value-Transaction
    • VAET - "Reverse index" for reverse lookup of ref types

    Create an Index molecule by instantiating an Index object with one or more arguments in the order of the Index's elements. Datoms are returned as tuples of data depending of which generic attributes you add to the Index molecule:

    // Create EAVT Index molecule with 1 entity id argument
    EAVT(e1).e.a.v.t.get === List(
      (e1, ":Person/name", "Ben", t1),
      (e1, ":Person/age", 42, t2),
      (e1, ":Golf/score", 5.7, t2)
    )
    
    // Maybe we are only interested in the attribute/value pairs:
    EAVT(e1).a.v.get === List(
      (":Person/name", "Ben"),
      (":Person/age", 42),
      (":Golf/score", 5.7)
    )
    
    // Two arguments to narrow the search
    EAVT(e1, ":Person/age").a.v.get === List(
      (":Person/age", 42)
    )
    Definition Classes
    generic
    Note

    The Molecule Index API's don't allow returning the whole Index/the whole database. So omitting arguments constructing the Index object (like EAVT.e.a.v.t.get) will throw an exception.
    Please use Datomics API if you need to return the whole database Index:
    conn.db.datoms(datomic.Database.EAVT)

    See also

    Tests for more Index query examples.

  • AEVT
  • AEVT_0
  • AEVT_1
  • AEVT_2
  • AEVT_3
  • AEVT_4
  • AEVT_5
  • AEVT_6
  • AEVT_7
  • AVET
  • AVET_0
  • AVET_1
  • AVET_2
  • AVET_3
  • AVET_4
  • AVET_5
  • AVET_6
  • AVET_7
  • EAVT
  • EAVT_0
  • EAVT_1
  • EAVT_2
  • EAVT_3
  • EAVT_4
  • EAVT_5
  • EAVT_6
  • EAVT_7
  • GenericAEVT
  • GenericAVET
  • GenericEAVT
  • GenericVAET
  • VAET
  • VAET_0
  • VAET_1
  • VAET_2
  • VAET_3
  • VAET_4
  • VAET_5
  • VAET_6
  • VAET_7
  • package schema

    Generic Schema attribute interfaces of all arities.

    Generic Schema attribute interfaces of all arities.

    The generic Schema interface provides attributes to build molecules that query the Schema structure of the current database.

    // List of attribute entity ids
    val attrIds: Seq[Long] = Schema.id.get
    
    // Attribute name elements
    Schema.a.part.ns.nsFull.attr.get === List (
      (":sales_Customer/name", "sales", "Customer", "sales_Customer", "name"),
      (":sales_Customer/name", "sales", "Customer", "sales_Customer", "name"),
      // etc..
    )
    
    // Datomic type and cardinality of attributes
    Schema.a.tpe.card.get === List (
      (":sales_Customer/name", "string", "one"),
      (":accounting_Invoice/invoiceLine", "ref", "many"),
    )
    
    // Optional docs and attribute options
    // These can be retrieved as mandatory or optional values
    Schema.a
          .index
          .doc$
          .unique$
          .fulltext$
          .isComponent$
          .noHistory$
          .get === List(
      (":sales_Customer/name",
        true,            // indexed
        "Customer name", // doc
        None,            // Uniqueness not set
        Some(true),      // Fulltext search set so that we can search for names
        None,            // Not a component
        None             // History is preserved (noHistory not set)
        ),
      (":accounting_Invoice/invoiceLine",
        true,                   // indexed
        "Ref to Invoice lines", // doc
        None,                   // Uniqueness not set
        None,                   // Fulltext search not set
        Some(true),             // Invoice is a component - owns invoice lines
        None                    // History is preserved (noHistory not set)
        ),
    )
    
    // Defined enum values
    Schema.a.enum.get.groupBy(_._1).map(g => g._1 -> g._2) === Map(
      ":Person/gender" -> List("female", "male"),
      ":Interests/sports" -> List("golf", "basket", "badminton")
    )
    
    // Schema transaction times
    Schema.t.tx.txInstant.get === List(
      (t1, tx1, <Date: 2018-11-07 09:28:10>), // Initial schema transaction
      (t2, tx2, <Date: 2019-01-12 12:43:27>), // Additional schema attribute definitions...
    )

    Apply expressions to narrow the returned selection of Schema data:

    // Namespaces in the "gen" partition (partition name tacit)
    Schema.part_("location").ns.get === List("Country", "Region", etc...)
    
    // Attributes in the "Person" namespace
    Schema.ns_("Person").attr.get === List("name", "age", "hobbies", etc...)
    
    // How many enum attributes?
    Schema.enum_.a(count).get === List(2)
    Definition Classes
    generic
    Note

    Schema attributes defined in Datomic's bootstrap process that are not related to the current database are transparently filtered out from all Schema queries.

    See also

    Tests for more Schema query examples.

package index

Datomic Index APIs in Molecule.

Datomic maintains four indexes that contain ordered sets of datoms. Each of these indexes is named based on the sort order used:

  • EAVT - Datoms sorted by Entity-Attribute-Value-Transaction
  • AVET - Datoms sorted by Attribute-Value-Entity-Transaction
  • AEVT - Datoms sorted by Attribute-Entity-Value-Transaction
  • VAET - "Reverse index" for reverse lookup of ref types

Create an Index molecule by instantiating an Index object with one or more arguments in the order of the Index's elements. Datoms are returned as tuples of data depending of which generic attributes you add to the Index molecule:

// Create EAVT Index molecule with 1 entity id argument
EAVT(e1).e.a.v.t.get === List(
  (e1, ":Person/name", "Ben", t1),
  (e1, ":Person/age", 42, t2),
  (e1, ":Golf/score", 5.7, t2)
)

// Maybe we are only interested in the attribute/value pairs:
EAVT(e1).a.v.get === List(
  (":Person/name", "Ben"),
  (":Person/age", 42),
  (":Golf/score", 5.7)
)

// Two arguments to narrow the search
EAVT(e1, ":Person/age").a.v.get === List(
  (":Person/age", 42)
)
Source
package.scala
Note

The Molecule Index API's don't allow returning the whole Index/the whole database. So omitting arguments constructing the Index object (like EAVT.e.a.v.t.get) will throw an exception.
Please use Datomics API if you need to return the whole database Index:
conn.db.datoms(datomic.Database.EAVT)

See also

Tests for more Index query examples.

Linear Supertypes
AnyRef, Any

Type Members

  1. trait AEVT extends GenericNs

    AEVT Index.

    AEVT Index.

    "The AEVT index provides efficient access to all values for a given attribute, comparable to traditional column access style." (from Datomic documentation)

    Access the AEVT Index in Molecule by instantiating an AEVT object with one or more arguments and then add generic attributes:

    // Create AEVT Index molecule with 1 entity id argument
    AEVT(":Person/name").e.v.t.get === List(
      (e1, "Ben", t2),
      (e2, "Liz", t5)
    )
    
    // Narrow search with multiple arguments
    AEVT(":Person/name", e1).e.v.get === List( (e1, "Ben") )
    AEVT(":Person/name", e1, "Ben").e.v.get === List( (e1, "Ben") )
    AEVT(":Person/name", e1, "Ben", t2).e.v.get === List( (e1, "Ben") )

    Index attributes available:

    • e - Entity id (Long)
    • a - Full attribute name like ":Person/name" (String)
    • v - Value of Datoms (Any)
    • t - Transaction pointer (Long/Int)
    • tx - Transaction entity id (Long)
    • txInstant - Transaction wall clock time (java.util.Date)
    • op - Operation status: assertion (true) / retraction (false)
    Note

    The Molecule Index API's don't allow returning the whole Index/the whole database. So omitting arguments constructing the Index object (like AEVT.a.e.v.t.get) will throw an exception.
    Please use Datomics API if you need to return the whole database Index:
    conn.db.datoms(datomic.Database.AEVT)

    See also

    Tests for more Index query examples.

  2. trait AEVT_0 extends AEVT with OutIndex_0

    AEVT interface to add a first generic attribute to molecule.

  3. trait AEVT_1[A] extends AEVT with OutIndex_1[A]

    AEVT interface to add a second generic attribute to molecule.

  4. trait AEVT_2[A, B] extends AEVT with OutIndex_2[A, B]
  5. trait AEVT_3[A, B, C] extends AEVT with OutIndex_3[A, B, C]
  6. trait AEVT_4[A, B, C, D] extends AEVT with OutIndex_4[A, B, C, D]
  7. trait AEVT_5[A, B, C, D, E] extends AEVT with OutIndex_5[A, B, C, D, E]
  8. trait AEVT_6[A, B, C, D, E, F] extends AEVT with OutIndex_6[A, B, C, D, E, F]
  9. trait AEVT_7[A, B, C, D, E, F, G] extends AEVT with OutIndex_7[A, B, C, D, E, F, G]
  10. trait AVET extends GenericNs

    AVET Index.

    AVET Index.

    "The AVET index provides efficient access to particular combinations of attribute and value." (from Datomic documentation)

    Access the AVET Index in Molecule by instantiating an AVET object with one or more arguments and then add generic attributes:

    // Create AVET Index molecule with 1 entity id argument
    AVET(":Person/age").e.v.t.get === List(
      (e1, 42, t2),
      (e2, 37, t5)
      (e3, 14, t7),
    )
    
    // Narrow search with multiple arguments
    AVET(":Person/age", 42).e.t.get === List( (e1, t2) )
    AVET(":Person/age", 42, e1).e.v.get === List( (e1, t2) )
    AVET(":Person/age", 42, e1, t2).e.v.get === List( (e1, t2) )

    The AVET Index can be filtered by a range of values between from (inclusive) and until (exclusive) for an attribute:

    AVET.range(":Person/age", Some(14), Some(37)).v.e.t.get === List(
      (14, e4, t7) // 14 is included in value range
                   // 37 not included in value range
                   // 42 outside value range
    )
    
    // If `from` is None, the range starts from the beginning
    AVET.range(":Person/age", None, Some(40)).v.e.t.get === List(
      (14, e3, t7),
      (37, e2, t5),
    )
    
    // If `until` is None, the range goes to the end
    AVET.range(":Person/age", Some(20), None).v.e.t.get === List(
      (37, e2, t5),
      (42, e1, t2)
    )

    Index attributes available:

    • e - Entity id (Long)
    • a - Full attribute name like ":Person/name" (String)
    • v - Value of Datoms (Any)
    • t - Transaction pointer (Long/Int)
    • tx - Transaction entity id (Long)
    • txInstant - Transaction wall clock time (java.util.Date)
    • op - Operation status: assertion (true) / retraction (false)
    Note

    The Molecule Index API's don't allow returning the whole Index/the whole database. So omitting arguments constructing the Index object (like AVET.a.v.e.t.get) will throw an exception.
    Please use Datomics API if you need to return the whole database Index:
    conn.db.datoms(datomic.Database.AVET)

    from and until cannot both be None since Molecule doesn't allow returning all datoms.

    See also

    Tests for more Index query examples.

  11. trait AVET_0 extends AVET with OutIndex_0

    AVET interface to add a first generic attribute to molecule.

  12. trait AVET_1[A] extends AVET with OutIndex_1[A]

    AVET interface to add a second generic attribute to molecule.

  13. trait AVET_2[A, B] extends AVET with OutIndex_2[A, B]
  14. trait AVET_3[A, B, C] extends AVET with OutIndex_3[A, B, C]
  15. trait AVET_4[A, B, C, D] extends AVET with OutIndex_4[A, B, C, D]
  16. trait AVET_5[A, B, C, D, E] extends AVET with OutIndex_5[A, B, C, D, E]
  17. trait AVET_6[A, B, C, D, E, F] extends AVET with OutIndex_6[A, B, C, D, E, F]
  18. trait AVET_7[A, B, C, D, E, F, G] extends AVET with OutIndex_7[A, B, C, D, E, F, G]
  19. trait EAVT extends GenericNs

    EAVT Index.

    EAVT Index.

    "The EAVT index provides efficient access to everything about a given entity. Conceptually this is very similar to row access style in a SQL database, except that entities can possess arbitrary attributes rather then being limited to a predefined set of columns." (from Datomic documentation)

    Access the EAVT Index in Molecule by instantiating an EAVT object with one or more arguments and then add generic attributes:

    // Create EAVT Index molecule with 1 entity id argument
    EAVT(e1).e.a.v.t.get === List(
      (e1, ":Person/name", "Ben", t1),
      (e1, ":Person/age", 42, t2),
      (e1, ":Golf/score", 5.7, t2)
    )
    
    // Narrow search with multiple arguments
    EAVT(e1, ":Person/age").a.v.get === List( (":Person/age", 42) )
    EAVT(e1, ":Person/age", 42).a.v.get === List( (":Person/age", 42) )
    EAVT(e1, ":Person/age", 42, t1).a.v.get === List( (":Person/age", 42) )

    Index attributes available:

    • e - Entity id (Long)
    • a - Full attribute name like ":Person/name" (String)
    • v - Value of Datoms (Any)
    • t - Transaction pointer (Long/Int)
    • tx - Transaction entity id (Long)
    • txInstant - Transaction wall clock time (java.util.Date)
    • op - Operation status: assertion (true) / retraction (false)
    Note

    The Molecule Index API's don't allow returning the whole Index/the whole database. So omitting arguments constructing the Index object (like EAVT.e.a.v.t.get) will throw an exception.
    Please use Datomics API if you need to return the whole database Index:
    conn.db.datoms(datomic.Database.EAVT)

    See also

    Tests for more Index query examples.

  20. trait EAVT_0 extends EAVT with OutIndex_0

    EAVT interface to add a first generic attribute to molecule.

  21. trait EAVT_1[A] extends EAVT with OutIndex_1[A]

    EAVT interface to add a second generic attribute to molecule.

  22. trait EAVT_2[A, B] extends EAVT with OutIndex_2[A, B]
  23. trait EAVT_3[A, B, C] extends EAVT with OutIndex_3[A, B, C]
  24. trait EAVT_4[A, B, C, D] extends EAVT with OutIndex_4[A, B, C, D]
  25. trait EAVT_5[A, B, C, D, E] extends EAVT with OutIndex_5[A, B, C, D, E]
  26. trait EAVT_6[A, B, C, D, E, F] extends EAVT with OutIndex_6[A, B, C, D, E, F]
  27. trait EAVT_7[A, B, C, D, E, F, G] extends EAVT with OutIndex_7[A, B, C, D, E, F, G]
  28. trait GenericAEVT extends AnyRef

    Container for AEVT Index object.

  29. trait GenericAVET extends AnyRef

    Container for AVET Index object.

  30. trait GenericEAVT extends AnyRef

    Container for EAVT Index object.

  31. trait GenericVAET extends AnyRef

    Container for VAET reverse Index object.

  32. trait VAET extends GenericNs

    VAET reverse Index.

    VAET reverse Index.

    "The VAET index contains all and only datoms whose attribute has a :db/valueType of :db.type/ref. This is also known as the reverse index, since it allows efficient navigation of relationships in reverse." (from Datomic documentation)

    Access the VAET Index in Molecule by instantiating a VAET object with one or more arguments and then add generic attributes:

    // Say we have 3 entities pointing to one entity:
    Release.e.name.Artists.e.name.get === List(
      (r1, "Abbey Road", a1, "The Beatles"),
      (r2, "Magical Mystery Tour", a1, "The Beatles"),
      (r3, "Let it be", a1, "The Beatles"),
    )
    
    // .. then we can get the reverse relationships with the VAET Index:
    VAET(a1).v.a.e.get === List(
      (a1, ":Release/artists", r1),
      (a1, ":Release/artists", r2),
      (a1, ":Release/artists", r3),
    )
    
    // Narrow search with multiple arguments
    VAET(a1, ":Release/artist").e.get === List(r1, r2, r3)
    VAET(a1, ":Release/artist", r2).e.get === List(r2)
    VAET(a1, ":Release/artist", r2, t7).e.get === List(r2)

    Index attributes available:

    • e - Entity id (Long)
    • a - Full attribute name like ":Person/name" (String)
    • v - Value of Datoms (Any)
    • t - Transaction pointer (Long/Int)
    • tx - Transaction entity id (Long)
    • txInstant - Transaction wall clock time (java.util.Date)
    • op - Operation status: assertion (true) / retraction (false)
    Note

    The Molecule Index API's don't allow returning the whole Index/the whole database. So omitting arguments constructing the Index object (like VAET.v.a.e.t.get) will throw an exception.
    Please use Datomics API if you need to return the whole database Index:
    conn.db.datoms(datomic.Database.VAET)

    See also

    Tests for more Index query examples.

  33. trait VAET_0 extends VAET with OutIndex_0

    VAET interface to add a first generic attribute to molecule.

  34. trait VAET_1[A] extends VAET with OutIndex_1[A]

    VAET interface to add a second generic attribute to molecule.

  35. trait VAET_2[A, B] extends VAET with OutIndex_2[A, B]
  36. trait VAET_3[A, B, C] extends VAET with OutIndex_3[A, B, C]
  37. trait VAET_4[A, B, C, D] extends VAET with OutIndex_4[A, B, C, D]
  38. trait VAET_5[A, B, C, D, E] extends VAET with OutIndex_5[A, B, C, D, E]
  39. trait VAET_6[A, B, C, D, E, F] extends VAET with OutIndex_6[A, B, C, D, E, F]
  40. trait VAET_7[A, B, C, D, E, F, G] extends VAET with OutIndex_7[A, B, C, D, E, F, G]

Inherited from AnyRef

Inherited from Any

Ungrouped