Files
Baradb/clients/nim-allographer/PLAN_BARADB.md
T
dimgigov 6bfc5b3a3c
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
feat(clients): add nim-allographer client with BaraDB driver support
- Pure Nim wire protocol client (async + sync, no C FFI)
- Query Builder: fluent API, SQL generator, execution, transactions
- Schema Builder: create/alter/drop tables, column operations
- Connection pool with aging and timeout handling
- ORM integration via compile-time DB_BARADB switch
- Tests: test_open, test_query
- Documentation: README.md, PLAN_BARADB.md
2026-05-21 15:49:11 +03:00

17 KiB
Raw Blame History

План за интеграция на BaraDB в nim-allographer

Цел

BaraDB е пълноценен драйвер в nim-allographer. Използва се чист Nim клиент (BaraClient / SyncClient) без C зависимости. Compile-time switch: DB_BARADB.


Актуално състояние (2026-05-21)

Статус по фази

Фаза Състояние Бележки
1. Инфраструктура и типове ГОТОВО env.nim, connection.nim, query_builder.nim, schema_builder.nim — всичко е интегрирано
2. Query Builder — SQL генерация ГОТОВО baradb_generator.nim (397 реда), baradb_builder.nim (237 реда) — всички CRUD + агрегати
3. Query Builder — execution ГОТОВО (с бележки) baradb_exec.nim (716 реда) — всички операции работят, но insertId използва SELECT MAX вместо RETURNING
4. Schema Builder СКЕЛЕТ Flow-ът е налице, но column type mapping е 24 реда вместо 466 (PostgreSQL)
5. Тестове и документация МИНИМАЛНО Само test_open.nim и test_query.nim

Какво е ГОТОВО (не пипай)

Wire Protocol клиент — query_builder/libs/baradb/baradb_client.nim (706 реда)

  • Pure Nim, async + sync, без C FFI
  • Binary serialization (big-endian) на всички WireValue типове (13 типа: fkNull..fkJson)
  • mkQuery, mkQueryParams, mkAuth, mkPing съобщения
  • readQueryResponse — парсва mkData, mkComplete, mkError, mkReady
  • Вграден QueryBuilder (fluent) за standalone употреба

Connection Pool — baradb_open.nim + baradb_exec.nim

  • dbOpen(Baradb, database, user, pass, host, port, maxConnections, timeout)
  • getFreeConn() — async с deque-based waiters и timeout
  • returnConn() — освобождава и буди чакащи
  • Connection aging: maxConnectionLifetime, maxConnectionIdleTime
  • refreshConn(), hasConnExpired(), openBaradbConn()

Query Builder — baradb_query.nim (386 реда)

  • Всички fluent методи: select, table, distinct, join, leftJoin
  • where / orWhere (string|int|float, bool, nil overloads)
  • whereBetween, whereNotBetween, whereIn, whereNotIn, whereNull
  • groupBy, having, orderBy, limit, offset
  • raw(sql, args) — суров SQL с параметри

SQL Generator — baradb_generator.nim (397 реда)

  • Всички SQL конструкции: SELECT, INSERT, UPDATE, DELETE, агрегати
  • Quoting с backtick ` (MySQL/SQLite стил, не PostgreSQL ")
  • Placeholder: ? (не $1)

Execution — baradb_exec.nim (716 реда)

  • get(), first(), find()seq[JsonNode] / Option[JsonNode]
  • getPlain(), firstPlain(), findPlain()seq[seq[string]]
  • insert(JsonNode), insert(seq[JsonNode]), insertId(...)
  • update(JsonNode), delete(), delete(id)
  • count(), min(), max(), avg(), sum()
  • begin(), commit(), rollback() + transaction макро
  • Raw query варианти за всички операции
  • seeder шаблони

ORM — споделен модул

  • orm() template работи с BaraDB

Schema Code Generation — usecases/baradb/create_schema.nim

  • Четене от information_schema и генериране на Nim типове

Какво трябва да се ДОИЗПИПА

1. Prepared Statements — САМО типове, НЯМА имплементация

Текущо състояние: Типовете са дефинирани в baradb_types.nim:

  • BaradbPreparedEntrysql, nArgs, refCount, lastUsedAt
  • BaradbPreparedContextowner, connI
  • BaradbPreparedStatementowner, entry, sql, nArgs, isClosed
  • preparedCache е инициализиран в baradb_open.nim

Липсващо:

  • prepare() proc — да създава BaradbPreparedStatement
  • ensureStmt() — да кешира и преизползва statement-и
  • get*() / exec*() procs върху BaradbPreparedStatement
  • withConn() proc за context-based изпълнение
  • flushStmt() / clearStmtCache()

Wire protocol поддръжка: baradb_client.nim вече има mkQueryParams — параметризираните заявки са вградени на ниво протокол. Трябва само да се свърже от allographer слоя.

Проблем: В момента baradb_exec.nim използва client-side string interpolation (formatSql + escapeSqlValue) вместо server-side параметри. Това е по-малко сигурно и по-малко ефективно.

Референция: PostgreSQL драйверът има ~300 реда prepared statement код (postgres_exec.nimensureStmt, preparedQuery, preparedExec, deallocate, flush, clearCache, context API).

План:

Файл: baradb_exec.nim
- [ ] prepare(sql: string): BaradbPreparedStatement
- [ ] ensureStmt(conn, sql, nArgs): BaradbPreparedEntry — кеширане в preparedCache
- [ ] preparedGet(stmt, args): seq[JsonNode] — използва mkQueryParams
- [ ] preparedExec(stmt, args): void
- [ ] withConn(pool, callback): auto — context-based
- [ ] flushStmt(stmt): void — deallocate
- [ ] clearStmtCache(): void

2. RETURNING id за INSERT — използва SELECT MAX (race condition)

Текущо състояние в baradb_exec.nim:

discard await self.pools.conns[connI].client.exec(sql)
let idSql = &"SELECT MAX(\"{key}\") FROM \"{table}\""
let qr = await self.pools.conns[connI].client.query(idSql)

Проблем: Race condition при конкурентни INSERT-и — друг INSERT може да мине между двете заявки.

Варианти:

  1. INSERT ... RETURNING id — ако BaraDB го поддържа (за предпочитане, атомарно)
  2. last_insert_rowid() — ако BaraDB има такава функция (както SQLite)
  3. SELECT LAST_INSERT_ID() — MySQL-стил
  4. CTE с INSERT ... RETURNINGWITH inserted AS (INSERT ...) SELECT id FROM inserted

План:

Файл: baradb_exec.nim — insertId proc
- [ ] Проверка дали BaraDB поддържа RETURNING
- [ ] Ако да: INSERT ... RETURNING "id" (като PostgreSQL)
- [ ] Ако не: използване на заявката за последно вмъкнат ID от wire protocol-а
- [ ] Премахване на SELECT MAX workaround

3. Schema Builder — Column Type Mapping е СКЕЛЕТ

Текущо състояние в queries/baradb/sub/create_column_query.nim (24 реда):

query.add(&"`{column.name}` {column.typ}")
# Само: NOT NULL, UNIQUE, DEFAULT

Проблем: Изкарва raw RdbTypeKind enum стойности (rdbIncrements, rdbString) вместо SQL типове (SERIAL, VARCHAR(256)).

Референция: PostgreSQL sub/create_column_query.nim466 реда, обработва всички RdbTypeKind:

  • rdbIncrementsSERIAL PRIMARY KEY
  • rdbBigIncrementsBIGSERIAL PRIMARY KEY
  • rdbIntegerINTEGER
  • rdbBigIntegerBIGINT
  • rdbBooleanBOOLEAN
  • rdbString(n)VARCHAR(n) (default 255)
  • rdbTextTEXT
  • rdbFloatDOUBLE PRECISION
  • rdbDecimal(p,s)DECIMAL(p,s)
  • rdbDateDATE
  • rdbDateTime / rdbTimestampTIMESTAMP
  • rdbTimestampzTIMESTAMPTZ
  • rdbTimeTIME
  • rdbBinaryBYTEA
  • rdbUuidUUID
  • rdbJson / rdbJsonbJSON / JSONB
  • rdbEnumVARCHAR(255) + CHECK constraint
  • Foreign keys: REFERENCES "table"("column") ON DELETE/UPDATE CASCADE/SET NULL/...
  • Indexes, comments, unsigned

План:

Файл: queries/baradb/sub/create_column_query.nim
- [ ] Пълен mapping на RdbTypeKind → SQL тип (по PostgreSQL референцията)
- [ ] Auto-increment: SERIAL / BIGSERIAL PRIMARY KEY
- [ ] String/Text: VARCHAR(n), TEXT с default 255
- [ ] Числови: INTEGER, BIGINT, SMALLINT, DOUBLE PRECISION, DECIMAL(p,s)
- [ ] Дати: DATE, TIME, TIMESTAMP, TIMESTAMPTZ
- [ ] Бинарни: BYTEA
- [ ] Специални: UUID, JSON, JSONB, BOOLEAN, ENUM
- [ ] Foreign key constraints: REFERENCES ... ON DELETE/UPDATE
- [ ] Index генерация
- [ ] Column comments

Файл: queries/baradb/create_table.nim
- [ ] Да използва create_column_query вместо raw {column.typ}

Файлове: rename_column.nim, rename_table.nim
- [ ] Fix: `changeTo` → `previousName` (ако е bug)

Файл: create_migration_table.nim
- [ ] Консистентност: backtick quoting вместо double-quote

Файл: schema_utils.nim
- [ ] shouldRun() — checksum-based skip (вместо винаги true)

4. SQL Quoting Inconsistency

Проблем: baradb_generator.nim използва backtick `, но create_migration_table.nim използва double-quote ". Трябва да е консистентно.

Въпрос: Какво използва BaraDB сървърът? Ако поддържа и двете — изберем едно. Ако само едно — коригираме навсякъде.


5. Database URL Support — липсва

PostgreSQL/MySQL/MariaDB драйверите поддържат databaseUrl = asDatabaseUrl("postgresql://..."). BaraDB dbOpen приема само позиционни параметри.

Файл: baradb_open.nim
- [ ] Парсване на `baradb://user:pass@host:port/db` URL
- [ ] Интеграция с `libs/database_url.nim`

6. Paginate / fastPaginate — липсват

Налични в други драйвери, липсват в BaraDB query builder.

Файл: baradb_exec.nim
- [ ] paginate(page, perPage): seq[JsonNode] + metadata
- [ ] fastPaginate(key, perPage): cursor-based

7. whereNull Bug

Проблем: baradb_generator.nim:205whereNullSql референцира row["symbol"], но baradb_query.nim whereNull не задава "symbol" ключ. Ще даде runtime crash.

Файл: baradb_query.nim — whereNull proc
- [ ] Добавяне на "symbol": "IS" или "IS NOT" в JSON а

Тестове — какво липсва

Тестов файл Съществува за Липсва за BaraDB
test_open.nim postgres, sqlite, mysql, mariadb, surreal, baradb
test_query.nim postgres, sqlite, mysql, mariadb, surreal, baradb
test_prepared_statement.nim postgres, sqlite, mysql, mariadb, surreal baradb
test_schema.nim postgres, sqlite, mysql, mariadb, surreal baradb
test_create_schema.nim postgres, sqlite, mysql, mariadb, surreal baradb
test_pool_wait.nim postgres baradb
test_transaction.nim postgres, sqlite, mysql, mariadb, surreal baradb

Приоритети

# Подобрение Сложност Ефект Приоритет
1 Schema Builder column mapping Средна Без него migrations не работят ВИСОК
2 INSERT RETURNING id Ниска Премахва race condition ВИСОК
3 Prepared Statements Висока Security + performance СРЕДЕН
4 Database URL support Ниска UX удобство НИСЪК
5 Paginate / fastPaginate Ниска Feature parity НИСЪК
6 whereNull fix Ниска Bug fix ВИСОК
7 SQL quoting консистентност Ниска Потенциален runtime error СРЕДЕН
8 Schema utils checksum Ниска Migration skip optimization НИСЪК

Архитектура — файлова карта

src/allographer/
├── env.nim                          # DB_BARADB compile switch ✅
├── connection.nim                   # Import/export Baradb типове ✅
├── query_builder.nim                # Import/export baradb модули ✅
├── schema_builder.nim               # Import/export baradb schema ✅
│
├── query_builder/
│   ├── libs/baradb/
│   │   └── baradb_client.nim        # Wire protocol (706 реда) ✅
│   │
│   └── models/baradb/
│       ├── baradb_types.nim         # Типове (90 реда) ✅
│       ├── baradb_open.nim          # dbOpen + pool (52 реда) ✅
│       ├── baradb_query.nim         # Fluent API (386 реда) ✅
│       ├── baradb_exec.nim          # Execution (716 реда) ✅⚠️
│       ├── baradb_transaction.nim   # Transaction макро (42 реда) ✅
│       └── query/
│           ├── baradb_builder.nim   # SQL builder (237 реда) ✅
│           └── baradb_generator.nim # SQL generator (397 реда) ✅
│
├── schema_builder/
│   ├── queries/baradb/
│   │   ├── baradb_query_type.nim    # Типове (14 реда) ✅
│   │   ├── create_table.nim         # CREATE TABLE (16 реда) ⚠️ skeletal
│   │   ├── add_column.nim           # ADD COLUMN (8 реда) ⚠️ minimal
│   │   ├── change_column.nim        # ALTER COLUMN (8 реда) ⚠️ minimal
│   │   ├── drop_column.nim          # DROP COLUMN (8 реда) ✅
│   │   ├── drop_table.nim           # DROP TABLE (7 реда) ✅
│   │   ├── rename_column.nim        # RENAME COLUMN (8 реда) ⚠️ possible bug
│   │   ├── rename_table.nim         # RENAME TABLE (7 реда) ⚠️ possible bug
│   │   ├── reset_table.nim          # DELETE FROM (7 реда) ✅
│   │   ├── create_migration_table.nim (12 реда) ⚠️ quoting inconsistency
│   │   ├── schema_utils.nim         # shouldRun (12 реда) ⚠️ always true
│   │   └── sub/
│   │       ├── create_column_query.nim  # (24 реда) ❌ skeletal
│   │       ├── add_column_query.nim     # (8 реда) ⚠️ minimal
│   │       └── change_column_query.nim  # (6 реда) ⚠️ minimal
│   │
│   └── usecases/baradb/
│       ├── create.nim               # Table creation flow (24 реда) ✅
│       ├── alter.nim                # Alter flow (45 реда) ✅
│       ├── drop.nim                 # Drop flow (18 реда) ✅
│       ├── create_schema.nim        # Code gen from DB (60 реда) ✅
│       └── create_query_def.nim     # Factory (10 реда) ✅

tests/baradb/
├── config.nims                      # DB_BARADB=true ✅
├── connections.nim                  # Connection setup ✅
├── test_open.nim                    # Basic connection test ✅
├── test_query.nim                   # Integration tests ✅
├── test_prepared_statement.nim      # ❌ липсва
├── test_schema.nim                  # ❌ липсва
├── test_create_schema.nim           # ❌ липсва
├── test_pool_wait.nim               # ❌ липсва
└── test_transaction.nim             # ❌ липсва

Легенда: готово | ⚠️ partial/needs work | липсва | ⚠️ работи но с workaround


Краткосрочен план (следващи стъпки)

Седмица 1: Schema Builder + Bug fixes

  1. sub/create_column_query.nim — пълен RdbTypeKind → SQL mapping (по PostgreSQL референция)
  2. create_table.nim — да използва column query вместо raw тип
  3. Fix whereNull bug в baradb_query.nim
  4. Fix quoting inconsistency в create_migration_table.nim
  5. Fix rename_column.nim / rename_table.nim ако changeTo не съществува

Седмица 2: INSERT RETURNING + Prepared Statements (част 1)

  1. insertId — проучване дали BaraDB поддържа RETURNING, имплементация
  2. prepare() / ensureStmt() — prepared statement кеш
  3. preparedGet() / preparedExec() — изпълнение през mkQueryParams

Седмица 3: Тестове + Prepared Statements (част 2)

  1. test_schema.nim — schema builder тестове
  2. test_prepared_statement.nim — prepared statement тестове
  3. test_transaction.nim — transaction тестове
  4. test_pool_wait.nim — pool timeout тестове

Седмица 4: Polish

  1. Database URL support
  2. Paginate / fastPaginate
  3. Schema utils checksum
  4. Документация в documents/