tx2-query
SQL Analytics Layer for TX-2 ECS - enabling advanced analytics, complex queries, and external tool integration while keeping the ECS world as the source of truth.
Overview
tx2-query provides a SQL side-car database for TX-2 applications. It's designed as an analytics layer, NOT an ORM:
- ECS World → SQL Database: One-way synchronization from ECS to SQL
- Component → Table Mapping: Automatic schema generation from component types
- Incremental Sync: Track and sync only changed entities/components
- Multiple Backends: PostgreSQL, SQLite, and extensible to more
Philosophy
- ECS world is always the source of truth
- SQL database is a read-only projection for analytics
- No bi-directional sync - changes flow ECS → SQL only
- Optimized for analytical queries, not transactional workloads
Features
- Schema Generation: Automatic DDL creation from component definitions
- Query Builder: Ergonomic SQL query construction
- Sync API: Incremental synchronization with batching
- Backend Abstraction: Support for multiple SQL databases
- Type-Safe: Leverages Rust's type system for safety
- DuckDB Support: OLAP workloads with columnar storage and window functions
Installation
Add to your Cargo.toml:
[]
= { = "0.1", = ["postgres", "sqlite", "duckdb"] }
= { = "1.0", = ["full"] }
Quick Start
use *;
use json;
;
async
Database Backends
SQLite
use SqliteBackend;
// In-memory database
let backend = memory.await?;
// File-based database
let backend = file.await?;
PostgreSQL
use PostgresBackend;
let backend = connect.await?;
DuckDB
use DuckDBBackend;
// In-memory database (perfect for analytics)
let backend = memory.await?;
// File-based database
let backend = file.await?;
// Export to Parquet for external analysis
backend.export_parquet.await?;
// Import from Parquet
backend.import_parquet.await?;
Query Builder
The query builder provides an ergonomic, type-safe way to construct SQL queries:
// SELECT with WHERE
let query = new
.select
.where_eq
.where_gt
.build?;
// Aggregations
let query = new
.aggregate
.aggregate
.build?;
// Ordering and pagination
let query = new
.select_all
.order_desc
.limit
.offset
.build?;
// Complex conditions
let query = new
.select_all
.where_in
.where_like
.build?;
Schema Generation
Components automatically map to SQL tables:
;
schema_gen.?;
Generated DDL:
(
entity_id BIGINT NOT NULL,
name TEXT NOT NULL,
score INTEGER NOT NULL,
notes TEXT,
_tx2_updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (entity_id)
);
Synchronization
Incremental Sync
Track changes as they happen in your ECS world:
// Entity created
sync.track_entity_created.await?;
// Component added/modified
sync.track_component_change.await?;
// Entity deleted
sync.track_entity_deleted.await?;
// Flush changes to database
sync.flush.await?;
Full Sync
Perform a full synchronization of all entities:
let entities = vec!;
sync.full_sync.await?;
Configuration
let config = SyncConfig ;
let sync = with_config;
Note on Transactions: Transaction support is limited when using connection pooling. For production use with proper transaction isolation, consider implementing connection affinity or using a dedicated transaction connection.
SQL Types
Supported SQL types:
SqlType::BigInt- 64-bit integerSqlType::Integer- 32-bit integerSqlType::SmallInt- 16-bit integerSqlType::Real- Single precision floatSqlType::DoublePrecision- Double precision floatSqlType::Text- Variable length textSqlType::Boolean- BooleanSqlType::Timestamp- TimestampSqlType::Json- JSON/JSONB dataSqlType::Bytea- Binary data
Why DuckDB for Analytics?
DuckDB is optimized for OLAP workloads and provides several advantages:
- Columnar Storage: Efficient storage and query performance for analytics
- Window Functions: Advanced analytics with
ROW_NUMBER(),RANK(),LAG(), etc. - Parquet Integration: Export/import data in industry-standard format
- No Server Required: Embedded database, no separate process
- Fast Aggregations: Optimized for
GROUP BY,SUM(),AVG(), etc. - Join Performance: Excellent performance on complex joins
Example analytical query:
use DuckDBBackend;
use *;
let mut backend = memory.await?;
let sync = new;
// Complex analytical query with window functions
let results = sync.query.await?;
Use Cases
Analytics Dashboard
// Get player statistics
let query = new
.aggregate
.aggregate
.aggregate
.build?;
Leaderboards
// Top 10 players
let query = new
.select
.where_eq
.order_desc
.limit
.build?;
External Tools
Connect BI tools, data visualization platforms, or SQL clients directly to the SQL database for analysis without affecting your ECS world.
Performance Tips
- Batch Operations: Use appropriate
batch_sizeto balance memory and performance - Indexes: Add indexes for frequently queried columns
- Selective Sync: Only sync components needed for analytics
- Background Sync: Enable background sync for non-blocking updates
- Clear Unused Data: Periodically use
clear_all()if full re-sync is needed
Testing
# Run all tests
# Run with specific backend
# Run integration tests (requires database)
License
MIT
Contributing
Contributions are welcome! Please open an issue or PR on GitHub.
Roadmap
- DuckDB backend for OLAP workloads
- ClickHouse backend for time-series analytics
- Historical queries via tx2-pack integration
- Materialized views support
- Query result caching
- Automatic index recommendations
Related Crates
- tx2-core: Core ECS framework
- tx2-link: Serialization and messaging
- tx2-pack: Delta compression and time travel