Implementa todas las funcionalidades restantes de la paridad con go-sqlite3: Callbacks y Hooks: - Authorizer callback para control de operaciones SQL - Pre-update hook con acceso a valores antes/despues del cambio - Progress handler para interrumpir queries largos - Busy handler personalizado (custom callback) APIs adicionales: - Limits API (getLimit/setLimit) para control de limites SQLite - Column metadata extendida (columnDatabaseName, columnTableName, columnOriginName) - Expanded SQL (stmt.expandedSql) - Timestamp binding (bindTimestamp, bindCurrentTime) con formato ISO8601 Build: - Habilitado SQLITE_ENABLE_PREUPDATE_HOOK en build.zig - Definido @cDefine en @cImport para exponer APIs opcionales Tests: - Tests para authorizer, progress handler, limits, expanded SQL - Tests para column metadata y pre-update hook - Tests para timestamp binding Documentacion actualizada con todos los nuevos APIs y ejemplos. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
338 lines
10 KiB
Markdown
338 lines
10 KiB
Markdown
# Analisis de Paridad con CGo go-sqlite3
|
|
|
|
> **Fecha**: 2025-12-08
|
|
> **Objetivo**: Identificar todas las funcionalidades de go-sqlite3 para replicarlas en zsqlite
|
|
|
|
## Resumen
|
|
|
|
go-sqlite3 (https://github.com/mattn/go-sqlite3) es el wrapper SQLite mas maduro para Go.
|
|
Este documento analiza todas sus funcionalidades para asegurar paridad en zsqlite.
|
|
|
|
---
|
|
|
|
## Estado de Implementacion
|
|
|
|
### Leyenda
|
|
- ✅ Implementado en zsqlite
|
|
- ⏳ Pendiente de implementar
|
|
- 🔄 Parcialmente implementado
|
|
- ❌ No aplicable a Zig
|
|
|
|
---
|
|
|
|
## 1. Conexion a Base de Datos
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Notas |
|
|
|---------------|------------|---------|-------|
|
|
| Open basico | ✅ | ✅ | `sqlite.open()` |
|
|
| Open con flags | ✅ | ✅ | `Database.openWithFlags()` |
|
|
| Close | ✅ | ✅ | `db.close()` |
|
|
| URI connection string | ✅ | ⏳ | Parsear `file:path?mode=ro&cache=shared` |
|
|
| DSN parameters | ✅ | ⏳ | Configuracion via string |
|
|
| Connection pooling | ✅ (via database/sql) | ⏳ | Pool propio |
|
|
|
|
---
|
|
|
|
## 2. Configuracion de Pragmas
|
|
|
|
| Pragma | go-sqlite3 | zsqlite | Prioridad |
|
|
|--------|------------|---------|-----------|
|
|
| auto_vacuum | ✅ | ⏳ | Media |
|
|
| busy_timeout | ✅ | ✅ | `db.setBusyTimeout()` |
|
|
| cache_size | ✅ | ⏳ | Media |
|
|
| case_sensitive_like | ✅ | ⏳ | Baja |
|
|
| defer_foreign_keys | ✅ | ⏳ | Media |
|
|
| foreign_keys | ✅ | ✅ | `db.setForeignKeys()` |
|
|
| journal_mode | ✅ | ✅ | `db.setJournalMode()` |
|
|
| locking_mode | ✅ | ⏳ | Media |
|
|
| query_only | ✅ | ⏳ | Baja |
|
|
| recursive_triggers | ✅ | ⏳ | Baja |
|
|
| secure_delete | ✅ | ⏳ | Baja |
|
|
| synchronous | ✅ | ✅ | `db.setSynchronous()` |
|
|
|
|
---
|
|
|
|
## 3. Prepared Statements
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Notas |
|
|
|---------------|------------|---------|-------|
|
|
| Prepare | ✅ | ✅ | `db.prepare()` |
|
|
| Exec (sin resultados) | ✅ | ✅ | `db.exec()` |
|
|
| Query (con resultados) | ✅ | ✅ | `stmt.step()` loop |
|
|
| Bind posicional (?) | ✅ | ✅ | `stmt.bindInt(1, val)` |
|
|
| Bind named (:name) | ✅ | ✅ | `stmt.bindIntNamed(":name", val)` |
|
|
| Bind named (@name) | ✅ | ✅ | `stmt.bindIntNamed("@name", val)` |
|
|
| Bind named ($name) | ✅ | ✅ | `stmt.bindIntNamed("$name", val)` |
|
|
| Readonly check | ✅ | ✅ | `stmt.isReadOnly()` |
|
|
| SQL text | ✅ | ✅ | `stmt.sql()` |
|
|
| Expanded SQL | ✅ | ✅ | `stmt.expandedSql()` |
|
|
|
|
---
|
|
|
|
## 4. Bind de Parametros
|
|
|
|
| Tipo | go-sqlite3 | zsqlite | Notas |
|
|
|------|------------|---------|-------|
|
|
| NULL | ✅ | ✅ | `stmt.bindNull()` |
|
|
| int64 | ✅ | ✅ | `stmt.bindInt()` |
|
|
| float64 | ✅ | ✅ | `stmt.bindFloat()` |
|
|
| string/text | ✅ | ✅ | `stmt.bindText()` |
|
|
| []byte/blob | ✅ | ✅ | `stmt.bindBlob()` |
|
|
| bool | ✅ | ✅ | `stmt.bindBool()` |
|
|
| time.Time | ✅ | ✅ | `stmt.bindTimestamp()` ISO8601 |
|
|
| Zeroblob | ✅ | ✅ | `stmt.bindZeroblob()` |
|
|
|
|
---
|
|
|
|
## 5. Lectura de Columnas
|
|
|
|
| Tipo | go-sqlite3 | zsqlite | Notas |
|
|
|------|------------|---------|-------|
|
|
| Column count | ✅ | ✅ | `stmt.columnCount()` |
|
|
| Column name | ✅ | ✅ | `stmt.columnName()` |
|
|
| Column type | ✅ | ✅ | `stmt.columnType()` |
|
|
| int64 | ✅ | ✅ | `stmt.columnInt()` |
|
|
| float64 | ✅ | ✅ | `stmt.columnFloat()` |
|
|
| text | ✅ | ✅ | `stmt.columnText()` |
|
|
| blob | ✅ | ✅ | `stmt.columnBlob()` |
|
|
| NULL check | ✅ | ✅ | `stmt.columnIsNull()` |
|
|
| Column bytes | ✅ | ✅ | `stmt.columnBytes()` |
|
|
| Declared type | ✅ | ✅ | `stmt.columnDeclType()` |
|
|
| Database name | ✅ | ✅ | `stmt.columnDatabaseName()` |
|
|
| Table name | ✅ | ✅ | `stmt.columnTableName()` |
|
|
| Origin name | ✅ | ✅ | `stmt.columnOriginName()` |
|
|
|
|
---
|
|
|
|
## 6. Transacciones
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Notas |
|
|
|---------------|------------|---------|-------|
|
|
| BEGIN | ✅ | ✅ | `db.begin()` |
|
|
| BEGIN IMMEDIATE | ✅ | ✅ | `db.beginImmediate()` |
|
|
| BEGIN EXCLUSIVE | ✅ | ✅ | `db.beginExclusive()` |
|
|
| BEGIN DEFERRED | ✅ | ✅ | `db.begin()` (default) |
|
|
| COMMIT | ✅ | ✅ | `db.commit()` |
|
|
| ROLLBACK | ✅ | ✅ | `db.rollback()` |
|
|
| SAVEPOINT | ✅ | ✅ | `db.savepoint(alloc, "name")` |
|
|
| RELEASE | ✅ | ✅ | `db.release(alloc, "name")` |
|
|
| ROLLBACK TO | ✅ | ✅ | `db.rollbackTo(alloc, "name")` |
|
|
|
|
---
|
|
|
|
## 7. Metadatos y Utilidades
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Notas |
|
|
|---------------|------------|---------|-------|
|
|
| LastInsertRowId | ✅ | ✅ | `db.lastInsertRowId()` |
|
|
| Changes | ✅ | ✅ | `db.changes()` |
|
|
| TotalChanges | ✅ | ✅ | `db.totalChanges()` |
|
|
| Error message | ✅ | ✅ | `db.errorMessage()` |
|
|
| Error code | ✅ | ✅ | `db.errorCode()` |
|
|
| Extended error code | ✅ | ✅ | `db.extendedErrorCode()` |
|
|
| SQLite version | ✅ | ✅ | `sqlite.version()` |
|
|
| Version number | ✅ | ✅ | `sqlite.versionNumber()` |
|
|
| Database filename | ✅ | ✅ | `db.filename()` |
|
|
| Is readonly | ✅ | ✅ | `db.isReadOnly()` |
|
|
|
|
---
|
|
|
|
## 8. Limites y Control
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Prioridad |
|
|
|---------------|------------|---------|-----------|
|
|
| GetLimit | ✅ | ✅ | `db.getLimit()` |
|
|
| SetLimit | ✅ | ✅ | `db.setLimit()` |
|
|
| SetFileControlInt | ✅ | ⏳ | Baja |
|
|
| Interrupt | ✅ | ✅ | `db.interrupt()` |
|
|
|
|
---
|
|
|
|
## 9. Callbacks y Hooks
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Prioridad |
|
|
|---------------|------------|---------|-----------|
|
|
| Commit hook | ✅ | ✅ | `db.setCommitHook()` |
|
|
| Rollback hook | ✅ | ✅ | `db.setRollbackHook()` |
|
|
| Update hook | ✅ | ✅ | `db.setUpdateHook()` |
|
|
| Pre-update hook | ✅ | ✅ | `db.setPreUpdateHook()` |
|
|
| Authorizer | ✅ | ✅ | `db.setAuthorizer()` |
|
|
| Progress handler | ✅ | ✅ | `db.setProgressHandler()` |
|
|
| Busy handler | ✅ | ✅ | `db.setBusyHandler()` |
|
|
| Busy timeout | ✅ | ✅ | `db.setBusyTimeout()` |
|
|
|
|
---
|
|
|
|
## 10. Funciones Personalizadas
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Prioridad |
|
|
|---------------|------------|---------|-----------|
|
|
| RegisterFunc (scalar) | ✅ | ✅ | `db.createScalarFunction()` |
|
|
| RegisterAggregator | ✅ | ✅ | `db.createAggregateFunction()` |
|
|
| RegisterCollation | ✅ | ✅ | `db.createCollation()` |
|
|
| User-defined window func | ✅ | ⏳ | Baja |
|
|
|
|
---
|
|
|
|
## 11. Backup API
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Prioridad |
|
|
|---------------|------------|---------|-----------|
|
|
| Backup init | ✅ | ✅ | `Backup.init()` |
|
|
| Backup step | ✅ | ✅ | `backup.step()` |
|
|
| Backup finish | ✅ | ✅ | `backup.finish()` |
|
|
| Backup remaining | ✅ | ✅ | `backup.remaining()` |
|
|
| Backup pagecount | ✅ | ✅ | `backup.pageCount()` |
|
|
|
|
---
|
|
|
|
## 12. Blob I/O
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Prioridad |
|
|
|---------------|------------|---------|-----------|
|
|
| Blob open | ✅ | ✅ | `Blob.open()` |
|
|
| Blob close | ✅ | ✅ | `blob.close()` |
|
|
| Blob read | ✅ | ✅ | `blob.read()` |
|
|
| Blob write | ✅ | ✅ | `blob.write()` |
|
|
| Blob bytes | ✅ | ✅ | `blob.bytes()` |
|
|
| Blob reopen | ✅ | ✅ | `blob.reopen()` |
|
|
|
|
---
|
|
|
|
## 13. Extensiones
|
|
|
|
| Funcionalidad | go-sqlite3 | zsqlite | Notas |
|
|
|---------------|------------|---------|-------|
|
|
| Load extension | ✅ | ❌ | Deshabilitado por seguridad |
|
|
| Enable load ext | ✅ | ❌ | |
|
|
|
|
---
|
|
|
|
## Plan de Implementacion
|
|
|
|
### Fase 2A - Prioridad Alta ✅ COMPLETADA
|
|
1. ✅ Busy timeout/handler - `db.setBusyTimeout()`
|
|
2. ✅ WAL mode (journal_mode pragma) - `db.setJournalMode()`, `db.enableWalMode()`
|
|
3. ✅ Named parameters - `stmt.bindTextNamed()`, etc.
|
|
4. ✅ SAVEPOINT/RELEASE/ROLLBACK TO - `db.savepoint()`, etc.
|
|
5. ✅ BEGIN EXCLUSIVE - `db.beginExclusive()`
|
|
|
|
### Fase 2B - Prioridad Alta ✅ COMPLETADA
|
|
1. ✅ Backup API completo - `Backup` struct, `backupToFile()`, `loadFromFile()`
|
|
2. ✅ User-defined functions (scalar) - `db.createScalarFunction()`
|
|
3. ✅ Collations personalizadas - `db.createCollation()`
|
|
4. ✅ ATTACH/DETACH - `db.attach()`, `db.detach()`, `db.listDatabases()`
|
|
|
|
### Fase 3A - Prioridad Media ✅ COMPLETADA
|
|
1. ✅ Blob I/O streaming - `Blob` struct con `read()`, `write()`, `reopen()`
|
|
2. ✅ Hooks (commit, rollback, update) - `db.setCommitHook()`, etc.
|
|
3. ✅ Aggregator functions - `db.createAggregateFunction()`
|
|
4. ⏳ Mas pragmas
|
|
|
|
### Fase 3B - Prioridad Baja ✅ COMPLETADA
|
|
1. ✅ Authorizer - `db.setAuthorizer()`
|
|
2. ✅ Progress handler - `db.setProgressHandler()`
|
|
3. ✅ Pre-update hook - `db.setPreUpdateHook()`
|
|
4. ✅ Limits API - `db.getLimit()`, `db.setLimit()`
|
|
5. ✅ Busy handler (custom callback) - `db.setBusyHandler()`
|
|
6. ✅ Timestamp binding - `stmt.bindTimestamp()`
|
|
7. ✅ Column metadata - `stmt.columnDatabaseName()`, etc.
|
|
8. ✅ Expanded SQL - `stmt.expandedSql()`
|
|
9. ⏳ Window functions (baja prioridad)
|
|
|
|
---
|
|
|
|
## Funciones SQLite C Relevantes (Referencia)
|
|
|
|
```c
|
|
// Conexion
|
|
sqlite3_open_v2()
|
|
sqlite3_close_v2()
|
|
|
|
// Statements
|
|
sqlite3_prepare_v2()
|
|
sqlite3_finalize()
|
|
sqlite3_reset()
|
|
sqlite3_clear_bindings()
|
|
sqlite3_step()
|
|
sqlite3_sql()
|
|
sqlite3_expanded_sql()
|
|
sqlite3_stmt_readonly()
|
|
|
|
// Bind
|
|
sqlite3_bind_parameter_index()
|
|
sqlite3_bind_parameter_name()
|
|
sqlite3_bind_null()
|
|
sqlite3_bind_int64()
|
|
sqlite3_bind_double()
|
|
sqlite3_bind_text()
|
|
sqlite3_bind_blob()
|
|
sqlite3_bind_zeroblob()
|
|
|
|
// Column
|
|
sqlite3_column_count()
|
|
sqlite3_column_name()
|
|
sqlite3_column_type()
|
|
sqlite3_column_int64()
|
|
sqlite3_column_double()
|
|
sqlite3_column_text()
|
|
sqlite3_column_blob()
|
|
sqlite3_column_bytes()
|
|
sqlite3_column_decltype()
|
|
sqlite3_column_database_name()
|
|
sqlite3_column_table_name()
|
|
sqlite3_column_origin_name()
|
|
|
|
// Utilidades
|
|
sqlite3_last_insert_rowid()
|
|
sqlite3_changes()
|
|
sqlite3_total_changes()
|
|
sqlite3_errmsg()
|
|
sqlite3_errcode()
|
|
sqlite3_extended_errcode()
|
|
sqlite3_libversion()
|
|
sqlite3_libversion_number()
|
|
sqlite3_db_filename()
|
|
sqlite3_db_readonly()
|
|
|
|
// Busy
|
|
sqlite3_busy_timeout()
|
|
sqlite3_busy_handler()
|
|
|
|
// Hooks
|
|
sqlite3_commit_hook()
|
|
sqlite3_rollback_hook()
|
|
sqlite3_update_hook()
|
|
sqlite3_preupdate_hook()
|
|
|
|
// Funciones
|
|
sqlite3_create_function_v2()
|
|
sqlite3_create_collation_v2()
|
|
sqlite3_create_window_function()
|
|
|
|
// Backup
|
|
sqlite3_backup_init()
|
|
sqlite3_backup_step()
|
|
sqlite3_backup_finish()
|
|
sqlite3_backup_remaining()
|
|
sqlite3_backup_pagecount()
|
|
|
|
// Blob
|
|
sqlite3_blob_open()
|
|
sqlite3_blob_close()
|
|
sqlite3_blob_read()
|
|
sqlite3_blob_write()
|
|
sqlite3_blob_bytes()
|
|
sqlite3_blob_reopen()
|
|
|
|
// Control
|
|
sqlite3_interrupt()
|
|
sqlite3_limit()
|
|
sqlite3_progress_handler()
|
|
sqlite3_set_authorizer()
|
|
```
|
|
|
|
---
|
|
|
|
**© zsqlite - CGo Parity Analysis**
|
|
*2025-12-08*
|