line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package EnsEMBL::Web::Record; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
### Inside-out class representing persistent user information. This class |
4
|
|
|
|
|
|
|
### follows the Active Record design pattern: it contains both the domain |
5
|
|
|
|
|
|
|
### logic required to create and manipulate a piece of persistent data, and |
6
|
|
|
|
|
|
|
### the information necessary to maintain this data in a database. |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
### It allows the storage of arbitrary hash keys and their values |
9
|
|
|
|
|
|
|
### (user bookmarks, etc) in a single database field, and uses autoloading |
10
|
|
|
|
|
|
|
### to enable new data to be stored at will without the need for additional code |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 NAME |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
EnsEMBL::Web::Record - A family of modules used for managing a user's |
15
|
|
|
|
|
|
|
persistant data in a database. |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 VERSION |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
Version 1.01 |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=cut |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
our $VERSION = '1.01'; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 SYNOPSIS |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
Many web sites now encourage users to register and login to access |
28
|
|
|
|
|
|
|
more advanced features, and to customise a site to their needs. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
The EnsEMBL::Web::Record group of Perl modules is design to manage |
31
|
|
|
|
|
|
|
any arbitrary type of user created data in an SQL database. This |
32
|
|
|
|
|
|
|
module follows the Active Record design pattern, in that each new |
33
|
|
|
|
|
|
|
instantiated Record object represents a single row of a database. |
34
|
|
|
|
|
|
|
That object can be manipulated programatically, and any changes made |
35
|
|
|
|
|
|
|
can be stored in the database with a single record->save function |
36
|
|
|
|
|
|
|
call. |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
Because arbitrary Perl data structures can be stored in this |
39
|
|
|
|
|
|
|
manner, EnsEMBL::Web::Record allows user preferences to be easily |
40
|
|
|
|
|
|
|
saved, and allows developers to implement new featurs quickly. |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
This module was first used (and has been abstracted from) the |
43
|
|
|
|
|
|
|
Ensembl genome browser (http://www.ensembl.org). |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
New user data can be added to the database: |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
use EnsEMBL::Web::Record; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
my $bookmark = EnsEMBL::Web::Record->new(); |
50
|
|
|
|
|
|
|
$bookmark->url('http://www.ensembl.org'); |
51
|
|
|
|
|
|
|
$bookmark->name('Ensembl'); |
52
|
|
|
|
|
|
|
$bookmark->save; |
53
|
|
|
|
|
|
|
... |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
The Record can be associated with an user id: |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
$record->user($id); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
The same record can also be removed: |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
$bookmark->delete; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
EnsEMBL::Web::Record also provides a number of methods for getting |
64
|
|
|
|
|
|
|
collections of records from the database, using a field selector. |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
EnsEMBL::Web::Record::find_bookmarks_by_user_id($id). |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
=cut |
69
|
|
|
|
|
|
|
|
70
|
1
|
|
|
1
|
|
58744
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
44
|
|
71
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
29
|
|
72
|
1
|
|
|
1
|
|
1078
|
use Data::Dumper; |
|
1
|
|
|
|
|
18103
|
|
|
1
|
|
|
|
|
1600
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
our $AUTOLOAD; |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
{ |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
my %Adaptor_of; |
79
|
|
|
|
|
|
|
my %Fields_of; |
80
|
|
|
|
|
|
|
my %ParameterSet_of; |
81
|
|
|
|
|
|
|
my %Records_of; |
82
|
|
|
|
|
|
|
my %Tainted_of; |
83
|
|
|
|
|
|
|
my %Id_of; |
84
|
|
|
|
|
|
|
my %CreatedAt_of; |
85
|
|
|
|
|
|
|
my %ModifiedAt_of; |
86
|
|
|
|
|
|
|
my %Type_of; |
87
|
|
|
|
|
|
|
my %Owner_of; |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=head1 METHODS |
90
|
|
|
|
|
|
|
=cut |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head2 AUTOLOAD |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
The AUTOLOAD method allows EnsEMBL::Web::Record to automatically provide |
95
|
|
|
|
|
|
|
getter and setter functionality for an arbitrary set of fields. It also |
96
|
|
|
|
|
|
|
automatically dispatches find_by requests. |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
Field attributes are not validated against the database. |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=cut |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub AUTOLOAD { |
103
|
|
|
|
|
|
|
### AUTOLOAD method for getting and setting record attributes, and processing |
104
|
|
|
|
|
|
|
### find_by requests. Attributes should be named after columns in the |
105
|
|
|
|
|
|
|
### appropriate database table. |
106
|
|
|
|
|
|
|
### |
107
|
|
|
|
|
|
|
### Attribute names are not validated against the database table. |
108
|
0
|
|
|
0
|
|
|
my $self = shift; |
109
|
0
|
|
|
|
|
|
my ($key) = ($AUTOLOAD =~ /::([a-z].*)$/); |
110
|
0
|
|
|
|
|
|
my ($value, $options) = @_; |
111
|
|
|
|
|
|
|
#warn "AUTOLOADING $key"; |
112
|
0
|
0
|
|
|
|
|
if ($value) { |
113
|
0
|
0
|
|
|
|
|
if (my ($find, $by) = ($key =~ /find_(.*)_by_(.*)/)) { |
114
|
0
|
|
|
|
|
|
my $table = "user"; |
115
|
0
|
|
|
|
|
|
my $record_type = "User"; |
116
|
0
|
0
|
|
|
|
|
if ($find eq "records") { |
117
|
0
|
|
|
|
|
|
$find = ""; |
118
|
|
|
|
|
|
|
} |
119
|
0
|
0
|
|
|
|
|
if ($find eq "group_records") { |
120
|
0
|
|
|
|
|
|
$find = ""; |
121
|
0
|
|
|
|
|
|
$table = "group"; |
122
|
|
|
|
|
|
|
} |
123
|
0
|
0
|
|
|
|
|
if ($by =~ /group_record/) { |
124
|
0
|
|
|
|
|
|
$table = "group"; |
125
|
0
|
|
|
|
|
|
$record_type = "Group"; |
126
|
|
|
|
|
|
|
} |
127
|
0
|
|
|
|
|
|
return find_records(( record_type => $record_type, type => $find, $by => $value, table => $table, options => $options)); |
128
|
|
|
|
|
|
|
} else { |
129
|
0
|
0
|
|
|
|
|
if (my ($type) = ($key =~ /(.*)_records/)) { |
130
|
0
|
|
|
|
|
|
return $self->records_of_type($type, $value); |
131
|
|
|
|
|
|
|
} |
132
|
0
|
|
|
|
|
|
$self->fields($key, $value); |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
} else { |
135
|
0
|
0
|
|
|
|
|
if (my ($type) = ($key =~ /(.*)_records/)) { |
136
|
0
|
|
|
|
|
|
return $self->records_of_type($type); |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
} |
139
|
0
|
|
|
|
|
|
return $self->fields($key); |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=head2 new |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
Creates a new Record object. This module follows the Active Record pattern: it contains both the domain |
146
|
|
|
|
|
|
|
logic required to create and manipulate a piece of persistent data, and |
147
|
|
|
|
|
|
|
the information necessary to maintain this data in a database. |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
You should pass in a valid database adaptor, which contains the necessary sql requests. An example adaptor can be found in the distribution. |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
$record = EnsEMBL::Web::Record->new(( adaptor => $adaptor )); |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=cut |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub new { |
156
|
|
|
|
|
|
|
### c |
157
|
0
|
|
|
0
|
1
|
|
my ($class, %params) = @_; |
158
|
0
|
|
|
|
|
|
my $self = bless \my($scalar), $class; |
159
|
0
|
0
|
|
|
|
|
$Adaptor_of{$self} = defined $params{'adaptor'} ? $params{'adaptor'} : undef; |
160
|
0
|
0
|
|
|
|
|
$Records_of{$self} = defined $params{'records'} ? $params{'records'} : []; |
161
|
0
|
0
|
|
|
|
|
$ParameterSet_of{$self} = defined $params{'parameter_set'} ? $params{'parameter_set'} : undef; |
162
|
0
|
0
|
|
|
|
|
$Id_of{$self} = defined $params{'id'} ? $params{'id'} : undef; |
163
|
0
|
0
|
|
|
|
|
$CreatedAt_of{$self} = defined $params{'created_at'} ? $params{'created_at'} : undef; |
164
|
0
|
0
|
|
|
|
|
$ModifiedAt_of{$self} = defined $params{'modified_at'} ? $params{'modified_at'} : undef; |
165
|
0
|
0
|
|
|
|
|
$Type_of{$self} = defined $params{'type'} ? $params{'type'} : "record"; |
166
|
0
|
|
|
|
|
|
$Fields_of{$self} = {}; |
167
|
0
|
|
|
|
|
|
$Tainted_of{$self} = {}; |
168
|
0
|
0
|
|
|
|
|
if ($params{'data'}) { |
169
|
|
|
|
|
|
|
#$self->data($params{'data'}); |
170
|
0
|
|
|
|
|
|
my $eval = eval($params{'data'}); |
171
|
0
|
|
|
|
|
|
$Fields_of{$self} = $eval; |
172
|
|
|
|
|
|
|
} else { |
173
|
0
|
|
|
|
|
|
$Fields_of{$self} = {}; |
174
|
|
|
|
|
|
|
} |
175
|
0
|
|
|
|
|
|
return $self; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=head2 taint |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
Marks a particular collection of records for an update. Tainted |
182
|
|
|
|
|
|
|
records are updated in the database when the Record's save method |
183
|
|
|
|
|
|
|
is called. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=cut |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub taint { |
188
|
|
|
|
|
|
|
### Marks a particular collection of records for an update. Tainted |
189
|
|
|
|
|
|
|
### records are updated in the database when the Record's save method |
190
|
|
|
|
|
|
|
### is called. |
191
|
0
|
|
|
0
|
1
|
|
my ($self, $type) = @_; |
192
|
0
|
|
|
|
|
|
$self->tainted->{$type} = 1; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=head2 dump_data |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
Uses Data::Dumper to format a record's data for storage, |
198
|
|
|
|
|
|
|
and also handles escaping of quotes to avoid SQL errors |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=cut |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub dump_data { |
203
|
|
|
|
|
|
|
### Uses Data::Dumper to format a record's data for storage, |
204
|
|
|
|
|
|
|
### and also handles escaping of quotes to avoid SQL errors |
205
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
206
|
0
|
|
|
|
|
|
my $temp_fields = {}; |
207
|
0
|
|
|
|
|
|
foreach my $key (keys %{ $self->fields }) { |
|
0
|
|
|
|
|
|
|
208
|
0
|
|
|
|
|
|
$temp_fields->{$key} = $self->fields->{$key}; |
209
|
0
|
|
|
|
|
|
$temp_fields->{$key} =~ s/'/\\'/g; |
210
|
|
|
|
|
|
|
} |
211
|
0
|
|
|
|
|
|
my $dump = Dumper($temp_fields); |
212
|
|
|
|
|
|
|
#$dump =~ s/'/\\'/g; |
213
|
0
|
|
|
|
|
|
$dump =~ s/^\$VAR1 = //; |
214
|
0
|
|
|
|
|
|
return $dump; |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=head2 fields |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
Accessor for the fields property. |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=cut |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub fields { |
224
|
|
|
|
|
|
|
### a |
225
|
0
|
|
|
0
|
1
|
|
my ($self, $key, $value) = @_; |
226
|
0
|
0
|
|
|
|
|
if ($key) { |
227
|
0
|
0
|
|
|
|
|
if ($value) { |
228
|
0
|
|
|
|
|
|
$value =~ s/'/\\'/g; |
229
|
0
|
|
|
|
|
|
$Fields_of{$self}->{$key} = $value; |
230
|
|
|
|
|
|
|
} |
231
|
0
|
|
|
|
|
|
return $Fields_of{$self}->{$key} |
232
|
|
|
|
|
|
|
} else { |
233
|
0
|
|
|
|
|
|
return $Fields_of{$self}; |
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=head2 records |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Accessor for the records property. |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=cut |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub records { |
244
|
|
|
|
|
|
|
### a |
245
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
246
|
0
|
0
|
|
|
|
|
$Records_of{$self} = shift if @_; |
247
|
0
|
|
|
|
|
|
return $Records_of{$self}; |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=head2 type |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
Accessor for the type property. |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
=cut |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
sub type { |
257
|
|
|
|
|
|
|
### a |
258
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
259
|
0
|
0
|
|
|
|
|
$Type_of{$self} = shift if @_; |
260
|
0
|
|
|
|
|
|
return $Type_of{$self}; |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=head2 tainted |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
Accessor for the tainted property. |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=cut |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub tainted { |
270
|
|
|
|
|
|
|
### a |
271
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
272
|
0
|
0
|
|
|
|
|
$Tainted_of{$self} = shift if @_; |
273
|
0
|
|
|
|
|
|
return $Tainted_of{$self}; |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=head2 adaptor |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
Accessor for the tainted property. |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=cut |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub adaptor { |
283
|
|
|
|
|
|
|
### a |
284
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
285
|
0
|
0
|
|
|
|
|
$Adaptor_of{$self} = shift if @_; |
286
|
0
|
|
|
|
|
|
return $Adaptor_of{$self}; |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
=head2 parameter_set |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
Accessor for the parameter_set property. |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=cut |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
sub parameter_set { |
296
|
|
|
|
|
|
|
### a |
297
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
298
|
0
|
0
|
|
|
|
|
$ParameterSet_of{$self} = shift if @_; |
299
|
0
|
|
|
|
|
|
return $ParameterSet_of{$self}; |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=head2 id |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
Accessor for the id property. |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=cut |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub id { |
309
|
|
|
|
|
|
|
### a |
310
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
311
|
0
|
0
|
|
|
|
|
$Id_of{$self} = shift if @_; |
312
|
0
|
|
|
|
|
|
return $Id_of{$self}; |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=head2 created_at |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
Accessor for the created_at property. |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=cut |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
sub created_at { |
322
|
|
|
|
|
|
|
### a |
323
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
324
|
0
|
0
|
|
|
|
|
$CreatedAt_of{$self} = shift if @_; |
325
|
0
|
|
|
|
|
|
return $CreatedAt_of{$self}; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=head2 modified_at |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
Accessor for the modified_at property. |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=cut |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
sub modified_at { |
335
|
|
|
|
|
|
|
### a |
336
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
337
|
0
|
0
|
|
|
|
|
$ModifiedAt_of{$self} = shift if @_; |
338
|
0
|
|
|
|
|
|
return $ModifiedAt_of{$self}; |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=head2 records_of_type |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
Returns an array of records, that match a particular type. |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=cut |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
sub records_of_type { |
348
|
|
|
|
|
|
|
### Returns an array of records |
349
|
|
|
|
|
|
|
### Argument 1: Type - string corresponding to a type of record, e.g. 'bookmark' |
350
|
|
|
|
|
|
|
### Argument 2: Options - hash ref ('order_by' => sort expression, e.g.) |
351
|
0
|
|
|
0
|
1
|
|
my ($self, $type, $options) = @_; |
352
|
0
|
|
|
|
|
|
my @return = (); |
353
|
0
|
0
|
|
|
|
|
if ($self->records) { |
354
|
0
|
|
|
|
|
|
foreach my $record (@{ $self->records }) { |
|
0
|
|
|
|
|
|
|
355
|
0
|
0
|
|
|
|
|
if ($record->type eq $type) { |
356
|
0
|
|
|
|
|
|
push @return, $record; |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
} |
360
|
0
|
0
|
|
|
|
|
if ($options->{'order_by'}) { |
361
|
0
|
|
|
|
|
|
my $sorter = $options->{'order_by'}; |
362
|
0
|
|
|
|
|
|
@return = reverse sort { $a->$sorter <=> $b->$sorter } sort @return; |
|
0
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
} |
364
|
0
|
|
|
|
|
|
return @return; |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
=head2 find_records |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
Returns an array of records. This method is called by the autoloading mechanism, and is not intended for |
370
|
|
|
|
|
|
|
public use. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=cut |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
sub find_records { |
375
|
0
|
|
|
0
|
1
|
|
my (%params) = @_; |
376
|
0
|
|
|
|
|
|
my $record_type = "User"; |
377
|
0
|
0
|
|
|
|
|
if ($params{record_type}) { |
378
|
0
|
|
|
|
|
|
$record_type = $params{record_type}; |
379
|
0
|
|
|
|
|
|
delete $params{record_type}; |
380
|
|
|
|
|
|
|
} |
381
|
0
|
|
|
|
|
|
$record_type = "EnsEMBL::Web::Record::" . $record_type; |
382
|
0
|
|
|
|
|
|
my $user_adaptor = undef; |
383
|
0
|
0
|
|
|
|
|
if ($params{options}->{adaptor}) { |
384
|
0
|
|
|
|
|
|
$user_adaptor = $params{options}->{adaptor}; |
385
|
0
|
|
|
|
|
|
warn "ADAPTOR for FIND: " . $user_adaptor; |
386
|
|
|
|
|
|
|
} |
387
|
0
|
|
|
|
|
|
my $results = $user_adaptor->find_records(%params); |
388
|
0
|
|
|
|
|
|
my @records = (); |
389
|
0
|
|
|
|
|
|
foreach my $result (@{ $results }) { |
|
0
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
#if (&dynamic_use($record_type)) { |
391
|
0
|
|
|
|
|
|
my $record = $record_type->new(( |
392
|
|
|
|
|
|
|
id => $result->{id}, |
393
|
|
|
|
|
|
|
type => $result->{type}, |
394
|
|
|
|
|
|
|
user => $result->{user}, |
395
|
|
|
|
|
|
|
data => $result->{data}, |
396
|
|
|
|
|
|
|
created_at => $result->{created_at}, |
397
|
|
|
|
|
|
|
modified_at => $result->{modified_at} |
398
|
|
|
|
|
|
|
)); |
399
|
0
|
|
|
|
|
|
push @records, $record; |
400
|
|
|
|
|
|
|
#} |
401
|
|
|
|
|
|
|
} |
402
|
0
|
0
|
|
|
|
|
if ($params{options}) { |
403
|
0
|
|
|
|
|
|
my %options = %{ $params{options} }; |
|
0
|
|
|
|
|
|
|
404
|
0
|
0
|
|
|
|
|
if ($options{order_by}) { |
405
|
0
|
|
|
|
|
|
@records = sort { $b->click <=> $a->click } @records; |
|
0
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
} |
408
|
0
|
|
|
|
|
|
return @records; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
=head2 owner |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
Accessor for the owner property. |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
=cut |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
sub owner { |
418
|
|
|
|
|
|
|
### a |
419
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
420
|
0
|
0
|
|
|
|
|
$Owner_of{$self} = shift if @_; |
421
|
0
|
|
|
|
|
|
return $Owner_of{$self}; |
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
=head2 DESTROY |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
Called automatically by Perl when object reference count reaches zero. |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
=cut |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
sub DESTROY { |
431
|
|
|
|
|
|
|
### d |
432
|
0
|
|
|
0
|
|
|
my $self = shift; |
433
|
0
|
|
|
|
|
|
delete $Adaptor_of{$self}; |
434
|
0
|
|
|
|
|
|
delete $Fields_of{$self}; |
435
|
0
|
|
|
|
|
|
delete $Id_of{$self}; |
436
|
0
|
|
|
|
|
|
delete $CreatedAt_of{$self}; |
437
|
0
|
|
|
|
|
|
delete $ModifiedAt_of{$self}; |
438
|
0
|
|
|
|
|
|
delete $Records_of{$self}; |
439
|
0
|
|
|
|
|
|
delete $ParameterSet_of{$self}; |
440
|
0
|
|
|
|
|
|
delete $Tainted_of{$self}; |
441
|
0
|
|
|
|
|
|
delete $Type_of{$self}; |
442
|
0
|
|
|
|
|
|
delete $Owner_of{$self}; |
443
|
|
|
|
|
|
|
} |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
} |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
=head1 AUTHOR |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
Matt Wood, C<< >> |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
=head1 BUGS |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
454
|
|
|
|
|
|
|
C, or through the web interface at |
455
|
|
|
|
|
|
|
L. |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
=head1 SUPPORT |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
perldoc EnsEMBL::Web::Record |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
You can also look for information at: http://www.ensembl.org |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=over 4 |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
L |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
=item * CPAN Ratings |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
L |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
L |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
=item * Search CPAN |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
L |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=back |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
Many thanks to everyone on the Ensembl team, in particular James Smith, Anne Parker, Fiona Cunningham and Beth Prichard. |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
Copyright (c) 1999-2006 The European Bioinformatics Institute and Genome Research Limited, and others. All rights reserved. |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
496
|
|
|
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
497
|
|
|
|
|
|
|
3. The name Ensembl must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact ensembl-dev@ebi.ac.uk |
498
|
|
|
|
|
|
|
4. Products derived from this software may not be called "Ensembl" nor may "Ensembl" appear in their names without prior written permission of the Ensembl developers. |
499
|
|
|
|
|
|
|
5. Redistributions of any form whatsoever must retain the following acknowledgment: "This product includes software developed by Ensembl (http://www.ensembl.org/). |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE ENSEMBL GROUP "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ENSEMBL GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=cut |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
1; |