yamlbase 0.7.2

A lightweight SQL server that serves YAML-defined tables over standard SQL protocols
Documentation
use std::sync::Arc;
use tokio::sync::RwLock;
use tracing::info;

use crate::database::Storage;
use super::postgres_catalog::PostgresCatalog;
use super::postgres_information_schema::PostgresInformationSchema;
use super::catalog_router::CatalogRouter;

/// Shared catalog state that persists across connections
pub struct SharedCatalogState {
    pub postgres_catalog: PostgresCatalog,
    pub information_schema: PostgresInformationSchema,
    pub catalog_router: CatalogRouter,
}

impl SharedCatalogState {
    pub async fn new(storage: Arc<Storage>) -> crate::Result<Self> {
        // Initialize catalog and information schema with user tables
        let mut catalog = PostgresCatalog::new(storage.clone());
        let mut information_schema = PostgresInformationSchema::new(storage.clone());

        // Add user tables to catalog and information schema
        let db_arc = storage.database();
        let db = db_arc.read().await;

        let mut table_oid = 16384; // Start user table OIDs at 16384 (above system range)
        for (table_name, table) in &db.tables {
            info!("Adding table '{}' with OID {} to shared catalog", table_name, table_oid);
            catalog.add_user_table(table_name, table_oid, &table.columns);
            information_schema.add_user_table(table_name, &table.columns);
            table_oid += 1;
        }
        
        // Debug: check what constraints we have after initialization
        info!("Shared catalog initialization complete");
        let constraints_result = catalog.query_pg_constraint();
        info!("Total constraints in shared catalog: {} rows", constraints_result.rows.len());
        for row in &constraints_result.rows {
            if let (Some(crate::database::Value::Text(name)), Some(crate::database::Value::Text(contype))) = 
                (row.get(1), row.get(2)) {
                info!("  - Constraint: {} (type={})", name, contype);
            }
        }

        drop(db);

        // Create catalog router with the populated catalog and information_schema
        let catalog_router = CatalogRouter::new(catalog.clone(), information_schema.clone());

        Ok(Self {
            postgres_catalog: catalog,
            information_schema,
            catalog_router,
        })
    }
}

pub type SharedCatalog = Arc<RwLock<SharedCatalogState>>;

/// Create a new shared catalog instance
pub async fn create_shared_catalog(storage: Arc<Storage>) -> crate::Result<SharedCatalog> {
    let state = SharedCatalogState::new(storage).await?;
    Ok(Arc::new(RwLock::new(state)))
}