docs: clarify sqlc DDL support limitations and correct implementation
**Discovery**: sqlc's DDL support is database-engine specific: ✅ **PostgreSQL**: sqlc generates functions for CREATE INDEX, CREATE FUNCTION ❌ **SQLite**: sqlc does NOT generate CREATE INDEX functions ❌ **Both**: sqlc does NOT generate CREATE TRIGGER functions **Corrected Implementation**: - Use sqlc-generated setup functions where available (tables always, PostgreSQL indexes) - Use manual SQL where sqlc doesn't support (SQLite indexes, all triggers) - Comments clarify why manual SQL is needed in each case **Architecture Principle**: Use sqlc for what it supports, supplement with manual SQL for what it doesn't - this is the recommended hybrid approach.
This commit is contained in:
12
TODO.md
12
TODO.md
@@ -238,4 +238,14 @@ CREATE INDEX IF NOT EXISTS idx_content_site_id ON content(site_id);
|
||||
- Keep schema in separate `.sql` files
|
||||
- **Trade-off**: Not processed by sqlc, less type safety
|
||||
|
||||
**Next Action**: Implement Option 1 (Schema-as-Query) to maintain consistency with sqlc workflow while eliminating duplicate schema definitions.
|
||||
**✅ COMPLETED**: Implemented Option 1 (Schema-as-Query) with important discovery:
|
||||
|
||||
**sqlc Limitations Discovered**:
|
||||
- ✅ sqlc generates functions for `CREATE TABLE` and `ALTER TABLE` statements
|
||||
- ❌ sqlc does **NOT** generate functions for `CREATE INDEX` or `CREATE TRIGGER` statements
|
||||
- 🔧 **Solution**: Handle table creation via sqlc-generated functions, handle indexes/triggers manually in Go initialization code
|
||||
|
||||
**Final Implementation**:
|
||||
- `db/*/setup.sql` - Contains table creation queries (sqlc generates type-safe functions)
|
||||
- `internal/db/database.go` - Manual index/trigger creation using raw SQL
|
||||
- **Best Practice**: Use sqlc for what it supports, manual SQL for what it doesn't
|
||||
|
||||
Binary file not shown.
@@ -108,7 +108,7 @@ func (db *Database) initializeSQLiteSchema() error {
|
||||
return fmt.Errorf("failed to create content_versions table: %w", err)
|
||||
}
|
||||
|
||||
// Create indexes (manual for now since sqlc didn't generate them)
|
||||
// Create indexes manually (sqlc doesn't generate CREATE INDEX functions for SQLite)
|
||||
indexQueries := []string{
|
||||
"CREATE INDEX IF NOT EXISTS idx_content_site_id ON content(site_id);",
|
||||
"CREATE INDEX IF NOT EXISTS idx_content_updated_at ON content(updated_at);",
|
||||
@@ -121,7 +121,7 @@ func (db *Database) initializeSQLiteSchema() error {
|
||||
}
|
||||
}
|
||||
|
||||
// Create update trigger (manual for now)
|
||||
// Create update trigger manually (sqlc doesn't generate trigger creation functions)
|
||||
triggerQuery := `
|
||||
CREATE TRIGGER IF NOT EXISTS update_content_updated_at
|
||||
AFTER UPDATE ON content
|
||||
@@ -141,7 +141,7 @@ func (db *Database) initializeSQLiteSchema() error {
|
||||
func (db *Database) initializePostgreSQLSchema() error {
|
||||
ctx := context.Background()
|
||||
|
||||
// Create tables
|
||||
// Create tables using sqlc-generated functions
|
||||
if err := db.postgresqlQueries.InitializeSchema(ctx); err != nil {
|
||||
return fmt.Errorf("failed to create content table: %w", err)
|
||||
}
|
||||
@@ -150,7 +150,7 @@ func (db *Database) initializePostgreSQLSchema() error {
|
||||
return fmt.Errorf("failed to create content_versions table: %w", err)
|
||||
}
|
||||
|
||||
// Create indexes using generated functions
|
||||
// Create indexes using sqlc-generated functions (PostgreSQL supports this)
|
||||
if err := db.postgresqlQueries.CreateContentSiteIndex(ctx); err != nil {
|
||||
return fmt.Errorf("failed to create content site index: %w", err)
|
||||
}
|
||||
@@ -163,12 +163,12 @@ func (db *Database) initializePostgreSQLSchema() error {
|
||||
return fmt.Errorf("failed to create versions lookup index: %w", err)
|
||||
}
|
||||
|
||||
// Create update function and trigger
|
||||
// Create update function using sqlc-generated function
|
||||
if err := db.postgresqlQueries.CreateUpdateFunction(ctx); err != nil {
|
||||
return fmt.Errorf("failed to create update function: %w", err)
|
||||
}
|
||||
|
||||
// Create trigger manually (sqlc didn't generate this)
|
||||
// Create trigger manually (sqlc doesn't generate trigger creation functions)
|
||||
triggerQuery := `
|
||||
DROP TRIGGER IF EXISTS update_content_updated_at ON content;
|
||||
CREATE TRIGGER update_content_updated_at
|
||||
|
||||
Reference in New Issue
Block a user