dbmodule db
import q = query
// Types
type database = data
type record = map(data)
type recordID = data // actually a ref
type query = <opaque>
// Get databases (since PR 1160)
def mainDB : database
def appDB : string -> database
def localInMemDB : string -> database
def globalInMemDB : string -> database
def remoteDB : string -> string -> database // since PR1571
// Primitive storing and retrieving
def getOne : database -> recordID -> record
def getOneWithDefault : record -> database -> recordID -> record
def getArray : database -> array(recordID) -> array(record)
def getStream : database -> array(recordID) -> stream(record) // since PR1612
def getStreamWithDefault : record -> database -> array(recordID) -> stream(record) // since PR1612
def get : database -> array(recordID) -> stream(record)
def getWithDefault : record -> database -> array(recordID) -> stream(record)
def saveOne : appstate -> database -> record -> record
def saveOneGetID : appstate -> database -> record -> recordID // since PR1612
def saveArray : appstate -> database -> array(record) -> array(record) // since PR1612
def saveArrayGetIDs : appstate -> database -> array(record) -> array(recordID) // since PR1612
def saveStream : appstate -> database -> stream(record) -> stream(record) // since PR1612
def saveStreamGetIDs : appstate -> database -> stream(record) -> stream(recordID) // since PR1612
def save : appstate -> database -> stream(record) -> stream(record)
def upsertOne : appstate -> database -> record -> record
def upsertOneGetID : appstate -> database -> record -> recordID // since PR1612
def upsertArray : appstate -> database -> array(record) -> array(record) // since PR1612
def upsertArrayGetIDs : appstate -> database -> array(record) -> array(recordID) // since PR1612
def upsertStream : appstate -> database -> stream(record) -> stream(record) // since PR1612
def upsertStreamGetIDs : appstate -> database -> stream(record) -> stream(recordID) // since PR1612
def upsert : appstate -> database -> stream(record) -> stream(record)
def deleteOne : appstate -> database -> recordID -> record
def deleteOneStm : appstate -> database -> recordID -> null // since PR1612
def deleteArray : appstate -> database -> array(recordID) -> array(record) // since PR1612
def deleteArrayStm : appstate -> database -> array(recordID) -> null // since PR1612
def deleteStream : appstate -> database -> stream(recordID) -> stream(record) // since PR1612
def deleteStreamStm : appstate -> database -> stream(recordID) -> null // since PR1612
def delete : appstate -> database -> stream(recordID) -> stream(record)
def deref : database -> data -> data
// deprecated
def retrieve // replace with getOne
def retrieveWithDefault // replace with getOneWithDefault
// Sources
def head : database -> query
def all : database -> query
def query : database -> string -> query
def database : query -> database
// Modifiers
def includeDeleted : bool -> query -> query
def includeSuperseded : bool -> query -> query
def unrestricted : bool -> query -> query
def label : string -> query -> query
// Filters
def filter : (record -> bool) -> query -> query
def filterWithFallback : (record -> bool) -> query -> query
// Mapping (projecting)
def map : (record -> record) -> query -> query
def mapWithFallback : (record -> record) -> query -> query
// Sorting
def sort : (record -> data) -> query -> query
def dirSort : bool -> (record -> data) -> query -> query
// Extracting results
def length : query -> number
def isEmpty : query -> bool
def isNotEmpty : query -> bool
def exists : (record -> bool) -> query -> bool
def toArray : query -> array(record)
def toStream : query -> record*
// Special elements, slicing:
def first : query -> record
def firstWithDefault : record -> query -> record
def last : query -> record
def lastWithDefault : record -> query -> record
def skip : query -> query
def skipn : number -> query -> query
def firstn : number -> query -> query
def lastn : number -> query -> query
// ast
def eval : q.ast -> data
// low-level execution
def process : q.ast -> query -> query
def processWithFallback : q.ast -> (stream(record) -> stream(record)) -> query -> query
def processPipeline : array(q.ast) -> query -> query
// query string parsing
def parse : string -> q.ast
def parseQueryString : database -> string -> q.ast // since PR1651
// "Magic link"
def makeAnonymousLink : appstate -> database -> string -> result(string, string)
// references
private case ref(string) // since PR#1813
type reference = ref | null // since PR#1813
def makeRef: string -> recordID
def stringRef : recordID -> string // since PR 1169
def isRef: recordID -> bool
module end
type database = data
type record = map(data)
type recordID = data // really a ref
type query = <opaque>
The type database designates the database to access; see next section for details.
The type record is a record coming from the database.
The type query is a query that will lead to the emission of a stream of records when executed.
Depending on the runtime environment, many varieties of database may be available. Typically, there is at least the “main” db associated with the current app, but there are generally others. These are summarized in the table below:
| Kind | On disk? | Platform server? | Browser runtimes? | Helper function | Notes |
|---|---|---|---|---|---|
| main | ✅ | ✅ | ✅ | db.mainDB/null |
|
| app DB | ✅ | ✅ | ✅ | db.appDB(name) |
|
| session DB | ❌ | ✅ | ❌ | db.localInMemDB(name) |
|
| in-mem app DB | ❌ | ✅ | ❌ | db.globalInMemDB(name) |
global in-mem DB, tied to particular global app DB, with same access rules |
| remote DB | N/A | ✅ | ✅ | db.remoteDB(url, name) |
connect to a remote DB over HTTP |
Other than representing the main DB as null, the database type is represented internally as a map, which you can also construct directly:
{"type": "rmx", "db": <name>, "scope": ["local"|"global"], "inmem": [true|false] }: access the session-local in-memory database dbname (or the main database of the app if the name is "main"){"type": "rmx_remote", "url": "baseURL", "db": <name> }: access the database db on the amp server with the given url. This is using the HTTP protocol. See below under db.remoteDB for more information.{"type": <other>, ...}: not used currentlyA series of options have been added to save to enable recording of original metadata -
KeepOriginal makes an _rmx_original map and adds individual meta records from the original record there, like _rmx_original/_rmx_idOriginalIdAlways always stores a _rmx_original_id and _rmx_original_rev from the original recordDontUseId: if an input record has an _rmx_id that is well-formed but not found in the database, the default is to preserve the ID. This option disables this behavior.