The database functionality in Dataforge helps you work with data in both Node.js and browser environments. It uses SQLite for Node.js and alasql for browsers, making it easier to store and retrieve data consistently across platforms.
This guide covers:
The database functionality in Dataforge provides:
Database operations in Dataforge are synchronous by default. This is a key difference from many other database libraries that use async patterns.
// CORRECT: Synchronous database usage - NO await needed
let df = New('Dataforge');
let result = df.forge(data, [
{SelectDB: "myDatabase"},
{ReplaceIntoDB: "myDatabase.users"}
]);
console.log(result); // Available immediately
// INCORRECT: Don't use async/await for standard database operations
// This is unnecessary and may cause confusion
let df = New('Dataforge');
let result = await df.forge(data, [ // unnecessary await
{SelectDB: "myDatabase"},
{ReplaceIntoDB: "myDatabase.users"}
]);
When to use AsyncDataforge: Only use AsyncDataforge
when your data pipeline includes truly asynchronous operations like HTTP requests (Fetch
, Post
) or other I/O operations. The database commands themselves work identically in both Dataforge
and AsyncDataforge
patterns.
SelectDB
Selects or creates a database for subsequent operations. Crucially to browsers, this also Attaches the database at it's name. This is because alasql doesn't support opening by filename, meaning there is no default database we can rely on. The solution is to always references tables by their database name (dbname.tablename).
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"}
]);
In Node.js, this creates/opens an SQLite database in the /dbs
directory. In browsers, it uses alasql with localStorage persistence.
CloseDB
Closes the current database connection.
let df = New('Dataforge');
df.forge(null, ["CloseDB"]);
CreateTableInDB
Creates a new table with specified schema.
Basic table creation (id/data columns):
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{CreateTableInDB: "myDatabase.users"}
]);
Custom schema:
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{CreateTableInDB: ["myDatabase.customTable", {
id: "TEXT PRIMARY KEY",
name: "TEXT",
age: "INTEGER"
}]}
]);
TruncateTableInDB
Removes all records from a table.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{TruncateTableInDB: "myDatabase.users"}
]);
ReplaceIntoDB
Inserts or updates a record in the database. This command is designed for use with the default Idea Schema (tables with id
and data
columns). For tables with custom schemas, use RunInDB
with an INSERT OR REPLACE
SQL statement.
let df = New('Dataforge');
df.forge({
id: "user1",
name: "John",
age: 30
}, [
{SelectDB: "myDatabase"},
{ReplaceIntoDB: "myDatabase.users"}
]);
SelectIdeaFromDB
Retrieves a specific record by ID.
let df = New('Dataforge');
let result = df.forge(null, [
{SelectDB: "myDatabase"},
{SelectIdeaFromDB: ["myDatabase.users", "user1"]}
]);
console.log(result); // Available immediately, no await needed
SelectAllIdeasFromDB
Retrieves all records from a table.
let df = New('Dataforge');
let allUsers = df.forge(null, [
{SelectDB: "myDatabase"},
{SelectAllIdeasFromDB: "myDatabase.users"}
]);
console.log(allUsers); // Array of all users, available immediately
DeleteIdeaFromDB
Removes a specific record by ID.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{DeleteIdeaFromDB: ["myDatabase.users", "user1"]}
]);
IndexPropertyInDB
Creates an index on a JSON property within the data column.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{IndexPropertyInDB: ["myDatabase.users", "name"]}
]);
SelectIdeaPropertyFromDB
Retrieves a specific property from a record.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{SelectIdeaPropertyFromDB: ["myDatabase.users", "user1", "name"]}
]);
SelectIdeaByPropertyFromDB
Finds records where a property matches a specific value.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{SelectIdeaByPropertyFromDB: ["myDatabase.users", "name", "John"]}
]);
QueryDB
Executes a custom SQL query with optional parameters.
let df = New('Dataforge');
let results = df.forge(null, [
{SelectDB: "myDatabase"},
{QueryDB: [
"SELECT * FROM myDatabase.users WHERE age > ?",
[21]
]}
]);
// Results available immediately, no await needed
RunInDB
Executes a SQL statement that doesn't return results (DDL, DML).
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{RunInDB: [
"UPDATE myDatabase.users SET age = age + 1 WHERE id = ?",
["user1"]
]}
]);
SearchInDB
Performs a text search on a specific property.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{SearchInDB: ["myDatabase.users", "Jo", "name"]}
]);
StartTransactionInDB
Begins a database transaction.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
"StartTransactionInDB",
// ... operations in transaction
{EndTransactionInDB: true} // commit
]);
EndTransactionInDB
Ends a transaction with commit or rollback.
let df = New('Dataforge');
// Commit
df.forge(null, [{EndTransactionInDB: true}]);
// Rollback
df.forge(null, [{EndTransactionInDB: false}]);
Understanding Synchronous Operations
Dataforge
for most database work, AsyncDataforge
only when mixing with HTTP requests or other async operationsConnection Management
Data Storage
Error Handling
Cross-Environment Compatibility
Here's a complete example showing a typical database workflow:
let df = New('Dataforge');
// All operations below are synchronous - no await needed
let results = df.forge(null, [
// Select database
{SelectDB: "myApp"},
// Create table
{CreateTableInDB: "myApp.users"},
// Start transaction
"StartTransactionInDB",
// Insert some data
{ReplaceIntoDB: ["myApp.users", {
id: "user1",
data: JSON.stringify({
name: "John Doe",
email: "john@example.com",
preferences: {
theme: "dark",
notifications: true
}
})
}]},
// Create an index
{IndexPropertyInDB: ["myApp.users", "name"]},
// Commit transaction
{EndTransactionInDB: true},
// Query the data
{SearchInDB: ["myApp.users", "John", "name"]},
// Close the connection
"CloseDB"
]);
console.log(results); // Results available immediately
/dbs
directoryIf your workflow combines database operations with truly asynchronous operations (like HTTP requests, file operations, or timed operations), use AsyncDataforge
:
// Using AsyncDataforge when mixing with truly async operations
let adf = New('AsyncDataforge');
let result = await adf.forge(null, [
{SelectDB: "myDatabase"},
{SelectAllIdeasFromDB: "myDatabase.users"},
// Now doing something that actually requires async
{Fetch: "/api/external-data"},
// Process combined data...
]);
Remember: The database operations themselves are still synchronous internally, even when used within an AsyncDataforge pipeline.