使用这个DBIx::Class插件管理文件轻而易举

管理应用程序文件上传具有挑战性:存储、去重、检索和权限都需要处理。DBIx::Class::InflateColumn::FS通过处理文件的底层存储,简化了挑战,使得程序员可以专注于应用程序开发。让我们更深入地了解一下它是如何工作的。
要求
为了使用此示例,您需要从CPAN安装DBIx::Class::InflateColumn::FS。CPAN测试人员结果显示,它应该在包括Windows在内的所有平台上运行。如果您还没有,还需要DBIx::Class::Schema::Loader和File::MimeInfo,以及SQLite3。要安装Perl模块,打开终端并输入
$ cpan DBIx::Class::InflateColumn::FS DBIx::Class::Schema::Loader File::MimeInfo
设置结果类
让我们创建一个用于处理文件上传的示例类。DBIx::Class将对象映射到数据库表,因此我们需要创建一个表示我们的文件上传对象的数据库表。这是创建上传表的SQL代码
create table upload (
id integer primary key,
file text not null,
mime text not null
);
将代码保存到名为create_upload.sql的脚本中,并在命令行中运行它
$ sqlite3 MyApp.db < create_upload.sql
这将创建上传表。接下来,我们可以使用随DBIx::Class::Schema::Loader一起提供的“dbicdump”应用程序为我们创建基本的结果类
$ dbicdump MyApp::Schema dbi:SQLite:MyApp.db
在文本编辑器中打开新创建的MyApp/Schema/Result/Upload.pm,在“# DO NOT MODIFY …”行下面添加以下代码
use File::MimeInfo 'extensions';
__PACKAGE__->load_components("InflateColumn::FS");
__PACKAGE__->add_columns(
"file",
{
data_type => 'TEXT',
is_fs_column => 1,
fs_column_path => 'uploads',
}
);
sub extension {
my ($self) = @_;
[ extensions($self->mime) ]->[0];
}
此代码在Upload类的“file”属性上启用了DBIx::Class::InflateColumn::FS插件。此外,我们还添加了一个名为“extension”的子程序,它将返回文件的扩展名。
创建上传
此脚本将创建一个上传对象
#!/usr/bin/env perl
use strict;
use warnings;
use MyApp::Schema;
use MIME::Types;
use lib '.';
open(my $file, '<', $ARGV[0]) or die $!;
my $schema = MyApp::Schema->connect('dbi:SQLite:MyApp.db');
# Add the file to the database and file system
my $upload = $schema->resultset('Upload')->
create({ file => $file,
mime => (MIME::Types->new->mimeTypeOf($ARGV[0])) });
将脚本保存为“create_upload.pl”,我们可以在终端中调用它,并传递我们想要保存的文件的文件路径
$ perl create_upload.pl perltricks_logo.png
仅通过创建对象,DBIx::Class::InflateColumn::FS就会将文件保存在我们的上传目录中。无需编写额外的代码来显式复制文件。
检索上传
此脚本将检索上传对象。DBIx::Class::InflateColumn::FS自动将“file”列扩展为Path::Class::File对象,这为我们提供了许多便利方法
#!/usr/bin/env perl
use strict;
use warnings;
use MyApp::Schema;
use lib '.';
my $schema = MyApp::Schema->connect('dbi:SQLite:MyApp.db');
# retrieve the upload
my $upload = $schema->resultset('Upload')->find(1);
# get the relative path
$upload->file->relative;
# get the absolute path
$upload->file->absolute;
# get the base filename
$upload->file->basename;
# get the mime type (image/png)
$upload->mime;
# get the file extension
$upload->extension;
# get a read filehandle
$upload->file->openr;
# get a write filehandle
$upload->file->openw;
# get an append filehandle
$upload->file->opena;
删除上传
DBIx::Class::InflateColumn::FS使得删除文件变得超级简单。只需在结果对象上调用delete即可从表和文件系统中删除它
#!/usr/bin/env perl
use strict;
use warnings;
use MyApp::Schema;
use lib '.';
my $schema = MyApp::Schema->connect('dbi:SQLite:MyApp.db');
# retrieve the upload
my $upload = $schema->resultset('Upload')->find(1);
# delete the file from the database and file system
$upload->delete;
结论
DBIx::Class::InflateColumn::FS作为现成的工具很有用,但在某些情况下表现得尤为出色。例如,如果您正在管理图像文件,存储原始高质量图像并在请求时动态调整图像大小是非常有益的。这样,您可以最小化磁盘使用,并在应用程序逻辑中保留调整图像所需的灵活性。
感谢Devin Austin,他的Catalyst advent calendar 文章是本文的有用来源。
喜欢这篇文章吗?帮助我们并推文关于它!
本文最初发布在PerlTricks.com上。
标签
反馈
这篇文章有问题吗?请通过在GitHub上打开一个问题或拉取请求来帮助我们。