line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Backed_Objects; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
28266
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
29
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1226
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 NAME |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
Backed_Objects - Create static files from a database. |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 VERSION |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
Version 1.16 |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=cut |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our $VERSION = '1.16'; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 SYNOPSIS |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
Create static files from a database. |
21
|
|
|
|
|
|
|
Update the files every time when you update the database. |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
It can be used with any kind of database, for example SQL databases, |
24
|
|
|
|
|
|
|
Berkeley databases, data stored in .ini files, etc. |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 USAGE OF THE CLASS |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
The class C is an abstract base class and you need to |
29
|
|
|
|
|
|
|
derive your class from it. For further suppose you developed a class |
30
|
|
|
|
|
|
|
C derived from C. We will call HTML (for example) |
31
|
|
|
|
|
|
|
files which are updated by this module I. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
All methods can be called either as object methods or as class methods. |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Calling these as class methods may be convienient when you do not need to |
36
|
|
|
|
|
|
|
specify additional parameters to be put into an object. |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
Thus the following alternatives are possible: |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
HTML_DB->output_all_and_order; |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
or |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
my $obj = HTML_DB->new; |
45
|
|
|
|
|
|
|
$obj->output_all_and_order; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
Examples below assume that you are familiar with SQL and C module. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head1 Database update methods |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
The class C offers you flexibility on the way how you |
52
|
|
|
|
|
|
|
update your database. |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
One variant is to override C, C, C, C methods, |
55
|
|
|
|
|
|
|
so that they will update your database when C, C, C |
56
|
|
|
|
|
|
|
methods are called. |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
The other variant is to update the database yourself and I |
59
|
|
|
|
|
|
|
to call C, C, C which will call the default |
60
|
|
|
|
|
|
|
do-nothing C, C, C, C methods. |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=head1 The object and the ID |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
A database stores objects, every object stored in a database has an ID. |
65
|
|
|
|
|
|
|
An object may be without an ID when it is not yet stored into the DB, but |
66
|
|
|
|
|
|
|
you must assign an ID to an object when you store it in the DB, either |
67
|
|
|
|
|
|
|
by overriding C method which should set the object ID or yourself |
68
|
|
|
|
|
|
|
in your own code (without overriding C). C must have |
69
|
|
|
|
|
|
|
C method which receives an object and return its ID. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
The interface of this module does not specify what objects are. Objects may |
72
|
|
|
|
|
|
|
be hashes or any other data structures. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
Every object inserted into the database has ID (which may be a natural number, |
75
|
|
|
|
|
|
|
but is not required to be a number). |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
Sometimes you may want the objects and IDs to be the same. For example, it is |
78
|
|
|
|
|
|
|
often OK for an object and an ID to be a row ID in a SQL database. Or you may |
79
|
|
|
|
|
|
|
want an object to be a hash representing a row in an SQL DB. |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
Sometimes a middle solution is fit: Store an object as a hash with some |
82
|
|
|
|
|
|
|
values from the database and read the rest values from the DB when needed, |
83
|
|
|
|
|
|
|
using the ID stored in the object. |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
An other possibililty for an object is to be a hash based on user input in |
86
|
|
|
|
|
|
|
a HTML form. |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head1 METHODS |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head2 id |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
This abstract (not defined in C method) must be defined to |
93
|
|
|
|
|
|
|
return the ID of an object. |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
Examples: |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub id { |
98
|
|
|
|
|
|
|
my ($self, $obj) = @_; |
99
|
|
|
|
|
|
|
return $obj->{id}; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
or |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# Objects are simple IDs |
105
|
|
|
|
|
|
|
sub id { |
106
|
|
|
|
|
|
|
my ($self, $obj) = @_; |
107
|
|
|
|
|
|
|
return $obj; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=head2 all_ids |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
This abstract (not defined in C method) must return a list of |
113
|
|
|
|
|
|
|
all IDs in the database. |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub all_ids { |
116
|
|
|
|
|
|
|
my ($self) = @_; |
117
|
|
|
|
|
|
|
return @{ $dbh->selectcol_arrayref("SELECT id FROM table") }; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=cut |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=head2 do_select |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
This abstract method should return an object from the DB having a given ID. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub do_select { |
127
|
|
|
|
|
|
|
my ($self, $id) = @_; |
128
|
|
|
|
|
|
|
return $dbh->selectrow_hashref("SELECT * FROM table WHERE id=?", undef, $id); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
or |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# Objects are simple IDs |
134
|
|
|
|
|
|
|
sub do_select { |
135
|
|
|
|
|
|
|
my ($self, $id) = @_; |
136
|
|
|
|
|
|
|
return $id; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=head2 select |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
This method returns an object from the DB or C if the ID is absent |
142
|
|
|
|
|
|
|
(undefined or zero). |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
See its implementation: |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
sub select { |
147
|
|
|
|
|
|
|
my ($self, $id) = @_; |
148
|
|
|
|
|
|
|
return undef unless $id; |
149
|
|
|
|
|
|
|
return $self->do_select($id); |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=cut |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub select { |
155
|
0
|
|
|
0
|
1
|
|
my ($self, $id) = @_; |
156
|
0
|
0
|
|
|
|
|
return undef unless $id; |
157
|
0
|
|
|
|
|
|
return $self->do_select($id); |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head2 do_insert, do_update, do_delete, post_process |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
By default these methods do nothing. (In this case you need to update database |
163
|
|
|
|
|
|
|
yourself, before calling C, C, or C methods.) |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
You may override these methods to do database updates: |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
sub do_insert { |
168
|
|
|
|
|
|
|
my ($self, $obj) = @_; |
169
|
|
|
|
|
|
|
my @keys = keys %$obj; |
170
|
|
|
|
|
|
|
my @values = values %$obj; |
171
|
|
|
|
|
|
|
my $set = join ', ', map { "$_=?" } @keys; |
172
|
|
|
|
|
|
|
$dbh->do("INSERT table SET $set", undef, @values); |
173
|
|
|
|
|
|
|
$obj->{id} = $dbh->last_insert_id(undef, undef, undef, undef); |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub do_update { |
177
|
|
|
|
|
|
|
my ($self, $obj) = @_; |
178
|
|
|
|
|
|
|
my @keys = keys %$obj; |
179
|
|
|
|
|
|
|
my @values = values %$obj; |
180
|
|
|
|
|
|
|
my $set = join ', ', map { "$_=?" } @keys; |
181
|
|
|
|
|
|
|
$dbh->do("UPDATE table SET $set WHERE id=?", undef, @values, $obj->{id}); |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub do_delete { |
185
|
|
|
|
|
|
|
my ($self, $id) = @_; |
186
|
|
|
|
|
|
|
$dbh->do("DELETE FROM table WHERE id=?", undef, $id); |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
sub post_process { |
190
|
|
|
|
|
|
|
my ($self, $obj) = @_; |
191
|
|
|
|
|
|
|
... |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
C should set object ID after it is saved into the database. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
C is called by C after the object is inserted into |
197
|
|
|
|
|
|
|
the database (and the object ID is set). It can be used for amending the |
198
|
|
|
|
|
|
|
object with operations which require some object ID, for example for |
199
|
|
|
|
|
|
|
uploading files into a folder with name being based on the ID. |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
C is also called by C. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=cut |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
0
|
1
|
|
sub do_insert { } |
206
|
|
|
|
0
|
1
|
|
sub do_update { } |
207
|
|
|
|
0
|
1
|
|
sub do_delete { } |
208
|
|
|
|
0
|
1
|
|
sub post_process { } |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
=head2 outputter |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
This method should return a value used to output a view of the DB |
213
|
|
|
|
|
|
|
(for example it may be used to output HTML files and be a hash whose values |
214
|
|
|
|
|
|
|
are HTML templates). |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
Example: |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
use File::Slurp; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub outputter { |
221
|
|
|
|
|
|
|
my ($self) = @_; |
222
|
|
|
|
|
|
|
my $template_dir = "$ENV{DOCUMENT_ROOT}/templates"; |
223
|
|
|
|
|
|
|
return { main_tmpl => read_file("$template_dir/main.html"), |
224
|
|
|
|
|
|
|
announce_tmpl => read_file("$template_dir/announce.html") }; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
The default implementation returns C. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=cut |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
0
|
1
|
|
sub outputter { } |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
=head2 insert, update, delete |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
HTML_DB->insert($obj); |
236
|
|
|
|
|
|
|
HTML_DB->update($obj); |
237
|
|
|
|
|
|
|
HTML_DB->delete($id); |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
These functions update the view based on the value C<$obj> from the DB. |
240
|
|
|
|
|
|
|
They are to be called when an object is inserted, updated, or deleted in |
241
|
|
|
|
|
|
|
the DB. |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
If you've overridden the C, C, or C methods, |
244
|
|
|
|
|
|
|
then C, C, or C methods update the database before |
245
|
|
|
|
|
|
|
updating the view. |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
Note that C methods calls both C and C methods |
248
|
|
|
|
|
|
|
(as well as some other methods, see the source). |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
C and C also call C. |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
C also calls C before calling C. |
253
|
|
|
|
|
|
|
The C method can be used to update the data based on |
254
|
|
|
|
|
|
|
old data in the DB, before the DB is updated by C. |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=cut |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
# Calls both on_update() and on_insert() |
259
|
|
|
|
|
|
|
sub insert { |
260
|
0
|
|
|
0
|
1
|
|
my ($self, $obj) = @_; |
261
|
0
|
0
|
|
|
|
|
die "Inserting an object into DB second time!" if $self->id($obj); |
262
|
0
|
|
|
|
|
|
$self->do_insert($obj); |
263
|
0
|
|
|
|
|
|
$self->post_process($obj); |
264
|
0
|
|
|
|
|
|
$self->on_insert($obj); |
265
|
0
|
|
|
|
|
|
$self->on_update($obj); |
266
|
0
|
|
|
|
|
|
$self->on_order_change; |
267
|
0
|
|
|
|
|
|
$self->on_any_change; |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
sub update { |
271
|
0
|
|
|
0
|
1
|
|
my ($self, $obj) = @_; |
272
|
0
|
0
|
|
|
|
|
die "Updating an object not in DB!" unless $self->id($obj); |
273
|
0
|
|
|
|
|
|
$self->before_update($obj); |
274
|
0
|
|
|
|
|
|
$self->do_update($obj); |
275
|
0
|
|
|
|
|
|
$self->post_process($obj); |
276
|
0
|
|
|
|
|
|
$self->on_update($obj); |
277
|
0
|
|
|
|
|
|
$self->on_any_change; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub delete { |
281
|
0
|
|
|
0
|
1
|
|
my ($self, $id) = @_; |
282
|
0
|
|
|
|
|
|
$self->do_delete($id); |
283
|
0
|
|
|
|
|
|
$self->on_order_change; |
284
|
0
|
|
|
|
|
|
$self->on_delete($id); |
285
|
0
|
|
|
|
|
|
$self->on_any_change; |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head2 on_update, on_update_one |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
C method it called when an object in the database is updated or after |
291
|
|
|
|
|
|
|
a new object is inserted. |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
C is the method called by C. The C |
294
|
|
|
|
|
|
|
method is meant to update view of one object. Contrary to this, C |
295
|
|
|
|
|
|
|
may be overridden to update several objects by calling C several |
296
|
|
|
|
|
|
|
times. For example, when updating title of a HTML file, we may want to update |
297
|
|
|
|
|
|
|
two more HTML files with titles of prev/next links dependent on the title of |
298
|
|
|
|
|
|
|
this object. |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
By default C calls the C |
301
|
|
|
|
|
|
|
object. |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=cut |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
sub on_update { |
306
|
0
|
|
|
0
|
1
|
|
my ($self, $obj) = @_; |
307
|
0
|
|
|
|
|
|
$self->on_update_one($obj); |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
sub on_update_one { |
311
|
0
|
|
|
0
|
1
|
|
my ($self, $obj) = @_; |
312
|
0
|
|
|
|
|
|
$self->output(scalar($self->outputter), $obj, 1); |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=head2 on_insert, on_delete, on_order_change, before_update |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
sub on_insert { |
318
|
|
|
|
|
|
|
my ($self, $obj) = @_; |
319
|
|
|
|
|
|
|
... |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
sub on_delete { |
323
|
|
|
|
|
|
|
my ($self, $id) = @_; |
324
|
|
|
|
|
|
|
... |
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
sub on_order_change { |
328
|
|
|
|
|
|
|
my ($self) = @_; |
329
|
|
|
|
|
|
|
... |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
sub before_update { |
333
|
|
|
|
|
|
|
my ($self, $obj) = @_; |
334
|
|
|
|
|
|
|
... |
335
|
|
|
|
|
|
|
} |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
These methods (doing nothing by default) are called correspondingly when: |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=over |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=item inserting a new object into the database; |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=item deleting an object from the database; |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=item changing order of objects in the database (including the case of inserting a new object). |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=item before calling C to update the database. |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=back |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
By default these methods do nothing. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
You may update your view in your overrides of these methods. |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
C is called by C (but not by C) before updating |
356
|
|
|
|
|
|
|
the DB with C. |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=cut |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
0
|
1
|
|
sub on_insert { } |
361
|
|
|
|
0
|
1
|
|
sub on_delete { } |
362
|
|
|
|
0
|
1
|
|
sub on_order_change { } |
363
|
|
|
|
0
|
1
|
|
sub before_update { } |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=head2 on_any_change |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
sub on_any_change { |
368
|
|
|
|
|
|
|
my ($self) = @_; |
369
|
|
|
|
|
|
|
... |
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
This method is called after every change of the database, for example, |
373
|
|
|
|
|
|
|
after insertion, deletion, update, etc. |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
=cut |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
0
|
1
|
|
sub on_any_change { } |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=head2 do_output |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
sub do_output { |
382
|
|
|
|
|
|
|
my ($self, $outputter, $obj, $update) = @_; |
383
|
|
|
|
|
|
|
... |
384
|
|
|
|
|
|
|
} |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
This is the main method to output your files (the view). |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
It receives the object and the outputter returned by the C method. |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
$update is TRUE only if it is called from C method. It can be used |
391
|
|
|
|
|
|
|
not to update what needs not updating. (TODO: Document it better.) |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=cut |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
0
|
1
|
|
sub do_output { } |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
=head2 order_change |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
HTML_DB->order_change; |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
Call C after you changed the order of objects in the |
402
|
|
|
|
|
|
|
database (but not after calling C or C method which call |
403
|
|
|
|
|
|
|
C automatically). |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
=cut |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
sub order_change { |
408
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
409
|
0
|
|
|
|
|
|
$self->on_order_change; |
410
|
0
|
|
|
|
|
|
$self->on_any_change; |
411
|
|
|
|
|
|
|
} |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
=head2 output_by_id |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
An internal function. |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
=cut |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
sub output_by_id { |
420
|
0
|
|
|
0
|
1
|
|
my ($self, $id, $outputter) = @_; |
421
|
0
|
0
|
|
|
|
|
$outputter = $self->outputter unless $outputter; |
422
|
0
|
|
|
|
|
|
my $obj = $self->select($id); |
423
|
0
|
|
|
|
|
|
$self->output($outputter, $obj); |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=head2 output_all |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
HTML_DB->output_all; |
429
|
|
|
|
|
|
|
HTML_DB->output_all_and_order; |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
C updates the entire set of your files based on the |
432
|
|
|
|
|
|
|
data in the DB. |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
C additionally updates data dependent on the order |
435
|
|
|
|
|
|
|
of objects in the DB. |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
Use these methods to update your all files (for example, after your template |
438
|
|
|
|
|
|
|
changed). |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
=cut |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
sub output_all { |
443
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
444
|
0
|
|
|
|
|
|
my @ids = $self->all_ids; |
445
|
0
|
|
|
|
|
|
my $outputter = $self->outputter; |
446
|
0
|
|
|
|
|
|
for my $id (@ids) { |
447
|
0
|
|
|
|
|
|
$self->output_by_id($id, $outputter); |
448
|
|
|
|
|
|
|
} |
449
|
0
|
|
|
|
|
|
$self->on_any_change; |
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
# Is it better to first call output_all and then on_order_change, or the reverse |
453
|
|
|
|
|
|
|
sub output_all_and_order { |
454
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
455
|
0
|
|
|
|
|
|
$self->output_all; |
456
|
0
|
|
|
|
|
|
$self->on_order_change; |
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=head2 save |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
HTML_DB->save($obj); |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
This saves an object into the DB: updates it if it is already in the DB |
464
|
|
|
|
|
|
|
(has an ID) or inserts it into the DB if it has an undefined ID. |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
The actual code: |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
sub save { |
469
|
|
|
|
|
|
|
my ($self, $obj) = @_; |
470
|
|
|
|
|
|
|
if($self->id($obj)) { |
471
|
|
|
|
|
|
|
$self->update($obj); |
472
|
|
|
|
|
|
|
} else { |
473
|
|
|
|
|
|
|
$self->insert($obj); |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
=cut |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
sub save { |
480
|
0
|
|
|
0
|
1
|
|
my ($self, $obj) = @_; |
481
|
0
|
0
|
|
|
|
|
if($self->id($obj)) { |
482
|
0
|
|
|
|
|
|
$self->update($obj); |
483
|
|
|
|
|
|
|
} else { |
484
|
0
|
|
|
|
|
|
$self->insert($obj); |
485
|
|
|
|
|
|
|
} |
486
|
|
|
|
|
|
|
} |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
=head2 output |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
An internal function. |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
=cut |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
sub output { |
495
|
0
|
|
|
0
|
1
|
|
my ($self, $outputter, $obj, $update) = @_; |
496
|
0
|
0
|
|
|
|
|
die "Object has no ID!" unless $self->id($obj); |
497
|
0
|
|
|
|
|
|
$self->do_output(scalar($outputter), $obj, $update); |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
=head1 AUTHOR |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
Victor Porton, C<< >> |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
=head1 BUGS |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through |
507
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll |
508
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
In the current version of C there are no provision for passing |
511
|
|
|
|
|
|
|
file handles for example got from a HTML form with a C control. |
512
|
|
|
|
|
|
|
A complexity is that usually to upload a file we need to already know the |
513
|
|
|
|
|
|
|
ID of a row in a database what is possible only I inserting into the DB. |
514
|
|
|
|
|
|
|
Your suggestions how to deal with this problem are welcome. |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
=head1 SUPPORT |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
perldoc Backed_Objects |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
You can also look for information at: |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
=over 4 |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
L |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
L |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
=item * CPAN Ratings |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
L |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
=item * Search CPAN |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
L |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
=back |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
Copyright 2011 Victor Porton. |
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
550
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
551
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
=cut |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
1; # End of Backed_Objects |