# CHORM CLI Introspection Usage

## Generate Models from Existing Tables

From the project root (`/home/zwickvitaly/VSCodeProjects/CHORM`):

### Basic Usage

```bash
# Generate models from all tables in default database
.venv/bin/python -m chorm.cli introspect --host localhost --port 8123 --output models.py
```

### Specific Tables

```bash
# Generate models for specific tables only
.venv/bin/python -m chorm.cli introspect \
    --host localhost \
    --port 8123 \
    --tables test_users,test_orders,test_events \
    --output my_models.py
```

### Different Database

```bash
# Specify database
.venv/bin/python -m chorm.cli introspect \
    --host localhost \
    --port 8123 \
    --database mydb \
    --output models.py
```

### With Authentication

```bash
# With username and password
.venv/bin/python -m chorm.cli introspect \
    --host localhost \
    --port 8123 \
    --user myuser \
    --password mypass \
    --output models.py
```

### Using Config File

If you have `chorm.toml` in your project:

```bash
# Will use settings from chorm.toml
.venv/bin/python -m chorm.cli introspect --output models.py
```

## Example Output

The generated `models.py` will contain:

```python
"""
Generated by chorm-cli introspect
Generated at: 2025-12-04 12:16:02
"""

from chorm import Table, Column
from chorm.types import Array, DateTime, LowCardinality, Map, Nullable, String, UInt64, UInt8
from chorm.table_engines import MergeTree, ReplacingMergeTree

class TestUsers(Table):
    __tablename__ = 'test_users'
    __engine__ = MergeTree()
    __order_by__ = ['id', 'created_at']
    __partition_by__ = 'toYYYYMM(created_at)'
    
    id = Column(UInt64())
    name = Column(String())
    email = Column(String())
    age = Column(UInt8())
    country = Column(LowCardinality(String()))
    tags = Column(Array(String()))
    metadata = Column(Map(String(), String()))
    created_at = Column(DateTime())
```

## Notes

- File is created in current directory
- TODO comments added for types requiring manual configuration (e.g., Decimal precision/scale)
- **AggregateFunction types**: Fully supported! Generated as `AggregateFunction` instances
  - Example: `Column(AggregateFunction("sum", (UInt64())))`
  - These are used with `AggregatingMergeTree` engine tables
  - Full type support with proper imports
- All imports are automatically generated
- Works without `chorm.toml` if connection params provided via CLI

## AggregateFunction Support

When introspecting tables with `AggregatingMergeTree` engine that contain `AggregateFunction` columns, the CLI will:

1. **Detect AggregateFunction types** from ClickHouse schema
2. **Parse function name and arguments** (supports complex cases like `quantiles(0.5, 0.9)`)
3. **Generate proper `AggregateFunctionType` instances** with correct imports
4. **Fully supported** - no manual fixes needed!

### Example: AggregatingMergeTree Table

```python
# Generated code for table with AggregateFunction columns:
from chorm import Table, Column
from chorm.types import AggregateFunction, Date, UInt32, UInt64
from chorm.table_engines import AggregatingMergeTree

class SupplierWarehouseData(Table):
    __tablename__ = 'supplier_warehouse_data'
    __engine__ = AggregatingMergeTree()
    __order_by__ = ['id', 'date', 'warehouse']
    __partition_by__ = 'toYYYYMM(date)'

    id = Column(UInt32())
    date = Column(Date())
    warehouse = Column(UInt32())
    revenue_state = Column(AggregateFunction("sum", (UInt64())))
    uniq_wb_state = Column(AggregateFunction("uniqExact", (UInt32())))
```

### Using AggregateFunction in Code

You can use `AggregateFunction` directly in your models with functions from `func` namespace:

```python
from chorm import Table, Column
from chorm.types import AggregateFunction, UInt64, UInt32
from chorm.sql.expression import func
from chorm.table_engines import AggregatingMergeTree

class Metrics(Table):
    __tablename__ = "metrics"
    __engine__ = AggregatingMergeTree()
    __order_by__ = ["id"]
    
    id = Column(UInt32())
    # Using func namespace (preferred)
    revenue_state = Column(AggregateFunction(func.sum, (UInt64())))
    quantile_state = Column(AggregateFunction(func.quantile(0.5, "dummy"), (UInt64())))
    quantiles_state = Column(AggregateFunction(func.quantiles([0.5, 0.9], "dummy"), (UInt64())))
    
    # Or using string (for backward compatibility)
    # revenue_state = Column(AggregateFunction("sum", (UInt64())))
    # Or using string type specification:
    # revenue_state = Column("AggregateFunction(sum, UInt64)")
```

**Note**: 
- `AggregateFunction` (alias for `AggregateFunctionType`) is fully supported in CHORM
- First argument can be a function from `func` namespace (e.g., `func.sum`, `func.quantile(0.5, "dummy")`) or a string
- For functions with parameters (like `quantile`, `quantiles`), use dummy argument when creating FunctionCall
- Values are stored as binary states (bytes) and should be used with `-State` combinators for insertion and `-Merge` combinators for reading
