Ditch Carp::Clan for our own thing
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / InflateColumn / File.pm
CommitLineData
5acaa54e 1package DBIx::Class::InflateColumn::File;
4740bdb7 2
3use strict;
4use warnings;
5use base 'DBIx::Class';
6use File::Path;
7use File::Copy;
26ddc864 8use Path::Class;
70c28808 9use DBIx::Class::Carp;
9c1700e3 10use namespace::clean;
11
3814fdad 12carp 'InflateColumn::File has entered a deprecation cycle. This component '
13 .'has a number of architectural deficiencies that can quickly drive '
14 .'your filesystem and database out of sync and is not recommended '
15 .'for further use. It will be retained for backwards '
16 .'compatibility, but no new functionality patches will be accepted. '
17 .'Please consider using the much more mature and actively maintained '
18 .'DBIx::Class::InflateColumn::FS. You can set the environment variable '
19 .'DBIC_IC_FILE_NOWARN to a true value to disable this warning.'
20unless $ENV{DBIC_IC_FILE_NOWARN};
21
9c1700e3 22
23
28d4067a 24__PACKAGE__->load_components(qw/InflateColumn/);
4740bdb7 25
28d4067a 26sub register_column {
26ddc864 27 my ($self, $column, $info, @rest) = @_;
28 $self->next::method($column, $info, @rest);
29 return unless defined($info->{is_file_column});
30
31 $self->inflate_column($column => {
32 inflate => sub {
23f067d1 33 my ($value, $obj) = @_;
26ddc864 34 $obj->_inflate_file_column($column, $value);
35 },
36 deflate => sub {
23f067d1 37 my ($value, $obj) = @_;
26ddc864 38 $obj->_save_file_column($column, $value);
39 },
40 });
4740bdb7 41}
42
26ddc864 43sub _file_column_file {
44 my ($self, $column, $filename) = @_;
45
46 my $column_info = $self->column_info($column);
47
48 return unless $column_info->{is_file_column};
49
50 my $id = $self->id || $self->throw_exception(
51 'id required for filename generation'
52 );
53
54 $filename ||= $self->$column->{filename};
55 return Path::Class::file(
56 $column_info->{file_column_path}, $id, $filename,
57 );
58}
4740bdb7 59
60sub delete {
61 my ( $self, @rest ) = @_;
62
26ddc864 63 for ( $self->columns ) {
4740bdb7 64 if ( $self->column_info($_)->{is_file_column} ) {
26ddc864 65 rmtree( [$self->_file_column_file($_)->dir], 0, 0 );
66 last; # if we've deleted one, we've deleted them all
4740bdb7 67 }
68 }
69
26ddc864 70 return $self->next::method(@rest);
4740bdb7 71}
72
26ddc864 73sub insert {
4740bdb7 74 my $self = shift;
d4daee7b 75
26ddc864 76 # cache our file columns so we can write them to the fs
77 # -after- we have a PK
78 my %file_column;
79 for ( $self->columns ) {
28d4067a 80 if ( $self->column_info($_)->{is_file_column} ) {
26ddc864 81 $file_column{$_} = $self->$_;
82 $self->store_column($_ => $self->$_->{filename});
4740bdb7 83 }
84 }
26ddc864 85
86 $self->next::method(@_);
87
88 # write the files to the fs
89 while ( my ($col, $file) = each %file_column ) {
90 $self->_save_file_column($col, $file);
91 }
92
93 return $self;
4740bdb7 94}
95
4740bdb7 96
26ddc864 97sub _inflate_file_column {
98 my ( $self, $column, $value ) = @_;
4740bdb7 99
26ddc864 100 my $fs_file = $self->_file_column_file($column, $value);
4740bdb7 101
26ddc864 102 return { handle => $fs_file->open('r'), filename => $value };
4740bdb7 103}
104
105sub _save_file_column {
26ddc864 106 my ( $self, $column, $value ) = @_;
107
108 return unless ref $value;
109
110 my $fs_file = $self->_file_column_file($column, $value->{filename});
111 mkpath [$fs_file->dir];
f6ace689 112
113 # File::Copy doesn't like Path::Class (or any for that matter) objects,
114 # thus ->stringify (http://rt.perl.org/rt3/Public/Bug/Display.html?id=59650)
115 File::Copy::copy($value->{handle}, $fs_file->stringify);
26ddc864 116
117 $self->_file_column_callback($value, $self, $column);
118
119 return $value->{filename};
4740bdb7 120}
121
122=head1 NAME
123
5847820e 124DBIx::Class::InflateColumn::File - DEPRECATED (superseded by DBIx::Class::InflateColumn::FS)
125
126=head2 Deprecation Notice
127
3814fdad 128 This component has a number of architectural deficiencies that can quickly
129 drive your filesystem and database out of sync and is not recommended for
130 further use. It will be retained for backwards compatibility, but no new
131 functionality patches will be accepted. Please consider using the much more
132 mature and actively supported DBIx::Class::InflateColumn::FS. You can set
133 the environment variable DBIC_IC_FILE_NOWARN to a true value to disable
134 this warning.
4740bdb7 135
4740bdb7 136=head1 SYNOPSIS
137
138In your L<DBIx::Class> table class:
139
d88ecca6 140 use base 'DBIx::Class::Core';
141
142 __PACKAGE__->load_components(qw/InflateColumn::File/);
d4daee7b 143
4740bdb7 144 # define your columns
145 __PACKAGE__->add_columns(
146 "id",
147 {
148 data_type => "integer",
149 is_auto_increment => 1,
150 is_nullable => 0,
151 size => 4,
152 },
153 "filename",
154 {
155 data_type => "varchar",
156 is_file_column => 1,
157 file_column_path =>'/tmp/uploaded_files',
158 # or for a Catalyst application
159 # file_column_path => MyApp->path_to('root','static','files'),
160 default_value => undef,
161 is_nullable => 1,
162 size => 255,
163 },
164 );
d4daee7b 165
4740bdb7 166
167In your L<Catalyst::Controller> class:
168
0876072c 169FileColumn requires a hash that contains L<IO::File> as handle and the file's
170name as name.
4740bdb7 171
172 my $entry = $c->model('MyAppDB::Articles')->create({
173 subject => 'blah',
174 filename => {
175 handle => $c->req->upload('myupload')->fh,
176 filename => $c->req->upload('myupload')->basename
177 },
178 body => '....'
179 });
180 $c->stash->{entry}=$entry;
d4daee7b 181
4740bdb7 182
183And Place the following in your TT template
d4daee7b 184
4740bdb7 185 Article Subject: [% entry.subject %]
186 Uploaded File:
187 <a href="/static/files/[% entry.id %]/[% entry.filename.filename %]">File</a>
188 Body: [% entry.body %]
d4daee7b 189
0876072c 190The file will be stored on the filesystem for later retrieval. Calling delete
191on your resultset will delete the file from the filesystem. Retrevial of the
192record automatically inflates the column back to the set hash with the
193IO::File handle and filename.
194
195=head1 DESCRIPTION
196
197InflateColumn::File
198
199=head1 METHODS
200
201=head2 _file_column_callback ($file,$ret,$target)
202
48580715 203Method made to be overridden for callback purposes.
0876072c 204
205=cut
206
26ddc864 207sub _file_column_callback {}
4740bdb7 208
209=head1 AUTHOR
210
211Victor Igumnov
212
213=head1 LICENSE
214
215This library is free software, you can redistribute it and/or modify
216it under the same terms as Perl itself.
217
218=cut
219
2201;