CanDB

The CanDB module, containing all methods for initializing and interacting with the CanDB data structure

type ScalingLimitType = {#count : Nat; #heapSize : Nat}

Auto-Scaling Limit Type

A developer can choose to auto-scale by the count of entities that have been inserted or by the canister heap size

type ScalingOptions = { autoScalingHook : AutoScalingCanisterSharedFunctionHook; sizeLimit : ScalingLimitType }

ScalingOptions

autoScalingHook - The auto-scaling shared function in charge of scaling (located on the Index canister) sizeLimit - the auto-scaling limit for the canister: either limit the auto-scaling by the count or the heap size of the canister

Once a canister passes the sizeLimit, it will trigger an inter-canister call from the canister storage partition to the autoScalingHook to spin up a new canister for that partition. Then the scaling status is set to #complete, meaning that further insertions (after messages processed in that same consensus round) are sent to the newly spun up canister. However, updates to existing entity records in a canister storage partition can still happen until the canister hits the 1.75GB limit, held via the HEAP_SIZE_UPDATE LIMIT constant.

type DB = { pk : E.PK; var data : RT.RangeTree; var count : Nat; var scalingOptions : ScalingOptions; var scalingStatus : {#not_started; #started; #complete} }

CanDB Core

pk - the partition key of the CanDB instance. This also corresponds to the PK of the canister storage partition data - where the data for CanDB is stored count - the size/count of elements in CanDB (can be used for limit) scalingOptions - ScalingOptions

type DBInitOptions = { pk : E.PK; scalingOptions : ScalingOptions; btreeOrder : ?Nat }

public func init(options : DBInitOptions) : DB

initializes a CanDB data structure

type GetOptions = { sk : E.SK }

public func skExists(db : DB, sk : E.SK) : Bool

Returns a boolean indicating if an entity with a matching SK is present in CanDB

public func get(db : DB, options : GetOptions) : ?E.Entity

Get an entity if it exists in the DB

type PutOptions = { sk : E.SK; attributes : [(E.AttributeKey, E.AttributeValue)] }

public func put(db : DB, options : PutOptions) : async* ()

Create an entity or replace an entity if exists in the DB Auto scales by signaling the index canister to create a new canister with this PK if at capacity

type ReplaceOptions = PutOptions

public func replace(db : DB, options : ReplaceOptions) : async* ?E.Entity

Create an entity or replace an entity if exists in the DB, returning the replaced entity Auto scales by signaling the index canister to create a new canister with this PK if at capacity

public func batchPut(db : DB, options : [(PutOptions)]) : async* ()

Batch create or replace entities if exists in the DB

public func batchReplace(db : DB, options : [(ReplaceOptions)]) : async* [(?E.Entity)]

Batches creates or replaces a multiple entities if they exist in the DB, returning the replaced entity Auto scales by signaling the index canister to create a new canister with this PK if at capacity

type SubstituteKeyOptions = { oldSK : E.SK; newSK : E.SK }

public func substituteKey(db : DB, options : SubstituteKeyOptions) : ?E.Entity

Substitutes in a new key in for the current/old key, preserving the same attributes as the previous key (if the key previously exists in CanDB). This returns the old Entity if it existed, otherwise it returns null

type UpdateOptions = { sk : E.SK; updateAttributeMapFunction : (?E.AttributeMap) -> E.AttributeMap }

public func update(db : DB, options : UpdateOptions) : ?E.Entity

Similar to replace(), but provides the ability to pass a developer defined update function controlling how specific attributes of the entity are updated on match.

See the create() and update() functions in examples/simpleDB/src/main.mo, and the tests in updateSuite() in test/HashTreeTest for some examples of how to use CanDB.update()

type DeleteOptions = { sk : E.SK }

public func delete(db : DB, options : DeleteOptions) : ()

Removes an entity from the DB if exists

type RemoveOptions = DeleteOptions

public func remove(db : DB, options : RemoveOptions) : ?E.Entity

Remove an entity from the DB and return that entity if exists

type ScanOptions = { skLowerBound : E.SK; skUpperBound : E.SK; limit : Nat; ascending : ?Bool }

Options passed to scan

pk - type Text: The Partition Key skLowerBound - The Sort Key lower bound to scan from (inclusive) skUpperBound - The Sort Key upper bound to scan from (inclusive) limit - The limit of entries to scan within the sk bounds at a given time ascending - Determines the order of results and where scanning will start from, defaults to ascending (starting from the skLowerBound and ending at the skUpperBound)

type ScanResult = { entities : [E.Entity]; nextKey : ?E.SK }

Return type of scan()

entities - array of entities that match the scan nextKey - next key to be evaluated when the scan limit is hit, is ideal for pagination (i.e. if the limit was hit and the user desires to scan/view more matching results)

public func scan(db : DB) : ScanResult

Scans the DB by partition key, a lower/upper bounded sort key range, and a desired result limit Returns 0 or more items from the db matching the conditions of the ScanOptions passed