使用 Rose::DB::Object 在 SQLite 中处理 UTF8 编码文本

发布于 2024-10-17 13:34:09 字数 1289 浏览 3 评论 0原文

我正在使用 Rose::DB::ObjectSQLite 和中文文本。我的类如下所示:

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>

I am using Rose::DB::Object, SQLite, and Chinese text. My classes look like this:

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() };

The code used to store a record:

Motorcycle->new(
  type  => $self->param('type'),
  brand => $self->param('brand'),
  color => $self->param('color'),
)->save;

The code used to display the data (from within a Mojolicious app):

<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>

How can I eliminate the decoding step? I'd like the display code to look like this instead:

<td><%= $cycle->type %></td>
<td><%= $cycle->brand %></td>
<td><%= $cycle->color %></td>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏雨凉 2024-10-24 13:34:09

我认为您需要获取 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', @_)
}

我将在 John 的答案上留下评论,以便他可以对此进行健全性检查。

如果有效,那么您可能需要向 John Siracusa 发送补丁(他不仅已经解决了这个问题,而且还是 Rose::DB 维护者)。

I think you need to get the sqlite_unicode => 1 configuration value down to SQLite, there was a similar question about UTF-8 and SQLite, setting sqlite_unicode did the trick there.

I don't think Rose::DB::SQLite supports this configuration parameter though. Based on this possibly similar issue with MySQL you might be able to patch Rose::DB::SQLite to add support for sqlite_unicode by adding this to the driver:

sub sqlite_unicode {
{
  shift->dbh_attribute_boolean('sqlite_unicode', @_)
}

I'll leave a comment on John's answer so he can sanity check this.

If that works then you might want to send a patch to John Siracusa (who is not only already on this question but also the Rose::DB maintainer).

人心善变 2024-10-24 13:34:09

如果您将 UTF8 编码的文本输入 SQLite,它应该以相同的形式将其返回给您。例如,给定一个名为 test.db 的 SQLite 数据库,其中包含以下架构:

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;

If you feed UTF8-encoded text into SQLite, it should give it right back to you in the same form. For example, given an SQLite database named test.db containing this schema:

CREATE TABLE things
(
  id   INTEGER PRIMARY KEY AUTOINCREMENT,
  name VARCHAR(64) NOT NULL
);

Run this code in a script in the same directory as the test.db database:

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";

If this is not working for you, then perhaps your calls to get the form parameters (e.g., $self->param('type')) are returning character strings instead of UTF8-encoded strings. That is, in the case of the smiley face string, perhaps $self->param('foo') is returning "\x{263a}" and not "\x{e2}\x{98}\x{ba}". In that case, the solution would be to encode the strings as UTF8 before setting the object attributes:

Motorcycle->new(
  type  => utf8::encode($self->param('type')),
  brand => utf8::encode($self->param('brand')),
  color => utf8::encode($self->param('color')),
)->save;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文