Обработка текста в кодировке UTF8 в SQLite с использованием Rose::DB::Object
Я использую Rose:: DB:: Object, SQLite и китайский текст. Мои занятия выглядят так:
package My::DB;
use base qw(Rose::DB);
__PACKAGE__->use_private_registry;
__PACKAGE__->register_db(
driver => 'sqlite',
database => 'data/sqmple.db',
);
package Motorcycle;
use My::DB;
use base qw(Rose::DB::Object);
...
sub init_db { My::DB->new() };
Код, используемый для хранения записи:
Motorcycle->new(
type => $self->param('type'),
brand => $self->param('brand'),
color => $self->param('color'),
)->save;
Код, используемый для отображения данных (из приложения Mojolicious):
<td><%= Mojo::ByteStream->new($cycle->type)->decode("utf-8") %></td>
<td><%= Mojo::ByteStream->new($cycle->brand)->decode("utf-8") %></td>
<td><%= Mojo::ByteStream->new($cycle->color)->decode("utf-8") %></td>
Как я могу исключить этап декодирования? Я хотел бы, чтобы код дисплея выглядел так:
<td><%= $cycle->type %></td>
<td><%= $cycle->brand %></td>
<td><%= $cycle->color %></td>
2 ответа
Я думаю, вам нужно получить sqlite_unicode => 1
Значение конфигурации вплоть до SQLite, был похожий вопрос о UTF-8 и SQLite, настройка sqlite_unicode
сделал трюк там.
Я не думаю, что Rose:: DB:: SQLite поддерживает этот параметр конфигурации, хотя. Исходя из этой, возможно, похожей проблемы с MySQL, вы можете исправить патч Rose:: DB:: SQLite для добавления поддержки sqlite_unicode
добавив это в драйвер:
sub sqlite_unicode {
{
shift->dbh_attribute_boolean('sqlite_unicode', @_)
}
Я оставлю комментарий к ответу Джона, чтобы он смог проверить это.
Если это сработает, возможно, вы захотите отправить патч Джону Сиракузе (который уже не только по этому вопросу, но и сопровождающему Rose:: DB).
Если вы подаете текст в кодировке UTF8 в SQLite, он должен вернуть его вам в той же форме. Например, для базы данных SQLite с именем test.db, содержащей эту схему:
CREATE TABLE things
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(64) NOT NULL
);
Запустите этот код в сценарии в том же каталоге, что и база данных test.db:
package My::DB;
use base qw(Rose::DB);
__PACKAGE__->use_private_registry;
__PACKAGE__->register_db
(
driver => 'sqlite',
database => 'test.db',
);
package My::Thing;
use base qw(Rose::DB::Object);
__PACKAGE__->meta->setup
(
table => 'things',
columns =>
[
id => { type => 'serial', primary_key => 1, not_null => 1 },
name => { type => 'text', length => 64, not_null => 1 },
],
);
sub init_db { My::DB->new }
package main;
# Set the name to a UTF8-encoded smiley: Unicode 0x263A
my $thing = My::Thing->new(name => "\x{e2}\x{98}\x{ba}")->save;
$thing = My::Thing->new(id => $thing->id)->load;
# This will print the UTF8-encoded smiley; make sure your
# terminal can handle UTF8 output.
print $thing->name, "\n";
Если это не работает для вас, то, возможно, ваши звонки, чтобы получить параметры формы (например, $self->param('type')
) возвращают символьные строки вместо строк в кодировке UTF8. То есть в случае смайлика, возможно, $self->param('foo')
возвращает "\x{263a}", а не "\x{e2}\x{98}\x{ba}". В этом случае решением было бы закодировать строки как UTF8 перед установкой атрибутов объекта:
Motorcycle->new(
type => utf8::encode($self->param('type')),
brand => utf8::encode($self->param('brand')),
color => utf8::encode($self->param('color')),
)->save;