XDL Codebase Exploration - Complete Summary
Executive Summary
The XDL project has a well-architected database connectivity module (xdl-database) that currently supports 6 database systems: PostgreSQL, MySQL, DuckDB, ODBC, Redis, and Kafka.
Key Finding: SQLite is NOT currently supported, despite being one of the most popular embedded databases. This represents a clear gap in the system.
1. PROJECT STRUCTURE
Workspace Organization
- Location:
/Users/ravindraboddipalli/sources/xdl/ - Type: Rust workspace with 17 member crates
- Main Branch: master
- Current Branch: develop
Member Crates
xdl-core - Core types and data structures (XdlValue, etc.)
xdl-parser - XDL language parser
xdl-interpreter - Interpreter for parsed code
xdl-runtime - Runtime environment
xdl-stdlib - Standard library functions
xdl-cli - Command-line interface
xdl-ffi - Foreign function interface
xdl-gui - GUI applications
xdl-database - DATABASE CONNECTIVITY (Focus area)
xdl-viz3d - 3D visualization
xdl-charts - Charting support
xdl-matlab - MATLAB transpiler
xdl-amp - Accelerated math processing
[and others...]
2. CURRENT DATABASE SUPPORT
Supported Databases
| Database | Driver | Feature Flag | Status | Type |
|---|---|---|---|---|
| PostgreSQL | tokio-postgres + deadpool | postgres-support | Fully implemented | Relational (async) |
| MySQL | mysql_async | mysql-support | Fully implemented | Relational (async) |
| DuckDB | duckdb | duckdb-support | Fully implemented | Analytical (sync) |
| ODBC | odbc-api | odbc-support | Fully implemented | Generic (sync) |
| Redis | redis | redis-support | Fully implemented | Key-value store |
| Kafka | rdkafka | kafka-support | Fully implemented | Streaming/Messaging |
Not Supported
- SQLite - Missing (most used embedded database)
- MongoDB - Not implemented
- DynamoDB - Not implemented
- Cassandra - Not implemented
3. ARCHITECTURE OVERVIEW
Core Components
A. XDLDatabase (lib.rs)
- Main API for user code
- Manages connection lifecycle
- Auto-detects database type from connection string
- Provides
connect(),disconnect(),execute_sql(),execute_command()
B. DatabaseType Enum (lib.rs)
- Automatically detects database type
- Detection patterns:
- PostgreSQL:
postgresql://orpostgres:// - MySQL:
mysql:// - DuckDB:
duckdb://,.duckdb,.dbfiles - Redis:
redis:// - Kafka:
kafka:// - ODBC:
DRIVER={...}
- PostgreSQL:
C. DatabaseConnection Enum (connection.rs)
- Factory pattern dispatcher
- Routes to appropriate driver based on database type
- All drivers implement same async interface:
async fn execute(query) -> Recordsetasync fn execute_command(cmd) -> u64async fn close() -> Result<()>async fn is_connected() -> bool
D. Recordset (recordset.rs)
- Unified result representation
- Contains columns (metadata) and rows (data)
- Converts all data to JsonValue
- Provides access methods:
get_data()- Convert to XdlValueget_column(name)- Get single columncurrent_row()- Get current row as HashMap- Navigation:
next(),reset()
E. DatabaseRegistry (lib.rs)
- Global registry for XDL object system integration
- Maps object IDs to database/recordset instances
- Uses lazy_static for singleton pattern
Design Patterns Used
- Enum-based dispatch - DatabaseConnection enum routes to drivers
- Feature-gated code - Each database is optional via Cargo features
- Consistent interface - All drivers implement identical async API
- Type abstraction - All DB values converted to JsonValue then XdlValue
- Error handling - Unified DatabaseError with driver-specific variants
- Global registry - For object system integration
- Async/await - All operations use Tokio for async execution
File Structure
xdl-database/
├── Cargo.toml # Dependencies and features
├── README.md # Documentation
├── src/
│ ├── lib.rs # Main API, XDLDatabase, DatabaseType
│ ├── connection.rs # DatabaseConnection dispatcher
│ ├── error.rs # Error types
│ ├── recordset.rs # Result representation
│ └── drivers/
│ ├── mod.rs # Module declarations
│ ├── postgres.rs # PostgreSQL (async, pooled)
│ ├── mysql.rs # MySQL (async, pooled)
│ ├── duckdb.rs # DuckDB (sync, wrapped)
│ ├── odbc.rs # ODBC (sync)
│ ├── redis_driver.rs# Redis (async)
│ └── kafka.rs # Kafka (async)
└── examples/
├── postgresql_example.xdl
├── mysql_example.xdl
├── duckdb_analytics.xdl
├── odbc_sqlserver_example.xdl
└── kafka_streaming_example.xdl
4. CONNECTION STRING PATTERNS
Existing Patterns
- PostgreSQL:
postgresql://user:password@host:5432/dbnameorpostgres://... - MySQL:
mysql://user:password@host:3306/database - DuckDB:
duckdb:///path/to/db.duckdbor.duckdbfile - Redis:
redis://localhost:6379 - Kafka:
kafka://broker1:9092,broker2:9092 - ODBC:
DRIVER={PostgreSQL};SERVER=localhost
Proposed SQLite Patterns
- File-based:
sqlite:///path/to/database.sqlite - Relative:
sqlite://./local.db - In-memory:
sqlite://:memory: - Auto-detect:
.sqliteand.dbfile extensions
5. RECOMMENDED SQLITE IMPLEMENTATION
Why SQLite?
- Embedded database - No server required, perfect for single-user/desktop apps
- Widely compatible - Works on Linux, macOS, Windows
- Zero-config - File-based, simple connection strings
- Very popular - Used extensively in mobile and desktop apps
- Lightweight - Minimal dependencies, small footprint
Implementation Location
Primary File: /Users/ravindraboddipalli/sources/xdl/xdl-database/src/drivers/sqlite.rs
Files to Modify
xdl-database/Cargo.toml- Add rusqlite dependencyxdl-database/src/lib.rs- Add SQLite to DatabaseType enumxdl-database/src/connection.rs- Add SQLite to DatabaseConnection enumxdl-database/src/error.rs- Add SQLiteError variantxdl-database/src/drivers/mod.rs- Add SQLite module declarationxdl-database/src/drivers/sqlite.rs- Create new driver (NEW FILE)
Implementation Pattern
Follow existing DuckDB pattern (both are synchronous):
- Wrap rusqlite::Connection in Mutex
- Implement async interface (convert to async/await)
- Convert rows to Vec< Vec< JsonValue»
- Parse connection strings (detect file paths,
:memory:, etc.)
Key Dependencies
rusqlite = { version = "0.31", features = ["bundled"], optional = true }
hex = "0.4" # For blob encoding
Feature Flag
sqlite-support = ["rusqlite"]
6. EXISTING PATTERNS & ABSTRACTIONS
Common Driver Interface
Every driver implements the same 5 methods:
pub async fn connect(connection_string: &str) -> DatabaseResult<Self>
pub async fn execute(&self, query: &str) -> DatabaseResult<Recordset>
pub async fn execute_command(&self, command: &str) -> DatabaseResult<u64>
pub async fn close(&mut self) -> DatabaseResult<()>
pub async fn is_connected(&self) -> bool
Type Conversion Chain
Database Value → JsonValue → XdlValue
Examples:
- NULL → JsonValue::Null → XdlValue::Undefined
- 42 → JsonValue::Number → XdlValue::Long
- 3.14 → JsonValue::Number → XdlValue::Double
- "text" → JsonValue::String → XdlValue::String
- [1,2,3] → JsonValue::Array → XdlValue::NestedArray
Error Handling Strategy
- Unified
DatabaseErrorenum with driver-specific variants - All errors convert to
XdlError::RuntimeErrorat API boundary - Specific error types: ConnectionError, QueryError, ConversionError, NotConnected, etc.
Registration Pattern (Object System)
// Create database
let db = XDLDatabase::new();
db.connect(conn_str).await?;
// In object system:
let id = GLOBAL_DB_REGISTRY.register_database(db).await;
// Later: let db_ref = GLOBAL_DB_REGISTRY.get_database(id).await;
7. DEPENDENCIES USED
Core Dependencies (all databases)
tokiov1.0+ - Async runtimeserde&serde_json- Serializationthiserror- Error typesasync-trait- Async trait supporturl- URL parsing for connection stringslazy_static- Global registry
Database-Specific Dependencies
- PostgreSQL:
tokio-postgres,deadpool-postgres - MySQL:
mysql_async - DuckDB:
duckdb(v1.1 with bundled) - ODBC:
odbc-api(v8.0) - Redis:
redis(v0.27 with tokio-comp) - Kafka:
rdkafka(v0.36 with tokio)
Proposed for SQLite
rusqlitev0.31 (with bundled feature)hexv0.4 (optional, for blob encoding)
8. KEY DESIGN OBSERVATIONS
Strengths
- Modular - Each database is independently pluggable
- Consistent - All drivers implement identical interface
- Type-safe - Results converted to typed XdlValue
- Async-first - Full async/await support
- Feature-gated - Only compile in needed drivers
- Well-documented - Examples provided for each database
Areas for Enhancement
- SQLite missing - Should be added
- Connection pooling - Only PostgreSQL/MySQL have it
- Type metadata - Limited column type information
- Transaction support - Not exposed in current API
- Prepared statements - Not currently parameterized
9. QUICK REFERENCE - FILES TO READ
| File | Purpose | Key Patterns |
|---|---|---|
lib.rs | Main API, type detection | DatabaseType enum, XDLDatabase struct, registry |
connection.rs | Dispatcher | DatabaseConnection enum, factory pattern |
error.rs | Error types | Unified error enum with driver variants |
recordset.rs | Results | Type conversions, JsonValue to XdlValue |
drivers/duckdb.rs | Reference sync driver | Pattern for synchronous wrapper |
drivers/postgres.rs | Reference async driver | Pattern for async with pooling |
drivers/mysql.rs | Reference with pooling | Connection pool management |
10. USAGE EXAMPLE
XDL Code (Once SQLite Added)
; Create database object
objdb = OBJ_NEW('XDLdbDatabase')
; Connect to SQLite
objdb->Connect, CONNECTION='sqlite:///./data/mydb.sqlite'
; Create table
objdb->ExecuteCommand, 'CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)'
; Insert data
objdb->ExecuteCommand, "INSERT INTO users (name, age) VALUES ('Alice', 30)"
; Query data
recordset = objdb->ExecuteSQL('SELECT * FROM users WHERE age > 25')
; Get results
data = recordset->GetData()
PRINT, 'Users:', data
; Cleanup
recordset->Destroy()
objdb->Disconnect()
OBJ_DESTROY, objdb
11. SUMMARY TABLE: Database Support
| Feature | PostgreSQL | MySQL | DuckDB | ODBC | Redis | Kafka | SQLite |
|---|---|---|---|---|---|---|---|
| Status | Implemented | Implemented | Implemented | Implemented | Implemented | Implemented | NOT IMPLEMENTED |
| Async | Yes | Yes | No (wrapped) | No | Yes | Yes | No (should wrap) |
| Pooling | Yes | Yes | No | No | Built-in | N/A | No |
| File-based | No | No | Yes | Varies | No | N/A | Yes |
| Use Case | Production OLTP | Production OLTP | Analytics | Legacy/ODBC | Caching/Real-time | Streaming | Embedded/Desktop |
| Connection Pool | deadpool | mysql_async | N/A | N/A | redis | N/A | Not needed |
12. NEXT STEPS FOR IMPLEMENTATION
- Add dependency to
Cargo.toml:rusqlite = { version = "0.31", features = ["bundled"], optional = true } - Create driver
src/drivers/sqlite.rsfollowing DuckDB pattern - Update enums:
- Add
SQLitetoDatabaseType - Add
SQLite(SQLiteConnection)toDatabaseConnection
- Add
- Update error types - Add
SQLiteErrorvariant - Update dispatcher - Add match arms in
connection.rs - Update module - Add
pub mod sqlitetodrivers/mod.rs - Add tests - Unit tests for connection string parsing
- Create example - XDL example showing SQLite usage
- Update documentation - Add SQLite to README
Conclusion
The XDL database module is well-designed with clear patterns and abstractions. SQLite support can be added by following the existing DuckDB driver pattern (synchronous wrapper) and implementing the standard driver interface. The codebase is modular enough to make this a straightforward addition.