1SearchBuilder::Record(3U)ser Contributed Perl DocumentatiSoenarchBuilder::Record(3)
2
3
4
6 DBIx::SearchBuilder::Record - Superclass for records loaded by Search‐
7 Builder
8
10 package MyRecord;
11 use base qw/DBIx::SearchBuilder::Record/;
12
13 sub _Init {
14 my $self = shift;
15 my $DBIxHandle =
16 shift; # A DBIx::SearchBuilder::Handle::foo object for your database
17
18 $self->_Handle($DBIxHandle);
19 $self->Table("Users");
20 }
21
22 # Tell Record what the primary keys are
23 sub _PrimaryKeys {
24 return ['id'];
25 }
26
27 # Preferred and most efficient way to specify fields attributes in a derived
28 # class, used by the autoloader to construct Attrib and SetAttrib methods.
29
30 # read: calling $Object->Foo will return the value of this record's Foo column
31 # write: calling $Object->SetFoo with a single value will set Foo's value in
32 # both the loaded object and the database
33 sub _ClassAccessible {
34 {
35 Tofu => { 'read' => 1, 'write' => 1 },
36 Maz => { 'auto' => 1, },
37 Roo => { 'read' => 1, 'auto' => 1, 'public' => 1, },
38 };
39 }
40
41 # A subroutine to check a user's password without returning the current value
42 # For security purposes, we didn't expose the Password method above
43 sub IsPassword {
44 my $self = shift;
45 my $try = shift;
46
47 # note two __s in __Value. Subclasses may muck with _Value, but
48 # they should never touch __Value
49
50 if ( $try eq $self->__Value('Password') ) {
51 return (1);
52 }
53 else {
54 return (undef);
55 }
56 }
57
58 # Override DBIx::SearchBuilder::Create to do some checking on create
59 sub Create {
60 my $self = shift;
61 my %fields = (
62 UserId => undef,
63 Password => 'default', #Set a default password
64 @_
65 );
66
67 # Make sure a userid is specified
68 unless ( $fields{'UserId'} ) {
69 die "No userid specified.";
70 }
71
72 # Get DBIx::SearchBuilder::Record->Create to do the real work
73 return (
74 $self->SUPER::Create(
75 UserId => $fields{'UserId'},
76 Password => $fields{'Password'},
77 Created => time
78 )
79 );
80 }
81
83 DBIx::SearchBuilder::Record is designed to work with DBIx::Search‐
84 Builder.
85
86 What is it trying to do.
87
88 DBIx::SearchBuilder::Record abstracts the agony of writing the common
89 and generally simple SQL statements needed to serialize and De-serial‐
90 ize an object to the database. In a traditional system, you would
91 define various methods on your object 'create', 'find', 'modify', and
92 'delete' being the most common. In each method you would have a SQL
93 statement like:
94
95 select * from table where value='blah';
96
97 If you wanted to control what data a user could modify, you would have
98 to do some special magic to make accessors do the right thing. Etc.
99 The problem with this approach is that in a majority of the cases, the
100 SQL is incredibly simple and the code from one method/object to the
101 next was basically the same.
102
103 <trumpets>
104
105 Enter, DBIx::SearchBuilder::Record.
106
107 With::Record, you can in the simple case, remove all of that code and
108 replace it by defining two methods and inheriting some code. Its
109 pretty simple, and incredibly powerful. For more complex cases, you
110 can, gasp, do more complicated things by overriding certain methods.
111 Lets stick with the simple case for now.
112
113 The two methods in question are '_Init' and '_ClassAccessible', all
114 they really do are define some values and send you on your way. As you
115 might have guessed the '_' suggests that these are private methods,
116 they are. They will get called by your record objects constructor.
117
118 '_Init'
119 Defines what table we are talking about, and set a variable to
120 store the database handle.
121
122 '_ClassAccessible
123 Defines what operations may be performed on various data selected
124 from the database. For example you can define fields to be muta‐
125 ble, or immutable, there are a few other options but I don't under‐
126 stand what they do at this time.
127
128 And really, thats it. So lets have some sample code.
129
130 An Annotated Example
131
132 The example code below makes the following assumptions:
133
134 · The database is 'postgres',
135
136 · The host is 'reason',
137
138 · The login name is 'mhat',
139
140 · The database is called 'example',
141
142 · The table is called 'simple',
143
144 · The table looks like so:
145
146 id integer not NULL, primary_key(id),
147 foo varchar(10),
148 bar varchar(10)
149
150 First, let's define our record class in a new module named "Simple.pm".
151
152 000: package Simple;
153 001: use DBIx::SearchBuilder::Record;
154 002: @ISA = (DBIx::SearchBuilder::Record);
155
156 This should be pretty obvious, name the package, import ::Record and
157 then define ourself as a subclass of ::Record.
158
159 003:
160 004: sub _Init {
161 005: my $this = shift;
162 006: my $handle = shift;
163 007:
164 008: $this->_Handle($handle);
165 009: $this->Table("Simple");
166 010:
167 011: return ($this);
168 012: }
169
170 Here we set our handle and table name, while its not obvious so far,
171 we'll see later that $handle (line: 006) gets passed via ::Record::new
172 when a new instance is created. Thats actually an important concept,
173 the DB handle is not bound to a single object but rather, its shared
174 across objects.
175
176 013:
177 014: sub _ClassAccessible {
178 015: {
179 016: Foo => { 'read' => 1 },
180 017: Bar => { 'read' => 1, 'write' => 1 },
181 018: Id => { 'read' => 1 }
182 019: };
183 020: }
184
185 What's happening might be obvious, but just in case this method is
186 going to return a reference to a hash. That hash is where our columns
187 are defined, as well as what type of operations are acceptable.
188
189 021:
190 022: 1;
191
192 Like all perl modules, this needs to end with a true value.
193
194 Now, on to the code that will actually *do* something with this object.
195 This code would be placed in your Perl script.
196
197 000: use DBIx::SearchBuilder::Handle;
198 001: use Simple;
199
200 Use two packages, the first is where I get the DB handle from, the lat‐
201 ter is the object I just created.
202
203 002:
204 003: my $handle = DBIx::SearchBuilder::Handle->new();
205 004: $handle->Connect( 'Driver' => 'Pg',
206 005: 'Database' => 'test',
207 006: 'Host' => 'reason',
208 007: 'User' => 'mhat',
209 008: 'Password' => '');
210
211 Creates a new DBIx::SearchBuilder::Handle, and then connects to the
212 database using that handle. Pretty straight forward, the password ''
213 is what I use when there is no password. I could probably leave it
214 blank, but I find it to be more clear to define it.
215
216 009:
217 010: my $s = Simple->new($handle);
218 011:
219 012: $s->LoadById(1);
220
221 LoadById is one of four 'LoadBy' methods, as the name suggests it
222 searches for an row in the database that has id='0'. ::SearchBuilder
223 has, what I think is a bug, in that it current requires there to be an
224 id field. More reasonably it also assumes that the id field is unique.
225 LoadById($id) will do undefined things if there is >1 row with the same
226 id.
227
228 In addition to LoadById, we also have:
229
230 LoadByCol
231 Takes two arguments, a column name and a value. Again, it will do
232 undefined things if you use non-unique things.
233
234 LoadByCols
235 Takes a hash of columns=>values and returns the *first* to match.
236 First is probably lossy across databases vendors.
237
238 LoadFromHash
239 Populates this record with data from a DBIx::SearchBuilder. I'm
240 currently assuming that DBIx::SearchBuilder is what we use in cases
241 where we expect > 1 record. More on this later.
242
243 Now that we have a populated object, we should do something with it!
244 ::Record automagically generates accessos and mutators for us, so all
245 we need to do is call the methods. Accessors are named <Field>(), and
246 Mutators are named Set<Field>($). On to the example, just appending
247 this to the code from the last example.
248
249 013:
250 014: print "ID : ", $s->Id(), "\n";
251 015: print "Foo : ", $s->Foo(), "\n";
252 016: print "Bar : ", $s->Bar(), "\n";
253
254 Thats all you have to to get the data, now to change the data!
255
256 017:
257 018: $s->SetBar('NewBar');
258
259 Pretty simple! Thats really all there is to it. Set<Field>($) returns
260 a boolean and a string describing the problem. Lets look at an example
261 of what will happen if we try to set a 'Id' which we previously defined
262 as read only.
263
264 019: my ($res, $str) = $s->SetId('2');
265 020: if (! $res) {
266 021: ## Print the error!
267 022: print "$str\n";
268 023: }
269
270 The output will be:
271
272 >> Immutable field
273
274 Currently Set<Field> updates the data in the database as soon as you
275 call it. In the future I hope to extend ::Record to better support
276 transactional operations, such that updates will only happen when "you"
277 say so.
278
279 Finally, adding a removing records from the database. ::Record pro‐
280 vides a Create method which simply takes a hash of key=>value pairs.
281 The keys exactly map to database fields.
282
283 023: ## Get a new record object.
284 024: $s1 = Simple->new($handle);
285 025: $s1->Create('Id' => 4,
286 026: 'Foo' => 'Foooooo',
287 027: 'Bar' => 'Barrrrr');
288
289 Poof! A new row in the database has been created! Now lets delete the
290 object!
291
292 028:
293 029: $s1 = undef;
294 030: $s1 = Simple->new($handle);
295 031: $s1->LoadById(4);
296 032: $s1->Delete();
297
298 And its gone.
299
300 For simple use, thats more or less all there is to it. In the future,
301 I hope to exapand this HowTo to discuss using container classes, over‐
302 loading, and what ever else I think of.
303
305 Each method has a lower case alias; '_' is used to separate words. For
306 example, the method "_PrimaryKeys" has the alias "_primary_keys".
307
309 new
310
311 Instantiate a new record object.
312
313 id
314
315 Returns this row's primary key.
316
317 primary_keys
318
319 PrimaryKeys
320
321 Return a hash of the values of our primary keys for this function.
322
323 _Accessible KEY MODE
324
325 Private method.
326
327 Returns undef unless "KEY" is accessible in "MODE" otherwise returns
328 "MODE" value
329
330 _PrimaryKeys
331
332 Return our primary keys. (Subclasses should override this, but our
333 default is that we have one primary key, named 'id'.)
334
335 _ClassAccessible
336
337 An older way to specify fields attributes in a derived class. (The
338 current preferred method is by overriding "Schema"; if you do this and
339 don't override "_ClassAccessible", the module will generate an appro‐
340 priate "_ClassAccessible" based on your "Schema".)
341
342 Here's an example declaration:
343
344 sub _ClassAccessible {
345 {
346 Tofu => { 'read'=>1, 'write'=>1 },
347 Maz => { 'auto'=>1, },
348 Roo => { 'read'=>1, 'auto'=>1, 'public'=>1, },
349 };
350 }
351
352 ReadableAttributes
353
354 Returns an array of the attributes of this class defined as "read" => 1
355 in this class' _ClassAccessible datastructure
356
357 WritableAttributes
358
359 Returns an array of the attributes of this class defined as "write" =>
360 1 in this class' _ClassAccessible datastructure
361
362 __Value
363
364 Takes a field name and returns that field's value. Subclasses should
365 never override __Value.
366
367 _Value
368
369 _Value takes a single column name and returns that column's value for
370 this row. Subclasses can override _Value to insert custom access con‐
371 trol.
372
373 _Set
374
375 _Set takes a single column name and a single unquoted value. It
376 updates both the in-memory value of this column and the in-database
377 copy. Subclasses can override _Set to insert custom access control.
378
379 _Canonicalize PARAMHASH
380
381 This routine massages an input value (VALUE) for FIELD into something
382 that's going to be acceptable.
383
384 Takes
385
386 FIELD
387 VALUE
388 FUNCTION
389
390 Takes:
391
392 FIELD
393 VALUE
394 FUNCTION
395
396 Returns a replacement VALUE.
397
398 _Validate FIELD VALUE
399
400 Validate that VALUE will be an acceptable value for FIELD.
401
402 Currently, this routine does nothing whatsoever.
403
404 If it succeeds (which is always the case right now), returns true. Oth‐
405 erwise returns false.
406
407 TruncateValue KEY VALUE
408
409 Truncate a value that's about to be set so that it will fit inside the
410 database' s idea of how big the column is.
411
412 (Actually, it looks at SearchBuilder's concept of the database, not
413 directly into the db).
414
415 _Object
416
417 _Object takes a single column name and an array reference. It creates
418 new object instance of class specified in _ClassAccessable structure
419 and calls LoadById on recently created object with the current column
420 value as argument. It uses the array reference as the object construc‐
421 tor's arguments. Subclasses can override _Object to insert custom
422 access control or define default contructor arguments.
423
424 Note that if you are using a "Schema" with a "REFERENCES" field, this
425 is unnecessary: the method to access the column's value will automati‐
426 cally turn it into the appropriate object.
427
428 Load
429
430 Takes a single argument, $id. Calls LoadById to retrieve the row whose
431 primary key is $id
432
433 LoadByCol
434
435 Takes two arguments, a column and a value. The column can be any table
436 column which contains unique values. Behavior when using a non-unique
437 value is undefined
438
439 LoadByCols
440
441 Takes a hash of columns and values. Loads the first record that matches
442 all keys.
443
444 The hash's keys are the columns to look at.
445
446 The hash's values are either: scalar values to look for OR has refer‐
447 ences which contain 'operator' and 'value'
448
449 LoadById
450
451 Loads a record by its primary key. Your record class must define a sin‐
452 gle primary key column.
453
454 LoadByPrimaryKeys
455
456 Like LoadById with basic support for compound primary keys.
457
458 LoadFromHash
459
460 Takes a hashref, such as created by DBIx::SearchBuilder and populates
461 this record's loaded values hash.
462
463 _LoadFromSQL QUERYSTRING @BIND_VALUES
464
465 Load a record as the result of an SQL statement
466
467 Create
468
469 Takes an array of key-value pairs and drops any keys that aren't known
470 as columns for this recordtype
471
472 Delete
473
474 Delete this record from the database. On failure return a
475 Class::ReturnValue with the error. On success, return 1;
476
477 Table
478
479 Returns or sets the name of the current Table
480
481 _Handle
482
483 Returns or sets the current DBIx::SearchBuilder::Handle object
484
486 Jesse Vincent, <jesse@fsck.com>
487
488 Enhancements by Ivan Kohler, <ivan-rt@420.am>
489
490 Docs by Matt Knopp <mhat@netlag.com>
491
493 DBIx::SearchBuilder
494
495
496
497perl v5.8.8 2007-02-17 SearchBuilder::Record(3)