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

Add an actual test and switch to datetime2 #2

Merged
merged 3 commits into from
Oct 18, 2024
Merged

Add an actual test and switch to datetime2 #2

merged 3 commits into from
Oct 18, 2024

Conversation

jeme
Copy link
Contributor

@jeme jeme commented Oct 18, 2024

Summary by CodeRabbit

  • New Features

    • Added a new asynchronous test method for record insertion.
    • Introduced a new interface and classes for managing SQL Server schema states.
    • Added a static method for simplifying the locking mechanism.
  • Bug Fixes

    • Enhanced precision of date and time columns in SQL scripts.
  • Refactor

    • Removed outdated schema management interfaces and classes.
  • Chores

    • Updated project dependencies to include the System.Linq.Async package.

Copy link

coderabbitai bot commented Oct 18, 2024

Walkthrough

The changes in this pull request include the addition of a new package reference in the project file, the introduction of a new test method, the removal of an internal class, and the creation of new classes and an interface for managing SQL Server schema states. Additionally, modifications were made to SQL scripts to enhance data type precision for certain columns. The instantiation logic in a factory class was also updated, while several existing classes and interfaces related to schema management were removed.

Changes

File Path Change Summary
src/DotJEM.Json.Storage2.Test/DotJEM.Json.Storage2.Test.csproj Added package reference: System.Linq.Async version 6.0.1.
src/DotJEM.Json.Storage2.Test/SqlServerStorageAreaFactoryTest.cs Added method: InsertAsync_Record_ShouldAddToTable(). Whitespace changes in existing methods.
src/DotJEM.Json.Storage2/IsExternalInit.cs Removed class: internal static class IsExternalInit.
src/DotJEM.Json.Storage2/SqlServer/Initialization/ISqlServerSchemaStateManager.cs
src/DotJEM.Json.Storage2/SqlServer/Initialization/Temp.cs
Added interface: ISqlServerSchemaStateManager and classes: SqlServerSchemaStateManager, SqlServerAreaStateManager. Added method: ObtainLockAsync. Removed previous interface and implementations.
src/DotJEM.Json.Storage2/SqlServer/SqlServerStorageAreaFactory.cs Updated Create method to use schema.Schema instead of schema.SchemaName.
src/DotJEM.Json.Storage2/SqlServer/Statements/CreateDataTable.sql
src/DotJEM.Json.Storage2/SqlServer/Statements/CreateLogTable.sql
src/DotJEM.Json.Storage2/SqlServer/Statements/CreateSchemasTable.sql
Changed column types from datetime to datetime2 for Created, Updated, and Time. Commented out default constraint for Updated.

Poem

In the garden where data grows,
A new method blooms, as the schema flows.
With types refined, and tests anew,
We hop along, with joy in view.
So let’s celebrate, with a cheer and a dance,
For changes made, give us a chance! 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 9504170 and 905fa89.

📒 Files selected for processing (1)
  • src/DotJEM.Json.Storage2/SqlServer/Initialization/ISqlServerSchemaStateManager.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/DotJEM.Json.Storage2/SqlServer/Initialization/ISqlServerSchemaStateManager.cs

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>, please review it.
    • Generate unit testing code 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 testing code 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • 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/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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.

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (6)
src/DotJEM.Json.Storage2.Test/SqlServerStorageAreaFactoryTest.cs (2)

15-17: Consider removing extra whitespace for consistency.

The added empty lines don't affect the test's functionality, but they might be inconsistent with the coding style used in the rest of the file. Consider removing these lines to maintain a consistent formatting style throughout the codebase.


60-70: LGTM: Well-structured test method. Consider adding cleanup.

The new test method InsertAsync_Record_ShouldAddToTable is well-structured and follows the Arrange-Act-Assert pattern. It effectively tests both the insertion and retrieval functionality of the storage area, including an important check on the UpdatedBy property.

Consider adding a cleanup step at the end of the test to remove the inserted record. This would prevent test data accumulation and ensure a clean state for subsequent test runs. You could add something like:

[TearDown]
public async Task Cleanup()
{
    // Code to remove test data
}

Or, if you prefer cleanup within the test method:

finally
{
    // Code to remove the inserted record
}
src/DotJEM.Json.Storage2/SqlServer/Initialization/Temp.cs (4)

Line range hint 23-24: Replace generic Exception with a more specific exception

Using a generic Exception makes error handling less precise and can obscure the root cause of the problem. Instead, throw a more specific exception, such as InvalidOperationException or a custom exception, to provide clearer context.

Apply this diff to improve exception handling:

 await connection.OpenAsync().ConfigureAwait(false);

 //TODO: Throw better exception.
-int schemaExists = (int)(await command.ExecuteScalarAsync().ConfigureAwait(false) ?? throw new Exception());
+int schemaExists = (int)(await command.ExecuteScalarAsync().ConfigureAwait(false) ?? throw new InvalidOperationException("Failed to determine if the schema exists."));

Would you like help in defining a custom exception for this scenario?


Line range hint 27-27: Address the TODO: Pass a state object to track schema creation

The TODO comment indicates the need to pass a state object to track the creation of the schema. Implementing this will enhance the ability to manage schema states and improve the modularity of your code.

Do you need assistance in creating and integrating a state object for schema tracking?


Line range hint 37-39: Handle potential absence of '.' in tableName

If tableName does not contain a . character, LastIndexOf('.') will return -1, causing Substring to throw an ArgumentOutOfRangeException. To prevent this, add a check to ensure that tableName contains a . before attempting to extract the area.

Apply this diff to handle the case where tableName lacks a .:

 HashSet<string> names = new();
 while (await reader.ReadAsync())
 {
     string tableName = reader.GetString(0);
+    int lastDotIndex = tableName.LastIndexOf('.');
+    if (lastDotIndex == -1)
+    {
+        // Handle the case where tableName does not contain a '.'
+        throw new InvalidOperationException($"Invalid table name format: {tableName}");
+    }
-    string area = tableName.Substring(0, tableName.LastIndexOf('.'));
+    string area = tableName.Substring(0, lastDotIndex);
     names.Add(area);
 }

Would you like help refining this error handling or considering alternative parsing methods?


Line range hint 11-49: Consider adding unit tests for the new Create method

Adding unit tests for the Create method will ensure that it behaves as expected under various scenarios, such as when the schema exists or does not exist, and when exceptions are thrown.

Would you like assistance in writing unit tests for this method?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between fa0bd56 and 712a434.

📒 Files selected for processing (9)
  • src/DotJEM.Json.Storage2.Test/DotJEM.Json.Storage2.Test.csproj (1 hunks)
  • src/DotJEM.Json.Storage2.Test/SqlServerStorageAreaFactoryTest.cs (3 hunks)
  • src/DotJEM.Json.Storage2/IsExternalInit.cs (0 hunks)
  • src/DotJEM.Json.Storage2/SqlServer/Initialization/ISqlServerSchemaStateManager.cs (1 hunks)
  • src/DotJEM.Json.Storage2/SqlServer/Initialization/Temp.cs (1 hunks)
  • src/DotJEM.Json.Storage2/SqlServer/SqlServerStorageAreaFactory.cs (1 hunks)
  • src/DotJEM.Json.Storage2/SqlServer/Statements/CreateDataTable.sql (1 hunks)
  • src/DotJEM.Json.Storage2/SqlServer/Statements/CreateLogTable.sql (1 hunks)
  • src/DotJEM.Json.Storage2/SqlServer/Statements/CreateSchemasTable.sql (1 hunks)
💤 Files with no reviewable changes (1)
  • src/DotJEM.Json.Storage2/IsExternalInit.cs
🧰 Additional context used
🔇 Additional comments (8)
src/DotJEM.Json.Storage2/SqlServer/Statements/CreateSchemasTable.sql (1)

5-6: Approved: Upgrade to datetime2 improves precision and range

The change from datetime to datetime2 for the Created and Updated columns is a positive improvement. datetime2 offers higher precision, a wider date range, and potentially more efficient storage.

Consider the following points:

  1. Ensure that any existing data migration scripts handle the conversion from datetime to datetime2 correctly.
  2. Update any queries or stored procedures that interact with these columns to account for the increased precision.
  3. Verify that all systems connecting to this database support datetime2 (introduced in SQL Server 2008).

To help verify the impact, you can run the following script:

This will help identify any other SQL scripts or queries that might need updating to align with this change.

✅ Verification successful

Verified: Changes to 'Created' and 'Updated' columns are correctly localized

The updates from datetime to datetime2 for the Created and Updated columns are properly confined to the intended SQL scripts. No further changes are necessary.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of Created and Updated columns in SQL files
rg --type sql -i '(created|updated).*datetime' src/

Length of output: 467

src/DotJEM.Json.Storage2/SqlServer/Statements/CreateLogTable.sql (1)

5-5: Approved: Upgrade to datetime2 improves precision and range

The change from datetime to datetime2 for the Time column is a positive improvement. datetime2 offers higher precision (100 nanoseconds vs 3.33 milliseconds) and a wider date range, which can be beneficial for accurate logging.

Consider the following to ensure a smooth transition:

  1. Review any existing queries or application code that interacts with this table to ensure compatibility with datetime2.
  2. If this change is applied to an existing table, plan for data migration.
  3. Be aware of potential slight changes in sorting behavior due to increased precision.
  4. Consider updating other tables or columns in the database for consistency if they also use datetime.

To check for other datetime usages that might benefit from this upgrade, run:

✅ Verification successful

Verified: No additional datetime usages found

The codebase has been checked for other instances of datetime in SQL files, and no usages (excluding datetime2) were found. This ensures consistency with the upgrade to datetime2.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for 'datetime' usage in SQL files
rg --type sql 'datetime(?!2)' -g '*.sql'

Length of output: 267


Script:

#!/bin/bash
# Search for 'datetime' usage in SQL files excluding 'datetime2'
rg --type sql 'datetime[^2]' -g '*.sql'

Length of output: 41

src/DotJEM.Json.Storage2.Test/DotJEM.Json.Storage2.Test.csproj (1)

13-13: LGTM! Verify usage in test methods.

The addition of the System.Linq.Async package (version 6.0.1) is appropriate for enabling asynchronous LINQ operations in your test project. This aligns with the PR objective of adding "an actual test", potentially allowing for more sophisticated asynchronous testing scenarios.

To ensure this package is being utilized effectively, please run the following script to check for its usage in test methods:

If there are no matches, consider adding examples of how this package will be used in future tests.

src/DotJEM.Json.Storage2/SqlServer/Statements/CreateDataTable.sql (2)

Line range hint 18-18: Verify impact of removing default constraint for Updated column

The default constraint for the Updated column has been commented out. This means the column will no longer be automatically set to the current date and time when a row is inserted or updated.

To ensure this change doesn't introduce issues, please verify:

  1. The application code explicitly sets the Updated column value when inserting or updating rows.
  2. There are no existing queries or procedures that rely on this default constraint.
#!/bin/bash
# Description: Check for potential issues related to the Updated column

# Test 1: Search for insert statements that might not set the Updated column
rg --type sql 'INSERT\s+INTO.*\[@{area_name}\.data\]' -g '*.sql'

# Test 2: Search for update statements that might not set the Updated column
rg --type sql 'UPDATE\s+.*\[@{area_name}\.data\]' -g '*.sql'

# Test 3: Search for any direct references to the Updated column
rg --type cs 'Updated' -g '*.cs'

# Expected result: Review the output to ensure that the Updated column is properly handled in all relevant code

If you confirm that the application correctly manages the Updated column, this change is acceptable. Otherwise, consider keeping the default constraint or updating the application logic accordingly.


5-6: Improved timestamp precision with datetime2

The change from datetime to datetime2 for the Created and Updated columns is a good improvement. datetime2 offers higher precision and a wider date range, which can be beneficial for accurate timestamp storage.

To ensure consistency across the codebase, let's verify if other tables use datetime2:

src/DotJEM.Json.Storage2/SqlServer/SqlServerStorageAreaFactory.cs (1)

48-48: LGTM. Verify interface change and update documentation if needed.

The change from schema.SchemaName to schema.Schema looks like a valid refactoring. It improves naming consistency and better represents the nature of the Schema property.

To ensure this change is consistent across the codebase:

  1. Verify that the ISqlServerSchemaStateManager interface has been updated to reflect this change.
  2. Check if any other usages of SchemaName need to be updated.

Also, please update any relevant documentation or comments to reflect this change if necessary.

✅ Verification successful

Verified: The ISqlServerSchemaStateManager interface has been updated, and there are no remaining usages of SchemaName.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the interface change and find any remaining usages of SchemaName

# Test 1: Check if ISqlServerSchemaStateManager interface has been updated
echo "Checking ISqlServerSchemaStateManager interface:"
rg --type csharp "interface ISqlServerSchemaStateManager" -A 10

# Test 2: Look for any remaining usages of SchemaName
echo "Searching for remaining usages of SchemaName:"
rg --type csharp "SchemaName"

Length of output: 1470

src/DotJEM.Json.Storage2.Test/SqlServerStorageAreaFactoryTest.cs (2)

59-59: LGTM: Improved readability with whitespace.

The added empty line before the new test method improves readability by clearly separating test methods. This is consistent with good coding practices and enhances the overall structure of the file.


Line range hint 1-71: Overall, the changes look good with room for minor improvements.

The additions to this file, particularly the new test method InsertAsync_Record_ShouldAddToTable, enhance the test coverage of the SqlServerStorageContext class. The test is well-structured and checks important functionality.

A few minor suggestions for improvement:

  1. Consider removing extra whitespace in the EnsureLogTable_NoTableExists_ShouldCreateTable method for consistency.
  2. Think about adding a cleanup step in the new test method to prevent test data accumulation.

These changes will further improve the quality and maintainability of the test suite.

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.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 712a434 and 9504170.

📒 Files selected for processing (1)
  • src/DotJEM.Json.Storage2/SqlServer/Initialization/ISqlServerSchemaStateManager.cs (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
src/DotJEM.Json.Storage2/SqlServer/Initialization/ISqlServerSchemaStateManager.cs (4)

6-11: LGTM: Interface definition is clear and concise.

The ISqlServerSchemaStateManager interface provides a clean contract for schema state management with a Schema property and an Ensure() method.


13-51: LGTM: Improved thread-safety in SqlServerSchemaStateManager.

The implementation of SqlServerSchemaStateManager looks good. The use of ObtainLockAsync() (line 33) addresses the previous concern about ensuring the semaphore is always released, even in case of exceptions. The double-checked locking pattern is correctly implemented, and the use of ConfigureAwait(false) is consistent throughout the asynchronous operations.


53-65: LGTM: Excellent SemaphoreSlim extension for safe locking.

The SemaphoreSlimExt class provides a clean and safe way to use SemaphoreSlim with a using statement. This implementation ensures that the semaphore is always released, even in case of exceptions, addressing the concerns raised in previous reviews. The use of a nested ObtainedLock class is a good pattern for implementing IDisposable.


1-123: Overall assessment: Good implementation with minor improvements needed.

The file implements SQL Server schema state management effectively. The ISqlServerSchemaStateManager interface and its implementations are well-structured. The SemaphoreSlimExt class provides a robust solution for safe locking.

The main area for improvement is in SqlServerAreaStateManager, where asynchronous patterns should be applied consistently. Once these changes are made, the file will provide a solid foundation for managing SQL Server schema states in an asynchronous and thread-safe manner.

@jeme jeme merged commit 57d7c20 into dotJEM:main Oct 18, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant