
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.
SelectDBSelects 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.
CloseDBCloses the current database connection.
let df = New('Dataforge');
df.forge(null, ["CloseDB"]);
CreateTableInDBCreates 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"
}]}
]);
TruncateTableInDBRemoves all records from a table.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{TruncateTableInDB: "myDatabase.users"}
]);
ReplaceIntoDBInserts 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"}
]);
SelectIdeaFromDBRetrieves 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
SelectAllIdeasFromDBRetrieves 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
DeleteIdeaFromDBRemoves a specific record by ID.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{DeleteIdeaFromDB: ["myDatabase.users", "user1"]}
]);
IndexPropertyInDBCreates an index on a JSON property within the data column.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{IndexPropertyInDB: ["myDatabase.users", "name"]}
]);
SelectIdeaPropertyFromDBRetrieves a specific property from a record.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{SelectIdeaPropertyFromDB: ["myDatabase.users", "user1", "name"]}
]);
SelectIdeaByPropertyFromDBFinds records where a property matches a specific value.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{SelectIdeaByPropertyFromDB: ["myDatabase.users", "name", "John"]}
]);
QueryDBExecutes 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
RunInDBExecutes 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"]
]}
]);
SearchInDBPerforms a text search on a specific property.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
{SearchInDB: ["myDatabase.users", "Jo", "name"]}
]);
StartTransactionInDBBegins a database transaction.
let df = New('Dataforge');
df.forge(null, [
{SelectDB: "myDatabase"},
"StartTransactionInDB",
// ... operations in transaction
{EndTransactionInDB: true} // commit
]);
EndTransactionInDBEnds 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"},
// Create an index
{IndexPropertyInDB: ["myApp.users", "name"]},
// Start transaction
"StartTransactionInDB",
// Insert some data
{ReplaceIntoDB: ["myApp.users", {
id: "user1",
name: "John Doe",
email: "john@example.com",
preferences: {
theme: "dark",
notifications: true
}
}]},
// Commit transaction
"EndTransactionInDB",
// 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
"Append",
{Fetch: "/api/external-data"},
// Process combined data...
]);
Remember: The database operations themselves are still synchronous internally, even when used within an AsyncDataforge pipeline.