Add SelectQuery.First and Selective Relation Columns#124
Conversation
- Implement SelectQuery.First(ctx, dest) for ergonomic single-row fetching. - Add Columns field to RelationConfig for selective column loading in relational queries. - Ensure join keys are automatically included in relational subqueries. - Add unit and integration tests. Co-authored-by: cungminh2710 <8063319+cungminh2710@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Greptile SummaryThis PR adds two features: a
Confidence Score: 4/5Safe to merge for all single-level selective relation usage; the nested relation + selective columns combination produces silent data loss and should be fixed or documented before production use. The pkg/rain/relation_loading.go — specifically the
|
| Filename | Overview |
|---|---|
| pkg/rain/query_select.go | Adds First(ctx, dest) convenience method that clones the query, applies LIMIT 1, and delegates to Scan. Implementation is clean and minimal. |
| pkg/rain/relation_loading.go | Adds RelationConfig.Columns selective loading with ensureTargetColumnSelected guard. The guard correctly covers single-level loading but omits auto-inclusion of child-relation SourceColumns, which causes silent empty/wrong nested results when Columns is set on a non-leaf relation. |
| pkg/rain/query_select_test.go | Adds TestSelectFirst which validates LIMIT 1 SQL generation; does not invoke First() directly but tests the underlying mechanism; reasonable given prior review feedback. |
| pkg/rain/sqlite_integration_test.go | Adds integration tests for selective relation columns (single-level, with FK field in dest struct) and for First including ErrNoRows validation; both tests are well-structured and cover the happy path and the no-rows case. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Caller
participant SelectQuery
participant loadRelationNode
participant loadRelatedRows
participant ensureTargetColumnSelected
participant DB
Caller->>SelectQuery: First(ctx, dest)
SelectQuery->>SelectQuery: clone().Limit(1)
SelectQuery->>DB: Scan(ctx, dest)
DB-->>SelectQuery: rows
SelectQuery-->>Caller: nil or sql.ErrNoRows
Caller->>SelectQuery: Scan + Relation(posts, Columns:[title])
SelectQuery->>DB: "SELECT * FROM users"
DB-->>SelectQuery: parent rows
SelectQuery->>loadRelationNode: load posts node
loadRelationNode->>loadRelatedRows: sourceKeys, Columns:[title]
loadRelatedRows->>ensureTargetColumnSelected: ensure posts.user_id
loadRelatedRows->>DB: SELECT title, user_id FROM posts WHERE user_id IN (...)
DB-->>loadRelatedRows: "post rows (id=0 in struct)"
loadRelatedRows-->>loadRelationNode: relatedRows
Note over loadRelationNode: node.children: posts.id missing
loadRelationNode->>DB: SELECT FROM comments WHERE post_id IN (0)
DB-->>loadRelationNode: empty result - silent data loss
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Caller
participant SelectQuery
participant loadRelationNode
participant loadRelatedRows
participant ensureTargetColumnSelected
participant DB
Caller->>SelectQuery: First(ctx, dest)
SelectQuery->>SelectQuery: clone().Limit(1)
SelectQuery->>DB: Scan(ctx, dest)
DB-->>SelectQuery: rows
SelectQuery-->>Caller: nil or sql.ErrNoRows
Caller->>SelectQuery: Scan + Relation(posts, Columns:[title])
SelectQuery->>DB: "SELECT * FROM users"
DB-->>SelectQuery: parent rows
SelectQuery->>loadRelationNode: load posts node
loadRelationNode->>loadRelatedRows: sourceKeys, Columns:[title]
loadRelatedRows->>ensureTargetColumnSelected: ensure posts.user_id
loadRelatedRows->>DB: SELECT title, user_id FROM posts WHERE user_id IN (...)
DB-->>loadRelatedRows: "post rows (id=0 in struct)"
loadRelatedRows-->>loadRelationNode: relatedRows
Note over loadRelationNode: node.children: posts.id missing
loadRelationNode->>DB: SELECT FROM comments WHERE post_id IN (0)
DB-->>loadRelationNode: empty result - silent data loss
Reviews (3): Last reviewed commit: "refactor(rain): remove FirstToSQL test h..." | Re-trigger Greptile
- Implement SelectQuery.First(ctx, dest) for ergonomic single-row fetching. - Add Columns field to RelationConfig for selective column loading in relational queries. - Ensure join keys are automatically included in relational subqueries. - Add unit and integration tests. - Fix linting and formatting issues found in CI. Co-authored-by: cungminh2710 <8063319+cungminh2710@users.noreply.github.com>
- Removed FirstToSQL test helper from query_select.go as requested. - Updated query_select_test.go to verify First() behavior using standard methods. - Fixed linting issue (unused struct) in query_select_test.go. - Verified all tests pass with make precommit. Co-authored-by: cungminh2710 <8063319+cungminh2710@users.noreply.github.com>
This PR introduces two key enhancements to Rain ORM:
SelectQuery.First(ctx, dest): A convenience method that executes the query with an implicit
LIMIT 1and scans the result intodest. It returnssql.ErrNoRowsif no result is found, matching Drizzle's behavior.Selective Relation Columns: Enhanced
RelationConfigto support aColumnsfield, allowing users to specify which columns to load for a relation. The implementation automatically ensures that relationship mapping keys (source/target columns) are included in the underlying SQL query to preserve data mapping integrity.Test coverage includes both unit tests for SQL generation and integration tests using SQLite.
PR created automatically by Jules for task 9720018403007912893 started by @cungminh2710