Skip to content

feat(mapper): add case-insensitive per-map override#336

Open
moxplod wants to merge 4 commits into
alirezanet:masterfrom
moxplod:map-override-caseinsensitivity
Open

feat(mapper): add case-insensitive per-map override#336
moxplod wants to merge 4 commits into
alirezanet:masterfrom
moxplod:map-override-caseinsensitivity

Conversation

@moxplod

@moxplod moxplod commented May 5, 2026

Copy link
Copy Markdown
Contributor

Description

I am working with some large tables with a lot of columns, I have had to specifically decide which columns a user should be allowed to query in a case-insensitive manner. We do not want the user to have to enter /i in the queries.

Some columns in our case are needed to be Case-Sensitive for performance reasons. Exact strings matching is much faster in postgres and in clickhouse with large data. Than case-insensitive matching.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist

  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or that my feature works
  • I have made corresponding changes to the documentation
  • I have commented my code, particularly in hard-to-understand areas
  • New and existing unit tests pass locally with my changes

@what-the-diff

what-the-diff Bot commented May 5, 2026

Copy link
Copy Markdown

PR Summary

  • Introduction of Sensitivity Choice Parameter
    The flexibility of handling case sensitivity per map has been improved, by introducing an optional caseInsensitive parameter in the AddMap method across multiple data files.

  • Mapping Logic Enhancement
    The algorithms in files like BaseQueryBuilder.cs, LinqQueryBuilder.cs, and other associated methods have been evolved to use the new caseInsensitive choice when developing queries.

  • Documentation Improvement
    To ensure everyone understands how to utilize the new caseInsensitive parameter, our instruction manual gridifyMapper.md has been expanded with detailed explanations and practical examples.

  • Inclusion of Validation Measures
    To confirm the correct functionality of case sensitivity choice for each map, we added CaseInsensitivePerMapTests.cs, a new testing documentation file that shows different test scenarios for this feature.

  • Property Adjustments in Classes
    Two class definitions, GMap and CompositeGMap, were adjusted to add a CaseInsensitive property. This addition allows for the storage and retrieval of the case sensitivity option set for individual maps.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a per-map override to control case-insensitive filtering behavior, allowing specific mapped fields to opt in/out independently of the global CaseInsensitiveFiltering configuration.

Changes:

  • Extends mapping metadata (IGMap) to carry an optional per-map CaseInsensitive override.
  • Threads the per-map override into query building so string filtering can be forced case-sensitive/insensitive per mapping.
  • Adds documentation and a dedicated test suite covering per-map override behavior for string and List<string> mappings.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test/Gridify.Tests/IssueTests/CaseInsensitivePerMapTests.cs Adds tests validating per-map case sensitivity overrides for string and list-of-string mappings.
src/Gridify/IGridifyMapper.cs Adds optional caseInsensitive parameter to selected AddMap overloads.
src/Gridify/IGMap.cs Adds CaseInsensitive property to maps to support per-map override behavior.
src/Gridify/GridifyMapper.cs Persists the per-map CaseInsensitive override when creating GMap instances via AddMap.
src/Gridify/GMap.cs Stores per-map CaseInsensitive override on concrete map implementation.
src/Gridify/CompositeGMap.cs Stores per-map CaseInsensitive override on composite map implementation.
src/Gridify/Builder/LinqQueryBuilder.cs Passes per-map override into nested-expression query building.
src/Gridify/Builder/BaseQueryBuilder.cs Incorporates per-map override when determining case-insensitive handling for string filtering.
docs/pages/guide/gridifyMapper.md Documents the new caseInsensitive per-map override and provides usage example.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Gridify/Builder/BaseQueryBuilder.cs
Comment thread src/Gridify/Builder/LinqQueryBuilder.cs
Comment thread src/Gridify/IGMap.cs
Comment thread src/Gridify/IGridifyMapper.cs
Comment thread test/Gridify.Tests/IssueTests/CaseInsensitivePerMapTests.cs Outdated
@alirezanet

Copy link
Copy Markdown
Owner

Hi @moxplod, thanks for the PR, I'll review it soon, meanwhile if you have time, please check the Copilot comments and let me know if you think they are irrelevant (happens a lot :))

@moxplod

moxplod commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

@alirezanet yea - i went through and added my responses to the copilot comments. Let me know if you agree with my comments. If you are on the same page, I will make all the changes at once. Thanks!

@alirezanet

This comment was marked as outdated.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@moxplod

moxplod commented May 7, 2026

Copy link
Copy Markdown
Contributor Author

@alirezanet Updated all the changes requested. Please take a look.

@alirezanet alirezanet added this to the V3 milestone May 11, 2026

@alirezanet alirezanet left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Hi @moxplod, thanks again for the PR! I spent some time reviewing this and I like the feature but because this touches the public mapper interfaces/API, I’m planning to target it for v3, so I’m not worried about the breaking interface/signature changes here.

I also thought more about your point around /i having the highest precedence. I agree that it makes sense if we treat /i as the client’s explicit intent and mapper/global settings as defaults.

However, I think for this feature we also need a way for the API/mapper author to enforce case behavior for specific maps. The original use case mentions columns that should stay case-sensitive for performance reasons. If /i always wins, then caseInsensitive: false is not really an override; it is a default that clients can bypass.

Since this is going into v3, I think we may want to model this more explicitly with an enum instead of bool?, and use the same concept for global config, mapper config, and map config:

public enum GridifyCaseSensitivity
{
   Default,
   CaseSensitive,
   CaseInsensitive
}

The meaning would be:

  • Default = do not force behavior; allow lower-priority settings or query-level /i to decide
  • CaseSensitive = force case-sensitive
  • CaseInsensitive = force case-insensitive

Then resolution could be:

  1. Map setting
  2. Mapper setting
  3. Global setting
  4. Query-level /i
  5. Built-in default case-sensitive behavior

This way, users who want to respect /i can leave the setting as Default, while users who need server-side enforcement can choose CaseSensitive or CaseInsensitive.


I also found a few things I think we should address before merging:

  1. Preserve the setting when composing nested mappers

In AddNestedMapperInternal, the nested map setting is currently not carried over:

AddMap(compositeKey, composedExpression, nestedMap.Convertor, overrideIfExists);

So a nested map configured as case-sensitive could lose that behavior when composed into the parent mapper. I think we should pass the nested map’s case-sensitivity value through here. Composite nested maps may need the same treatment.

  1. Make the API support consistent

Since this is v3, I think the feature should either be supported consistently across map creation paths or the limitations should be documented. For example:

  • indexed/keyed AddMap overloads
  • AddCompositeMap
  • possibly IQueryBuilder.AddMap, if that should mirror mapper behavior
  1. Add a few more tests

Suggested coverage:

  • map-level CaseSensitive beats query-level /i
  • map-level setting beats mapper/global setting
  • nested mapper preserves case-sensitive/case-insensitive settings
  • composite map behavior
  • indexed/keyed map behavior if supported

Overall, I like the direction but feel like it still need a bit more refining... please let me know what do you think

@moxplod

moxplod commented May 13, 2026

Copy link
Copy Markdown
Contributor Author

Hey @alirezanet

I personally prefer having the bool? over the enum. IMO its pretty clear the 3 states are: true, false, null. Null defaults to don't override. But, I can see that this one might be a matter of preference, so I am open to either.

Regarding the nested mapper - I have not used that feature, so I was not aware of testing that out. But it makes sense to follow the same pattern with that. I can look for the tests that cover that and add this feature there. Also what about CompositeMap (see comment below)?

Regarding the more tests - Happy to add them!

Regarding Make the API support consistent - This one might be a bit tricky. I can see wanting to add this to CompositeMap as well. The CompositeMap interface would need to change to support this and will be a breaking change as it takes multiple expressions and we could have case-sensitive per expression.

@alirezanet

alirezanet commented May 16, 2026

Copy link
Copy Markdown
Owner

Hi @moxplod,

I personally prefer having the bool? over the enum. IMO its pretty clear the 3 states are: true, false, null. Null defaults to don't override. But, I can see that this one might be a matter of preference, so I am open to either.

actually I also prefer bool?, but I couldn't find a way to provide an enforcing path for users if they want to lock the case-sensitivity for a field. That's why I suggested it. I think the current design is getting so complicated that even I sometimes struggle to understand it well. honestly I'm not sure still what is the best design yet, I already shared my ideas but I'll leave it to you for now, hope you can come up with a better design.

Regarding Make the API support consistent - This one might be a bit tricky. I can see wanting to add this to CompositeMap as well. The CompositeMap interface would need to change to support this and will be a breaking change as it takes multiple expressions and we could have case-sensitive per expression.

I was thinking to adding another overload, instead of the optional parameter, could easily solve it, but yeah, I'm not sure. Regarding the multiple expressions in a CompositeMap, I don't think we should worry about it too much. I consider the whole CompositeMap a single map in the Gridify API, so, if a user defines a composite map instead of a regular map, they can only provide a single case-sensitivity config for it (which we can internally reuse per map).

@moxplod

moxplod commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Hey @alirezanet - got busy with work and just getting back to this. I agree that the current design is quite convoluted and hard to track and maintain.

When are you thinking of doing v3?

I would like to get this merged into v2 or v3 as you prefer as I am currently using my updated version from a local build.

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.

3 participants