Metadata-Version: 2.4
Name: dbbridgekit
Version: 0.1.0
Summary: Plataforma genérica de conversão/análise/migração entre bancos de dados via Intermediate Representation (IR) canônica — SQLite, PostgreSQL, MySQL (em progresso), SQL Server (planejado).
Author-email: Otavio R Santana <tvostrodrigues8@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/tvost2/dbbridge
Project-URL: Repository, https://github.com/tvost2/dbbridge
Project-URL: Issues, https://github.com/tvost2/dbbridge/issues
Project-URL: Documentation, https://github.com/tvost2/dbbridge/blob/main/docs/guide.md
Project-URL: Changelog, https://github.com/tvost2/dbbridge/blob/main/CHANGELOG.md
Keywords: sql,sqlite,postgresql,mysql,migration,ir,database
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: psycopg[binary]>=3.1
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# DBBridge

Plataforma genérica de conversão, análise e migração entre bancos de dados, baseada numa
**Intermediate Representation (IR)** canônica — não um conversor pareado por combinação de bancos.

```txt
Banco origem → Parser do dialeto origem → IR canônica → Renderer do dialeto destino → Banco destino
```

Evolução do [PostgresModel](../postgresmodel) generalizada: em vez de assumir SQLite→PostgreSQL
sempre, qualquer par de dialetos suportados passa pelo mesmo pipeline.

## Status (Fase 1)

| Dialeto | Parser | Renderer |
|---|---|---|
| SQLite | ✅ | ✅ |
| PostgreSQL | ✅ | ✅ |
| MySQL | estrutura registrada (Fase 2) | estrutura registrada (Fase 2) |
| SQL Server | estrutura registrada (Fase 5) | estrutura registrada (Fase 5) |

`dbbridge.dialects.mysql`/`sqlserver` já registram um dialeto "conhecido, ainda não implementado" —
`dbbridge dialects` lista os dois, e chamar `.parse()`/`.render_schema()` neles levanta
`NotImplementedError` com a fase planejada, em vez de um erro genérico de dialeto desconhecido.

167 testes, 99% de cobertura (`pytest --cov=dbbridge`). Os poucos pontos não cobertos são código
genuinamente inalcançável (stubs de método abstrato, guard `if __name__ == "__main__"`) — ver
[docs/guide.md](docs/guide.md#cobertura-de-testes).

## Instalação

```bash
pip install -e .
# ou, pra rodar contra PostgreSQL de verdade:
pip install -e ".[dev]"
```

## Uso rápido

### Traduzir um schema

```bash
dbbridge translate --from sqlite --to postgres schema.sql
```

Casos que o parser/renderer não reconhecem com segurança viram `REVIEW_REQUIRED` no stderr — nunca
uma tradução inventada.

### Escanear um projeto Python

```bash
dbbridge scan --from sqlite --to postgres ./meu_projeto
```

Encontra `execute()`/`executemany()` com SQL potencialmente incompatível entre os dois dialetos:
placeholders (`?` vs `%s`), `sqlite_master`, `PRAGMA`, `INSERT OR IGNORE`/`OR REPLACE`,
case-sensitivity de `LIKE`, autoincrement, e mais.

### Migrar código-fonte automaticamente

```bash
dbbridge patch --from sqlite --to postgres ./meu_projeto   # dry-run, mostra o plano
dbbridge apply --from sqlite --to postgres ./meu_projeto   # aplica com backup automático
dbbridge rollback ./meu_projeto                            # desfaz, restaura do backup
```

Reescreve só literais de string simples sem ambiguidade (troca de placeholder). `f-strings`,
concatenação e casos ambíguos (aspas duplas, `INSERT OR REPLACE`, etc.) nunca são alterados
automaticamente — viram `REVIEW_REQUIRED`/`SKIPPED_COMPLEX_EXPRESSION` no plano.

### Migrar dados entre bancos de verdade

```bash
dbbridge migrate-data --from sqlite --to postgres \
    --source-dsn ./app.db --target-dsn "host=localhost dbname=app" --tables users leads
dbbridge validate --from sqlite --to postgres \
    --source-dsn ./app.db --target-dsn "host=localhost dbname=app" --tables users leads
```

Copia em lotes, nunca faz `DROP`/`TRUNCATE`, sempre acrescenta. `validate` compara contagens e
checksum (SHA-256) linha a linha quando a tabela é pequena o bastante.

### Compatibility Mode (código antigo continua rodando)

```python
from dbbridge import connect

db = connect(source_dialect="sqlite", target_dialect="postgres", dsn="host=localhost dbname=app")
db.execute("SELECT * FROM users WHERE id=?", (1,))  # vira %s por baixo, roda no Postgres de verdade
```

Permite migrar a aplicação por partes: o código continua escrito na sintaxe de origem enquanto o
banco de verdade já é o destino.

## Exemplos executáveis

```bash
python examples/translate_schema.py         # traduz um schema via API Python
python examples/scan_and_patch_project.py    # scan -> patch -> apply -> rollback num mini-app
python examples/compat_mode.py                # Compatibility Mode de ponta a ponta
DBBRIDGE_EXAMPLE_PG_DSN="host=localhost dbname=..." python examples/full_data_migration.py
```

Todos os quatro rodam de verdade (não são pseudocódigo) — os três primeiros só precisam do SQLite
da stdlib; o último precisa de um PostgreSQL acessível via a variável de ambiente indicada.

## Arquitetura

```txt
dbbridge/
  cli.py                   # scan|report|translate|patch|apply|migrate-data|validate|rollback|doctor|dialects
  core/
    ir.py                  # Schema, Table, Column, ForeignKey, UniqueConstraint, CheckConstraint, Index, View, Trigger, Enum
    types.py                # CanonicalType, Ambiguity
    parser.py / renderer.py # contratos + registry (register_parser/get_parser/available_parsers, idem renderer)
    planner.py              # translate(sql, source, target) — o pipeline completo numa função
  dialects/
    sqlite.py, postgres.py  # implementados
    mysql.py, sqlserver.py  # stubs registrados (NotImplementedError com a fase planejada)
  scanner/scanner.py        # AST — encontra SQL arriscado por par de dialetos
  codemod/codemod.py         # AST — reescreve só literais simples sem ambiguidade
  migration/
    schema_migration.py     # traduz + aplica DDL (aditivo, nunca DROP/TRUNCATE)
    data_migration.py        # copia dados em lotes
    validator.py              # contagens + checksum
    rollback.py                # restaura código a partir de backup
  compat/runtime.py          # connect() — Compatibility Mode
  reports/report.py           # normaliza qualquer resultado pra texto/JSON
```

Por que IR em vez de conversores pareados: com N dialetos, um conversor direto por par cresce O(N²)
e duplica a mesma lógica de tipos/constraints em cada combinação. Com um modelo canônico no meio,
cada dialeto novo precisa de só 1 parser + 1 renderer (O(N)) pra já converter de/para todos os
outros já implementados.

## Segurança

- Toda alteração de código gera backup antes de escrever, e pode ser revertida via `dbbridge rollback`.
- Migração de schema/dados é sempre aditiva — nunca `DROP`/`TRUNCATE`/`DELETE`.
- Casos ambíguos (aspas duplas em literal, `INSERT OR REPLACE`, f-strings, expressões dinâmicas)
  nunca são "adivinhados" — viram `REVIEW_REQUIRED` pra revisão manual.
- `apply_changes` verifica `ast.parse()` do arquivo resultante antes de considerar sucesso; se o
  resultado tiver `SyntaxError`, reverte sozinho a partir do backup.

## Fases

1. **IR + SQLite ↔ PostgreSQL** — atual, completo: parser/renderer dos dois dialetos, scanner,
   codemod, migração de schema/dados, validação por checksum, rollback, CLI, Compatibility Mode.
2. MySQL (parser + renderer reais).
3. Codemod genérico validado contra os 3 dialetos.
4. Data migration validada nos 4 pares centrais (SQLite/Postgres/MySQL cruzados).
5. SQL Server.
6. **Fases futuras (levantadas, ainda não priorizadas):** shadow migration (rodar origem e destino
   em paralelo comparando resultados antes do cutover final), query replay (reproduzir tráfego real
   de produção contra o destino como teste de carga/compatibilidade), dashboard web, relatórios em
   HTML/PDF (hoje só texto/JSON via `reports/report.py`), mecanismo de plugin formal pra dialetos
   externos (hoje a extensão já é possível via `register_parser`/`register_renderer` — falta só
   empacotar como plugin instalável separadamente, ex. entry points do Python), e suporte a bancos
   não-relacionais como MongoDB (exigiria uma IR paralela pra documentos/coleções — ver
   [docs/compatibility-matrix.md](docs/compatibility-matrix.md#roadmap-além-do-sql-relacional)).

Cada fase só avança depois da anterior validada — ver [docs/guide.md](docs/guide.md) para detalhes
de arquitetura e extensão pra novos dialetos, [docs/cli-reference.md](docs/cli-reference.md) pra
todos os comandos, [docs/compatibility-matrix.md](docs/compatibility-matrix.md) pro que já
funciona vs. planejado, [docs/migration-tutorial.md](docs/migration-tutorial.md) pro passo a passo
completo, e [docs/production-checklist.md](docs/production-checklist.md) antes de rodar contra
dados reais.
