Crate tx2_query

Crate tx2_query 

Source
Expand description

tx2-query - SQL Analytics Layer for TX-2 ECS

tx2-query provides a SQL side-car database for TX-2 applications, enabling advanced analytics, complex queries, and external tool integration while keeping the ECS world as the source of truth.

§Architecture

  • 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, DuckDB, and more

§Features

  • Schema Generation: Automatic DDL creation from component definitions
  • Query Builder: Ergonomic SQL query construction
  • Sync API: Incremental synchronization with batching and transactions
  • Read-Only Projection: Analytics layer, not an ORM
  • Backend Abstraction: Support for multiple SQL databases

§Example

use tx2_query::*;
use tx2_query::schema::{SchemaGenerator, SqlType};
use tx2_query::builder::SelectBuilder;

#[derive(Debug)]
struct Player;

#[tokio::main]
async fn main() -> Result<()> {
    // Create schema generator
    let mut schema_gen = SchemaGenerator::new();
    schema_gen.register::<Player>(
        "Player",
        vec![
            ("name", SqlType::Text, false),
            ("email", SqlType::Text, false),
            ("score", SqlType::Integer, false),
        ],
    )?;

    // Connect to database (requires postgres feature)
    #[cfg(feature = "postgres")]
    {
        use tx2_query::postgres::PostgresBackend;
        let backend = PostgresBackend::connect("postgresql://localhost/mydb").await?;
        let sync = tx2_query::sync::QuerySync::new(backend, schema_gen);

        // Initialize schema
        sync.initialize_schema().await?;

        // Build and execute queries
        let query = SelectBuilder::new("Player")
            .select(vec!["name", "score"])
            .where_gt("score", serde_json::json!(1000))
            .order_desc("score")
            .limit(10)
            .build()?;

        let results = sync.query(&query).await?;
        println!("Top players: {:?}", results);
    }

    Ok(())
}

§Backend Support

Enable backends via Cargo features:

[dependencies]
tx2-query = { version = "0.1", features = ["postgres", "sqlite", "duckdb"] }

§Philosophy

tx2-query is designed as an analytics layer, NOT an ORM:

  • 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

Re-exports§

pub use backend::DatabaseBackend;
pub use backend::QueryResult;
pub use backend::QueryRow;
pub use backend::Transaction;
pub use builder::AggregateFunc;
pub use builder::ComparisonOp;
pub use builder::Condition;
pub use builder::DeleteBuilder;
pub use builder::JoinType;
pub use builder::LogicalOp;
pub use builder::SelectBuilder;
pub use builder::SortDirection;
pub use builder::UpdateBuilder;
pub use error::QueryError;
pub use error::Result;
pub use schema::ColumnDef;
pub use schema::IndexDef;
pub use schema::SchemaGenerator;
pub use schema::SqlType;
pub use schema::TableSchema;
pub use sync::ComponentChange;
pub use sync::EntityChange;
pub use sync::QuerySync;
pub use sync::SyncBatch;
pub use sync::SyncConfig;
pub use postgres::PostgresBackend;
pub use sqlite::SqliteBackend;
pub use duckdb::DuckDBBackend;

Modules§

backend
builder
duckdb
error
postgres
prelude
Prelude for common imports
schema
sqlite
sync