-
Notifications
You must be signed in to change notification settings - Fork 934
Add locate support for SQLite #2392
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
Changes from all commits
ae30a07
519835d
8ac1850
8806c61
e591737
6f20f87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Data; | ||
using System.Data.Common; | ||
using System.Linq; | ||
using System.Text; | ||
using NHibernate.Dialect.Function; | ||
using NHibernate.Engine; | ||
using NHibernate.SqlCommand; | ||
using NHibernate.Type; | ||
using NHibernate.Util; | ||
|
||
namespace NHibernate.Dialect | ||
|
@@ -109,6 +113,7 @@ protected virtual void RegisterFunctions() | |
RegisterFunction("trim", new AnsiTrimEmulationFunction()); | ||
RegisterFunction("replace", new StandardSafeSQLFunction("replace", NHibernateUtil.String, 3)); | ||
RegisterFunction("chr", new StandardSQLFunction("char", NHibernateUtil.Character)); | ||
RegisterFunction("locate", new LocateFunction()); | ||
|
||
RegisterFunction("mod", new ModulusFunctionTemplate(false)); | ||
|
||
|
@@ -513,5 +518,72 @@ protected override bool CastingIsRequired(string sqlType) | |
return true; | ||
} | ||
} | ||
|
||
[Serializable] | ||
private class LocateFunction : ISQLFunction, ISQLFunctionExtended | ||
{ | ||
// Since v5.3 | ||
[Obsolete("Use GetReturnType method instead.")] | ||
public IType ReturnType(IType columnType, IMapping mapping) | ||
{ | ||
return NHibernateUtil.Int32; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public IType GetReturnType(IEnumerable<IType> argumentTypes, IMapping mapping, bool throwOnError) | ||
{ | ||
#pragma warning disable 618 | ||
return ReturnType(argumentTypes.FirstOrDefault(), mapping); | ||
#pragma warning restore 618 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit continuing: this pattern is used for existing externally visible types, with an overridable obsolete member. In this case, an external derived class overriding the obsolete member would be broken without that pattern. |
||
} | ||
|
||
/// <inheritdoc /> | ||
public IType GetEffectiveReturnType(IEnumerable<IType> argumentTypes, IMapping mapping, bool throwOnError) | ||
{ | ||
return GetReturnType(argumentTypes, mapping, throwOnError); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public string Name => "instr"; | ||
|
||
public bool HasArguments => true; | ||
|
||
public bool HasParenthesesIfNoArguments => true; | ||
|
||
public SqlString Render(IList args, ISessionFactoryImplementor factory) | ||
{ | ||
if (args.Count != 2 && args.Count != 3) | ||
{ | ||
throw new QueryException("'locate' function takes 2 or 3 arguments. Provided count: " + args.Count); | ||
} | ||
|
||
if (args.Count == 2) | ||
{ | ||
return new SqlString("instr(", args[1], ", ", args[0], ")"); | ||
} | ||
|
||
var text = args[1]; | ||
var value = args[0]; | ||
var startIndex = args[2]; | ||
//ifnull( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Other nit: I tend to favor the use of functions which are in the SQL Standard, which is the case of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a dialect specific function implementation, so using non-standard function should be fine here. |
||
// nullif( | ||
// instr(substr(text, startIndex), value) | ||
// , 0) | ||
// + startIndex -1 | ||
//, 0) | ||
return | ||
new SqlString( | ||
"ifnull(nullif(instr(substr(", | ||
text, | ||
", ", | ||
startIndex, | ||
"), ", | ||
value, | ||
"), 0) + ", | ||
startIndex, | ||
" -1, 0)" | ||
); | ||
} | ||
} | ||
} | ||
} |
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.
Nit (not required to change): it seems better to me to explicitly implement obsolete interface members. So when the member is dropped from the interface, its implementation cannot be forgotten. And it would also hide the obsolete member when manipulating a reference typed as the class.
Uh oh!
There was an error while loading. Please reload this page.
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.
Ok. Noted for future... But I just copy/pasted it from some other
LocateFunction
for other dialect.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.
Which was likely already released, and so had to avoid breaking changes. This one is not released, so the nit.