Comment trier le texte dans sqlite3 avec les paramètres régionaux spécifiés?
-
03-07-2019 - |
Question
Sqlite3 ne trie par défaut que les lettres ASCII. J'ai essayé de chercher dans google, mais la seule chose que j'ai trouvée était des informations sur les collations. SQLite3 ne contient que des collations NOCASE
, RTRIM
et BIARY
. Comment ajouter un support pour une locale spécifique?
(Je l'utilise dans l'application Rails)
La solution
SQLite prend en charge l'intégration à ICU . Selon le fichier Lisez-moi,
sqlite / ext / icu / README.txt
le répertoire sqlite / ext / icu /
contient le code source de SQLite "ICU". extension, un
intégration des "Composants internationaux pour Unicode". bibliothèque avec SQLite.
1. Features
1.1 SQL Scalars upper() and lower()
1.2 Unicode Aware LIKE Operator
1.3 ICU Collation Sequences
1.4 SQL REGEXP Operator
Autres conseils
J'ai accepté la réponse de Doug Currie, mais je souhaite ajouter des "algorithmes". comment le faire, car la documentation de sqlite3 est très étrange (du moins pour moi).
Ok, nous avons sqlite3 et maintenant:
-
Compilez-le:
gcc -shared icu.c `icu-config --ldflags` -o libSqliteIcu.so
C’est pour Linux. Je devais également installer un package de développement ICU supplémentaire:
sudo apt-get install libicu-dev
Je travaille sur une architecture 64 bits et j'obtiens une erreur avec
__ relocalisation R_X86_64_32S __
(peu importe ce que cela signifie :). GCC a suggéré d'ajouter-fPIC
pour compiler les options et cela a été utile. -
Exécutez sqlite3. Nous pouvons charger l'extension avec la commande suivante:
.load './libSqliteIcu.so'
En supposant qu'il se trouve dans le répertoire en cours, nous pouvons également spécifier le chemin complet.
-
Créer un nouveau classement:
SELECT icu_load_collation('pl_PL', 'POLISH');
Le premier paramètre correspond aux paramètres régionaux souhaités et le second à son choix (il
-
Nous pouvons maintenant trier les données avec nos nouveaux paramètres régionaux:
SELECT * FROM some_table ORDER BY name COLLATE POLISH;
Et c'est insensible à la casse!
Si vous ne pouvez vous permettre de compiler l’extension ICU, vous pouvez demander à un fichier UDF de faire de même. En PHP / PDO:
$pdo->sqliteCreateFunction('locale',
function ($data, $locale = 'root')
{
static $collators = array();
if (isset($collators[$locale]) !== true)
{
$collators[$locale] = new \Collator($locale);
}
return $collators[$locale]->getSortKey($data);
}
);
Exemple d'utilisation:
SELECT * FROM "table" ORDER BY locale("column", 'pt_PT');
Je ne m'attends pas à ce que cette approche soit aussi efficace que l'extension native, mais elle est sûrement plus portable.
Pour ceux qui ne sont pas capables de construire l'extension eux-mêmes, j'ai mis ici des versions compilées disponibles pour macOS et Linux: http://files.tempel.org/Various/Sqlite3ICUExtention
Les versions Linux, tant pour Intel 32 que 64 bits, ont été construites sur Ubuntu 16, si cela compte.
En règle générale, vous ne devriez pas faire confiance au code compilé fourni par d’autres personnes, mais je suis une personne assez publique, ce qui signifie que je courrais un assez grand risque si je fournissais un "mauvais" version. Et pour être sûr qu'aucune attaque de type "man-in-the-middle" ou piratage de mon serveur ne soit commis, voici les hachages MD5 pour les 3 fichiers:
libSqliteIcu-i386.so = 6decd73f27d9c61243128e798304508f
libSqliteIcu-x86_64.so = b127c8a1f65503c91c61a21732eb11be
sqlite3_icu_extension.dylib = a29d59f6b74e7ef234691729b82da660