In SQLite I want to case-insensitive \"SELECT LIKE name\"
works fine for normal latin names, but when the name is in UTF-8 with non-latin characters then the se
An improved version of LIKE
overloading via a UDF:
$db->sqliteCreateFunction('like',
function ($pattern, $data, $escape = null) use ($db)
{
static $modifiers = null;
if (isset($modifiers) !== true)
{
$modifiers = ((strncmp($db->query('PRAGMA case_sensitive_like;')->fetchColumn(), '1', 1) === 0) ? '' : 'i') . 'suS';
}
if (isset($data) === true)
{
if (strpbrk($pattern = preg_quote($pattern, '~'), '%_') !== false)
{
$regex = array
(
'~%+~S' => '.*',
'~_~S' => '.',
);
if (strlen($escape = preg_quote($escape, '~')) > 0)
{
$regex = array
(
'~(? '.*',
'~(? '.',
'~(?:' . preg_quote($escape, '~') . ')([%_])~S' => '$1',
);
}
$pattern = preg_replace(array_keys($regex), $regex, $pattern);
}
return (preg_match(sprintf('~^%s$~%s', $pattern, $modifiers), $data) > 0);
}
return false;
}
);
Respects the case_sensitive_like PRAGMA and correctly handles x LIKE y ESCAPE z syntax.
I also wrote another version that does basic and extended romanization of x
and y
values, so that an accented character will match it's unaccented counterpart, for instance: SELECT 'Á' LIKE 'à%';
.
You can star the gist to keep an eye on occasional updates.