BoxLang ๐ A New JVM Dynamic Language Learn More...
|:------------------------------------------------------: |
| โก๏ธ B o x L a n g โก๏ธ
| Dynamic : Modular : Productive
|:------------------------------------------------------: |
Copyright Since 2023 by Ortus Solutions, Corp
www.boxlang.io | www.ortussolutions.com
ย
This module provides a BoxLang JDBC driver for SQLite databases, enabling seamless integration between BoxLang applications and SQLite for both in-memory and file-based database operations.
org.xerial:sqlite-jdbc driverqueryExecute() and datasource managementbox install bx-sqlite
# Into the BoxLang HOME
install-bx-module bx-sqlite
# Or a local folder
install-bx-module bx-sqlite --local
Once installed, you can immediately start using SQLite databases in your BoxLang applications:
// Define an in-memory datasource for quick testing (shared cache)
this.datasources[ "testDB" ] = {
"driver": "sqlite",
"database": "memory:testDB"
};
// Use it in your code
result = queryExecute("SELECT 1 as test", [], {"datasource": "testDB"});
See BoxLang's Defining Datasources documentation for full examples on where and how to construct a datasource connection pool.
Perfect for testing, caching, or temporary data storage. Named
in-memory databases use SQLite's shared cache mode
(file:<name>?mode=memory&cache=shared),
allowing multiple connections to access the same in-memory database:
// Named in-memory database (shared across connections)
this.datasources["testDB"] = {
"driver": "sqlite",
"database": "memory:testDB"
};
// With additional parameters (parameters after ; are preserved for connection props)
this.datasources["cacheDB"] = {
"driver": "sqlite",
"database": "memory:cacheDB;create=true"
};
// Anonymous in-memory database (single connection only)
this.datasources["anonDB"] = {
"driver": "sqlite",
"database": ":memory: "
};
// Blank memory name resolves to :memory:
this.datasources["blankDB"] = {
"driver": "sqlite",
"database": "memory:"
};
For persistent data storage:
// Absolute path (recommended)
this.datasources["mainDB"] = {
"driver": "sqlite",
"database": "/var/www/myapp/data/main.db"
};
// Relative path (from application root)
this.datasources["localDB"] = {
"driver": "sqlite",
"database": "./data/local.db"
};
// Windows path example
this.datasources["winDB"] = {
"driver": "sqlite",
"database": "C:\\MyApp\\data\\app.db"
};
You can also specify additional connection parameters:
this.datasources["advancedDB"] = {
"driver": "sqlite",
"database": "/path/to/database.db",
// Optional: Custom connection properties
"custom": {
"journal_mode": "WAL",
"synchronous": "NORMAL",
"cache_size": "10000"
}
};
// Create a table
queryExecute("
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
", [], {"datasource": "mainDB"});
// Insert data
queryExecute("
INSERT INTO users (name, email)
VALUES (?, ?)
", ["John Doe", "[email protected]"], {"datasource": "mainDB"});
// Query data
users = queryExecute("
SELECT * FROM users
WHERE email = ?
", ["[email protected]"], {"datasource": "mainDB"});
// Update data
queryExecute("
UPDATE users
SET name = ?
WHERE id = ?
", ["John Smith", 1], {"datasource": "mainDB"});
try {
// Begin transaction
queryExecute("BEGIN TRANSACTION", [], {"datasource": "mainDB"});
// Multiple operations
queryExecute("INSERT INTO users (name, email) VALUES (?, ?)",
["User 1", "[email protected]"], {"datasource": "mainDB"});
queryExecute("INSERT INTO users (name, email) VALUES (?, ?)",
["User 2", "[email protected]"], {"datasource": "mainDB"});
// Commit transaction
queryExecute("COMMIT", [], {"datasource": "mainDB"});
} catch (any e) {
// Rollback on error
queryExecute("ROLLBACK", [], {"datasource": "mainDB"});
rethrow;
}
Perfect for unit tests:
// Test setup
this.datasources["testDB"] = {
"driver": "sqlite",
"database": "memory:testDB"
};
function beforeTests() {
// Create test schema
queryExecute("
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2)
)
", [], {"datasource": "testDB"});
// Insert test data
queryExecute("
INSERT INTO products (name, price) VALUES
('Product A', 10.50),
('Product B', 25.00)
", [], {"datasource": "testDB"});
}
function testProductQuery() {
var result = queryExecute("
SELECT COUNT(*) as total FROM products
", [], {"datasource": "testDB"});
expect(result.total).toBe(2);
}
# Clone the repository
git clone https://github.com/ortus-boxlang/bx-sqlite.git
cd bx-sqlite
# Build the module
./gradlew build
# Run tests
./gradlew test
# Create module structure for local testing
./gradlew createModuleStructure
bx-sqlite/
โโโ src/
โ โโโ main/
โ โ โโโ bx/
โ โ โ โโโ ModuleConfig.bx # Module configuration
โ โ โโโ java/
โ โ โ โโโ ortus/boxlang/modules/
โ โ โ โโโ sqlite/
โ โ โ โโโ SQLiteDriver.java # JDBC driver implementation
โ โ โโโ resources/
โ โโโ test/
โ โโโ java/ # Unit and integration tests
โ โโโ resources/
โโโ build.gradle # Build configuration
โโโ box.json # ForgeBox module manifest
โโโ readme.md # This file
The module includes comprehensive tests:
# Run all tests
./gradlew test
# Run with verbose output
./gradlew test --info
# Run specific test class
./gradlew test --tests "SQLiteDriverTest"
git checkout -b feature/amazing-feature)./gradlew test)./gradlew spotlessApply)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)| bx-sqlite Version | BoxLang Version | SQLite JDBC Version |
|---|---|---|
| 1.2.x | 1.4.0+ | 3.53.0.0 |
| 1.1.x | 1.4.0+ | 3.50.3.0 |
| 1.0.x | 1.3.0+ | 3.50.1.0 |
Ensure the directory exists and BoxLang has write permissions:
mkdir -p /path/to/database/directory
chmod 755 /path/to/database/directory
The database property is required. Ensure your datasource configuration includes:
"database": "/path/to/file.db" or "database": "memory:dbname"
Integration tests require the module to be built first:
./gradlew createModuleStructure
Enable debug logging in your BoxLang application:
// In your Application.bx
this.datasources["debugDB"] = {
"driver": "sqlite",
"database": "/path/to/debug.db",
"logSql": true,
"logLevel": "DEBUG"
};
See CHANGELOG.md for a complete list of changes and version history.
Licensed under the Apache License, Version 2.0. See LICENSE for details.
BoxLang is a professional open-source project and it is completely funded by the community and Ortus Solutions, Corp. Ortus Patreons get many benefits like a cfcasts account, a FORGEBOX Pro account and so much more. If you are interested in becoming a sponsor, please visit our patronage page: https://patreon.com/ortussolutions
"I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
database values using the memory: prefix to SQLite in-memory URIs (file:<name>?mode=memory&cache=shared) so they no longer create files on disk.memory:<name>, memory:<name>;create=true, and :memory: connection URL generation.Query API indexing semantics and validate UPDATE/DELETE behavior via SELECT results instead of expecting row payloads from DML results.Bump org.xerial:sqlite-jdbc from 3.50.1.0 to 3.50.3.0
Bump Boxlang version from 1.3.0 to 1.4.0
fixes on build process thanks to new module schema
Integration tests to avoid context caching issues with v1.4
$
box install bx-sqlite