Skip to content
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

Allow fetching the count from GetPage #9

Merged
merged 2 commits into from
Mar 20, 2024
Merged

Allow fetching the count from GetPage #9

merged 2 commits into from
Mar 20, 2024

Conversation

mstg
Copy link
Contributor

@mstg mstg commented Mar 20, 2024

This change adds an optional count argument to GetPage. To make it optional it's implemented as a variadic function but only one count pointer is accepted if set.

Summary by CodeRabbit

  • New Features
    • Introduced an optional count parameter in the GetPage method for fetching page counts alongside query results.
    • Added new message types TestRequest1 and SimpleModel1 to enhance request parameter and model data handling.
  • Refactor
    • Updated the ParsePageToken method to Decode for more accurate base64 string handling.
  • Tests
    • Implemented a new test TestGetPageCount to verify correct page count retrieval functionality.

This change adds an optional count argument to GetPage. To make it optional it's implemented as a variadic function but only one count pointer is accepted if set.
Copy link

coderabbitai bot commented Mar 20, 2024

Walkthrough

The recent update enhances the pika project with new functionalities and improvements. The GetPage method now supports an optional count parameter for better query control. The PageToken struct's method has evolved from parsing to decoding, reflecting its enhanced capability. Additionally, a new test ensures the GetPage functionality works as expected. The introduction of new message types in the test.proto file expands the project's data handling capabilities, making it more versatile.

Changes

Files Summary
pika.go, pika_psql.go Updated GetPage to include an optional count parameter. Added error handling for countPointer.
pika_page_token.go Renamed method ParsePageToken to Decode, reflecting its decoding functionality.
pika_psql_test.go Added TestGetPageCount to verify page count retrieval functionality.
parser/gen.go, pika_aip_filter.go, pika_aip_filter_proto.go, pika_aip_filter_proto_test.go, pika_aip_filter_psql_test.go, pika_psql_experimental.go, testproto/gen.go, utils.go Updated copyright year to "2023-2024" for relevant files.

🐇✨
In the realm of code, where changes abound,
A rabbit hopped in, improvements were found.
With tweaks and tests, and types anew,
The project grows, as our excitement flew.
So here's to the code, may it run swift and true,
As we celebrate changes, with a hop and a chew.
🌟📚

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?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

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 as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between fb9b56f and d128fa6.
Files ignored due to path filters (1)
  • testproto/test.pb.go is excluded by: !**/*.pb.go
Files selected for processing (5)
  • pika.go (1 hunks)
  • pika_page_token.go (1 hunks)
  • pika_psql.go (2 hunks)
  • pika_psql_test.go (2 hunks)
  • testproto/test.proto (1 hunks)
Additional comments: 5
testproto/test.proto (2)
  • 36-40: The TestRequest1 message is well-structured and follows protobuf best practices. It appropriately supports pagination and filtering functionalities.
  • 43-46: The SimpleModel1 message is appropriately designed to represent simple model data with fields for id, title, and description.
pika_page_token.go (1)
  • 60-60: While the Decode method is correctly implemented, it's important to ensure that user-provided data is validated before deserialization to prevent potential security vulnerabilities.
pika.go (1)
  • 158-160: The addition of the variadic count parameter to the GetPage method is a thoughtful way to enhance functionality while maintaining backward compatibility. It would be beneficial to clarify in the documentation the expected behavior when multiple count arguments are passed, as the current design strictly allows only one count pointer to be set.
pika_psql.go (1)
  • 542-552: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [545-589]

The implementation of the GetPage method with the optional countPointer parameter is well thought out, ensuring backward compatibility and preventing misuse by limiting the count pointer to at most one. However, there are a few areas for improvement and clarification:

  1. Error Handling and Messages: The error message "too many arguments (count should be one pointer or none)" is clear, but consider including the method name in the error message for easier debugging, e.g., "GetPage: too many arguments (count should be one pointer or none)".

  2. Performance Consideration: The method performs a count operation regardless of whether a count pointer is provided. This could lead to unnecessary performance overhead in cases where the count is not needed. Consider optimizing this by only performing the count operation if a count pointer is provided.

  3. Documentation: While the code changes are straightforward, adding documentation for the GetPage method, especially regarding the new countPointer parameter, would be beneficial for future maintainability and clarity for other developers.

func (b *basePsql[T]) GetPage(paginatable Paginatable, options AIPFilterOptions, countPointer ...*int) ([]*T, string, error) {
	if len(countPointer) > 1 {
-		return nil, "", fmt.Errorf("too many arguments (count should be one pointer or none)")
+		return nil, "", fmt.Errorf("GetPage: too many arguments (count should be one pointer or none)")
	}

+	// Perform count operation only if countPointer is provided to optimize performance
+	var count int
+	var err error
+	if len(countPointer) > 0 {
+		count, err = b.Count()
+		if err != nil {
+			return nil, "", fmt.Errorf("GetPage: getting count: %w", err)
+		}
+	}
+
	if b.err != nil {
		return nil, "", b.err
	}

	// Only decode if token is not empty
	if paginatable.GetPageToken() != "" {
		err := b.PageToken.Decode(paginatable.GetPageToken())
		if err != nil {
			return nil, "", err
		}
	} else {
		// Otherwise use initial filter
		b.PageToken.Offset = 0
		b.PageToken.Filter = paginatable.GetFilter()
		b.PageToken.OrderBy = paginatable.GetOrderBy()
		b.PageToken.PageSize = uint(paginatable.GetPageSize())
	}

	qs, err := b.pageToken(b, options)
	if err != nil {
		return nil, "", err
	}

	result, err := qs.All()
	if err != nil {
		return nil, "", err
	}

	b.PageToken.Offset += uint(len(result))

-	// Get count and check if there are more results
-	count, err := b.Count()
-	if err != nil {
-		return nil, "", fmt.Errorf("getting count: %w", err)
-	}
-
	if len(countPointer) > 0 {
		*countPointer[0] = count
	}

	// If no more results after this page, return empty page token
	if b.PageToken.Offset >= uint(count) {
		return result, "", nil
	}

	tk, err := b.PageToken.Encode()
	if err != nil {
		return nil, "", err
	}

	return result, tk, nil
}

Consider optimizing the performance by only performing the count operation if a count pointer is provided. Additionally, enhance the error message for clarity and add documentation for the GetPage method to explain the new functionality.

Comment on lines +1740 to +1756
func TestGetPageCount(t *testing.T) {
psql := newPsql(t)
createTestEntries(t, psql)
qs := Q[simpleModel1](psql)

aipOptions := ProtoReflect(&pikatestpb.SimpleModel1{})
req := &pikatestpb.TestRequest1{
PageSize: int32(1),
}
var count int
page, nt, err := qs.GetPage(req, aipOptions, &count)
require.Nil(t, err)

require.Equal(t, 1, len(page))
require.NotEmpty(t, nt)
require.Equal(t, 3, count)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test function TestGetPageCount correctly sets up a test environment, creates test entries, and calls the GetPage method with a count pointer to verify the functionality of retrieving a page count along with the page data. The assertions check for the expected length of the returned page, the presence of a next token, and the correct count of entries.

However, there are a few improvements and considerations:

  1. Error Handling: It's good practice to include error handling for the setup functions like createTestEntries. While the current test assumes these functions always succeed, explicitly checking for errors can prevent false negatives in test results if setup fails.
  2. Test Isolation: Consider using table-driven tests or subtests (t.Run()) for different scenarios, such as varying page sizes or testing boundary conditions. This enhances test readability and maintainability.
  3. Magic Numbers: The test uses magic numbers, such as the expected count of 3. It would be more maintainable to derive these values programmatically or define them as constants, especially if the setup data changes in the future.
func TestGetPageCount(t *testing.T) {
	psql := newPsql(t)
-	createTestEntries(t, psql)
+	err := createTestEntries(t, psql)
+	require.Nil(t, err, "setup: creating test entries failed")
	qs := Q[simpleModel1](psql)

	aipOptions := ProtoReflect(&pikatestpb.SimpleModel1{})
	req := &pikatestpb.TestRequest1{
		PageSize: int32(1),
	}
	var count int
	page, nt, err := qs.GetPage(req, aipOptions, &count)
	require.Nil(t, err)

	require.Equal(t, 1, len(page))
	require.NotEmpty(t, nt)
-	require.Equal(t, 3, count)
+	const expectedCount = 3 // Consider deriving this value programmatically if possible
+	require.Equal(t, expectedCount, count)
}

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.

Suggested change
func TestGetPageCount(t *testing.T) {
psql := newPsql(t)
createTestEntries(t, psql)
qs := Q[simpleModel1](psql)
aipOptions := ProtoReflect(&pikatestpb.SimpleModel1{})
req := &pikatestpb.TestRequest1{
PageSize: int32(1),
}
var count int
page, nt, err := qs.GetPage(req, aipOptions, &count)
require.Nil(t, err)
require.Equal(t, 1, len(page))
require.NotEmpty(t, nt)
require.Equal(t, 3, count)
}
func TestGetPageCount(t *testing.T) {
psql := newPsql(t)
err := createTestEntries(t, psql)
require.Nil(t, err, "setup: creating test entries failed")
qs := Q[simpleModel1](psql)
aipOptions := ProtoReflect(&pikatestpb.SimpleModel1{})
req := &pikatestpb.TestRequest1{
PageSize: int32(1),
}
var count int
page, nt, err := qs.GetPage(req, aipOptions, &count)
require.Nil(t, err)
require.Equal(t, 1, len(page))
require.NotEmpty(t, nt)
const expectedCount = 3 // Consider deriving this value programmatically if possible
require.Equal(t, expectedCount, count)
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between d128fa6 and cdd9dd1.
Files selected for processing (12)
  • parser/gen.go (1 hunks)
  • pika.go (2 hunks)
  • pika_aip_filter.go (1 hunks)
  • pika_aip_filter_proto.go (1 hunks)
  • pika_aip_filter_proto_test.go (1 hunks)
  • pika_aip_filter_psql_test.go (1 hunks)
  • pika_page_token.go (2 hunks)
  • pika_psql.go (3 hunks)
  • pika_psql_experimental.go (1 hunks)
  • pika_psql_test.go (3 hunks)
  • testproto/gen.go (1 hunks)
  • utils.go (1 hunks)
Files skipped from review due to trivial changes (8)
  • parser/gen.go
  • pika_aip_filter.go
  • pika_aip_filter_proto.go
  • pika_aip_filter_proto_test.go
  • pika_aip_filter_psql_test.go
  • pika_psql_experimental.go
  • testproto/gen.go
  • utils.go
Files skipped from review as they are similar to previous changes (4)
  • pika.go
  • pika_page_token.go
  • pika_psql.go
  • pika_psql_test.go

@mstg mstg merged commit c97a81e into ctrliq:main Mar 20, 2024
1 check passed
@mstg mstg deleted the page-count branch March 20, 2024 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants