+ now search is case-insensitive for non-latin characters in sqlite database

This commit is contained in:
maxpozdeev 2022-11-10 21:24:41 +03:00
parent 37e6f30a57
commit 40f9d33a93
6 changed files with 45 additions and 4 deletions

View file

@ -72,8 +72,10 @@ class TagsController extends ApiController {
$db = DBConnection::instance();
$begin = trim(_get('q'));
$limit = 8;
$q = $db->dq("SELECT name,id FROM {$db->prefix}tags INNER JOIN {$db->prefix}tag2task ON id=tag_id WHERE list_id=$listId AND name LIKE ".
$db->quoteForLike('%s%%',$begin) ." GROUP BY tag_id ORDER BY name LIMIT $limit");
$q = $db->dq("SELECT name,id FROM {$db->prefix}tags
INNER JOIN {$db->prefix}tag2task ON id=tag_id
WHERE list_id=$listId AND ". $db->like('name', '%s%%', $begin). "
GROUP BY tag_id ORDER BY name LIMIT $limit");
$t = array();
while ($r = $q->fetchRow()) {
$t[] = $r[0];

View file

@ -73,8 +73,12 @@ class TasksController extends ApiController {
$s = trim(_get('s'));
if ($s != '') {
if (preg_match("|^#(\d+)$|", $s, $m)) $sqlWhere .= " AND {$db->prefix}todolist.id = ". (int)$m[1];
else $sqlWhere .= " AND (title LIKE ". $db->quoteForLike("%%%s%%",$s). " OR note LIKE ". $db->quoteForLike("%%%s%%",$s). ")";
if (preg_match("|^#(\d+)$|", $s, $m)) {
$sqlWhere .= " AND {$db->prefix}todolist.id = ". (int)$m[1];
}
else {
$sqlWhere .= " AND (". $db->like("title", "%%%s%%", $s). " OR ". $db->like("note", "%%%s%%", $s). ")";
}
}
$sort = (int)_get('sort');

View file

@ -170,6 +170,12 @@ class Database_Mysql extends Database_Abstract
return '\''. sprintf($format, $string). '\'';
}
function like(string $column, string $format, string $string): string
{
$column = str_replace('`', '``', $column);
return '`'. $column. '` LIKE '. $this->quoteForLike($format, $string);
}
function lastInsertId(?string $name = null): ?string
{
$ret = $this->dbh->lastInsertId();

View file

@ -143,6 +143,12 @@ class Database_Mysqli extends Database_Abstract
return '\''. sprintf($format, $string). '\'';
}
function like(string $column, string $format, string $string): string
{
$column = str_replace('`', '``', $column);
return '`'. $column. '` LIKE '. $this->quoteForLike($format, $string);
}
function tableExists(string $table): bool
{
$r = $this->sq("SELECT 1 FROM information_schema.tables WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?",

View file

@ -73,6 +73,8 @@ class Database_Sqlite3 extends Database_Abstract
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
$this->dbh = new PDO("sqlite:$filename", null, null, $options); //throws PDOException
$this->dbh->sqliteCreateFunction('utf8_lower', [$this, 'utf8lower'], 1);
$this->dbh->sqliteCreateCollation('UTF8CI', [$this, 'utf8ci']);
}
/*
@ -162,6 +164,15 @@ class Database_Sqlite3 extends Database_Abstract
return $this->dbh->quote(sprintf($format, $string)). " ESCAPE '\'";
}
/**
* Produce case-insensitive like
*/
function like(string $column, string $format, string $string): string
{
$column = str_replace('"', '""', $column);
return 'utf8_lower("'. $column. '") LIKE '. $this->quoteForLike($format, mb_strtolower($string, 'UTF-8'));
}
function lastInsertId(?string $name = null): ?string
{
$ret = $this->dbh->lastInsertId();
@ -192,4 +203,15 @@ class Database_Sqlite3 extends Database_Abstract
}
return false;
}
public function utf8lower($value)
{
if (is_null($value)) return '';
return mb_strtolower((string)$value, 'UTF-8');
}
public function utf8ci(string $str1, string $str2): int
{
return strcmp(mb_strtolower($str1, 'UTF-8'), mb_strtolower($str2, 'UTF-8'));
}
}

View file

@ -49,6 +49,7 @@ abstract class Database_Abstract
abstract function affected(): int;
abstract function quote($value): string;
abstract function quoteForLike(string $format, string $string): string;
abstract function like(string $column, string $format, string $string): string;
abstract function lastInsertId(?string $name = null): ?string;
abstract function tableExists(string $table): bool;
abstract function tableFieldExists(string $table, string $field): bool;