1DBIx::SearchBuilder::ReUcsoerrd(C3o)ntributed Perl DocumDeBnItxa:t:iSoenarchBuilder::Record(3)
2
3
4

NAME

6       DBIx::SearchBuilder::Record - Superclass for records loaded by
7       SearchBuilder
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
84       DBIx::SearchBuilder.
85
86   What is it trying to do.
87       DBIx::SearchBuilder::Record abstracts the agony of writing the common
88       and generally simple SQL statements needed to serialize and De-
89       serialize an object to the database.  In a traditional system, you
90       would define various methods on your object 'create', 'find', 'modify',
91       and 'delete' being the most common.  In each method you would have a
92       SQL statement like:
93
94         select * from table where value='blah';
95
96       If you wanted to control what data a user could modify, you would have
97       to do some special magic to make accessors do the right thing. Etc.
98       The problem with this approach is that in a majority of the cases, the
99       SQL is incredibly simple and the code from one method/object to the
100       next was basically the same.
101
102       <trumpets>
103
104       Enter, DBIx::SearchBuilder::Record.
105
106       With Record, you can in the simple case, remove all of that code and
107       replace it by defining two methods and inheriting some code.  It's
108       pretty simple, and incredibly powerful.  For more complex cases, you
109       can do more complicated things by overriding certain methods.  Let's
110       stick with the simple case for now.
111
112       The two methods in question are "_Init" and "_ClassAccessible". All
113       they really do are define some values and send you on your way.  As you
114       might have guessed the '_' means that these are private methods.  They
115       will get called by your record object's constructor.
116
117       '_Init'
118           Defines what table we are talking about, and set a variable to
119           store the database handle.
120
121       '_ClassAccessible
122           Defines what operations may be performed on various data selected
123           from the database.  For example you can define fields to be
124           mutable, or immutable, there are a few other options but I don't
125           understand what they do at this time.
126
127       And really, that's it.  So let's have some sample code.
128
129   An Annotated Example
130       The example code below makes the following assumptions:
131
132       ·   The database is 'postgres',
133
134       ·   The host is 'reason',
135
136       ·   The login name is 'mhat',
137
138       ·   The database is called 'example',
139
140       ·   The table is called 'simple',
141
142       ·   The table looks like so:
143
144                 id     integer     not NULL,   primary_key(id),
145                 foo    varchar(10),
146                 bar    varchar(10)
147
148       First, let's define our record class in a new module named "Simple.pm".
149
150         000: package Simple;
151         001: use DBIx::SearchBuilder::Record;
152         002: @ISA = (DBIx::SearchBuilder::Record);
153
154       This should be pretty obvious, name the package, import ::Record and
155       then define ourself as a subclass of ::Record.
156
157         003:
158         004: sub _Init {
159         005:   my $this   = shift;
160         006:   my $handle = shift;
161         007:
162         008:   $this->_Handle($handle);
163         009:   $this->Table("Simple");
164         010:
165         011:   return ($this);
166         012: }
167
168       Here we set our handle and table name, while its not obvious so far,
169       we'll see later that $handle (line: 006) gets passed via ::Record::new
170       when a new instance is created.  That's actually an important concept:
171       the DB handle is not bound to a single object but rather, it is shared
172       across objects.
173
174         013:
175         014: sub _ClassAccessible {
176         015:   {
177         016:     Foo => { 'read'  => 1 },
178         017:     Bar => { 'read'  => 1, 'write' => 1  },
179         018:     Id  => { 'read'  => 1 }
180         019:   };
181         020: }
182
183       What's happening might be obvious, but just in case this method is
184       going to return a reference to a hash. That hash is where our columns
185       are defined, as well as what type of operations are acceptable.
186
187         021:
188         022: 1;
189
190       Like all perl modules, this needs to end with a true value.
191
192       Now, on to the code that will actually *do* something with this object.
193       This code would be placed in your Perl script.
194
195         000: use DBIx::SearchBuilder::Handle;
196         001: use Simple;
197
198       Use two packages, the first is where I get the DB handle from, the
199       latter is the object I just created.
200
201         002:
202         003: my $handle = DBIx::SearchBuilder::Handle->new();
203         004:    $handle->Connect( 'Driver'   => 'Pg',
204         005:                    'Database' => 'test',
205         006:                    'Host'     => 'reason',
206         007:                    'User'     => 'mhat',
207         008:                    'Password' => '');
208
209       Creates a new DBIx::SearchBuilder::Handle, and then connects to the
210       database using that handle.  Pretty straight forward, the password ''
211       is what I use when there is no password.  I could probably leave it
212       blank, but I find it to be more clear to define it.
213
214         009:
215         010: my $s = Simple->new($handle);
216         011:
217         012: $s->LoadById(1);
218
219       LoadById is one of four 'LoadBy' methods,  as the name suggests it
220       searches for an row in the database that has id='0'.  ::SearchBuilder
221       has, what I think is a bug, in that it current requires there to be an
222       id field. More reasonably it also assumes that the id field is unique.
223       LoadById($id) will do undefined things if there is >1 row with the same
224       id.
225
226       In addition to LoadById, we also have:
227
228       LoadByCol
229           Takes two arguments, a column name and a value.  Again, it will do
230           undefined things if you use non-unique things.
231
232       LoadByCols
233           Takes a hash of columns=>values and returns the *first* to match.
234           First is probably lossy across databases vendors.
235
236       LoadFromHash
237           Populates this record with data from a DBIx::SearchBuilder.  I'm
238           currently assuming that DBIx::SearchBuilder is what we use in cases
239           where we expect > 1 record.  More on this later.
240
241       Now that we have a populated object, we should do something with it!
242       ::Record automagically generates accessos and mutators for us, so all
243       we need to do is call the methods.  Accessors are named <Field>(), and
244       Mutators are named Set<Field>($).  On to the example, just appending
245       this to the code from the last example.
246
247         013:
248         014: print "ID  : ", $s->Id(),  "\n";
249         015: print "Foo : ", $s->Foo(), "\n";
250         016: print "Bar : ", $s->Bar(), "\n";
251
252       That's all you have to to get the data. Now to change the data!
253
254         017:
255         018: $s->SetBar('NewBar');
256
257       Pretty simple! That's really all there is to it.  Set<Field>($) returns
258       a boolean and a string describing the problem.  Let's look at an
259       example of what will happen if we try to set a 'Id' which we previously
260       defined as read only.
261
262         019: my ($res, $str) = $s->SetId('2');
263         020: if (! $res) {
264         021:   ## Print the error!
265         022:   print "$str\n";
266         023: }
267
268       The output will be:
269
270         >> Immutable field
271
272       Currently Set<Field> updates the data in the database as soon as you
273       call it.  In the future I hope to extend ::Record to better support
274       transactional operations, such that updates will only happen when "you"
275       say so.
276
277       Finally, adding a removing records from the database.  ::Record
278       provides a Create method which simply takes a hash of key=>value pairs.
279       The keys exactly   map to database fields.
280
281         023: ## Get a new record object.
282         024: $s1 = Simple->new($handle);
283         025: $s1->Create('Id'  => 4,
284         026:             'Foo' => 'Foooooo',
285         027:             'Bar' => 'Barrrrr');
286
287       Poof! A new row in the database has been created!  Now let's delete the
288       object!
289
290         028:
291         029: $s1 = undef;
292         030: $s1 = Simple->new($handle);
293         031: $s1->LoadById(4);
294         032: $s1->Delete();
295
296       And it's gone.
297
298       For simple use, that's more or less all there is to it.  In the future,
299       we hope to expand this how-to to discuss using container classes,
300       overloading, etc.
301

METHOD NAMING

303       Each method has a lower case alias; '_' is used to separate words.  For
304       example, the method "_PrimaryKeys" has the alias "_primary_keys".
305

METHODS

307   new
308       Instantiate a new record object.
309
310   id
311       Returns this row's primary key.
312
313   primary_keys
314   PrimaryKeys
315       Return a hash of the values of our primary keys for this function.
316
317   _Accessible KEY MODE
318       Private method.
319
320       Returns undef unless "KEY" is accessible in "MODE" otherwise returns
321       "MODE" value
322
323   _PrimaryKeys
324       Return our primary keys. (Subclasses should override this, but our
325       default is that we have one primary key, named 'id'.)
326
327   _ClassAccessible
328       An older way to specify fields attributes in a derived class.  (The
329       current preferred method is by overriding "Schema"; if you do this and
330       don't override "_ClassAccessible", the module will generate an
331       appropriate "_ClassAccessible" based on your "Schema".)
332
333       Here's an example declaration:
334
335         sub _ClassAccessible {
336           {
337                Tofu  => { 'read'=>1, 'write'=>1 },
338                Maz   => { 'auto'=>1, },
339                Roo   => { 'read'=>1, 'auto'=>1, 'public'=>1, },
340           };
341         }
342
343   ReadableAttributes
344       Returns an array of the attributes of this class defined as "read" => 1
345       in this class' _ClassAccessible datastructure
346
347   WritableAttributes
348       Returns an array of the attributes of this class defined as "write" =>
349       1 in this class' _ClassAccessible datastructure
350
351   __Value
352       Takes a field name and returns that field's value. Subclasses should
353       never override __Value.
354
355   _Value
356       _Value takes a single column name and returns that column's value for
357       this row.  Subclasses can override _Value to insert custom access
358       control.
359
360   _Set
361       _Set takes a single column name and a single unquoted value.  It
362       updates both the in-memory value of this column and the in-database
363       copy.  Subclasses can override _Set to insert custom access control.
364
365   _Canonicalize PARAMHASH
366       This routine massages an input value (VALUE) for FIELD into something
367       that's going to be acceptable.
368
369       Takes
370
371       FIELD
372       VALUE
373       FUNCTION
374
375       Takes:
376
377       FIELD
378       VALUE
379       FUNCTION
380
381       Returns a replacement VALUE.
382
383   _Validate FIELD VALUE
384       Validate that VALUE will be an acceptable value for FIELD.
385
386       Currently, this routine does nothing whatsoever.
387
388       If it succeeds (which is always the case right now), returns true.
389       Otherwise returns false.
390
391   TruncateValue  KEY VALUE
392       Truncate a value that's about to be set so that it will fit inside the
393       database' s idea of how big the column is.
394
395       (Actually, it looks at SearchBuilder's concept of the database, not
396       directly into the db).
397
398   _Object
399       _Object takes a single column name and an array reference.  It creates
400       new object instance of class specified in _ClassAccessable structure
401       and calls LoadById on recently created object with the current column
402       value as argument. It uses the array reference as the object
403       constructor's arguments.  Subclasses can override _Object to insert
404       custom access control or define default constructor arguments.
405
406       Note that if you are using a "Schema" with a "REFERENCES" field, this
407       is unnecessary: the method to access the column's value will
408       automatically turn it into the appropriate object.
409
410   Load
411       Takes a single argument, $id. Calls LoadById to retrieve the row whose
412       primary key is $id
413
414   LoadByCol
415       Takes two arguments, a column and a value. The column can be any table
416       column which contains unique values.  Behavior when using a non-unique
417       value is undefined
418
419   LoadByCols
420       Takes a hash of columns and values. Loads the first record that matches
421       all keys.
422
423       The hash's keys are the columns to look at.
424
425       The hash's values are either: scalar values to look for OR has
426       references which contain 'operator' and 'value'
427
428   LoadById
429       Loads a record by its primary key. Your record class must define a
430       single primary key column.
431
432   LoadByPrimaryKeys
433       Like LoadById with basic support for compound primary keys.
434
435   LoadFromHash
436       Takes a hashref, such as created by DBIx::SearchBuilder and populates
437       this record's loaded values hash.
438
439   _LoadFromSQL QUERYSTRING @BIND_VALUES
440       Load a record as the result of an SQL statement
441
442   Create
443       Takes an array of key-value pairs and drops any keys that aren't known
444       as columns for this recordtype
445
446   Delete
447       Delete this record from the database. On failure return a
448       Class::ReturnValue with the error. On success, return 1;
449
450   Table
451       Returns or sets the name of the current Table
452
453   _Handle
454       Returns or sets the current DBIx::SearchBuilder::Handle object
455

AUTHOR

457       Jesse Vincent, <jesse@fsck.com>
458
459       Enhancements by Ivan Kohler, <ivan-rt@420.am>
460
461       Docs by Matt Knopp <mhat@netlag.com>
462

SEE ALSO

464       DBIx::SearchBuilder
465
466
467
468perl v5.32.0                      2020-07-28    DBIx::SearchBuilder::Record(3)
Impressum