-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add indexes to tag join-tables and update tag query for threads #360
base: main
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 2 Skipped Deployments
|
📝 WalkthroughWalkthroughThe changes introduce a comprehensive enhancement to the tagging system in the application, specifically focusing on creating many-to-many relationships between tags and nodes/posts. A new intermediary entity structure is implemented using Changes
Sequence DiagramsequenceDiagram
participant Client
participant TagNodeClient
participant TagPostClient
participant Database
Client->>TagNodeClient: Create TagNode
TagNodeClient->>Database: Insert tag_nodes record
Client->>TagPostClient: Create TagPost
TagPostClient->>Database: Insert tag_posts record
Client->>Database: Query nodes/posts with tags
Poem
Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
ee596c6
to
8a4531d
Compare
8a4531d
to
587b4f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
🔭 Outside diff range comments (1)
internal/ent/tag_update.go (1)
Line range hint
821-873
: Review the necessity of creating new entities during updates.In the
sqlSave
method, the code creates newTagPostCreate
instances when updating edges. This could lead to unintended data creation. Ensure that this behavior is desired, or modify the code to update existing relationships without creating new entities.Apply this diff to remove unnecessary entity creation:
- createE := &TagPostCreate{config: tuo.config, mutation: newTagPostMutation(tuo.config, OpCreate)} - createE.defaults() - _, specE := createE.createSpec() - edge.Target.Fields = specE.Fields - if specE.ID.Value != nil { - edge.Target.Fields = append(edge.Target.Fields, specE.ID) - }
🧹 Nitpick comments (18)
internal/ent/node/node.go (1)
120-126
: Consider consolidating duplicate table name constants.The table name "tag_nodes" is defined in both
TagsTable
andNodeTagsTable
constants. Consider using a single constant to avoid potential maintenance issues.-// NodeTagsTable is the table that holds the node_tags relation/edge. -NodeTagsTable = "tag_nodes" +// NodeTagsTable is the table that holds the node_tags relation/edge. +NodeTagsTable = TagsTableinternal/ent/tagnode_query.go (4)
1-2
: Add a package documentation comment.The file lacks a package-level comment that briefly describes the purpose of the
ent
package and its usage. Adding this will improve code readability and maintainability.
10-19
: Organize imports according to Go conventions.The imports can be grouped into standard library, third-party, and local package imports, separated by blank lines, to enhance code readability.
Apply this diff to organize the imports:
import ( + "context" + "fmt" + "math" "entgo.io/ent" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" + "github.com/rs/xid" + "github.com/Southclaws/storyden/internal/ent/node" + "github.com/Southclaws/storyden/internal/ent/predicate" + "github.com/Southclaws/storyden/internal/ent/tag" + "github.com/Southclaws/storyden/internal/ent/tagnode" )
21-34
: Consider adding context cancellation handling.In the
TagNodeQuery
struct, it would be beneficial to handle context cancellation to ensure that database queries are properly canceled if the context is done.
605-705
: Avoid mixing concerns in theModify
method.The
Modify
method attaches custom logic to queries but returns aTagNodeSelect
. This can be confusing. Consider splitting the functionality or ensuring that the method's purpose is clear.internal/ent/tag_update.go (4)
82-111
: Consider documenting the new methods for clarity.The newly added methods for managing "post_tags" and "node_tags" edges lack comments. Adding documentation comments describing their purpose and usage would improve code maintainability.
180-221
: Consider consistency in edge management methods.The methods for clearing and removing "post_tags" and "node_tags" edges could be made consistent with the existing pattern used for other edges in the file. This would enhance readability and maintainability.
598-627
: Add documentation for new methods inTagUpdateOne
.Similar to the
TagUpdate
struct, the new methods inTagUpdateOne
lack documentation comments. Adding them will help other developers understand their purpose.
696-737
: Maintain consistency in method ordering and grouping.The newly added methods for managing "post_tags" and "node_tags" edges in
TagUpdateOne
should be grouped logically with related methods and ordered consistently to improve code readability.internal/ent/mutation.go (3)
15187-15189
: Inconsistent field naming inNodeMutation
structThe newly added fields
node_tags
,removednode_tags
, andclearednode_tags
use underscores in their names, while existing fields likecollections
,removedcollections
, andclearedcollections
use camelCase without underscores. For consistency with Go naming conventions, consider renaming these fields tonodeTags
,removedNodeTags
, andclearedNodeTags
.This naming inconsistency appears throughout the code changes. Please review all new additions to ensure consistent naming conventions.
18041-18043
: Inconsistent field naming inPostMutation
structThe newly added fields
post_tags
,removedpost_tags
, andclearedpost_tags
use underscores, while existing fields use camelCase. Consider renaming them topostTags
,removedPostTags
, andclearedPostTags
for consistency.
23140-23163
: Inconsistent field naming inTagMutation
structThe newly added fields
post_tags
,removedpost_tags
,clearedpost_tags
,node_tags
,removednode_tags
, andclearednode_tags
use underscores. To maintain consistency, consider renaming them topostTags
,removedPostTags
,clearedPostTags
,nodeTags
,removedNodeTags
, andclearedNodeTags
.internal/ent/schema/tag_post.go (1)
43-47
: Consider adding a composite index for better performance.While the index on
post_id
is good, a composite index on(tag_id, post_id)
would be beneficial for:
- Enforcing uniqueness of tag-post combinations
- Improving query performance when filtering by both fields
func (TagPost) Indexes() []ent.Index { return []ent.Index{ index.Fields("post_id"), + index.Fields("tag_id", "post_id").Unique(), } }
internal/ent/schema/tag_node.go (1)
43-47
: Consider adding a composite index for better performance.Similar to the TagPost schema, a composite index on
(tag_id, node_id)
would be beneficial for:
- Enforcing uniqueness of tag-node combinations
- Improving query performance when filtering by both fields
func (TagNode) Indexes() []ent.Index { return []ent.Index{ index.Fields("node_id"), + index.Fields("tag_id", "node_id").Unique(), } }
internal/ent/schema/post.go (1)
63-63
: Consider adding indexes for the many-to-many relationship.The change to use a join table (
post_tags
) for the tags relationship is good. However, since this is a many-to-many relationship that will be frequently queried, consider adding indexes to optimize query performance.You might want to add the following indexes:
- A composite index on
(post_id, tag_id)
for queries from posts to tags- A composite index on
(tag_id, post_id)
for queries from tags to postsinternal/ent/tagnode.go (1)
1-1
: Consider composite indexes for performance optimization.Since these are join tables used for many-to-many relationships, consider adding composite indexes on (tag_id, post_id) and (tag_id, node_id) pairs in addition to individual column indexes. This can improve query performance when searching for specific tag-post or tag-node combinations.
app/resources/post/thread/db.go (1)
Line range hint
404-408
: Consider adding an index on the tag_post table.Since the query now uses a join table, adding an index on
(post_id, tag_id)
would optimize the performance of tag lookups by post.internal/ent/node_update.go (1)
Line range hint
849-901
: Consider batch processing for tag operations.The SQL graph specifications are correct, but consider implementing batch processing for tag operations to improve performance when handling multiple tags.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (47)
app/resources/post/thread/db.go
(2 hunks)internal/ent/client.go
(12 hunks)internal/ent/ent.go
(2 hunks)internal/ent/er.html
(2 hunks)internal/ent/hook/hook.go
(1 hunks)internal/ent/migrate/schema.go
(3 hunks)internal/ent/mutation.go
(32 hunks)internal/ent/node.go
(3 hunks)internal/ent/node/node.go
(4 hunks)internal/ent/node/where.go
(1 hunks)internal/ent/node_create.go
(4 hunks)internal/ent/node_query.go
(9 hunks)internal/ent/node_update.go
(13 hunks)internal/ent/post.go
(3 hunks)internal/ent/post/post.go
(4 hunks)internal/ent/post/where.go
(1 hunks)internal/ent/post_create.go
(4 hunks)internal/ent/post_query.go
(9 hunks)internal/ent/post_update.go
(13 hunks)internal/ent/predicate/predicate.go
(1 hunks)internal/ent/runtime.go
(2 hunks)internal/ent/schema/node.go
(1 hunks)internal/ent/schema/post.go
(1 hunks)internal/ent/schema/tag.go
(1 hunks)internal/ent/schema/tag_node.go
(1 hunks)internal/ent/schema/tag_post.go
(1 hunks)internal/ent/tag.go
(3 hunks)internal/ent/tag/tag.go
(4 hunks)internal/ent/tag/where.go
(1 hunks)internal/ent/tag_create.go
(5 hunks)internal/ent/tag_query.go
(8 hunks)internal/ent/tag_update.go
(19 hunks)internal/ent/tagnode.go
(1 hunks)internal/ent/tagnode/tagnode.go
(1 hunks)internal/ent/tagnode/where.go
(1 hunks)internal/ent/tagnode_create.go
(1 hunks)internal/ent/tagnode_delete.go
(1 hunks)internal/ent/tagnode_query.go
(1 hunks)internal/ent/tagnode_update.go
(1 hunks)internal/ent/tagpost.go
(1 hunks)internal/ent/tagpost/tagpost.go
(1 hunks)internal/ent/tagpost/where.go
(1 hunks)internal/ent/tagpost_create.go
(1 hunks)internal/ent/tagpost_delete.go
(1 hunks)internal/ent/tagpost_query.go
(1 hunks)internal/ent/tagpost_update.go
(1 hunks)internal/ent/tx.go
(2 hunks)
🔇 Additional comments (114)
internal/ent/node/node.go (2)
392-404
: LGTM! Ordering functions follow consistent patterns.The implementation of
ByNodeTagsCount
andByNodeTags
functions aligns well with the existing ordering functions in the codebase.
482-488
: Verify index creation on the tag_nodes table.The PR objective mentions adding indexes to tag join-tables. Let's verify that the appropriate index exists on the
node_id
column in thetag_nodes
table.✅ Verification successful
Index is properly defined on the tag_nodes table
The schema correctly defines an index on the
node_id
column in thetag_nodes
table through the ent framework's schema definition. This satisfies the PR objective for adding necessary indexes to tag join-tables.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for index definitions in migration files or schema files # Look for CREATE INDEX statements in .sql files rg -i "create\s+index.*tag_nodes.*node_id" -g "*.sql" # Look for index definitions in schema files rg "Index\(.*tag_nodes.*node_id" -g "*.go"Length of output: 249
Script:
#!/bin/bash # First, find any .sql files echo "=== SQL Files ===" fd -e sql # Look for tag-related schema definitions echo -e "\n=== Tag Schema Definitions ===" rg -g "*.go" "type.*Tag.*struct" # Look for any index definitions in schema echo -e "\n=== Index Definitions ===" rg -g "*.go" "Index\(" -A 2 # Look for tag_nodes table definition echo -e "\n=== Tag Nodes Table Definition ===" ast-grep --pattern 'Table = "tag_nodes"'Length of output: 8515
Script:
#!/bin/bash # Check the tag_node schema file for index definitions echo "=== Tag Node Schema ===" cat internal/ent/schema/tag_node.go # Look for any index-related configurations in schema echo -e "\n=== Index Configuration in Schema ===" rg "Index|index" internal/ent/schema/tag_node.go -B 2 -A 2Length of output: 1306
internal/ent/tagnode_update.go (1)
1-438
: Code conforms to theent
framework standardsThe
tagnode_update.go
file is generated by theent
framework. The code follows the standard patterns and conventions expected forent
generated code. No issues found.internal/ent/tagpost_create.go (1)
1-610
: Code conforms to theent
framework standardsThe
tagpost_create.go
file is generated by theent
framework. The code adheres to the standard patterns and conventions expected forent
generated code. No issues found.internal/ent/tagnode_create.go (1)
1-610
: Code conforms to theent
framework standardsThe
tagnode_create.go
file is generated by theent
framework. The code follows the standard patterns and conventions expected forent
generated code. No issues found.internal/ent/tag_update.go (1)
Line range hint
275-327
: Verify the edge specifications for correctness.The edge specifications in the
sqlSave
method for handling "posts" relationships involve creating aTagPostCreate
instance, which might not be necessary. Ensure that the edge is correctly defined for the existing relationships.Please verify that the edge specifications correctly represent the intended relationships, and that creating new
TagPostCreate
instances is required.✅ Verification successful
Edge specifications and TagPostCreate usage is correct and necessary
The creation of
TagPostCreate
instances is a deliberate design pattern used consistently across the codebase for handling M2M relationships between Tags and Posts. This pattern ensures proper initialization of defaults and field configurations for edge specifications.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for the necessity of TagPostCreate instances in edge specifications. # Search for similar patterns in other update files rg -A 5 'createE := &TagPostCreate' internal/ent/Length of output: 6332
internal/ent/mutation.go (26)
40-41
: New imports fortagnode
andtagpost
addedThe imports for
tagnode
andtagpost
are correctly added to the import statements.
78-79
: New mutation types definedThe constants
TypeTagNode
andTypeTagPost
are properly defined to represent the new mutation types.
16324-16377
: Methods for managingNodeTags
edgeThe methods for handling the
NodeTags
edge inNodeMutation
are appropriately implemented.
16811-16813
: Duplicate comment
16867-16872
: Duplicate comment
16895-16897
: Duplicate comment
16935-16940
: Duplicate comment
16975-16977
: Duplicate comment
17003-17004
: Duplicate comment
17060-17062
: Duplicate comment
19596-19648
: Methods for managingPostTags
edgeThe methods for handling the
PostTags
edge inPostMutation
are correctly implemented.
20158-20160
: Duplicate comment
20249-20253
: Duplicate comment
20291-20293
: Duplicate comment
20362-20366
: Duplicate comment
20419-20421
: Duplicate comment
20459-20460
: Duplicate comment
20537-20539
: Duplicate comment
23504-23611
: Methods for managingPostTags
andNodeTags
edgesThe methods for handling the
PostTags
andNodeTags
edges inTagMutation
are properly implemented.
23772-23777
: Duplicate comment
23832-23836
: Duplicate comment
23863-23873
: Duplicate comment
23891-23895
: Duplicate comment
23909-23912
: Duplicate comment
23938-23943
: Duplicate comment
23948-24918
: New mutation typesTagNodeMutation
andTagPostMutation
addedThe
TagNodeMutation
andTagPostMutation
types have been introduced and correctly implement methods for managing mutations onTagNode
andTagPost
entities.internal/ent/schema/tag.go (1)
27-28
: LGTM! Well-structured many-to-many relationships.The implementation correctly uses join tables for tag relationships with posts and nodes, which is the recommended approach for many-to-many relationships in ent.
internal/ent/schema/tag_post.go (1)
20-41
: LGTM! Well-structured join table schema.The implementation includes proper field types, required constraints, and cascade delete behavior which ensures data consistency.
internal/ent/schema/node.go (1)
61-61
: LGTM! Consistent implementation of many-to-many relationship.The change properly establishes the many-to-many relationship with tags through the TagNode join table, maintaining consistency with the Tag schema.
internal/ent/tagpost_delete.go (1)
1-88
: Generated code looks good!The generated code follows standard
ent
patterns and includes proper error handling, predicate support, and both bulk and single-entity deletion capabilities.internal/ent/tagnode_delete.go (1)
1-88
: Generated code looks good!The generated code follows the same standard
ent
patterns astagpost_delete.go
and includes all necessary functionality for managingTagNode
deletions.internal/ent/predicate/predicate.go (1)
80-85
: Generated predicates look good!The new predicate types for
TagNode
andTagPost
follow the established pattern and are properly documented.internal/ent/tagpost.go (1)
17-161
: Implementation looks good!The TagPost entity is well-structured with:
- Proper type safety for ID fields
- Comprehensive error handling for edge relationships
- Clear transaction management
internal/ent/tagnode.go (1)
17-161
: Implementation looks good!The TagNode entity is well-structured with:
- Proper type safety for ID fields
- Comprehensive error handling for edge relationships
- Clear transaction management
internal/ent/tag.go (4)
39-42
: LGTM: New edge fields properly defined.The new edge fields
PostTags
andNodeTags
are correctly added to theTagEdges
struct, following the established pattern.
45-45
: LGTM: Array size updated for new edges.The
loadedTypes
array size is correctly updated to accommodate the two new edges.
75-91
: LGTM: Edge accessor methods properly implemented.The
PostTagsOrErr
andNodeTagsOrErr
methods are correctly implemented, following the same pattern as other edge accessors.
165-173
: LGTM: Query methods properly implemented.The
QueryPostTags
andQueryNodeTags
methods are correctly implemented, following the established pattern for edge queries.internal/ent/tag/tag.go (4)
28-31
: LGTM: New edge constants properly defined.The edge constants for
post_tags
andnode_tags
are correctly added.
49-62
: LGTM: Table and column constants properly defined.The table and column constants for the new relationships are correctly defined, maintaining consistency with existing patterns.
163-189
: LGTM: Ordering functions properly implemented.The new ordering functions for post_tags and node_tags follow the established patterns and are correctly implemented.
211-224
: LGTM: Step functions properly implemented.The new step functions for post_tags and node_tags relationships are correctly implemented, following the established patterns.
internal/ent/tag/where.go (2)
243-264
: LGTM: PostTags predicates properly implemented.The
HasPostTags
andHasPostTagsWith
predicates are correctly implemented, following the established patterns.
266-287
: LGTM: NodeTags predicates properly implemented.The
HasNodeTags
andHasNodeTagsWith
predicates are correctly implemented, following the established patterns.internal/ent/tagpost/where.go (2)
207-251
: LGTM: Edge predicates properly implemented.The
HasTag
,HasTagWith
,HasPost
, andHasPostWith
predicates are correctly implemented, following the established patterns.
107-135
: Consider the necessity of string operations on ID fields.The implementation includes string-based operations (Contains, HasPrefix, HasSuffix, EqualFold, ContainsFold) on
tag_id
field which is anxid.ID
. These operations might not be practically useful for ID fields and could potentially be confusing to users.Run this script to check if these operations are used in the codebase:
internal/ent/tagnode/where.go (1)
1-266
: Auto-generated code looks good!The code follows the standard ent framework patterns for predicate generation, with well-structured query builders and proper edge handling.
internal/ent/tx.go (1)
65-68
: LGTM! Transaction client properly extended.The new TagNode and TagPost clients are correctly integrated into the transaction system, following the established patterns.
Also applies to: 224-225
internal/ent/tagpost_update.go (1)
1-438
: Auto-generated update operations look good!The code follows ent framework patterns with proper validation, error handling, and edge mutations for both bulk and single-entity updates.
app/resources/post/thread/db.go (1)
Line range hint
404-408
: Query updated to use new tag-post relationship model.The change from
HasPostsWith
toHasPostTagsWith
correctly reflects the architectural shift to using a join table for tag-post relationships.internal/ent/node.go (3)
79-80
: LGTM! TheNodeEdges
struct is correctly updated.The changes properly add support for the new
TagNode
relationship and correctly update theloadedTypes
array size.Also applies to: 85-85
177-184
: LGTM! TheNodeTagsOrErr
method is well-implemented.The method follows the established pattern and correctly handles error cases.
380-384
: LGTM! TheQueryNodeTags
method is properly implemented.The method follows the established pattern for edge queries.
internal/ent/hook/hook.go (2)
300-310
: LGTM! TheTagNodeFunc
type and itsMutate
method are well-implemented.The implementation follows the established pattern for hook types.
312-322
: LGTM! TheTagPostFunc
type and itsMutate
method are well-implemented.The implementation follows the established pattern for hook types.
internal/ent/ent.go (2)
39-40
: LGTM! The imports are correctly added.The new imports follow the established pattern.
125-126
: LGTM! The column checks are properly added.The new column checks follow the established pattern.
internal/ent/tag_create.go (4)
19-20
: LGTM! The imports are correctly added.The new imports follow the established pattern.
111-124
: LGTM! TheTagPost
relationship methods are well-implemented.The methods follow the established pattern and correctly handle ID conversion.
126-139
: LGTM! TheTagNode
relationship methods are well-implemented.The methods follow the established pattern and correctly handle ID conversion.
305-336
: LGTM! The edge specifications are properly implemented.The edge specifications correctly define one-to-many relationships for both
TagPost
andTagNode
.internal/ent/post.go (4)
Line range hint
83-84
: LGTM: Edge constant properly defined.The
EdgePostTags
constant correctly defines the edge name for post-tag relationships in mutations.
Line range hint
172-178
: LGTM: Table and column constants properly defined.The constants properly define the database structure for post-tag relationships:
PostTagsTable
defines the join tablePostTagsInverseTable
avoids circular dependenciesPostTagsColumn
specifies the foreign key column
Line range hint
530-542
: LGTM: Ordering functions properly implemented.The ordering functions provide necessary functionality for sorting results:
ByPostTagsCount
allows ordering by the number of tagsByPostTags
enables ordering by tag-specific terms
Line range hint
648-654
: LGTM: SQL graph step properly defined.The
newPostTagsStep
function correctly sets up the SQL graph step for the post-tag relationship with proper edge type (O2M) and table configuration.internal/ent/tagpost_query.go (3)
21-34
: LGTM: Query builder struct properly defined.The
TagPostQuery
struct follows ent's standard patterns with all necessary fields for query building:
- Configuration and context
- Order and predicates
- Edge loading support
- SQL query building
67-87
: LGTM: Edge query methods properly implemented.The
QueryTag
andQueryPost
methods correctly implement the edge traversal logic:
- Proper error handling
- Correct SQL graph step configuration
- Appropriate neighbor selection
Also applies to: 89-109
408-451
: LGTM: SQL query execution properly implemented.The
sqlAll
method correctly handles:
- Node scanning and assignment
- Edge loading
- Error handling
- Query specification
internal/ent/tag_query.go (3)
35-36
: LGTM: New relationship fields properly added.The
withPostTags
andwithNodeTags
fields are correctly added to support eager loading of tag relationships.
521-526
: LGTM: Loaded types array properly updated.The
loadedTypes
array size is correctly updated to accommodate the new relationships:
- Increased from 3 to 5 elements
- Properly tracks loading state of new relationships
771-800
: LGTM: Post tags loading function properly implemented.The
loadPostTags
function correctly implements the relationship loading logic:
- Proper foreign key handling
- Correct error handling
- Appropriate node assignment
internal/ent/node/where.go (2)
1126-1135
: Implementation of HasNodeTags looks good!The function correctly implements the one-to-many relationship between nodes and tag_nodes using the standard ent predicate pattern.
1137-1147
: HasNodeTagsWith implementation is correct!The function properly implements predicate chaining for the node_tags edge, following ent's established patterns.
internal/ent/migrate/schema.go (3)
794-831
: Well-designed schema for tag_nodes table!The schema includes appropriate indexes for both lookup performance (tagnode_node_id) and data integrity (unique constraint on tag_id + node_id pair). The cascade delete behavior ensures referential integrity.
832-869
: TagPosts table schema maintains consistency!The schema follows the same well-designed pattern as tag_nodes, with appropriate indexes and constraints for efficient querying and data integrity.
1046-1047
: Correct registration of new tables!The tables are properly added to the Tables registry while maintaining alphabetical order.
internal/ent/runtime.go (1)
947-996
: Runtime configuration for TagNode and TagPost is properly implemented!The code correctly sets up mixins, field descriptors, default values, and validators following ent's patterns.
internal/ent/node_query.go (3)
280-300
: QueryNodeTags implementation is correct!The edge traversal is properly implemented following ent's query builder patterns, with correct table and column references.
633-642
: WithNodeTags eager loading is properly implemented!The method correctly follows ent's patterns for configuring eager loading of edges.
1237-1266
: loadNodeTags implementation is robust!The loading logic properly handles foreign key relationships with appropriate error handling and clear error messages.
internal/ent/post/where.go (2)
1379-1388
: LGTM! The HasPostTags predicate is correctly implemented.The function follows ent's standard pattern for edge predicates, properly setting up the graph traversal for the "post_tags" edge.
1390-1400
: LGTM! The HasPostTagsWith predicate is correctly implemented.The function properly extends the basic predicate with additional filtering capabilities, following ent's conventions.
internal/ent/node_create.go (2)
340-354
: LGTM! The node tag relationship methods are correctly implemented.Both methods follow ent's standard pattern for managing many-to-many relationships:
AddNodeTagIDs
for direct ID managementAddNodeTags
as a convenience wrapper
614-620
: LGTM! The tag relationship handling in createSpec is correct.The implementation properly initializes the edge specification with default values and handles the ID field appropriately.
internal/ent/post_query.go (3)
421-441
: LGTM! The QueryPostTags method is correctly implemented.The method properly sets up the graph traversal for the "post_tags" edge, following ent's conventions for edge queries.
1052-1058
: LGTM! The eager loading implementation is correct.The code properly handles the eager loading of post tags, including initialization and assignment of the loaded relationships.
1632-1661
: LGTM! The loadPostTags method is correctly implemented.The method follows ent's patterns for loading relationships:
- Proper handling of foreign keys
- Correct error handling
- Efficient batch loading
internal/ent/post_create.go (2)
451-464
: LGTM! The post tag relationship methods are correctly implemented.Both methods follow ent's standard pattern for managing relationships:
AddPostTagIDs
for direct ID managementAddPostTags
as a convenience wrapper
894-909
: LGTM! The tag relationship handling in edge specifications is correct.The implementation properly sets up the database relationships with correct table and column specifications.
internal/ent/node_update.go (3)
21-21
: Import changes look good.The addition of the tagnode import is necessary for implementing the new tag relationship functionality.
382-396
: Methods for adding node tags are well implemented.The AddNodeTagIDs and AddNodeTags methods follow the established ent patterns for relationship management and are implemented correctly.
531-550
: Tag removal methods are properly implemented.The ClearNodeTags, RemoveNodeTagIDs, and RemoveNodeTags methods complete the CRUD operations for tag relationships and follow consistent patterns.
internal/ent/post_update.go (2)
523-536
: Post tag management implementation mirrors node tag management.The implementation maintains consistency with the node tag management patterns, which is good for maintainability and understanding of the codebase.
Also applies to: 783-802, 2072-2085
Line range hint
2558-2610
: SQL specifications match node implementation.The SQL graph specifications mirror those in node_update.go. The same batch processing optimization suggested for nodes would be beneficial here.
internal/ent/client.go (9)
43-44
: LGTM: Import statements for new tag-related packages.The imports for
tagnode
andtagpost
packages are correctly added to support the new tag functionality.
102-105
: LGTM: New client fields for tag relationships.The
TagNode
andTagPost
client fields are properly added to theClient
struct with clear documentation.
141-142
: LGTM: Client initialization for tag relationships.The initialization of
TagNode
andTagPost
clients is correctly implemented in theinit
method.
3693-3707
: LGTM: Node query method for tag relationships.The
QueryNodeTags
method is correctly implemented to query thenode_tags
edge of aNode
entity using proper SQL graph traversal.
4263-4277
: LGTM: Post query method for tag relationships.The
QueryPostTags
method is correctly implemented to query thepost_tags
edge of aPost
entity using proper SQL graph traversal.
5072-5102
: LGTM: Tag query methods for relationships.The
QueryPostTags
andQueryNodeTags
methods are correctly implemented to query the tag relationships from theTag
entity's perspective.
5129-5292
: LGTM: TagNode client implementation.The
TagNodeClient
implementation follows the standard pattern with all necessary methods for CRUD operations and relationship queries.
5294-5457
: LGTM: TagPost client implementation.The
TagPostClient
implementation follows the standard pattern with all necessary methods for CRUD operations and relationship queries.
5465-5465
: LGTM: Hook and interceptor type updates.The hooks and interceptors structs are correctly updated to include the new tag-related clients.
Also applies to: 5471-5471
internal/ent/er.html (3)
246-250
: LGTM: TagNode entity definition.The
TagNode
entity is correctly defined with all necessary fields:id
,tag_id
, andnode_id
.
251-254
: LGTM: TagPost entity definition.The
TagPost
entity is correctly defined with all necessary fields:id
,tag_id
, andpost_id
.
307-310
: LGTM: Tag relationship definitions.The relationships between tags and their associated entities are correctly defined:
- TagNode to Tag (many-to-one)
- TagNode to Node (many-to-one)
- TagPost to Tag (many-to-one)
- TagPost to Post (many-to-one)
internal/ent/post/post.go (2)
83-84
: LGTM! Constants are well-defined and documented.The new constants for post tags follow the established naming pattern and are properly documented.
Also applies to: 172-178
530-542
: LGTM! Ordering functions are consistent with the codebase.The new ordering functions
ByPostTagsCount
andByPostTags
follow the same implementation pattern as other ordering functions in the file.
// QueryNode chains the current query on the "node" edge. | ||
func (tnq *TagNodeQuery) QueryNode() *NodeQuery { | ||
query := (&NodeClient{config: tnq.config}).Query() | ||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { | ||
if err := tnq.prepareQuery(ctx); err != nil { | ||
return nil, err | ||
} | ||
selector := tnq.sqlQuery(ctx) | ||
if err := selector.Err(); err != nil { | ||
return nil, err | ||
} | ||
step := sqlgraph.NewStep( | ||
sqlgraph.From(tagnode.Table, tagnode.FieldID, selector), | ||
sqlgraph.To(node.Table, node.FieldID), | ||
sqlgraph.Edge(sqlgraph.M2O, false, tagnode.NodeTable, tagnode.NodeColumn), | ||
) | ||
fromU = sqlgraph.SetNeighbors(tnq.driver.Dialect(), step) | ||
return fromU, nil | ||
} | ||
return query | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for possible nil pointer dereference.
Similarly, in the QueryNode
method, add a nil check for tnq.sql
after tnq.prepareQuery(ctx)
to prevent potential runtime errors.
Apply this diff:
func (tnq *TagNodeQuery) QueryNode() *NodeQuery {
query := (&NodeClient{config: tnq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := tnq.prepareQuery(ctx); err != nil {
return nil, err
}
+ if tnq.sql == nil {
+ return nil, fmt.Errorf("unexpected nil selector")
+ }
selector := tnq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
Committable suggestion skipped: line range outside the PR's diff.
func (tnq *TagNodeQuery) sqlQuery(ctx context.Context) *sql.Selector { | ||
builder := sql.Dialect(tnq.driver.Dialect()) | ||
t1 := builder.Table(tagnode.Table) | ||
columns := tnq.ctx.Fields | ||
if len(columns) == 0 { | ||
columns = tagnode.Columns | ||
} | ||
selector := builder.Select(t1.Columns(columns...)...).From(t1) | ||
if tnq.sql != nil { | ||
selector = tnq.sql | ||
selector.Select(selector.Columns(columns...)...) | ||
} | ||
if tnq.ctx.Unique != nil && *tnq.ctx.Unique { | ||
selector.Distinct() | ||
} | ||
for _, m := range tnq.modifiers { | ||
m(selector) | ||
} | ||
for _, p := range tnq.predicates { | ||
p(selector) | ||
} | ||
for _, p := range tnq.order { | ||
p(selector) | ||
} | ||
if offset := tnq.ctx.Offset; offset != nil { | ||
// limit is mandatory for offset clause. We start | ||
// with default value, and override it below if needed. | ||
selector.Offset(*offset).Limit(math.MaxInt32) | ||
} | ||
if limit := tnq.ctx.Limit; limit != nil { | ||
selector.Limit(*limit) | ||
} | ||
return selector | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Ensure proper handling of default limit for offset queries.
In the sqlQuery
method, when offset is set without a limit, the default limit is set to math.MaxInt32
. This could lead to performance issues. Consider setting a reasonable default limit or requiring a limit to be set when using offset.
Apply this diff to set a reasonable default limit:
if offset := tnq.ctx.Offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
- selector.Offset(*offset).Limit(math.MaxInt32)
+ defaultLimit := 100
+ selector.Offset(*offset).Limit(defaultLimit)
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
func (tnq *TagNodeQuery) sqlQuery(ctx context.Context) *sql.Selector { | |
builder := sql.Dialect(tnq.driver.Dialect()) | |
t1 := builder.Table(tagnode.Table) | |
columns := tnq.ctx.Fields | |
if len(columns) == 0 { | |
columns = tagnode.Columns | |
} | |
selector := builder.Select(t1.Columns(columns...)...).From(t1) | |
if tnq.sql != nil { | |
selector = tnq.sql | |
selector.Select(selector.Columns(columns...)...) | |
} | |
if tnq.ctx.Unique != nil && *tnq.ctx.Unique { | |
selector.Distinct() | |
} | |
for _, m := range tnq.modifiers { | |
m(selector) | |
} | |
for _, p := range tnq.predicates { | |
p(selector) | |
} | |
for _, p := range tnq.order { | |
p(selector) | |
} | |
if offset := tnq.ctx.Offset; offset != nil { | |
// limit is mandatory for offset clause. We start | |
// with default value, and override it below if needed. | |
selector.Offset(*offset).Limit(math.MaxInt32) | |
} | |
if limit := tnq.ctx.Limit; limit != nil { | |
selector.Limit(*limit) | |
} | |
return selector | |
} | |
func (tnq *TagNodeQuery) sqlQuery(ctx context.Context) *sql.Selector { | |
builder := sql.Dialect(tnq.driver.Dialect()) | |
t1 := builder.Table(tagnode.Table) | |
columns := tnq.ctx.Fields | |
if len(columns) == 0 { | |
columns = tagnode.Columns | |
} | |
selector := builder.Select(t1.Columns(columns...)...).From(t1) | |
if tnq.sql != nil { | |
selector = tnq.sql | |
selector.Select(selector.Columns(columns...)...) | |
} | |
if tnq.ctx.Unique != nil && *tnq.ctx.Unique { | |
selector.Distinct() | |
} | |
for _, m := range tnq.modifiers { | |
m(selector) | |
} | |
for _, p := range tnq.predicates { | |
p(selector) | |
} | |
for _, p := range tnq.order { | |
p(selector) | |
} | |
if offset := tnq.ctx.Offset; offset != nil { | |
// limit is mandatory for offset clause. We start | |
// with default value, and override it below if needed. | |
defaultLimit := 100 | |
selector.Offset(*offset).Limit(defaultLimit) | |
} | |
if limit := tnq.ctx.Limit; limit != nil { | |
selector.Limit(*limit) | |
} | |
return selector | |
} |
// QueryTag chains the current query on the "tag" edge. | ||
func (tnq *TagNodeQuery) QueryTag() *TagQuery { | ||
query := (&TagClient{config: tnq.config}).Query() | ||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { | ||
if err := tnq.prepareQuery(ctx); err != nil { | ||
return nil, err | ||
} | ||
selector := tnq.sqlQuery(ctx) | ||
if err := selector.Err(); err != nil { | ||
return nil, err | ||
} | ||
step := sqlgraph.NewStep( | ||
sqlgraph.From(tagnode.Table, tagnode.FieldID, selector), | ||
sqlgraph.To(tag.Table, tag.FieldID), | ||
sqlgraph.Edge(sqlgraph.M2O, false, tagnode.TagTable, tagnode.TagColumn), | ||
) | ||
fromU = sqlgraph.SetNeighbors(tnq.driver.Dialect(), step) | ||
return fromU, nil | ||
} | ||
return query | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for possible nil pointer dereference.
In the QueryTag
method, after calling tnq.prepareQuery(ctx)
, it's good practice to check if tnq.sql
is not nil before proceeding, to avoid potential nil pointer dereferences.
Apply this diff to add the nil check:
func (tnq *TagNodeQuery) QueryTag() *TagQuery {
query := (&TagClient{config: tnq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := tnq.prepareQuery(ctx); err != nil {
return nil, err
}
+ if tnq.sql == nil {
+ return nil, fmt.Errorf("unexpected nil selector")
+ }
selector := tnq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
Committable suggestion skipped: line range outside the PR's diff.
if tu.mutation.PostTagsCleared() { | ||
edge := &sqlgraph.EdgeSpec{ | ||
Rel: sqlgraph.O2M, | ||
Inverse: true, | ||
Table: tag.PostTagsTable, | ||
Columns: []string{tag.PostTagsColumn}, | ||
Bidi: false, | ||
Target: &sqlgraph.EdgeTarget{ | ||
IDSpec: sqlgraph.NewFieldSpec(tagpost.FieldID, field.TypeString), | ||
}, | ||
} | ||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge) | ||
} | ||
if nodes := tu.mutation.RemovedPostTagsIDs(); len(nodes) > 0 && !tu.mutation.PostTagsCleared() { | ||
edge := &sqlgraph.EdgeSpec{ | ||
Rel: sqlgraph.O2M, | ||
Inverse: true, | ||
Table: tag.PostTagsTable, | ||
Columns: []string{tag.PostTagsColumn}, | ||
Bidi: false, | ||
Target: &sqlgraph.EdgeTarget{ | ||
IDSpec: sqlgraph.NewFieldSpec(tagpost.FieldID, field.TypeString), | ||
}, | ||
} | ||
for _, k := range nodes { | ||
edge.Target.Nodes = append(edge.Target.Nodes, k) | ||
} | ||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge) | ||
} | ||
if nodes := tu.mutation.PostTagsIDs(); len(nodes) > 0 { | ||
edge := &sqlgraph.EdgeSpec{ | ||
Rel: sqlgraph.O2M, | ||
Inverse: true, | ||
Table: tag.PostTagsTable, | ||
Columns: []string{tag.PostTagsColumn}, | ||
Bidi: false, | ||
Target: &sqlgraph.EdgeTarget{ | ||
IDSpec: sqlgraph.NewFieldSpec(tagpost.FieldID, field.TypeString), | ||
}, | ||
} | ||
for _, k := range nodes { | ||
edge.Target.Nodes = append(edge.Target.Nodes, k) | ||
} | ||
_spec.Edges.Add = append(_spec.Edges.Add, edge) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure correct relationship direction in edge specifications.
In the sqlSave
method, for the "post_tags" edge, the Inverse
field is set to true
, which may not accurately represent the relationship direction. Verify that the edge specification correctly models the intended relationship between Tag
and TagPost
.
Apply this diff if the edge direction is incorrect:
edge := &sqlgraph.EdgeSpec{
- Rel: sqlgraph.O2M,
- Inverse: true,
+ Rel: sqlgraph.O2M,
+ Inverse: false,
Committable suggestion skipped: line range outside the PR's diff.
const ( | ||
// Label holds the string label denoting the tagpost type in the database. | ||
Label = "tag_post" | ||
// FieldID holds the string denoting the id field in the database. | ||
FieldID = "id" | ||
// FieldTagID holds the string denoting the tag_id field in the database. | ||
FieldTagID = "tag_id" | ||
// FieldPostID holds the string denoting the post_id field in the database. | ||
FieldPostID = "post_id" | ||
// EdgeTag holds the string denoting the tag edge name in mutations. | ||
EdgeTag = "tag" | ||
// EdgePost holds the string denoting the post edge name in mutations. | ||
EdgePost = "post" | ||
// Table holds the table name of the tagpost in the database. | ||
Table = "tag_posts" | ||
// TagTable is the table that holds the tag relation/edge. | ||
TagTable = "tag_posts" | ||
// TagInverseTable is the table name for the Tag entity. | ||
// It exists in this package in order to avoid circular dependency with the "tag" package. | ||
TagInverseTable = "tags" | ||
// TagColumn is the table column denoting the tag relation/edge. | ||
TagColumn = "tag_id" | ||
// PostTable is the table that holds the post relation/edge. | ||
PostTable = "tag_posts" | ||
// PostInverseTable is the table name for the Post entity. | ||
// It exists in this package in order to avoid circular dependency with the "post" package. | ||
PostInverseTable = "posts" | ||
// PostColumn is the table column denoting the post relation/edge. | ||
PostColumn = "post_id" | ||
) | ||
|
||
// Columns holds all SQL columns for tagpost fields. | ||
var Columns = []string{ | ||
FieldID, | ||
FieldTagID, | ||
FieldPostID, | ||
} | ||
|
||
// ValidColumn reports if the column name is valid (part of the table columns). | ||
func ValidColumn(column string) bool { | ||
for i := range Columns { | ||
if column == Columns[i] { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
var ( | ||
// DefaultID holds the default value on creation for the "id" field. | ||
DefaultID func() xid.ID | ||
// IDValidator is a validator for the "id" field. It is called by the builders before save. | ||
IDValidator func(string) error | ||
) | ||
|
||
// OrderOption defines the ordering options for the TagPost queries. | ||
type OrderOption func(*sql.Selector) | ||
|
||
// ByID orders the results by the id field. | ||
func ByID(opts ...sql.OrderTermOption) OrderOption { | ||
return sql.OrderByField(FieldID, opts...).ToFunc() | ||
} | ||
|
||
// ByTagID orders the results by the tag_id field. | ||
func ByTagID(opts ...sql.OrderTermOption) OrderOption { | ||
return sql.OrderByField(FieldTagID, opts...).ToFunc() | ||
} | ||
|
||
// ByPostID orders the results by the post_id field. | ||
func ByPostID(opts ...sql.OrderTermOption) OrderOption { | ||
return sql.OrderByField(FieldPostID, opts...).ToFunc() | ||
} | ||
|
||
// ByTagField orders the results by tag field. | ||
func ByTagField(field string, opts ...sql.OrderTermOption) OrderOption { | ||
return func(s *sql.Selector) { | ||
sqlgraph.OrderByNeighborTerms(s, newTagStep(), sql.OrderByField(field, opts...)) | ||
} | ||
} | ||
|
||
// ByPostField orders the results by post field. | ||
func ByPostField(field string, opts ...sql.OrderTermOption) OrderOption { | ||
return func(s *sql.Selector) { | ||
sqlgraph.OrderByNeighborTerms(s, newPostStep(), sql.OrderByField(field, opts...)) | ||
} | ||
} | ||
func newTagStep() *sqlgraph.Step { | ||
return sqlgraph.NewStep( | ||
sqlgraph.From(Table, FieldID), | ||
sqlgraph.To(TagInverseTable, FieldID), | ||
sqlgraph.Edge(sqlgraph.M2O, false, TagTable, TagColumn), | ||
) | ||
} | ||
func newPostStep() *sqlgraph.Step { | ||
return sqlgraph.NewStep( | ||
sqlgraph.From(Table, FieldID), | ||
sqlgraph.To(PostInverseTable, FieldID), | ||
sqlgraph.Edge(sqlgraph.M2O, false, PostTable, PostColumn), | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Add index for tag_id
column in TagPost schema
The schema only defines an index for post_id
, but tag_id
should also be indexed for optimal query performance. Update the Indexes()
method in internal/ent/schema/tag_post.go
:
func (TagPost) Indexes() []ent.Index {
return []ent.Index{
index.Fields("post_id"),
index.Fields("tag_id"), // Add this index
}
}
🔗 Analysis chain
Verify indexes on tag_posts table.
The PR objective mentions adding indexes to tag join-tables. While this generated code looks correct, we should verify that the appropriate indexes are defined in the schema file.
Run the following script to check the schema definition:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if indexes are defined in the schema file
# Expected: Find index definitions for tag_id and post_id columns
rg -A 10 'func \(.*TagPost\) Fields\(\)' internal/ent/schema/
Length of output: 671
Script:
#!/bin/bash
# Description: Check if Indexes() method is defined for TagPost
rg -A 5 'func \(.*TagPost\) Indexes\(\)' internal/ent/schema/tag_post.go
Length of output: 166
const ( | ||
// Label holds the string label denoting the tagnode type in the database. | ||
Label = "tag_node" | ||
// FieldID holds the string denoting the id field in the database. | ||
FieldID = "id" | ||
// FieldTagID holds the string denoting the tag_id field in the database. | ||
FieldTagID = "tag_id" | ||
// FieldNodeID holds the string denoting the node_id field in the database. | ||
FieldNodeID = "node_id" | ||
// EdgeTag holds the string denoting the tag edge name in mutations. | ||
EdgeTag = "tag" | ||
// EdgeNode holds the string denoting the node edge name in mutations. | ||
EdgeNode = "node" | ||
// Table holds the table name of the tagnode in the database. | ||
Table = "tag_nodes" | ||
// TagTable is the table that holds the tag relation/edge. | ||
TagTable = "tag_nodes" | ||
// TagInverseTable is the table name for the Tag entity. | ||
// It exists in this package in order to avoid circular dependency with the "tag" package. | ||
TagInverseTable = "tags" | ||
// TagColumn is the table column denoting the tag relation/edge. | ||
TagColumn = "tag_id" | ||
// NodeTable is the table that holds the node relation/edge. | ||
NodeTable = "tag_nodes" | ||
// NodeInverseTable is the table name for the Node entity. | ||
// It exists in this package in order to avoid circular dependency with the "node" package. | ||
NodeInverseTable = "nodes" | ||
// NodeColumn is the table column denoting the node relation/edge. | ||
NodeColumn = "node_id" | ||
) | ||
|
||
// Columns holds all SQL columns for tagnode fields. | ||
var Columns = []string{ | ||
FieldID, | ||
FieldTagID, | ||
FieldNodeID, | ||
} | ||
|
||
// ValidColumn reports if the column name is valid (part of the table columns). | ||
func ValidColumn(column string) bool { | ||
for i := range Columns { | ||
if column == Columns[i] { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
var ( | ||
// DefaultID holds the default value on creation for the "id" field. | ||
DefaultID func() xid.ID | ||
// IDValidator is a validator for the "id" field. It is called by the builders before save. | ||
IDValidator func(string) error | ||
) | ||
|
||
// OrderOption defines the ordering options for the TagNode queries. | ||
type OrderOption func(*sql.Selector) | ||
|
||
// ByID orders the results by the id field. | ||
func ByID(opts ...sql.OrderTermOption) OrderOption { | ||
return sql.OrderByField(FieldID, opts...).ToFunc() | ||
} | ||
|
||
// ByTagID orders the results by the tag_id field. | ||
func ByTagID(opts ...sql.OrderTermOption) OrderOption { | ||
return sql.OrderByField(FieldTagID, opts...).ToFunc() | ||
} | ||
|
||
// ByNodeID orders the results by the node_id field. | ||
func ByNodeID(opts ...sql.OrderTermOption) OrderOption { | ||
return sql.OrderByField(FieldNodeID, opts...).ToFunc() | ||
} | ||
|
||
// ByTagField orders the results by tag field. | ||
func ByTagField(field string, opts ...sql.OrderTermOption) OrderOption { | ||
return func(s *sql.Selector) { | ||
sqlgraph.OrderByNeighborTerms(s, newTagStep(), sql.OrderByField(field, opts...)) | ||
} | ||
} | ||
|
||
// ByNodeField orders the results by node field. | ||
func ByNodeField(field string, opts ...sql.OrderTermOption) OrderOption { | ||
return func(s *sql.Selector) { | ||
sqlgraph.OrderByNeighborTerms(s, newNodeStep(), sql.OrderByField(field, opts...)) | ||
} | ||
} | ||
func newTagStep() *sqlgraph.Step { | ||
return sqlgraph.NewStep( | ||
sqlgraph.From(Table, FieldID), | ||
sqlgraph.To(TagInverseTable, FieldID), | ||
sqlgraph.Edge(sqlgraph.M2O, false, TagTable, TagColumn), | ||
) | ||
} | ||
func newNodeStep() *sqlgraph.Step { | ||
return sqlgraph.NewStep( | ||
sqlgraph.From(Table, FieldID), | ||
sqlgraph.To(NodeInverseTable, FieldID), | ||
sqlgraph.Edge(sqlgraph.M2O, false, NodeTable, NodeColumn), | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Add missing index on tag_id column
The tag_nodes table currently only has an index on node_id. Since this is a join table, it should have indexes on both foreign key columns to ensure efficient querying from both the tags and nodes side.
- Add index on
tag_id
column ininternal/ent/schema/tag_node.go
🔗 Analysis chain
Verify indexes on tag_nodes table.
Similar to the tag_posts table, we should verify that appropriate indexes are defined for the tag_nodes join table in the schema file.
Run the following script to check the schema definition:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if indexes are defined in the schema file
# Expected: Find index definitions for tag_id and node_id columns
rg -A 10 'func \(.*TagNode\) Fields\(\)' internal/ent/schema/
Length of output: 671
Script:
#!/bin/bash
# Search for Indexes() method and unique constraints in tag_node schema
rg -A 10 'func \(.*TagNode\) (Indexes|Annotations)\(\)' internal/ent/schema/tag_node.go
# Also check for any unique constraints in the schema
ast-grep --pattern 'field.$_("$_").$$$Unique()' internal/ent/schema/tag_node.go
Length of output: 263
// PostIDContains applies the Contains predicate on the "post_id" field. | ||
func PostIDContains(v xid.ID) predicate.TagPost { | ||
vc := v.String() | ||
return predicate.TagPost(sql.FieldContains(FieldPostID, vc)) | ||
} | ||
|
||
// PostIDHasPrefix applies the HasPrefix predicate on the "post_id" field. | ||
func PostIDHasPrefix(v xid.ID) predicate.TagPost { | ||
vc := v.String() | ||
return predicate.TagPost(sql.FieldHasPrefix(FieldPostID, vc)) | ||
} | ||
|
||
// PostIDHasSuffix applies the HasSuffix predicate on the "post_id" field. | ||
func PostIDHasSuffix(v xid.ID) predicate.TagPost { | ||
vc := v.String() | ||
return predicate.TagPost(sql.FieldHasSuffix(FieldPostID, vc)) | ||
} | ||
|
||
// PostIDEqualFold applies the EqualFold predicate on the "post_id" field. | ||
func PostIDEqualFold(v xid.ID) predicate.TagPost { | ||
vc := v.String() | ||
return predicate.TagPost(sql.FieldEqualFold(FieldPostID, vc)) | ||
} | ||
|
||
// PostIDContainsFold applies the ContainsFold predicate on the "post_id" field. | ||
func PostIDContainsFold(v xid.ID) predicate.TagPost { | ||
vc := v.String() | ||
return predicate.TagPost(sql.FieldContainsFold(FieldPostID, vc)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Remove unused string operation predicates on ID fields
These string-based predicates (Contains, HasPrefix, HasSuffix, EqualFold, ContainsFold) on post_id
fields are:
- Unused in the codebase
- Not practically useful for ID fields which should use exact matching
- Potentially problematic as they could lead to incorrect matches
🔗 Analysis chain
Consider the necessity of string operations on ID fields.
Similar to the tag_id field, the implementation includes string-based operations on post_id
field which is an xid.ID
. These operations might not be practically useful for ID fields.
Run this script to check if these operations are used in the codebase:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for usage of string operations on post_id
# Test: Search for any calls to these functions. Expect: No matches if unused.
rg "PostIDContains|PostIDHasPrefix|PostIDHasSuffix|PostIDEqualFold|PostIDContainsFold"
Length of output: 6925
Script:
#!/bin/bash
# Search for actual usage of these predicates in function calls
rg "\.(PostIDContains|PostIDHasPrefix|PostIDHasSuffix|PostIDEqualFold|PostIDContainsFold)\(" --type go
Length of output: 104
func newPostTagsStep() *sqlgraph.Step { | ||
return sqlgraph.NewStep( | ||
sqlgraph.From(Table, FieldID), | ||
sqlgraph.To(PostTagsInverseTable, FieldID), | ||
sqlgraph.Edge(sqlgraph.O2M, true, PostTagsTable, PostTagsColumn), | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
The relationship type is incorrectly defined as one-to-many
The newPostTagsStep
function incorrectly defines a one-to-many (O2M) relationship, but the database schema clearly shows this is a many-to-many relationship:
- The
tag_posts
table is a junction table withtag_id
andpost_id
foreign keys - Both foreign keys have CASCADE delete behavior
- The table structure enables multiple posts to be associated with multiple tags
The relationship type should be changed from O2M
to M2M
in the sqlgraph.Edge
call.
🔗 Analysis chain
Verify the relationship type between posts and tags.
The newPostTagsStep
function defines a one-to-many (O2M) relationship from posts to post tags with true
for back reference. However, the table structure (tag_posts
) suggests this might be a many-to-many relationship. Please verify if this is the intended relationship type.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check the schema definition and other references to verify the relationship type
# Look for schema definitions containing tag_posts table
ast-grep --pattern 'Table($_, "tag_posts")'
# Look for other references to tag_posts table
rg -A 5 'tag_posts'
Length of output: 5669
No description provided.