Databases
Lua on Beans supports multiple database engines out of the box. Configure your database in config/database.json.
Multi-model graph database
Embedded SQL database
NewSQL cloud database
Distributed SQL database
PostgreSQL REST API
Any RDBMS via REST
settings Configuration
Database connections are configured in config/database.json. You can define multiple connections per environment.
{
"system": {
"db_name": "_system",
"url": "http://127.0.0.1:8529",
"username": "root",
"password": "password"
},
"development": [
{
"name": "primary",
"engine": "arangodb",
"db_name": "myapp_dev",
"url": "http://127.0.0.1:8529",
"username": "root",
"password": "password"
}
],
"production": [
{
"name": "primary",
"engine": "arangodb",
"db_name": "myapp_prod",
"url": "http://127.0.0.1:8529",
"username": "root",
"password": "password"
}
],
"test": [
{
"name": "primary",
"engine": "arangodb",
"db_name": "myapp_test",
"url": "http://127.0.0.1:8529",
"username": "root",
"password": "password"
}
]
}
info Initializing the Database
In your .init.lua, load the configuration and initialize:
local db_config = DecodeJson(LoadAsset("config/database.json"))
InitDB(db_config)
hub ArangoDB
ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values. It's the recommended database for Lua on Beans.
Configuration
config/database.json
{
"name": "primary",
"engine": "arangodb",
"db_name": "myapp_dev",
"url": "http://127.0.0.1:8529",
"username": "root",
"password": "password"
}
code Usage
-- Access via Adb.primary (or your connection name)
-- Run AQL queries
local result = Adb.primary:Aql("FOR u IN users RETURN u")
-- With bind variables
local result = Adb.primary:Aql(
"FOR u IN users FILTER u.email == @email RETURN u",
{ email = "john@example.com" }
)
-- Document operations
Adb.primary:CreateDocument("users", { name = "John", email = "john@example.com" })
Adb.primary:GetDocument("users/12345")
Adb.primary:UpdateDocument("users/12345", { name = "John Doe" })
Adb.primary:DeleteDocument("users/12345")
-- Collection operations
Adb.primary:CreateCollection("products")
Adb.primary:CreateCollectionWithTimestamps("orders") -- Adds c_at, u_at fields
Adb.primary:GetCollection("users")
Adb.primary:RenameCollection("users", { name = "customers" })
Adb.primary:TruncateCollection("temp_data")
Adb.primary:DeleteCollection("temp_data")
-- Index operations
Adb.primary:GetAllIndexes("users")
Adb.primary:CreateIndex("users", { type = "hash", fields = { "email" }, unique = true })
Adb.primary:DeleteIndex("users/12345")
-- Transactions
local tx = Adb.primary:BeginTransaction({ collections = { write = { "users" } } })
-- ... perform operations with transaction_id ...
Adb.primary:CommitTransaction(tx.result.id)
-- or: Adb.primary:AbortTransaction(tx.result.id)
functions ArangoDB Methods
| Method | Description |
|---|---|
| Query | |
| Aql(query, bindvars, options) | Execute AQL query with bind variables |
| Raw_aql(stm) | Execute raw AQL statement object |
| Documents | |
| CreateDocument(collection, data, options) | Create a document |
| GetDocument(handle) | Get document by handle (collection/key) |
| UpdateDocument(handle, data, options) | Update a document (PATCH) |
| DeleteDocument(handle) | Delete a document |
| Collections | |
| CreateCollection(name, options) | Create a collection |
| CreateCollectionWithTimestamps(name, options) | Create collection with c_at/u_at computed values |
| GetCollection(name) | Get collection info |
| UpdateCollection(name, params) | Update collection properties |
| RenameCollection(name, params) | Rename a collection |
| TruncateCollection(name, params) | Remove all documents from collection |
| DeleteCollection(name) | Delete a collection |
| Databases | |
| CreateDatabase(name, options, users) | Create a new database |
| DeleteDatabase(name) | Delete a database |
| Indexes | |
| GetAllIndexes(collection) | Get all indexes for a collection |
| CreateIndex(collection, params) | Create an index |
| DeleteIndex(handle) | Delete an index |
| Transactions | |
| BeginTransaction(params) | Begin a stream transaction |
| CommitTransaction(transaction_id) | Commit a stream transaction |
| AbortTransaction(transaction_id) | Abort a stream transaction |
| Transaction(params) | Execute a JavaScript transaction |
| Query Cache | |
| GetQueryCacheEntries() | Get cached query entries |
| GetQueryCacheConfiguration() | Get cache configuration |
| UpdateCacheConfiguration(params) | Update cache configuration |
| DeleteQueryCache() | Clear the query cache |
| User Defined Functions | |
| CreateFunction(params) | Create a custom AQL function |
| DeleteFunction(name) | Delete a custom AQL function |
| ListFunctions() | List all custom AQL functions |
| Authentication | |
| Auth() | Authenticate and get JWT token |
| RefreshToken() | Refresh JWT token (auto-refreshes after 10min) |
storage SQLite
SQLite is a C library that provides a lightweight, disk-based database. Perfect for development, testing, or small-scale applications.
Configuration
config/database.json
{
"name": "primary",
"engine": "sqlite",
"db_name": "myapp_dev"
}
Creates myapp_dev.sqlite3 file in your project root.
code Usage
-- Access via Sqlite.primary (or your connection name)
-- Execute SQL
Sqlite.primary:exec([[
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT,
email TEXT UNIQUE
)
]])
-- Query with callback
local users = {}
Sqlite.primary:exec("SELECT * FROM users", function(udata, cols, values, names)
local user = {}
for i = 1, cols do
user[names[i]] = values[i]
end
table.insert(users, user)
return 0
end)
-- Prepared statements
local stmt = Sqlite.primary:prepare("INSERT INTO users (name, email) VALUES (?, ?)")
stmt:bind_values("John", "john@example.com")
stmt:step()
stmt:finalize()
info SQLite Performance
Lua on Beans automatically configures SQLite with WAL journal mode and NORMAL synchronous for better performance.
cloud SurrealDB
SurrealDB is a NewSQL cloud database, suitable for serverless applications, jamstack sites, and traditional backends.
Configuration
config/database.json
{
"name": "primary",
"engine": "surrealdb",
"db_name": "myapp_dev",
"ns": "myapp",
"db": "main",
"url": "http://127.0.0.1:8000",
"username": "root",
"password": "root"
}
code Usage
-- Access via Surreal.primary (or your connection name)
-- Execute SurrealQL
local result = Surreal.primary:surreal_sql("SELECT * FROM users")
-- Create records
Surreal.primary:surreal_sql("CREATE users SET name = 'John', email = 'john@example.com'")
-- Query with filters
local users = Surreal.primary:surreal_sql("SELECT * FROM users WHERE email = 'john@example.com'")
-- Don't forget to refresh token for long-running apps
Surreal.primary:refresh_token()
analytics CrateDB
CrateDB is a distributed SQL database built on top of a NoSQL foundation. Great for time-series, IoT, and analytics workloads.
Configuration
config/database.json
{
"name": "primary",
"engine": "crate",
"url": "http://127.0.0.1:4200"
}
code Usage
-- Access via Crate.primary (or your connection name)
-- Execute SQL via HTTP API
local result = Crate.primary:sql("SELECT * FROM users")
api PostgREST
PostgREST serves a fully RESTful API from any existing PostgreSQL database. Use it when you already have a PostgreSQL database.
Configuration
config/database.json
{
"name": "primary",
"engine": "postgrest",
"url": "http://127.0.0.1:3000"
}
code Usage
-- Access via PGRest.primary (or your connection name)
-- GET request to fetch data
local users = PGRest.primary:get("/users")
-- POST to create
PGRest.primary:post("/users", { name = "John", email = "john@example.com" })
-- PATCH to update
PGRest.primary:patch("/users?id=eq.1", { name = "John Doe" })
-- DELETE
PGRest.primary:delete("/users?id=eq.1")
swap_horiz DB2REST
DB2REST provides a REST API for any relational database (MySQL, PostgreSQL, MariaDB, SQL Server, Oracle, etc.).
Configuration
config/database.json
{
"name": "primary",
"engine": "db2rest",
"db_name": "db",
"url": "http://127.0.0.1:7070/v1/rdbms/"
}
code Usage
-- Access via Rest.primary (or your connection name)
-- REST operations on your RDBMS tables
local users = Rest.primary:get("/users")
Rest.primary:post("/users", { name = "John" })
Rest.primary:patch("/users/1", { name = "John Doe" })
Rest.primary:delete("/users/1")
memory Redis (Cache)
Redis is supported as a caching layer. See the Features documentation for Redis usage.
Pro Tips
Multiple Connections: You can define multiple database connections with different names and access them via Adb.secondary, Sqlite.analytics, etc.
Environment-Specific: Configure different databases per environment (development, production, test) in database.json.
Token Refresh: For long-running applications, call :RefreshToken() or :refresh_token() in OnHttpRequest() to maintain database connections.
Migrations: Use beans db:migrate to run database migrations. Migrations live in the migrations/ folder.