line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package DBIx::Objects; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
74159
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
52
|
|
4
|
1
|
|
|
1
|
|
6
|
use warnings qw(all); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
502
|
|
5
|
1
|
|
|
1
|
|
6
|
use vars qw($VERSION); |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
75
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
BEGIN { |
8
|
1
|
|
|
1
|
|
193
|
$VERSION=0.04; |
9
|
|
|
|
|
|
|
} |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
### |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
package DBIx::Object; |
14
|
|
|
|
|
|
|
|
15
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
50
|
|
16
|
1
|
|
|
1
|
|
148
|
use warnings qw(all); |
|
1
|
|
|
|
|
10
|
|
|
1
|
|
|
|
|
4027
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Back-end methods |
19
|
|
|
|
|
|
|
sub _blank { # Default back-end for constructor |
20
|
|
|
|
|
|
|
# ARGS: $self, [$namespace,] @arglist |
21
|
|
|
|
|
|
|
# $namespace - Scalar (string) - Namespace of managing package for variables |
22
|
|
|
|
|
|
|
# @arglist - Array (string) - List of variables to be registered as methods |
23
|
0
|
|
|
0
|
|
|
my $self=shift; |
24
|
0
|
|
0
|
|
|
|
my $package= |
25
|
|
|
|
|
|
|
(UNIVERSAL::isa($_[0],__PACKAGE__) && # Looks like a descendant |
26
|
|
|
|
|
|
|
shift) || caller; # Shift or autodetect namespace to register |
27
|
0
|
0
|
|
|
|
|
warn "Package $package not listed in registry" |
28
|
|
|
|
|
|
|
unless defined($self->{_REGISTRY}{$package}); |
29
|
0
|
|
|
|
|
|
while (@_) { |
30
|
0
|
|
|
|
|
|
local $_=uc(shift); |
31
|
0
|
|
|
|
|
|
$self->{$_}=undef; |
32
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$_}{source}=$package; |
33
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$_}{access}=1; # default to rw |
34
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$_}{type}="basic"; |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub _register { # Default back-end for package registration |
39
|
|
|
|
|
|
|
# Call immediately after being bless()ed |
40
|
0
|
|
|
0
|
|
|
my $self=shift; |
41
|
0
|
|
|
|
|
|
my $package=caller; |
42
|
0
|
0
|
|
|
|
|
$self->{_REGISTRY}{$package}{prep}=0 unless (defined($self->{_REGISTRY}{$package})); |
43
|
0
|
|
|
|
|
|
return defined($self->{_REGISTRY}{$package}); |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub _unregister{# Default back-end for package de-registration |
47
|
|
|
|
|
|
|
# If you wish to partially destruct an object, make sure to call this |
48
|
|
|
|
|
|
|
# from each namespace being removed from the object |
49
|
0
|
|
|
0
|
|
|
my $self=shift; |
50
|
0
|
|
|
|
|
|
my $package=caller; |
51
|
0
|
|
|
|
|
|
$self->_taint($package); |
52
|
0
|
|
|
|
|
|
undef $self->{_REGISTRY}{$package}; |
53
|
0
|
|
|
|
|
|
return (!(defined($self->{_REGISTRY}{$package}))); |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub _primary { # Sets/detects whether a namespace contains the primary key |
57
|
|
|
|
|
|
|
# Used internally to assure that the primary key's namespace is always |
58
|
|
|
|
|
|
|
# in sync with the rest of the object |
59
|
0
|
|
|
0
|
|
|
my $self=shift; |
60
|
0
|
|
0
|
|
|
|
my $package=(UNIVERSAL::isa($_[0],__PACKAGE__) && shift) || caller; |
61
|
0
|
0
|
|
|
|
|
if ($_[0]) {$self->{_REGISTRY}{_PRIMARY}=$package;$self->_taint;} |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
62
|
0
|
|
0
|
|
|
|
return ($self->{_REGISTRY}{_PRIMARY} || 0); |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub _readonly { # Sets/detects whether a data mehod is tagged read-only |
66
|
|
|
|
|
|
|
# Used by AUTOLOAD to detect read-only method calls |
67
|
0
|
|
|
0
|
|
|
my $self=shift; |
68
|
0
|
|
0
|
|
|
|
my $package=(UNIVERSAL::isa($_[0],__PACKAGE__) && shift) || caller; |
69
|
0
|
|
|
|
|
|
my $var=uc(shift); |
70
|
0
|
0
|
|
|
|
|
if (@_) {local $_=shift;$self->{_REGISTRY}{_DATA}{$var}{access}=(!($_)?1:0) if (/[01]/);} #Set to "0" to catch in this check next time |
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
71
|
0
|
|
0
|
|
|
|
return (!($self->{_REGISTRY}{_DATA}{$var}{access}) || |
72
|
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{source} eq $self->_primary); |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
sub _validate { # Marks a namespace as tied to the back-end database |
76
|
|
|
|
|
|
|
# Intended to be called on first refresh - Paired with _taint |
77
|
0
|
|
|
0
|
|
|
my $self=shift; |
78
|
0
|
|
0
|
|
|
|
my $package=shift || caller; |
79
|
0
|
0
|
|
|
|
|
(my @vars=$self->_vars($package)) || return $self; |
80
|
0
|
|
|
|
|
|
foreach my $var (@vars) { |
81
|
0
|
0
|
|
|
|
|
if ($self->_isobject($var)) { # Reset embedded object information (only if needed) |
82
|
0
|
0
|
0
|
|
|
|
unless ($self->{var} && ($self->{_REGISTRY}{_DATA}{$var}{data} eq $self->{$var})) { |
83
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{data}=$self->{$var}; |
84
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{prep}=0; |
85
|
0
|
|
|
|
|
|
$self->{$var}=undef; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
} |
89
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{$package}{prep}=1; |
90
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{ref($self)}{prep}=1; |
91
|
0
|
|
|
|
|
|
$self->_clean($package); |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub _taint { # Marks a namespace as untied from the back-end database |
95
|
|
|
|
|
|
|
# Intended to be called on destruction only |
96
|
0
|
|
|
0
|
|
|
my $self=shift; |
97
|
0
|
|
0
|
|
|
|
my $package=shift || caller; |
98
|
0
|
|
|
|
|
|
$self->_dirty($package); |
99
|
0
|
0
|
|
|
|
|
(my @vars=$self->_vars($package)) || return $self; |
100
|
0
|
|
|
|
|
|
foreach my $var (@vars) { |
101
|
0
|
0
|
|
|
|
|
if ($self->_isobject($var)) { # Reset embedded object information (only if needed) |
102
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{prep}=0; |
103
|
0
|
|
|
|
|
|
$self->{$var}=undef; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
} |
106
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{$package}{prep}=0; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub _clean { # Marks a namespace as in-sync with the back-end database |
110
|
|
|
|
|
|
|
# Intended to be called on all calls to add(), refresh() and update() |
111
|
0
|
|
|
0
|
|
|
my $self=shift; |
112
|
0
|
|
0
|
|
|
|
my $package=shift || caller; |
113
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{$package}{dirty}=0; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub _dirty { # Marks a namespace as out-of-sync with the back-end databse |
117
|
|
|
|
|
|
|
# Intended to be called upon a write-access call to a class-method |
118
|
0
|
|
|
0
|
|
|
my $self=shift; |
119
|
0
|
|
0
|
|
|
|
my $package=shift || caller; |
120
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{$package}{dirty}=1; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub _vars { # Returns a list of variables registered to a specific namespace |
124
|
|
|
|
|
|
|
# Used internally by default _refresh() and update() methods |
125
|
0
|
|
|
0
|
|
|
my $self=shift; |
126
|
0
|
|
0
|
|
|
|
my $package=shift || caller; |
127
|
0
|
|
|
|
|
|
my @vars = (); |
128
|
0
|
|
|
|
|
|
my @keys = keys(%{$self->{_REGISTRY}{_DATA}}); |
|
0
|
|
|
|
|
|
|
129
|
0
|
|
|
|
|
|
foreach my $var(@keys) { |
130
|
0
|
0
|
|
|
|
|
push @vars,$var if ($self->{_REGISTRY}{_DATA}{$var}{source} eq $package); |
131
|
|
|
|
|
|
|
} |
132
|
0
|
|
|
|
|
|
return @vars; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub _refresh { # Default back-end for refresh |
136
|
|
|
|
|
|
|
# Inherited classes should implement a custom _refresh() |
137
|
|
|
|
|
|
|
# Alternatively, the default _refresh may be used if a valid DBI connection |
138
|
|
|
|
|
|
|
# is set using $__PACKAGE__::dbh and the table is set to $__PACKAGE__::table |
139
|
0
|
|
|
0
|
|
|
my $self=shift; |
140
|
0
|
|
0
|
|
|
|
my $package=(UNIVERSAL::isa($_[0],__PACKAGE__) && shift) || ref($self); |
141
|
0
|
|
0
|
|
|
|
my @vars=$self->_vars($package) || return $self; |
142
|
0
|
|
|
|
|
|
my $sth; |
143
|
|
|
|
|
|
|
{ |
144
|
1
|
|
|
1
|
|
10
|
no strict 'vars'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
183
|
|
|
0
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
|
eval "\$sth=\$dbh->prepare_cached('SELECT \@vars FROM \$table WHERE (ID=?)');"; |
146
|
|
|
|
|
|
|
} |
147
|
0
|
0
|
|
|
|
|
$sth->execute(@_) or return $self->blank; |
148
|
0
|
0
|
|
|
|
|
if ($sth->rows!=1) { |
149
|
0
|
|
|
|
|
|
$self->blank; |
150
|
|
|
|
|
|
|
} else { |
151
|
0
|
|
|
|
|
|
my $res=$sth->fetchrow_hashref; |
152
|
0
|
|
|
|
|
|
foreach my $var (@vars) { |
153
|
0
|
|
|
|
|
|
$self->{$var}=$res->{$var}; |
154
|
|
|
|
|
|
|
} |
155
|
0
|
|
|
|
|
|
$self->_validate; |
156
|
|
|
|
|
|
|
} |
157
|
0
|
|
|
|
|
|
$sth->finish; |
158
|
0
|
|
|
|
|
|
return $self; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub AUTOLOAD { # Default method call handler |
162
|
|
|
|
|
|
|
# Current support: |
163
|
|
|
|
|
|
|
# * Read/Write registered methods from internal hash |
164
|
0
|
|
|
0
|
|
|
my $param; |
165
|
|
|
|
|
|
|
my $package; |
166
|
|
|
|
|
|
|
{ |
167
|
1
|
|
|
1
|
|
7
|
no strict 'vars'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
5509
|
|
|
0
|
|
|
|
|
|
|
168
|
0
|
|
|
|
|
|
$AUTOLOAD=~s/(.*):://; |
169
|
0
|
|
|
|
|
|
$package=$1; |
170
|
0
|
|
|
|
|
|
$param=$AUTOLOAD; |
171
|
|
|
|
|
|
|
} |
172
|
0
|
0
|
|
|
|
|
if (UNIVERSAL::isa($_[0],__PACKAGE__)) { # Method call of a sub-class |
173
|
0
|
|
|
|
|
|
my $self=shift; |
174
|
0
|
0
|
|
|
|
|
if ($self->{_REGISTRY}{_DATA}{uc($param)}) { # Acceptable function call |
175
|
0
|
|
|
|
|
|
my $source=$self->{_REGISTRY}{_DATA}{uc($param)}{source}; |
176
|
0
|
0
|
|
|
|
|
if (!($self->valid($source))) { |
177
|
0
|
|
|
|
|
|
$self->refresh($source); |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
# SET access |
180
|
0
|
0
|
0
|
|
|
|
if ((@_) && !($self->_readonly($source,$param))) { # Update rewriteable request |
181
|
0
|
0
|
|
|
|
|
if ($self->_isbasic($param)) { |
|
|
0
|
|
|
|
|
|
182
|
0
|
|
|
|
|
|
$self->{uc($param)}=@_; |
183
|
0
|
|
|
|
|
|
$self->_taint; |
184
|
|
|
|
|
|
|
} elsif ($self->_isobject($param)) { # Object SET |
185
|
0
|
0
|
|
|
|
|
unless ($self->_isobjarray($param)) { # No SET allowed on arrays |
186
|
0
|
|
|
|
|
|
my ($temp,$pid)=@_; |
187
|
0
|
0
|
|
|
|
|
if (ref($temp) eq $self->{_REGISTRY}{_DATA}{uc($param)}{class}) { |
188
|
|
|
|
|
|
|
# TODO: see if temp->isa($self->{_REGISTRY}{_DATA}{uc($param)}{class}) |
189
|
0
|
|
|
|
|
|
$pid=$temp->id; #Retrieve ID from internal object |
190
|
|
|
|
|
|
|
} else { |
191
|
0
|
|
|
|
|
|
$pid=$temp; #Assume ID is specified if not compatible object |
192
|
|
|
|
|
|
|
} |
193
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{uc($param)}{data}=$pid; |
194
|
0
|
|
|
|
|
|
$self->_taint; |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
} # GET access |
198
|
0
|
0
|
|
|
|
|
if ($self->_isobject($param)) { # Prepare object |
199
|
0
|
0
|
|
|
|
|
return (wantarray?undef:0) unless $self->_o_prep($param); |
|
|
0
|
|
|
|
|
|
200
|
|
|
|
|
|
|
} |
201
|
0
|
0
|
|
|
|
|
if ($self->_isobjarray($param)) { # Object array returns special values |
202
|
0
|
0
|
|
|
|
|
return (wantarray?@{$self->{uc($param)}}:$self->{_REGISTRY}{_DATA}{uc($param)}{prep}); |
|
0
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
} else { |
204
|
0
|
|
|
|
|
|
return $self->{uc($param)}; |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
sub new { # Default constructor |
211
|
|
|
|
|
|
|
# Do not overload this unless you're SURE you know what you're doing |
212
|
0
|
|
|
0
|
|
|
my $self={ }; |
213
|
0
|
|
|
|
|
|
my $proto=shift; |
214
|
0
|
|
0
|
|
|
|
my $class=ref($proto) || $proto; |
215
|
0
|
|
|
|
|
|
bless $self,$class; |
216
|
0
|
|
|
|
|
|
eval "foreach \$_ (\@".$class."::ISA) {eval \$_.\"::blank(\\\$self);\";}"; |
217
|
0
|
|
|
|
|
|
$self->_register; |
218
|
0
|
|
|
|
|
|
$self->blank(@_); |
219
|
0
|
0
|
|
|
|
|
if (@_) { |
220
|
0
|
0
|
|
|
|
|
eval ($self->_primary."::_refresh(\$self,'".$self->_primary."',@_);") if ($self->_primary); |
221
|
0
|
|
|
|
|
|
$self->_refresh(@_); |
222
|
|
|
|
|
|
|
} |
223
|
0
|
|
|
|
|
|
return $self; |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
sub clean { # Returns true if namepace is in-sync with back-end database |
227
|
|
|
|
|
|
|
# Be sure to check for valid()ity BEFORE using this |
228
|
0
|
|
|
0
|
|
|
my $self=shift; |
229
|
0
|
|
0
|
|
|
|
my $package=shift || caller; |
230
|
0
|
|
|
|
|
|
return !($self->{_REGISTRY}{$package}{dirty}); |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
sub valid { # Returns true if namespace is tied and in-sync with back-end database |
234
|
0
|
|
|
0
|
|
|
my $self=shift; |
235
|
0
|
|
0
|
|
|
|
my $package=shift || ref($self); |
236
|
0
|
0
|
0
|
|
|
|
if ($self->_primary) |
|
0
|
|
|
|
|
|
|
237
|
0
|
|
0
|
|
|
|
{return ($self->{_REGISTRY}{$self->_primary}{prep} && |
238
|
|
|
|
|
|
|
$self->clean($self->_primary) && |
239
|
|
|
|
|
|
|
$self->{_REGISTRY}{$package}{prep} && |
240
|
|
|
|
|
|
|
$self->clean($package))} |
241
|
|
|
|
|
|
|
else {return $self->{_REGISTRY}{$package}{prep} && |
242
|
|
|
|
|
|
|
$self->clean($package)}; |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub blank { # Default (abstract) blank method - used by the default constructor |
246
|
|
|
|
|
|
|
# This should be overridden by any inherited class that's meant to be useful |
247
|
|
|
|
|
|
|
# A typical blank() method should look like: |
248
|
|
|
|
|
|
|
# sub blank { |
249
|
|
|
|
|
|
|
# my $self=shift; |
250
|
|
|
|
|
|
|
# $self->_register; |
251
|
|
|
|
|
|
|
# $self->_blank("FOO", "BAR", ... , "LAST"); |
252
|
|
|
|
|
|
|
# } |
253
|
0
|
|
|
0
|
|
|
$_[0]->_register; |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
sub refresh { # Default front-end for refresh |
257
|
0
|
|
|
0
|
|
|
my $self=shift; |
258
|
0
|
|
0
|
|
|
|
my $package=shift || ref($self); |
259
|
0
|
|
|
|
|
|
$self->_taint($package); |
260
|
0
|
|
|
|
|
|
eval $package."::_refresh(\$self,".$self->id.");"; |
261
|
0
|
|
|
|
|
|
return $self->valid; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
sub id { # Default id method - must be explicitly so that it can be overloaded |
265
|
|
|
|
|
|
|
# when needed for refresh, but not be dependant on the object being valid |
266
|
0
|
|
|
0
|
|
|
my $self=shift; |
267
|
|
|
|
|
|
|
# Set access |
268
|
0
|
0
|
0
|
|
|
|
if ((@_) && !($self->_readonly("id"))) { # Update rewriteable request |
269
|
0
|
|
|
|
|
|
$self->{ID}=@_; |
270
|
0
|
|
|
|
|
|
$self->_taint; |
271
|
|
|
|
|
|
|
} |
272
|
0
|
|
|
|
|
|
return $self->{ID}; |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub _isbasic { # Returns true if access method marked as basic (default) |
276
|
0
|
|
|
0
|
|
|
my $self=shift; |
277
|
0
|
|
|
|
|
|
my $var=uc(shift); |
278
|
0
|
|
|
|
|
|
return ($self->{_REGISTRY}{_DATA}{$var}{type} eq "basic"); |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
sub _isobject { # Returns true if access method marked as embedded object |
282
|
0
|
|
|
0
|
|
|
my $self=shift; |
283
|
0
|
|
|
|
|
|
my $var=uc(shift); |
284
|
0
|
|
|
|
|
|
return ($self->{_REGISTRY}{_DATA}{$var}{type} eq "object"); |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub _isobjarray { |
288
|
0
|
|
|
0
|
|
|
my $self=shift; |
289
|
0
|
|
|
|
|
|
my $var=uc(shift); |
290
|
0
|
|
0
|
|
|
|
return ($self->_isobject($var) && $self->{_REGISTRY}{_DATA}{$var}{array}); |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
sub _object { # Marks an access member as an object (call in blank) |
294
|
0
|
|
|
0
|
|
|
my $self=shift; |
295
|
0
|
|
|
|
|
|
my $var=uc(shift); |
296
|
0
|
|
0
|
|
|
|
my $package=(UNIVERSAL::isa($_[0],__PACKAGE__) && shift) || ref($self); |
297
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{prep}=0; |
298
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{class}=$package; |
299
|
0
|
|
0
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{data}=$self->{$var} || undef; |
300
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{array}=0; |
301
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{type}="object"; |
302
|
0
|
|
|
|
|
|
$self->{$var}=undef; |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
sub _objarray { # Marks an access member as an array of objects (call in blank) |
306
|
0
|
|
|
0
|
|
|
my $self=shift; |
307
|
0
|
|
|
|
|
|
my $var=uc(shift); |
308
|
0
|
|
0
|
|
|
|
my $package=(UNIVERSAL::isa($_[0],__PACKAGE__) && shift) || ref($self); |
309
|
0
|
|
|
|
|
|
$self->_object($var,$package); |
310
|
0
|
|
|
|
|
|
$self->_readonly($var,1); |
311
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{array}=1; |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
# This (objarray) won't be fully implemented until I can figure out how the heck |
315
|
|
|
|
|
|
|
# to set the data source as an array - it probably has to be dealt with by |
316
|
|
|
|
|
|
|
# end-module's refresh ($self->{$var}=@arrayofdata;) [UPDATE VALIDATE TO DEAL WITH THIS]... |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
sub _o_prep { |
319
|
0
|
|
|
0
|
|
|
my $self=shift; |
320
|
0
|
|
|
|
|
|
my $var=uc(shift); |
321
|
0
|
|
|
|
|
|
my $class=$self->{_REGISTRY}{_DATA}{$var}{class}; |
322
|
0
|
|
|
|
|
|
my $source=$self->{_REGISTRY}{_DATA}{$var}{source}; |
323
|
0
|
0
|
|
|
|
|
return 0 unless $self->valid($source); |
324
|
0
|
0
|
|
|
|
|
return $self->{_REGISTRY}{_DATA}{$var}{prep} if |
325
|
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{prep}; |
326
|
0
|
0
|
|
|
|
|
if ($self->_isobjarray($var)) { |
327
|
0
|
|
|
|
|
|
for (my $i=0;$i<=$#{$self->{_REGISTRY}{_DATA}{$var}{data}};$i++) { |
|
0
|
|
|
|
|
|
|
328
|
0
|
|
|
|
|
|
$self->{$var}[$i]=$class->new($self->{_REGISTRY}{_DATA}{$var}{data}[$i]); |
329
|
|
|
|
|
|
|
} |
330
|
0
|
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{prep}=$#{$self->{_REGISTRY}{_DATA}{$var}{data}}+1; |
|
0
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
} else { |
332
|
0
|
0
|
|
|
|
|
$self->{_REGISTRY}{_DATA}{$var}{prep}=(($self->{$var}=$class->new($self->{_REGISTRY}{_DATA}{$var}{data}))?1:0); |
333
|
|
|
|
|
|
|
} |
334
|
0
|
|
|
|
|
|
return $self->{_REGISTRY}{_DATA}{$var}{prep}; |
335
|
|
|
|
|
|
|
} |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
# TODO: Update updates recursively (into embedded objects) |
338
|
|
|
|
|
|
|
# UpdateNR updates non-0recursively (data ghets lost) |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
# DOCUMENT: _validate also initializes objects by setting internal DATA value and clearing external value |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
package DBIx::Object::DBI; #Shortcut functions for DBI-based backend |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
our @ISA=qw(DBIx::Object); |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
sub blank { |
348
|
0
|
|
|
0
|
|
|
$_[0]->_register; |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub _dbidbh { # Sets/returns the DBI connection to use |
352
|
0
|
|
|
0
|
|
|
my $self=shift; |
353
|
0
|
|
0
|
|
|
|
my $package=(UNIVERSAL::isa($_[0],__PACKAGE__) && shift) || caller; |
354
|
0
|
0
|
|
|
|
|
if($_[0]) {$self->{_REGISTRY}{$package}{DBI}{dbh}=$_[0];} |
|
0
|
|
|
|
|
|
|
355
|
0
|
|
|
|
|
|
return $self->{_REGISTRY}{$package}{DBI}{dbh}; |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
sub _dbirefresh { # Sets/returns the SQL statement to run on refresh calls |
359
|
0
|
|
|
0
|
|
|
my $self=shift; |
360
|
0
|
|
0
|
|
|
|
my $package=(UNIVERSAL::isa($_[0],__PACKAGE__) && shift) || caller; |
361
|
0
|
0
|
|
|
|
|
if($_[0]) {$self->{_REGISTRY}{$package}{DBI}{refresh}=$_[0];} |
|
0
|
|
|
|
|
|
|
362
|
0
|
|
|
|
|
|
return $self->{_REGISTRY}{$package}{DBI}{refresh}; |
363
|
|
|
|
|
|
|
} |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
sub _refresh { # Default back-end for DBI refresh |
366
|
|
|
|
|
|
|
# Inherited classes may implement a custom _refresh() |
367
|
0
|
|
|
0
|
|
|
my $self=shift; |
368
|
0
|
|
0
|
|
|
|
my $package=(UNIVERSAL::isa($_[0],__PACKAGE__) && shift) || ref($self); |
369
|
0
|
|
|
|
|
|
my $sth=$self->{_REGISTRY}{$package}{DBI}{dbh}->prepare_cached($self->{_REGISTRY}{$package}{DBI}{refresh}); |
370
|
0
|
0
|
|
|
|
|
$sth->execute(@_) or return $self->blank; |
371
|
0
|
0
|
|
|
|
|
if ($sth->rows!=1) { |
372
|
0
|
|
|
|
|
|
$self->blank; |
373
|
|
|
|
|
|
|
} else { |
374
|
0
|
|
|
|
|
|
my $res=$sth->fetchrow_hashref; |
375
|
0
|
|
|
|
|
|
foreach my $key (keys %{$res}) { |
|
0
|
|
|
|
|
|
|
376
|
0
|
|
|
|
|
|
$self->{uc($key)}=$res->{$key}; |
377
|
|
|
|
|
|
|
} |
378
|
0
|
|
|
|
|
|
$self->_validate($package); |
379
|
|
|
|
|
|
|
} |
380
|
0
|
|
|
|
|
|
$sth->finish; |
381
|
0
|
|
|
|
|
|
return $self; |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
1; |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
__END__ |