datastore

Summit Application Key/Value Store library.

summit.datastore provides Summit Applications with access to a read/write database. The database is not a SQL-like relational DB; instead, is a key/value store, although the values can be certain complex types.

Creating a table

For safety reasons, database tables cannot be created from within a Summit Application. To create a table, login to your Platform account and follow the steps listed there. Tables are per-application, although you can read database information for tables created by other applications within your tenant.

Basic Use

There are four complex types available: MapRow, ListRow, SetRow, and StringRow. Each is designed for a specific structure of data, and provides safe operations for working with that data.

First, let’s take a look at the basic functions to create a Lua object that reflects our database table:

local datastore = require "summit.datastore"
local my_table = datastore.get_table("my_table_name", "map")
print(type(my_table), tostring(my_table))  -- prints "table", "instance of class TableClass"

In this instance, my_table is a map type, visible in the second argument to datastore.get_table. Now that we have a reference to the table in our database, we can use this to perform simple operations like querying by key, creating a blank object, or just inserting raw data directly into the database. First, let’s look at just doing a raw insert:

my_data = {foo="bar", baz="qux"}
local result, err = my_table:create('123', my_data)
print(result, err)  -- prints true, nil

In this case, we have inserted the Lua table {foo="bar", baz="qux"} into our database, at the key '123'. Now, let’s query our database for that key and view our data:

local query_row = my_table:get_row_by_key('123')
print(query_row)  -- prints {key='123', data={foo="bar", baz="qux"}}

Because of the way the key/value store works, you can’t do SQL-like filtering or querying. Only the primary key can be used for lookups. Also, treat this key like you would a true database Primary Key: if you were to call my_table:create() again with the same key argument, it would overwrite the data we just wrote above. We recommend using random UUIDs as primary keys (a helper for this is provided at math.generate_uuid).

Next, let’s create a blank row, manipulate its attributes, and save it back:

local new_row = my_table()
new_row.key = '456'
new_row.data = {first="joe", last="smith"}
new_row:save()

All the Row types have a save() method available, which simply writes their current .data value back to the database at their .key location. This is basically the same thing as:

my_table:create(new_row.key, new_row.data)

However, while the :save() method is easy, it is not safe for concurrent use. If you have multiple applications reading and writing to the same Key in the database, you may run into race conditions like this:

local first_row = my_table:get_row_by_key('789')
local second_row = my_table:get_row_by_key('789')

first_row.data = {foo="bar"}
first_row:save()  -- database is now {'789' = {foo="bar"}}

second_row.data = {baz="qux"}
second_row:save()  -- database is now {'789' = {baz="qux"}}

As you can see, we accidentally ended up discarding the work done by first_row. For Summit Applications, concurrency probably going to be a very common occurrence, so we have provided some special methods on each Row type which are safe to use in multiple concurrent processes (“thread safe”, basically). For example, MapRow:update:

local first_row = my_table:get_row_by_key('321')
local second_row = my_table:get_row_by_key('321')

first_row:update({foo="bar"})  -- database is now {'321' = {foo="bar"}}

second_row:update({baz="qux"})  -- database is now {'321' = {foo="bar", baz="qux"}}

All the above examples used the MapRow type, but the other types are very similar. Each has its own safe operations, owing to the different needs and abilities of each type.

Safe Operations

The MapRow allows you to update or remove individual keys within the map safely.

The ListRow type allows you to store an ordered, non-unique list of values. It provides safe operations to insert and remove items.

The SetRow type provides an unordered, unique set of values. It allows for safe inserts and removals. Additionally, it guarantees uniqueness for each element.

The StringRow is the simplest type. It simply stores a string. This type provides no safe operations, but allows you to store arbitrarily complex structures (by JSON-encoding before store, and decoding afterwards) if necessary.

More details about the different operations for each type are listed below under the Class definitions or directly from the Functions table in this document.

Data Restrictions

One important restriction: all your keys and values must be strings. No other types are supported, nor are complex structures supported at the bottom level. For example, for the List type, you cannot have a list of functions or numbers. We recommend manually casting any non-string values to strings with tostring before storing in the database.

Classes

Name Summary
ListRow

ListRow type for ordered lists of data.

MapRow

MapRow row type, for storing data as a table (or a dict/map in other languages).

SetRow

SetRow type for unique sets of items.

StringRow

StringRow type for any generic string data.

TableClass

A class representing a database table.

Functions

Name Summary
get_table

Return an object that references a database table.

Classes : datastore

ListRow

ListRow type for ordered lists of data.

This type allows you to interact with an ordered list. Duplicates are allowed and order is maintained when you read or write from the database. In Lua terms, data will appear like:

print(row.data) -- prints {"foo", "bar", "baz", "qux"}

You can also perform a set of safe operations on a ListRow to alter the data without worrying about overwriting another Application’s changes.

Fields
Name Type Summary
key

string

String key referring to a database key. We do not recommend altering this value.

data

table

Table of data contained in the database at self.key. If you alter this directly, you must call self:save() to write those changes back to the database.

Functions
Name Returns Summary
append(value)

1: ListRow or nil

2: string or nil

Append an item safely to the end of the list.

delete()

1: ListRow or nil

2: string or nil

Delete this ListRow from the database.

prepend(value)

1: ListRow or nil

2: string or nil

Prepend and item safely to the beginning of the list.

remove(value)

1: ListRow or nil

2: string or nil

save()

1: ListRow or nil

2: string or nil

Write this ListRow instance back to the database.

ListRow:append(value)

Append an item safely to the end of the list. This operation will perform a safe append, adding value to the end of the list in the database. If another process has also written data into the list between when this row was fetched and this operation was called, both updates will be preserved.

Parameters
Name Type Default Summary

value

string

A value to insert at the end of the list

Returns
Type Summary

ListRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "list")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {"foo", "bar"}
my_row:append("qux")
print(my_row.key, my_row.data)  -- prints '123', {"foo", "bar", "qux"}

ListRow:delete()

Delete this ListRow from the database. This function issues a delete command to the database for self.key. Afterwards, this method will set self.key = nil and self.data = {}.

Returns
Type Summary

ListRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "list")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {"foo", "bar"}
my_row:delete()
print(my_row.key, my_row.data)  -- prints nil, {}
-- The entry in the database is also removed

ListRow:prepend(value)

Prepend and item safely to the beginning of the list. This command provides the same safety as ListRow:append, except it inserts value at the start of the list instead of the end.

Parameters
Name Type Default Summary

value

string

A value to insert at the end of the list

Returns
Type Summary

ListRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "list")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {"foo", "bar"}
my_row:prepend("qux")
print(my_row.key, my_row.data)  -- prints '123', {"qux", "foo", "bar"}

ListRow:remove(value)

This will safely remove all instances of value from the list in the database. It provides the same safety as ListRow:append and ListRow:prepend. Note that all instances, not just the first, will be removed.

Parameters
Name Type Default Summary

value

string

A value to remove from the list

Returns
Type Summary

ListRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "list")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {"foo", "bar", "foo", "qux"}
my_row:remove("foo")
print(my_row.key, my_row.data)  -- prints '123', {"bar", "qux"}

ListRow:save()

Write this ListRow instance back to the database. This method will take whatever is in self.data and write it back to the database at the self.key location. It will overwrite any existing data without reading first, or will create a new entry if no data currently exists at that key. If you are writing an application where multiple threads could be using (and writing) to the same key at the same time, you should NOT use this method, as it is not safe for concurrent access, and it will trample over any write made between when you first read data into the row and when you save it.

If you need operations that are safe for concurrent use, use ListRow:append, ListRow:prepend, and ListRow:remove instead.

Returns
Type Summary

ListRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "list")
print(tostring(my_table))  -- "instance of class TableClass"
local my_row = my_table()
my_row.key = '1234'
my_row.data = {"foo", "bar"}
my_row:save()  -- if anything was in the database at key='1234', I just overwrote it

MapRow

MapRow row type, for storing data as a table (or a dict/map in other languages).

This type is designed for storing table style data (key/value pairs) in the database. This row type allows atomic updates and removals of key/value pairs. However, this is not designed for nested values (it is NOT a “document store” style database). So, data = {foo="bar"} is allowed, but data = {foo={bar=baz}} is not.

All keys and values must be strings. Lua will do some type conversion, but its recommended that you manually cast any non-strings with tostring first. Data will look like:

-- prints {foo="bar", baz="qux"}
print(row.data)
Fields
Name Type Summary
key

string

String key referring to a database key. We do not recommend altering this value.

data

table

Table of data contained in the database at self.key. If you alter this directly, you must call self:save() to write those changes back to the database.

Functions
Name Returns Summary
delete()

1: MapRow or nil

2: string or nil

Delete this MapRow from the database.

remove()

1: MapRow or nil

2: string or nil

Update values in the MapRow to nil.

save()

1: MapRow or nil

2: string or nil

Write this MapRow instance back to the database.

update(update_data)

1: MapRow or nil

2: string or nil

Perform an atomic update of the data in the MapRow.

MapRow:delete()

Delete this MapRow from the database. This function issues a delete command to the database for self.key. Afterwards, this method will set self.key = nil and self.data = {}.

Returns
Type Summary

MapRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {foo="bar"}
my_row:delete()
print(my_row.key, my_row.data)  -- prints nil, {}
-- The entry in the database is also removed

MapRow:remove()

Update values in the MapRow to nil. This method is similar to MapRow:update, except it specifically sets keys within your map to nil. Because of how Lua tables work, we can’t do that directly in update, so this method provides that functionality.

Returns
Type Summary

MapRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {foo="bar", baz="qux", asdf="qwer"}
remove_data = {'foo', 'baz'}
my_row:remove(remove_data)
print(my_row.key, my_row.data)  -- prints '123', {asdf="qwer"}

MapRow:save()

Write this MapRow instance back to the database. This method will take whatever is in self.data and write it back to the database at the self.key location. It will overwrite any existing data without reading first, or will create a new entry if no data currently exists at that key. If you are writing an application where multiple threads could be using (and writing) to the same key at the same time, you should NOT use this method, as it is not safe for concurrent access, and it will trample over any write made between when you first read data into the row and when you save it.

If you need operations that are safe for concurrent use, use MapRow:update and MapRow:remove instead.

Returns
Type Summary

MapRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
print(tostring(my_table))  -- "instance of class TableClass"
local my_row = my_table()
my_row.key = '1234'
my_row.data = {foo="bar"}
my_row:save()  -- if anything was in the database at key='1234', I just overwrote it

MapRow:update(update_data)

Perform an atomic update of the data in the MapRow. This method is designed for safer updates of map data. While self:save() will trample over any changes made between read and write, this method will instead will only change the keys included in the update_data param. If you need to set a value to nil, use the MapRow:remove method instead, as update_data is a Lua table, so trying to issue an update for {foo=nil} is the same as issuing an update for {}, which means nothing would be changed.

Parameters
Name Type Default Summary

update_data

table

Table of key/value pairs to update in the database

Returns
Type Summary

MapRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {foo="bar"}
update_data = {baz="qux"}
my_row:update(update_data)
print(my_row.key, my_row.data)  -- prints '123', {foo="bar", baz="qux"}

-- A more advanced example, to show how this can support concurrency
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {foo="bar"}
local same_row = my_table:get_row_by_key('123')

my_row:update({baz="qux"})
print(my_table:get_row_by_key('123').data)  -- prints {foo="bar", baz="qux"}
same_row:update({asdf="qwer"})
print(my_table:get_row_by_key('123').data)  -- prints {foo="bar", baz="qux", asdf="qwer"}
-- Both changes are applied, each without overwriting the other

SetRow

SetRow type for unique sets of items.

The SetRow class allows you to store unique unsorted lists of items. You can think of it like a Map, except we only care about the keys, not the values. In Lua, a set looks like:

print(row.data)  -- prints {red=true, blue=true, green=true}

Sets have their own safe operations: SetRow:insert and SetRow:remove.

Fields
Name Type Summary
key

string

String key referring to a database key. We do not recommend altering this value.

data

table

Table of data contained in the database at self.key. If you alter this directly, you must call self:save() to write those changes back to the database.

Functions
Name Returns Summary
delete()

1: SetRow or nil

2: string or nil

Delete this SetRow from the database.

insert(value)

1: SetRow or nil

2: string or nil

Insert a new item into the Set.

remove(value)

1: SetRow or nil

2: string or nil

Remove an item from the Set.

save()

1: SetRow or nil

2: string or nil

Write this SetRow instance back to the database.

SetRow:delete()

Delete this SetRow from the database. This function issues a delete command to the database for self.key. Afterwards, this method will set self.key = nil and self.data = {}.

Returns
Type Summary

SetRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "set")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {foo=true, bar=true}
my_row:delete()
print(my_row.key, my_row.data)  -- prints nil, {}
-- The entry in the database is also removed

SetRow:insert(value)

Insert a new item into the Set. This is the safe way to insert items into a set. If value is already part of the set, nothing will happen. If not, it will be added. Note that since sets are unordered, no guarantees are made about the position of the new item.

Parameters
Name Type Default Summary

value

string

A value to add to the set

Returns
Type Summary

SetRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "set")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {foo=true, bar=true}
my_row:insert("baz")
print(my_row.key, my_row.data)  -- prints '123', {foo=true, bar=true, baz=true}

SetRow:remove(value)

Remove an item from the Set. This is a the safe way to remove an item from a SetRow. If the item is not part of the set, nothing will happen. Note that, since Set elements are unique unlike Lists, at most one element will be removed.

Parameters
Name Type Default Summary

value

string

A value to remove from the Set

Returns
Type Summary

SetRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "set")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', {foo=true, bar=true}
my_row:remove("foo")
print(my_row.key, my_row.data)  -- prints '123', {bar=true}

SetRow:save()

Write this SetRow instance back to the database. This method will take whatever is in self.data and write it back to the database at the self.key location. It will overwrite any existing data without reading first, or will create a new entry if no data currently exists at that key. If you are writing an application where multiple threads could be using (and writing) to the same key at the same time, you should NOT use this method, as it is not safe for concurrent access, and it will trample over any write made between when you first read data into the row and when you save it.

If you need operations that are safe for concurrent use, use SetRow:insert, and SetRow:remove instead.

Returns
Type Summary

SetRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "set")
print(tostring(my_table))  -- "instance of class TableClass"
local my_row = my_table()
my_row.key = '1234'
my_row.data = {foo=true, bar=true}
my_row:save()  -- if anything was in the database at key='1234', I just overwrote it

StringRow

StringRow type for any generic string data.

If your data does not fit into one of the most specific types, or you are not worried about concurrency safety, the StringRow type is available. There are no safe operations so you will be subject to race conditions if multiple processes are working with the same key at the same time.

Any string data is allowed here. If you desire, you can JSON-encode your own more complex data structures (like Lua tables) and use this store, although you lose the advantages of the MapRow type then. Row data will look like:

print(row.data)  -- prints "some string of data"
Functions
Name Returns Summary
delete()

1: StringRow or nil

2: string or nil

Delete this StringRow from the database.

save()

1: StringRow or nil

2: string or nil

Write this StringRow instance back to the database.

StringRow:delete()

Delete this StringRow from the database. This function issues a delete command to the database for self.key. Afterwards, this method will set self.key = nil and self.data = {}.

Returns
Type Summary

StringRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "set")
local my_row = my_table:get_row_by_key('123')
print(my_row.key, my_row.data)  -- prints '123', "some string of data"
my_row:delete()
print(my_row.key, my_row.data)  -- prints nil, {}
-- The entry in the database is also removed

StringRow:save()

Write this StringRow instance back to the database. This method will take whatever is in self.data and write it back to the database at the self.key location. It will overwrite any existing data without reading first, or will create a new entry if no data currently exists at that key. If you are writing an application where multiple threads could be using (and writing) to the same key at the same time, you should NOT use this method or this type, as it is not safe for concurrent access, and it will trample over any write made between when you first read data into the row and when you save it.

If you need operations that are safe for concurrent use, use a different row type instead.

Returns
Type Summary

StringRow or nil

self, or nil if an error occurred

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "string")
print(tostring(my_table))  -- "instance of class TableClass"
local my_row = my_table()
my_row.key = '1234'
my_row.data = "some string of data"
my_row:save()  -- if anything was in the database at key='1234', I just overwrote it

TableClass

A class representing a database table.

This object should not be used or instantiated directly. Call get_table to return an instance of this object.

Functions
Name Returns Summary
__call(key, value)

1: MapRow or ListRow or SetRow or StringRow or nil

2: string or nil

Return an empty or seeded RowClass instance.

create(key, value)

1: boolean or nil

2: string or nil

Insert data directly into the database.

get_row_by_key(key)

1: MapRow or ListRow or SetRow or StringRow or nil

2: string or nil

Return a RowClass instance for the specified key.

init_cache()

1: boolean or nil

2: string or nil

Load up a cache with data in table

invalidate_cache(key)

nil

Invalidate cached data

keys()

1: list or nil

2: string or nil

Get all the keys for this table

TableClass:__call(key, value)

Return an empty or seeded RowClass instance. If you use the __call method on a TableClass object, it returns an instance of a RowClass object. You can optionally provide a key and/or a data table to be used to instantiated that object. It does not require that the key already exists in the database, nor will it query the database for that key or any data referenced by it.

Parameters
Name Type Default Summary

key

string or nil

Optional key to set on the object

value

table or nil

Optional data to insert into the object

Returns
Type Summary

MapRow or ListRow or SetRow or StringRow or nil

An instance of a class representing the specified key and data (or nil and {}, respectively), or nil if an error occurred. See MapRow, ListRow, SetRow, or StringRow for more info, based on the type of this TableClass

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
if not err then
    -- Make an empty object that we can manipulate
    local new_row, err = my_table()
    print(type(new_row), tostring(new_row))  -- prints "table", "instance of class MapRow"
    print(new_row.key, new_row.data)  -- prints nil, {}

    -- You can also create an empty row but seed it with a key and/or data
    local seed_row, err = my_table('456', {baz=qux})
    print(type(seed_row), tostring(seed_row))  -- prints "table", "instance of class MapRow"
    print(seed_row.key, seed_row.data)  -- prints '456', {baz=qux}
end

TableClass:create(key, value)

Insert data directly into the database. If you don’t want to work with Row objects, you can write data directly into the database. This will not read-before-write, so it will overwrite anything already in the database for the specified key.

Parameters
Name Type Default Summary

key

string

The key to use for inserting the data

value

table

table of data to insert at the specified key

Returns
Type Summary

boolean or nil

Either true on success, or nil if an error occurred

string or nil

Either a string error message on error, or nil if no errors

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
if not err then
    local res, err = my_table:create('123', {foo="bar"})  -- create an entry with key '123' and data {foo="bar"}
    print(res, err)  -- prints true, nil
end

TableClass:get_row_by_key(key)

Return a RowClass instance for the specified key.

Parameters
Name Type Default Summary

key

string

Key to lookup in the database

Returns
Type Summary

MapRow or ListRow or SetRow or StringRow or nil

An instance of a class representing the row of data in the database, or nil if an error occurred. See MapRow, ListRow, SetRow, or StringRow for more info, based on the type of this TableClass

string or nil

An error if something went wrong, or nil if a row was found

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
if not err then
    local my_row, err = my_table:get_row_by_key('123')
    print(type(my_row), tostring(my_row))  -- prints 'table', 'instance of class MapRow'
    print(my_row.key, my_row.data)  -- prints '123', {foo="bar"}
end

TableClass:init_cache()

Load up a cache with data in table Calling this method will fetch the first 500 rows of your table and cache them. This should be the entire table for most cases. This will cause subsequent calls to get_row_by_name to be much faster. It also permanently enable row caching on the table, with all the benefits and perils that entails.

The cache behaves very differently for tables with composite values (ie, map, set, list) vs table with string values. For composite type tables, row values are shared across all instances rows retrieved from the same table instance. (unless you replace the row.data table completely with a new table) For string tables, this is not the case. For string tables, cache invalidation must be handled manually. Saving a row does not invalidate the cache — old row values will continue to be retrieved for string tables until the cached value for that row is cleared.

Returns
Type Summary

boolean or nil

true if table data was loaded successfully

string or nil

An error message if something went wrong, or nil otherwise

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
local my_string_table, err = datastore.get_table("my_string_table", "string")
if not err then
    local ok, err = my_table:init_cache()
    -- if ok, then cache is primed and get_row_by_key will use the cache
    local my_row, err = my_table:get_row_by_key('123')
end
-- Assuming the cache has been initialized
row1 = my_table:get_row_by_key('123')
row1.data.one = "one"
row2 = my_table:get_row_by_key('123')
print(row2.data.one)  -- prints "one"
row1.data.one = "two"
print(row2.data.one)  -- prints "two"

srow1 = my_string_table:get_row_by_key("abc")
print(srow1.data)  -- let's say it prints 'foo'
srow1.data = "bar"
srow1:save()
srow2 = my_string_table:get_row_by_key("abc")
print(srow2.data)  -- will print 'foo', since the cache is stale

TableClass:invalidate_cache(key)

Invalidate cached data

Parameters
Name Type Default Summary

key

string or nil

Optional key to invalidate. Will invalidate all keys if nil.

Returns
Type Summary

nil

Succeeds in all cases.

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
if not err then
    my_table:init_cache()
    local my_row, err = my_table:get_row_by_key('123')
    my_table:invalidate_cache('123')
    -- next call to my_table:get_row_by_key('123') will fetch data.
    my_table:invalidate_cache()
    -- clears whole cache,
    -- next call to my_table:get_row_by_key(k) will fetch data for any key.
end

TableClass:keys()

Get all the keys for this table Get a list of all the keys in this table.

Returns
Type Summary

list or nil

Either a list of all keys on success, or nil if an error occurred

string or nil

Either a string error message on error, or nil if no errors

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
if not err then
    for _, key in ipairs(my_table:keys()) do
        print(key)
    end
end

Functions : datastore

get_table(name, type[, appid])

Return an object that references a database table. This is the entry point for working with the database. This method will return a matching table (if one exists) of the given name and type.

Parameters
Name Type Default Summary

name

string

The name of the database table

type

string

The Type of the database table: must be in [‘map’, ‘list’, ‘set’, ‘string’]

appid

string or nil

Optional – Application ID. Defaults to current application, but can be set to retrieve data from other applications. If you are looking up data from a table which belongs to another application, this should be the UUID ID of that application (for example, if the git URL is git@code.corvisa.com:b8230674-03e2-4a0b-8da0-718fa579ac36, then the appid would be "b8230674-03e2-4a0b-8da0-718fa579ac36")

Returns
Type Summary

TableClass or nil

An instance of a class representing your database table, or nil if there was an error. See TableClass

string or nil

An error if something went wrong, or nil if successful

Usage
local datastore = require "summit.datastore"
local my_table, err = datastore.get_table("my_table", "map")
if not err then
    -- Insert some data directly into the DB
    my_table:create('123', {foo="bar"})  -- create an entry with key '123' and data {foo="bar"}

    -- Get an existing row so we can examine the data inside
    local my_row, err = my_table:get_row_by_key('123')
    print(my_row.key, my_row.data)  -- prints '123', {foo="bar"}

    -- Make an empty object that we can manipulate
    local new_row, err = my_table()
    print(new_row.key, new_row.data)  -- prints nil, {}

    -- You can also create an empty row but seed it with a key and/or value
    local seeded_row, err = my_table('456', {baz=qux})
    print(seeded_row.key, seeded_row.data)  -- prints '456', {baz=qux}

    -- For information about the methods available on Row objects, see the MapRow,
    -- ListRow, SetRow, and StringRow specific documentation below
end