Unable to mach strings in sqlite-net query in Greek language - xamarin.forms

I want to return from sqlite database some strings based on what the user typed. The comparison must be case-insensitive. While my query works for English data, it only works for Greek when all letters are Caps. So I guess that the method ToUpper() performs differently in the query and in the code.
I've narrowed down the problem to the ToUpper() method because when I run it outside of the query to the filter string it performs great for capital letters.
var filterString = filter.Designation?.ToUpper();
var sites = from c in MemoryService.DbContext.db.Table<Site>()
where filterString == null || c.Designation.ToUpper().Contains(filterString)

I think you need to use a culture specific comparison, see this post here.
Compare strings with non-English characters?
This assumes you know what language the compared strings will be typed in.

Related

Dynamic combination search on specific path in BaseX

I want to perform dynamic combination (AND OR) search on the basis of the provided parameter by the user.
Search Combination Example:
( (title = "United States" or isbn = "2345371242192") and author ="Jhon" )
In the above query each parameter will look on their XPATH e.g. (item/tigroup/title, item/isbn), XPATH not provided by the user, i have to generate XPATH dynamically with search combination
How Combination query can be formed dynamically to pass it to the BaseX?
User can perform any kind of AND OR search, their can be multiple AND OR criteria
Any suggestions much appreciated
With xquery:eval, strings can be evaluated as XQuery expression (see the documentation for more examples):
declare variable $QUERY := 'text()';
db:open('db')//*[xquery:eval($QUERY, map { '': . })]
Please note that it’s very risky to evaluate arbitrary strings as XQuery code. If the string contains user input, malicious strings may be passed on that do unexpected things. In the example above, a malicious string could be a file operation (e.g., file:delete(.)), or a query that runs very long and blocks your system.

TRIM BOTH Teradata not working for single quotes

SELECT TRIM(BOTH 'a' FROM 'aaaaaaaaaaaaasdfasa');
works fine and returns sdfas
but I am trying to remove quotes, so I did
SELECT TRIM(BOTH ''' FROM (''2565','5216','5364'') ;
I get error - Query ends within a string or comment block. Please suggest how to do this
This answer assumes that the .NET application successfully inserts data and the issue is at the time of SELECT or UPDATE i.e. the issue is not in a prepared SQL statement used within the .NET application. This also assumes that data sanity checks for using such logic in WHERE .. IN are already in place.
Assume your data values are:
2565,5216,5364
'2565','5216','5364'
Your application coverts these into following:
'2565,5216,5364'
''2565','5216','5364''
For ease of query design for this answer, we can convert these to string values for SQL by escaping each single quote in the value with an additional single quote, and then putting the entire thing inside a pair of single quotes to make it a string; which gives us:
'''2565,5216,5364'''
'''''2565'',''5216'',''5364'''''
If you want to remove all single quotes in these, you can use
SELECT OREPLACE( '''2565,5216,5364''', '''', '');
SELECT OREPLACE( '''''2565'',''5216'',''5364''''', '''', '');
Which means replace all single quotes with empty strings and gives us:
2565,5216,5364
2565,5216,5364
This may be the way to go in case you are comparing with integer values.
Now if you want your data to be preserved and remove only the enclosing quotes put by the .NET application, (e.g. if the comparison is also with character data) then you can combine this with further logic. Let us use the second data value, since it present more value for such an operation
SELECT TRIM(BOTH '''' FROM '''''2565'',''5216'',''5364''''');
The query above will give you following results which removes the enclosing quotes from application but also removes the first and the last quotes entered by the user
2565','5216','5364
A better option, but with the assumption that you application always encloses the data in quotes will be
SELECT SUBSTR('''''2565'',''5216'',''5364''''',2,CHARACTER_LENGTH('''''2565'',''5216'',''5364''''')-2);
This will perform substring operation from second character in the string till length-2, and will thus ignore both quotes inserted by the application
'2565','5216','5364'

azure documentdb culture while sorting

I have doucuments(json) in English and in French stores in my documentdb collection.
While doing query using sort descending by title ( a property of my document), the result seem to be wrong.
Instead of beginning by Z-A , its started by special character such as 'Ö', 'é', 'Á' and then go to Z-A.
DocumentDB uses UTF-8 strings per JSON standard. So sort by strings also follows UTF-8 order, i.e. this is the expected behavior.
For a different sort order, you have to store a canonicalized version of the string, then use it for sorting. For example, for case-insensitive sort, you'd store the lower case representation of the string as a separate property. If you want accents to be ignored (é = "e"), then you'd store a mapping of the string without accents.

How to escape string for SQLite FTS query

I'm trying to perform a SQLite FTS query with untrusted user input. I do not want to give the user access to the query syntax, that is they will not be able to perform a match query like foo OR bar AND cats. If they tried to query with that string I would want to interpret it as something more like foo \OR bar \AND cats.
There doesn't seem to be anything built in to SQLite for this, so I'll probably end up building my own escaping function, but this seems dangerous and error-prone. Is there a preferred way to do this?
The FTS MATCH syntax is its own little language. For FTS5, verbatim string literals are well defined:
Within an FTS expression a string may be specified in one of two ways:
By enclosing it in double quotes ("). Within a string, any embedded double quote characters may be escaped SQL-style - by adding a second double-quote character.
(redacted special case)
It turns out that correctly escaping a string for an FTS query is simple enough to implement completely and reliably: Replace " with "" and enclose the result in " on both ends.
In my case it then works perfectly when I put it into a prepared statement such as SELECT stuff FROM fts_table WHERE fts_table MATCH ?. I would then .bind(fts_escape(user_input)) where fts_escape is the function I described above.
OK I've investigated further, and with some heavy magic you can access the actual tokenizer used by SQLite's FTS. The "simple" tokenizer takes your string, separates it on any character that is not in [A-Za-z0-0], and lowercases the remaining. If you perform this same operation you will get a nicely "escaped" string suitable for FTS.
You can write your own, but you can access SQLite's internal one as well. See this question for details on that: Automatic OR queries using SQLite FTS4

NHibernate, SQLite, and Cyrillic characters: case sensitivity and fallback queries

I'm querying an SQLite database using NHibernate. Generally, I want to do case insensitive string queries. Recently, I've discovered that although I can insert a row with Cyrillic characters, I can not select it using a case insensitive query. This is what the query looks like:
string foo = "foo";
IList<T> list = session.CreateCriteria(typeof(T)).
Add(Expression.Eq("Foo", foo).IgnoreCase()).List<T>();
I can, however, select the row using the above query if IgnoreCase() is removed. A naive fix would be to check if list.Count == 0 after the first query, and make a subsequent case sensitive query. The major downside of this approach is that querying for non-existent rows is a reasonably common operation that would now consist of two queries.
The question is, how can I construct a single query that will select from the Foo column that is case insensitive yet will also select rows that contain Cyrillic characters?
Case insensitive queries by default only work with ASCII characters in SQLite.
See this FAQ: Case-insensitive matching of Unicode characters does not work.

Resources