1SearchBuilder::Record(3U)ser Contributed Perl DocumentatiSoenarchBuilder::Record(3)
2
3
4

NAME

6       DBIx::SearchBuilder::Record - Superclass for records loaded by Search‐
7       Builder
8

SYNOPSIS

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

DESCRIPTION

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

METHOD NAMING

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

METHODS

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

AUTHOR

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

SEE ALSO

493       DBIx::SearchBuilder
494
495
496
497perl v5.8.8                       2007-02-17          SearchBuilder::Record(3)
Impressum