falcon/database¶
Database connectivity and query interface for the Falcon autotuning system. Provides access to PostgreSQL-backed device characteristic storage with full CRUD operations and snapshot management.
⚠️ Prerequisites - IMPORTANT¶
This library requires an external PostgreSQL database to function. Unlike other Falcon libraries, the database package connects to a live database service that must be running before you can use this library or run its tests.
Required Setup Before Testing¶
- Install PostgreSQL (if not already installed)
- Start the Falcon database service using the
falcon-db-clitool - Initialize the database schema
- Set the connection environment variable
See the Database Setup section below for detailed instructions.
Installation¶
import "libs/database/database.fal";
Database Setup¶
The Falcon database uses PostgreSQL as its backend. Before running tests or using the database library, you must:
1. Start PostgreSQL Service¶
Ensure PostgreSQL is installed and running on your system:
# On Ubuntu/Debian
sudo systemctl start postgresql
# On macOS with Homebrew
brew services start postgresql
# Or using Docker
docker run -d --name falcon-postgres -p 5432:5432 \
-e POSTGRES_PASSWORD=falcon \
-e POSTGRES_DB=falcon_db \
postgres:latest
2. Set Connection Environment Variable¶
The library reads the database URL from the FALCON_DATABASE_URL environment variable:
export FALCON_DATABASE_URL="postgresql://username:password@localhost:5432/falcon_db"
Replace username, password, and falcon_db with your actual PostgreSQL credentials and database name.
3. Initialize Database Schema¶
Use the falcon-db-cli tool to create the required database tables:
falcon-db-cli init
This command is idempotent — it's safe to run multiple times. It will create the device_characteristics table and any required indexes.
4. Verify Connection¶
Test that everything is working:
falcon-db-cli help
For more information about the CLI tool, see /database/docs/CLI.md in the repository.
Running Tests¶
⚠️ CRITICAL: The test suite assumes:
- A PostgreSQL database is running and accessible
FALCON_DATABASE_URLenvironment variable is set correctly- The database schema has been initialized with
falcon-db-cli init - Data persists between test runs — tests are designed to be non-destructive
Test Execution¶
# Make sure database is running and initialized first!
export FALCON_DATABASE_URL="postgresql://falcon_test:falcon_test_password@localhost:5432/falcon_test"
falcon-db-cli init
# Now run the tests
cd libs/database/tests
falcon-test run_tests.fal
Test Data Persistence¶
Unlike in-memory tests, database tests have side effects:
- INSERT operations persist — data added by tests remains in the database
- DELETE operations are permanent — removed data does not automatically restore
- CLEAR operations are destructive — some admin tests are skipped to prevent data loss
The test suite is designed to be non-destructive by default:
- Uses queries that don't rely on specific pre-existing data
- Tests read operations extensively without requiring specific fixtures
- Skips dangerous operations like
ClearAll()that would delete all data - Uses unique identifiers for test data to avoid conflicts
Cleaning Up Test Data¶
If you need to reset the database to a clean state:
# Export a backup first (recommended)
falcon-db-cli snapshot export backup_$(date +%Y%m%d).json
# Clear all data (DESTRUCTIVE - cannot be undone!)
falcon-db-cli snapshot import empty.json --clear
# Or drop and recreate the schema
falcon-db-cli init
API Overview¶
Database Struct¶
Main database connection and query interface.
Database db = Database.New();
Connection Methods¶
| Method | Returns | Description |
|---|---|---|
New() |
Database |
Create a new database connection (lazy initialization) |
TestConnection() |
bool ok |
Test if database is reachable |
IsConnected() |
bool connected |
Check if connection has been established |
Read Methods¶
| Method | Returns | Description |
|---|---|---|
GetByName(string name) |
(DeviceCharacteristic, bool found) |
Retrieve single entry by name |
GetAll() |
DeviceCharacteristicList |
Retrieve all device characteristics |
GetByHashRange(string start, string end) |
DeviceCharacteristicList |
Query by hash range |
GetByQuery(DeviceCharacteristicQuery q) |
DeviceCharacteristicList |
Query with custom filters |
Count() |
int count |
Get total number of records |
Write Methods¶
| Method | Returns | Description |
|---|---|---|
Insert(DeviceCharacteristic dchar) |
() |
Insert a new device characteristic |
DeleteByName(string name) |
bool deleted |
Delete by name (returns true if found) |
DeleteByHash(string hash) |
int count |
Delete all matching hash (returns count deleted) |
Admin Methods¶
| Method | Returns | Description |
|---|---|---|
InitializeSchema() |
() |
Create database tables (idempotent) |
ClearAll() |
() |
DANGEROUS: Delete all records |
ExportToJson(string filename) |
() |
Export all data to JSON snapshot |
ImportFromJson(string filename, bool clear) |
() |
Import from JSON snapshot |
DeviceCharacteristic Struct¶
Represents a single device characteristic record.
string scope = dchar.GetScope();
string name = dchar.GetName();
string hash = dchar.GetHash();
int time = dchar.GetTime();
string state_val = dchar.GetState();
string unit_name = dchar.GetUnitName();
string json_str = dchar.ToJson();
DeviceCharacteristicList Struct¶
Collection of device characteristics returned from queries.
int count = list.Size();
DeviceCharacteristic first = list.Get(0);
DeviceCharacteristicQuery Struct¶
Builder pattern for constructing database queries.
DeviceCharacteristicQuery q = DeviceCharacteristicQuery.New();
q = q.SetScope("gpu")
.SetName("device_01")
.SetState("active")
.SetHash("abc123")
.SetUnitName("unit_0");
DeviceCharacteristicList results = db.GetByQuery(q);
All Set* methods return the query object for method chaining.
Example Usage¶
Basic Connection and Query¶
import "libs/database/database.fal";
Database db = Database.New();
// Test connection
bool ok = db.TestConnection();
if (ok) {
int total = db.Count();
// ... use database
}
Query by Name¶
Database db = Database.New();
string target_name = "my_device";
DeviceCharacteristic dchar;
bool found;
(dchar, found) = db.GetByName(target_name);
if (found) {
string scope = dchar.GetScope();
string hash = dchar.GetHash();
}
Complex Query with Filters¶
Database db = Database.New();
DeviceCharacteristicQuery q = DeviceCharacteristicQuery.New();
q = q.SetScope("gpu_compute")
.SetState("calibrated");
DeviceCharacteristicList results = db.GetByQuery(q);
int count = results.Size();
int i = 0;
while (i < count) {
DeviceCharacteristic item = results.Get(i);
string name = item.GetName();
// Process item...
i = i + 1;
}
Snapshot Export/Import¶
Database db = Database.New();
// Export current state
db.ExportToJson("backup_2026_03_12.json");
// Import (without clearing existing data)
db.ImportFromJson("previous_backup.json", false);
// Import and replace all data (DESTRUCTIVE!)
db.ImportFromJson("clean_slate.json", true);
Troubleshooting¶
"Connection failed" errors¶
- Verify PostgreSQL is running:
pg_isready - Check
FALCON_DATABASE_URLis set correctly - Ensure database exists:
psql -l - Check firewall settings for port 5432
"Table does not exist" errors¶
- Run
falcon-db-cli initto create the schema
Tests failing with "no data found"¶
- The test suite expects an empty or minimal database
- Some tests skip if no data is present
- Consider running with a test database separate from production
Permission errors¶
- Ensure the database user has
CREATE,INSERT,SELECT,DELETEprivileges - Check PostgreSQL
pg_hba.conffor connection authentication rules
Environment Variables¶
| Variable | Required | Description |
|---|---|---|
FALCON_DATABASE_URL |
Yes | PostgreSQL connection string (see above) |
See Also¶
- Database CLI Documentation:
/database/docs/CLI.md - Testing Framework:
libs/testing/README.md - Connection Implementation:
libs/database/database-wrapper.cpp
Maintainer¶
falcon-devs
For issues related to database connectivity or schema, refer to the main Falcon issue tracker.