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

Avoid Trim().Length as empty check and ToLowerInvariant() in string comparison #1567

Merged
merged 7 commits into from
Feb 1, 2018

Conversation

bahusoid
Copy link
Member

And made another round of setting ordinal string comparison

@@ -365,8 +365,8 @@ internal static bool IsNotRoot(string qualifiedName, out string root)
/// </returns>
public static bool BooleanValue(string value)
{
string trimmed = value.Trim().ToLowerInvariant();
return trimmed.Equals("true") || trimmed.Equals("t");
string trimmed = value.Trim();
Copy link
Member

Choose a reason for hiding this comment

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

This file has an old ascii corruption, at line 162: fa�ade, for façade, which is a fault by the way, since the comment is not in french. May you please fix that to facade? This thing cause some IDE (Rider) to alter the file at each opening, which is a nuisance, but not worth a dedicated PR.

@@ -78,7 +78,7 @@ public virtual bool HasOrphanDelete

#region Static helper methods

private static readonly Dictionary<string, CascadeStyle> Styles = new Dictionary<string, CascadeStyle>();
private static readonly Dictionary<string, CascadeStyle> Styles = new Dictionary<string, CascadeStyle>(StringComparer.OrdinalIgnoreCase);
Copy link
Member

Choose a reason for hiding this comment

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

This looks to me as an undue change. Cascade styles are not case insensitive, even if currently we would not have names conflict by going insensitive.

Copy link
Member Author

Choose a reason for hiding this comment

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

Are you sure? Change is based on the following line:

styles[i++] = CascadeStyle.GetCascadeStyle(token.ToLowerInvariant().Trim());

Copy link
Member

Choose a reason for hiding this comment

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

Well, so the internal usage of this public class is case insensitive. It is then unlikely it could be a breaking change for anyone to render the class case insensitive, but not strictly impossible either.

Well, keep your change in place.

@fredericDelaporte
Copy link
Member

fredericDelaporte commented Jan 31, 2018

There are also a bunch of ToUpperInvariant in Hql.g which should be converted to case insensitive comparison.

Update:

And in LiteralProcessor: "true" == constant.Text.ToLowerInvariant().

In SchemaExport and SchemaUpdate, we have for only one test:

autoKeyWordsImport = autoKeyWordsImport.ToLowerInvariant();
if (autoKeyWordsImport == Hbm2DDLKeyWords.AutoQuote)

@bahusoid
Copy link
Member Author

bahusoid commented Jan 31, 2018

In SchemaExport and SchemaUpdate, we have for only one test:

I didn't touch this autoKeyWordsImport because it's not string with string comparison. It's string compared with object Hbm2DDLKeyWords with implicit to string conversion.

public static Dictionary<string, string> HQL_COLLECTION_PROPERTIES;

private static readonly string COLLECTION_INDEX_LOWER = CollectionPropertyNames.Index.ToLowerInvariant();
public static readonly Dictionary<string, string> HQL_COLLECTION_PROPERTIES = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Copy link
Member

@hazzik hazzik Jan 31, 2018

Choose a reason for hiding this comment

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

Usage of this collection looks like just a normal HashSet(). As the class is internal, maybe it's better to replace it.

EDIT: Ok, saw a case where we need dictionary

/// <summary>
/// Returns true if content is empty or white space characters only
/// </summary>
public bool IsEmptyOrWhitespace()
Copy link
Member

Choose a reason for hiding this comment

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

Probably better to align with a String class: make it static; add support for null; call it IsNullOrWhitespace.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure it would give any benefits (at least from dev usability point of view). I tend to check instance methods for emptiness first (and sadly static methods are not even suggested). So I would find this method quicker.

Copy link
Member Author

Choose a reason for hiding this comment

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

But let majority rule :) @fredericDelaporte Any preferences?

Copy link
Member

Choose a reason for hiding this comment

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

Looking at it again, I see a third option: put that into SqlStringHelper. It has already an IsEmpty method (which is actually an IsNullOrEmpty), so it would be more consistent.

About discoverability, this can be improved by making it an extension method.

About aligning with string class, we would then have to move IsEmpty in SqlString too for consistency (and rename it by the way, of course).

Copy link
Member Author

@bahusoid bahusoid Feb 1, 2018

Choose a reason for hiding this comment

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

Some instance method is still required as I need to obtain data from GetTrimmedIndexes.
So I think I can add extension method IsNullOrWhitespace to SqlStringHelper that will do null check + call IsEmptyOrWhitespace . Does it make any sense?

Copy link
Member Author

Choose a reason for hiding this comment

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

From what I see instance method IsEmptyOrWhitspace needs to exists. So the main question does it improve anything adding additional wrappers over it.

Copy link
Member

Choose a reason for hiding this comment

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

Leave it as is.

Copy link
Member

Choose a reason for hiding this comment

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

I am not for having an IsEmptyOrWhitespace on instance along an IsNullOrWhitespace on helper. Better make GetTrimmedIndexes internal.

Copy link
Member

Choose a reason for hiding this comment

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

Leave it as is.

Simplest option. Agreed.

@fredericDelaporte fredericDelaporte added this to the 5.1 milestone Feb 1, 2018
@fredericDelaporte fredericDelaporte merged commit f8b1bc4 into nhibernate:master Feb 1, 2018
fredericDelaporte added a commit to fredericDelaporte/nhibernate-core that referenced this pull request May 10, 2018
Comparing SQL keywords should be done with ordinal comparisons. But
invariant comparisons are kept for object names, because at least with
SQL Server these comparisons are collation sensitive. (So ideally object
names comparisons should even have their culture configurable...)

An undue current culture comparison for
SqlString.EndsWithCaseInsensitive is also fixed.

Follow-up to nhibernate#1567.
hazzik pushed a commit that referenced this pull request May 14, 2018
Comparing SQL keywords should be done with ordinal comparisons. But
invariant comparisons are kept for object names, because at least with
SQL Server these comparisons are collation sensitive. (So ideally object
names comparisons should even have their culture configurable...)

An undue current culture comparison for
SqlString.EndsWithCaseInsensitive is also fixed.

Follow-up to #1567.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants