refactor(database): split LoadMetadataFor into orchestration + helpers#170
refactor(database): split LoadMetadataFor into orchestration + helpers#170dpage wants to merge 2 commits into
Conversation
The CTE-based metadata query and its 70-line row-scan loop lived in a single ~260-line function, making it hard to test the transformation in isolation and hard to spot defects in the scan loop (cf. #126 / PR #144). This commit splits the function along three seams: - `internal/database/load_metadata.sql` holds the SQL, embedded via `//go:embed`, so it can be diffed and reviewed as SQL. - `scanMetadataRow` in `internal/database/metadata.go` takes one `pgx.Rows` and returns a typed `metadataRow`. Nullable columns use `sql.NullString` / `sql.NullInt32`, preserving the zero-column-table tolerance from #126. - `buildTableInfo` in the same file is a pure function that takes `[]metadataRow` and produces the metadata map, schema set, and column count. It does no I/O and is covered by table-driven unit tests that do not need a database. `LoadMetadataFor` now orchestrates: query, scan loop, build, atomic swap, log. No behavior change. Closes #153
Up to standards ✅🟢 Issues
|
| Category | Results |
|---|---|
| Compatibility | 1 medium (1 false positive) |
| BestPractice | 3 medium (3 false positives) |
🟢 Metrics 51 complexity · 0 duplication
Metric Results Complexity 51 Duplication 0
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughThis PR refactors Client.LoadMetadataFor by embedding the metadata SQL, adding scanMetadataRow to produce typed rows, extracting a pure buildTableInfo transformer that groups rows into TableInfo per schema.table, and adding table-driven tests for buildTableInfo; LoadMetadataFor now orchestrates these parts. ChangesMetadata Loader Refactor
🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs:
Suggested reviewers:
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/database/load_metadata.sql`:
- Around line 73-88: The fk_columns CTE can emit multiple rows per source column
when a column participates in multiple foreign-key pairs, causing duplicate
ColumnInfo downstream; update the fk_columns CTE to collapse those duplicates by
grouping on schema_name, table_name, column_name and either aggregating
fk_reference (e.g., string_agg(DISTINCT fk_reference, ',') AS fk_reference) or
using DISTINCT ON (n.nspname, c.relname, a.attname) to pick one reference, so
the later join by (schema, table, column) returns a single row per source
column.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9330ba79-5c4a-4f1f-8319-402bc2c715ee
📒 Files selected for processing (5)
docs/changelog.mdinternal/database/connection.gointernal/database/load_metadata.sqlinternal/database/metadata.gointernal/database/metadata_test.go
…exity Codacy's Lizard flagged buildTableInfo at cyclomatic complexity 9 (limit 8) and TestBuildTableInfo_PreservesAllColumnAttributes at 10 (limit 8). Split the vector-detection branch and the ColumnInfo and TableInfo construction into their own helper functions (vectorColumnInfo, columnInfoFromRow, tableInfoFromRow), bringing buildTableInfo's body down to a single short loop. Consolidate the test to a single struct comparison. No behavior change. All existing tests still pass.
Codacy findings — summary of what I'm addressingCodacy's PR check is green ("Up to standards"), but the report lists 36 new findings. Here's how each category breaks down: Addressed in code
Not addressed — pre-existing SQL, out of scope per issue #153The remaining 34 findings all sit on
If we want to address the SQL-style findings now that the query is in its own file (which would be more justifiable than it was when it was a Go string literal), happy to do that in a follow-up PR — let me know. CodeRabbit FK-duplicate-rows threadLeft unresolved with a reply — same reasoning: the |
Summary
internal/database/load_metadata.sql(embedded with//go:embed) so it can be reviewed as SQL on its own.scanMetadataRowandbuildTableInfoininternal/database/metadata.go.buildTableInfois pure (no I/O, no time, no shared state) and produces the metadata map, schema set, and column count from a slice of scanned rows.LoadMetadataForininternal/database/connection.goto orchestration: query, scan loop, build, atomic swap, log. The file shrinks from 687 to 491 lines.buildTableInfocovering the zero-column-table case (issue Metadata loader fails with NULL column_name when database contains a table with no columns #126 regression), grouping, multiple schemas, vector columns (with and without dimensions), and full column-attribute preservation. Tests do not require a database.No behavior change. The existing live-DB regression test
TestLoadMetadata_TableWithNoColumns(PR #144) still passes.Test plan
make buildmake test— all existing tests still pass; 10 new unit tests forbuildTableInfopass.golangci-lint run ./internal/database/...— 0 issues. (make lintstill reports 3 pre-existing staticcheck findings ininternal/embedding/, untouched by this PR.)gofmt -l internal/database/— clean.go vet ./internal/database/...— clean.go test -race ./internal/database/...— passes.Closes #153
Summary by CodeRabbit
Refactor
Tests
Documentation