perl libSqliteIcu.so сопоставить icu

LibSqliteIcu прекрасно работает в терминале sqlite3 с:

sqlite3
...
.load './libSqliteIcu.so'
SELECT icu_load_collation('pl_PL', 'POLISH');
SELECT DISTINCT miasto FROM tab ORDER BY miasto COLLATE POLISH;

Как кодировать последовательность выше в Perl?

2 ответа

Непроверенные:

use DBI qw();
my $dbh = DBI->connect('DBI:SQLite:thedatabase.sqlite');
$dbh->sqlite_enable_load_extension(1);
$dbh->do(q{SELECT load_extension('./libSqliteIcu.so')});
$dbh->do(q{SELECT icu_load_collation('pl_PL', 'POLISH')};
my $miasto = $dbh->selectall_arrayref(q{SELECT DISTINCT miasto FROM tab ORDER BY miasto COLLATE POLISH});


Также можно отсортировать в Perl:

use utf8;
my @tongue_twister = qw(Król Karol kupił królowej Karolinie korale koloru koralowego);

use Unicode::ICU::Collator qw();    # ICU C library, fast
my $c = Unicode::ICU::Collator->new('pl_PL');

use Unicode::Collate qw();          # pure-perl, slow
my $c = Unicode::Collate->new(locale => 'pl_PL');

my @sorted = $c->sort(@tongue_twister);
# (
#     'Karol',
#     'Karolinie',
#     'koloru',
#     'korale',
#     'koralowego',
#     'Król',
#     'królowej',
#     'kupił'
# )

Одним простым, но не идеальным решением является использование pl_PL.UTF8 локали.

В sqlite3 мы готовим:

create table A(idA);
...
insert into A values('ź');
insert into A values('Ż');
insert into A values('ź');
insert into A values('Š');
...
insert into A values('ś');
...

и сейчас:

select * from A;

дает: Z ź Ż ź z ś ż S Š z.

Итак, мы загружаем:

.load './libSqliteIcu.so'
SELECT icu_load_collation('pl_PL', 'POLISH');
select idA from A order by idA collate POLISH;

и мы имеем: S Š ś zz Z ź ź ż Ż.

Итак, теперь в Perl мы можем положить:

SELECT idA FROM A ORDER BY idA

и получите не правильный заказ: SZ zz ś Š ź ź Ż ż

Теперь с помощью perllocale мы помещаем в perl:

SELECT idA FROM A ORDER BY idA COLLATE perllocale

и получите заказ: S Š ś zz Z ź ź ż Ż.

$dbh->do(q{SELECT load_extension('./libSqliteIcu.so')}); не работает в моем случае; это делает ошибку:

DBD:: SQLite:: db do не удалось: невозможно удалить / изменить пользовательскую функцию из-за ошибки активных операторов во время инициализации

Другие вопросы по тегам