1 package DBIx::Class::InflateColumn::File;
5 use base 'DBIx::Class';
10 use Carp::Clan qw/^DBIx::Class/;
11 carp 'InflateColumn::File has entered a deprecation cycle. This component '
12 .'has a number of architectural deficiencies that can quickly drive '
13 .'your filesystem and database out of sync and is not recommended '
14 .'for further use. It will be retained for backwards '
15 .'compatibility, but no new functionality patches will be accepted. '
16 .'Please consider using the much more mature and actively maintained '
17 .'DBIx::Class::InflateColumn::FS. You can set the environment variable '
18 .'DBIC_IC_FILE_NOWARN to a true value to disable this warning.'
19 unless $ENV{DBIC_IC_FILE_NOWARN};
21 __PACKAGE__->load_components(qw/InflateColumn/);
24 my ($self, $column, $info, @rest) = @_;
25 $self->next::method($column, $info, @rest);
26 return unless defined($info->{is_file_column});
28 $self->inflate_column($column => {
30 my ($value, $obj) = @_;
31 $obj->_inflate_file_column($column, $value);
34 my ($value, $obj) = @_;
35 $obj->_save_file_column($column, $value);
40 sub _file_column_file {
41 my ($self, $column, $filename) = @_;
43 my $column_info = $self->column_info($column);
45 return unless $column_info->{is_file_column};
47 my $id = $self->id || $self->throw_exception(
48 'id required for filename generation'
51 $filename ||= $self->$column->{filename};
52 return Path::Class::file(
53 $column_info->{file_column_path}, $id, $filename,
58 my ( $self, @rest ) = @_;
60 for ( $self->columns ) {
61 if ( $self->column_info($_)->{is_file_column} ) {
62 rmtree( [$self->_file_column_file($_)->dir], 0, 0 );
63 last; # if we've deleted one, we've deleted them all
67 return $self->next::method(@rest);
73 # cache our file columns so we can write them to the fs
74 # -after- we have a PK
76 for ( $self->columns ) {
77 if ( $self->column_info($_)->{is_file_column} ) {
78 $file_column{$_} = $self->$_;
79 $self->store_column($_ => $self->$_->{filename});
83 $self->next::method(@_);
85 # write the files to the fs
86 while ( my ($col, $file) = each %file_column ) {
87 $self->_save_file_column($col, $file);
94 sub _inflate_file_column {
95 my ( $self, $column, $value ) = @_;
97 my $fs_file = $self->_file_column_file($column, $value);
99 return { handle => $fs_file->open('r'), filename => $value };
102 sub _save_file_column {
103 my ( $self, $column, $value ) = @_;
105 return unless ref $value;
107 my $fs_file = $self->_file_column_file($column, $value->{filename});
108 mkpath [$fs_file->dir];
110 # File::Copy doesn't like Path::Class (or any for that matter) objects,
111 # thus ->stringify (http://rt.perl.org/rt3/Public/Bug/Display.html?id=59650)
112 File::Copy::copy($value->{handle}, $fs_file->stringify);
114 $self->_file_column_callback($value, $self, $column);
116 return $value->{filename};
121 DBIx::Class::InflateColumn::File - DEPRECATED (superseded by DBIx::Class::InflateColumn::FS)
123 =head2 Deprecation Notice
125 This component has a number of architectural deficiencies that can quickly
126 drive your filesystem and database out of sync and is not recommended for
127 further use. It will be retained for backwards compatibility, but no new
128 functionality patches will be accepted. Please consider using the much more
129 mature and actively supported DBIx::Class::InflateColumn::FS. You can set
130 the environment variable DBIC_IC_FILE_NOWARN to a true value to disable
135 In your L<DBIx::Class> table class:
137 use base 'DBIx::Class::Core';
139 __PACKAGE__->load_components(qw/InflateColumn::File/);
141 # define your columns
142 __PACKAGE__->add_columns(
145 data_type => "integer",
146 is_auto_increment => 1,
152 data_type => "varchar",
154 file_column_path =>'/tmp/uploaded_files',
155 # or for a Catalyst application
156 # file_column_path => MyApp->path_to('root','static','files'),
157 default_value => undef,
164 In your L<Catalyst::Controller> class:
166 FileColumn requires a hash that contains L<IO::File> as handle and the file's
169 my $entry = $c->model('MyAppDB::Articles')->create({
172 handle => $c->req->upload('myupload')->fh,
173 filename => $c->req->upload('myupload')->basename
177 $c->stash->{entry}=$entry;
180 And Place the following in your TT template
182 Article Subject: [% entry.subject %]
184 <a href="/static/files/[% entry.id %]/[% entry.filename.filename %]">File</a>
185 Body: [% entry.body %]
187 The file will be stored on the filesystem for later retrieval. Calling delete
188 on your resultset will delete the file from the filesystem. Retrevial of the
189 record automatically inflates the column back to the set hash with the
190 IO::File handle and filename.
198 =head2 _file_column_callback ($file,$ret,$target)
200 Method made to be overridden for callback purposes.
204 sub _file_column_callback {}
212 This library is free software, you can redistribute it and/or modify
213 it under the same terms as Perl itself.