← Index
NYTProf Performance Profile   « block view • line view • sub view »
For ddd2.pl
  Run on Tue May 25 16:52:24 2010
Reported on Tue May 25 16:56:46 2010

File /project/perl/lib/Ima/DBI.pm
Statements Executed 254
Statement Execution Time 7.06ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
13112.04ms3.67msIma::DBI::::set_sqlIma::DBI::set_sql
832392µs170msIma::DBI::::__ANON__[:316]Ima::DBI::__ANON__[:316]
1311380µs380µsIma::DBI::::_mk_sql_closureIma::DBI::_mk_sql_closure
222245µs6.79msIma::DBI::::__ANON__[:384]Ima::DBI::__ANON__[:384]
111229µs726µsIma::DBI::::set_dbIma::DBI::set_db
2732180µs180µsIma::DBI::::CORE:substIma::DBI::CORE:subst (opcode)
11186µs255µsIma::DBI::::_remember_handleIma::DBI::_remember_handle
11177µs197µsIma::DBI::::_add_default_attributesIma::DBI::_add_default_attributes
21151µs51µsIma::DBI::::transform_sqlIma::DBI::transform_sql
11137µs37µsIma::DBI::::_mk_db_closureIma::DBI::_mk_db_closure
11116µs16µsIma::DBI::::_default_attributesIma::DBI::_default_attributes
0000s0sIma::DBI::::BEGINIma::DBI::BEGIN
0000s0sIma::DBI::::DBIwarnIma::DBI::DBIwarn
0000s0sIma::DBI::::_croakIma::DBI::_croak
0000s0sIma::DBI::::commitIma::DBI::commit
0000s0sIma::DBI::::db_handlesIma::DBI::db_handles
0000s0sIma::DBI::::db_namesIma::DBI::db_names
0000s0sIma::DBI::::rollbackIma::DBI::rollback
0000s0sIma::DBI::::sql_namesIma::DBI::sql_names
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Ima::DBI;
2
316µs$VERSION = '0.34';
4
53103µs126µsuse strict;
# spent 26µs making 1 call to strict::import
6389µs10suse base 'Class::Data::Inheritable';
# spent 271µs making 1 call to base::import, recursion: max depth 4, time 271µs
73955µs1143µsuse DBI;
# spent 143µs making 1 call to Exporter::import
8
9# Some class data to store a per-class list of handles.
10137µs168µsIma::DBI->mk_classdata('__Database_Names');
# spent 68µs making 1 call to Class::Data::Inheritable::mk_classdata
11122µs149µsIma::DBI->mk_classdata('__Statement_Names');
# spent 49µs making 1 call to Class::Data::Inheritable::mk_classdata
12
13=head1 NAME
14
15Ima::DBI - Database connection caching and organization
16
17=head1 SYNOPSIS
18
19 package Foo;
20 use base 'Ima::DBI';
21
22 # Class-wide methods.
23 Foo->set_db($db_name, $data_source, $user, $password);
24 Foo->set_db($db_name, $data_source, $user, $password, \%attr);
25
26 my @database_names = Foo->db_names;
27 my @database_handles = Foo->db_handles;
28
29 Foo->set_sql($sql_name, $statement, $db_name);
30 Foo->set_sql($sql_name, $statement, $db_name, $cache);
31
32 my @statement_names = Foo->sql_names;
33
34 # Object methods.
35 $dbh = $obj->db_*; # Where * is the name of the db connection.
36 $sth = $obj->sql_*; # Where * is the name of the sql statement.
37 $sth = $obj->sql_*(@sql_pieces);
38
39 $obj->DBIwarn($what, $doing);
40
41 my $rc = $obj->commit;
42 my $rc = $obj->commit(@db_names);
43
44 my $rc = $obj->rollback;
45 my $rc = $obj->rollback(@db_names);
46
47
48=head1 DESCRIPTION
49
50Ima::DBI attempts to organize and facilitate caching and more efficient
51use of database connections and statement handles by storing DBI and
52SQL information with your class (instead of as seperate objects).
53This allows you to pass around just one object without worrying about
54a trail of DBI handles behind it.
55
56One of the things I always found annoying about writing large programs
57with DBI was making sure that I didn't have duplicate database handles
58open. I was also annoyed by the somewhat wasteful nature of the
59prepare/execute/finish route I'd tend to go through in my subroutines.
60The new DBI->connect_cached and DBI->prepare_cached helped a lot, but
61I still had to throw around global datasource, username and password
62information.
63
64So, after a while I grew a small library of DBI helper routines and
65techniques. Ima::DBI is the culmination of all this, put into a nice(?),
66clean(?) class to be inherited from.
67
68=head2 Why should I use this thing?
69
70Ima::DBI is a little odd, and it's kinda hard to explain. So lemme
71explain why you'd want to use this thing...
72
73=over 4
74
75=item * Consolidation of all SQL statements and database information
76
77No matter what, embedding one language into another is messy.
78DBI alleviates this somewhat, but I've found a tendency to have that
79scatter the SQL around inside the Perl code. Ima::DBI allows you to
80easily group the SQL statements in one place where they are easier to
81maintain (especially if one developer is writing the SQL, another writing
82the Perl). Alternatively, you can place your SQL statement alongside
83the code which uses it. Whatever floats your boat.
84
85Database connection information (data source, username, password,
86atrributes, etc...) can also be consolidated together and tracked.
87
88Both the SQL and the connection info are probably going to change a lot,
89so having them well organized and easy to find in the code is a Big Help.
90
91=item * Holds off opening a database connection until necessary.
92
93While Ima::DBI is informed of all your database connections and SQL
94statements at compile-time, it will not connect to the database until
95you actually prepare a statement on that connection.
96
97This is obviously very good for programs that sometimes never touch
98the database. It's also good for code that has lots of possible
99connections and statements, but which typically only use a few.
100Kinda like an autoloader.
101
102=item * Easy integration of the DBI handles into your class
103
104Ima::DBI causes each database handle to be associated with your class,
105allowing you to pull handles from an instance of your object, as well
106as making many oft-used DBI methods available directly from your
107instance.
108
109This gives you a cleaner OO design, since you can now just throw
110around the object as usual and it will carry its associated DBI
111baggage with it.
112
113=item * Honors taint mode
114
115It always struck me as a design deficiency that tainted SQL statements
116could be passed to $sth->prepare(). For example:
117
118 # $user is from an untrusted source and is tainted.
119 $user = get_user_data_from_the_outside_world;
120 $sth = $dbh->prepare('DELETE FROM Users WHERE User = $user');
121
122Looks innocent enough... but what if $user was the string "1 OR User LIKE
123'%'". You just blew away all your users. Hope you have backups.
124
125Ima::DBI turns on the DBI->connect Taint attribute so that all DBI
126methods (except execute()) will no longer accept tainted data.
127See L<DBI/Taint> for details.
128
129=item * Taints returned data
130
131Databases should be like any other system call. It's the scary Outside
132World, thus it should be tainted. Simple. Ima::DBI turns on DBI's Taint
133attribute on each connection. This feature is overridable by passing
134your own Taint attribute to set_db as normal for DBI. See L<DBI/Taint>
135for details.
136
137=item * Encapsulation of some of the more repetitive bits of everyday DBI usage
138
139I get lazy a lot and I forget to do things I really should, like using
140bind_cols(), or rigorous error checking. Ima::DBI does some of this
141stuff automatically, other times it just makes it more convenient.
142
143=item * Encapsulation of DBI's cache system
144
145DBI's automatic handle caching system is relatively new, and some people
146aren't aware of its use. Ima::DBI uses it automatically, so you don't
147have to worry about it. (It even makes it a bit more efficient)
148
149=item * Sharing of database and sql information amongst inherited classes
150
151Any SQL statements and connections created by a class are available to
152its children via normal method inheritance.
153
154=item * Guarantees one connection per program.
155
156One program, one database connection (per database user). One program,
157one prepared statement handle (per statement, per database user).
158That's what Ima::DBI enforces. Extremely handy in persistant environments
159(servers, daemons, mod_perl, FastCGI, etc...)
160
161=item * Encourages use of bind parameters and columns
162
163Bind parameters are safer and more efficient than embedding the column
164information straight into the SQL statement. Bind columns are more
165efficient than normal fetching. Ima::DBI pretty much requires the usage
166of the former, and eases the use of the latter.
167
168=back
169
170=head2 Why shouldn't I use this thing.
171
172=over 4
173
174=item * It's all about OO
175
176Although it is possible to use Ima::DBI as a stand-alone module as
177part of a function-oriented design, its generally not to be used
178unless integrated into an object-oriented design.
179
180=item * Overkill for small programs
181
182=item * Overkill for programs with only one or two SQL statements
183
184Its up to you whether the trouble of setting up a class and jumping
185through the necessary Ima::DBI hoops is worth it for small programs.
186To me, it takes just as much time to set up an Ima::DBI subclass as it
187would to access DBI without it... but then again I wrote the module.
188YMMV.
189
190=item * Overkill for programs that only use their SQL statements once
191
192Ima::DBI's caching might prove to be an unecessary performance hog if
193you never use the same SQL statement twice. Not sure, I haven't
194looked into it.
195
196=back
197
198
199=head1 USAGE
200
201The basic steps to "DBIing" a class are:
202
203=over 4
204
205=item 1
206
207Inherit from Ima::DBI
208
209=item 2
210
211Set up and name all your database connections via set_db()
212
213=item 3
214
215Set up and name all your SQL statements via set_sql()
216
217=item 4
218
219Use sql_* to retrieve your statement handles ($sth) as needed and db_*
220to retreive database handles ($dbh).
221
222
223=back
224
225Have a look at L<EXAMPLE> below.
226
227=head1 TAINTING
228
229Ima::DBI, by default, uses DBI's Taint flag on all connections.
230
231This means that Ima::DBI methods do not accept tainted data, and that all
232data fetched from the database will be tainted. This may be different
233from the DBI behavior you're used to. See L<DBI/Taint> for details.
234
235=head1 Class Methods
236
237=head2 set_db
238
239 Foo->set_db($db_name, $data_source, $user, $password);
240 Foo->set_db($db_name, $data_source, $user, $password, \%attr);
241
242This method is used in place of DBI->connect to create your database
243handles. It sets up a new DBI database handle associated to $db_name.
244All other arguments are passed through to DBI->connect_cached.
245
246A new method is created for each db you setup. This new method is called
247"db_$db_name"... so, for example, Foo->set_db("foo", ...) will create
248a method called "db_foo()". (Spaces in $db_name will be translated into
249underscores: '_')
250
251%attr is combined with a set of defaults (RaiseError => 1, AutoCommit
252=> 0, PrintError => 0, Taint => 1). This is a better default IMHO,
253however it does give databases without transactions (such as MySQL) a
254hard time. Be sure to turn AutoCommit back on if your database does
255not support transactions.
256
257The actual database handle creation (and thus the database connection)
258is held off until a prepare is attempted with this handle.
259
260=cut
261
262sub _croak { my $self = shift; require Carp; Carp::croak(@_) }
263
264
# spent 726µs (229+497) within Ima::DBI::set_db which was called # once (229µs+497µs) by Class::DBI::set_db at line 212 of Class/DBI.pm
sub set_db {
26512226µs my $class = shift;
266 my $db_name = shift or $class->_croak("Need a db name");
267 $db_name =~ s/\s/_/g;
# spent 8µs making 1 call to Ima::DBI::CORE:subst
268
269 my $data_source = shift or $class->_croak("Need a data source");
270 my $user = shift || "";
271 my $password = shift || "";
272 my $attr = shift || {};
273 ref $attr eq 'HASH' or $class->_croak("$attr must be a hash reference");
274 $attr = $class->_add_default_attributes($attr);
# spent 197µs making 1 call to Ima::DBI::_add_default_attributes
275
276 $class->_remember_handle($db_name);
# spent 255µs making 1 call to Ima::DBI::_remember_handle
2773739µs1102µs no strict 'refs';
# spent 102µs making 1 call to strict::unimport
278 *{ $class . "::db_$db_name" } =
# spent 37µs making 1 call to Ima::DBI::_mk_db_closure
279 $class->_mk_db_closure($data_source, $user, $password, $attr);
280
281 return 1;
282}
283
284
# spent 197µs (77+120) within Ima::DBI::_add_default_attributes which was called # once (77µs+120µs) by Ima::DBI::set_db at line 274
sub _add_default_attributes {
285478µs my ($class, $user_attr) = @_;
286 my %attr = $class->_default_attributes;
# spent 120µs making 1 call to Class::DBI::_default_attributes
287 @attr{ keys %$user_attr } = values %$user_attr;
288 return \%attr;
289}
290
291
# spent 16µs within Ima::DBI::_default_attributes which was called # once (16µs+0s) by Class::DBI::_default_attributes at line 201 of Class/DBI.pm
sub _default_attributes {
292 (
293124µs RaiseError => 1,
294 AutoCommit => 0,
295 PrintError => 0,
296 Taint => 1,
297 RootClass => "DBIx::ContextualFetch"
298 );
299}
300
301
# spent 255µs (86+169) within Ima::DBI::_remember_handle which was called # once (86µs+169µs) by Ima::DBI::set_db at line 276
sub _remember_handle {
302478µs my ($class, $db) = @_;
303 my $handles = $class->__Database_Names || [];
304 push @$handles, $db;
305 $class->__Database_Names($handles);
306}
307
308
# spent 37µs within Ima::DBI::_mk_db_closure which was called # once (37µs+0s) by Ima::DBI::set_db at line 278
sub _mk_db_closure {
309342µs my ($class, @connection) = @_;
310 my $dbh;
311
# spent 170ms (392µs+169) within Ima::DBI::__ANON__[/project/perl/lib/Ima/DBI.pm:316] which was called 8 times, avg 21.2ms/call: # 4 times (179µs+30.4ms) by Class::DBI::Pg::pg_version at line 90 of Class/DBI/Pg.pm, avg 7.64ms/call # 2 times (103µs+138ms) by Class::DBI::Pg::set_up_table at line 12 of Class/DBI/Pg.pm, avg 69.2ms/call # 2 times (110µs+734µs) by Ima::DBI::__ANON__[/project/perl/lib/Ima/DBI.pm:384] at line 376, avg 422µs/call
return sub {
31216656µs15169ms unless ($dbh && $dbh->FETCH('Active') && $dbh->ping) {
# spent 138ms making 1 call to DBI::connect_cached # spent 31.4ms making 7 calls to DBI::db::ping, avg 4.49ms/call # spent 112µs making 7 calls to DBI::common::FETCH, avg 16µs/call
313 $dbh = DBI->connect_cached(@connection);
314 }
315 return $dbh;
316 };
317}
318
319=head2 set_sql
320
321 Foo->set_sql($sql_name, $statement, $db_name);
322 Foo->set_sql($sql_name, $statement, $db_name, $cache);
323
324This method is used in place of DBI->prepare to create your statement
325handles. It sets up a new statement handle associated to $sql_name using
326the database connection associated with $db_name. $statement is passed
327through to either DBI->prepare or DBI->prepare_cached (depending on
328$cache) to create the statement handle.
329
330If $cache is true or isn't given, then prepare_cached() will be used to
331prepare the statement handle and it will be cached. If $cache is false
332then a normal prepare() will be used and the statement handle will be
333recompiled on every sql_*() call. If you have a statement which changes
334a lot or is used very infrequently you might not want it cached.
335
336A new method is created for each statement you set up. This new method
337is "sql_$sql_name"... so, as with set_db(), Foo->set_sql("bar", ...,
338"foo"); will create a method called "sql_bar()" which uses the database
339connection from "db_foo()". Again, spaces in $sql_name will be translated
340into underscores ('_').
341
342The actual statement handle creation is held off until sql_* is first
343called on this name.
344
345=cut
346
347
# spent 3.67ms (2.04+1.63) within Ima::DBI::set_sql which was called 13 times, avg 283µs/call: # 13 times (2.04ms+1.63ms) by Class::DBI::set_sql at line 933 of Class/DBI.pm, avg 283µs/call
sub set_sql {
3481562.14ms my ($class, $sql_name, $statement, $db_name, $cache) = @_;
349 $cache = 1 unless defined $cache;
350
351 # ------------------------- sql_* closure ----------------------- #
352 my $db_meth = $db_name;
353 $db_meth =~ s/\s/_/g;
# spent 112µs making 13 calls to Ima::DBI::CORE:subst, avg 9µs/call
354 $db_meth = "db_$db_meth";
355
356 (my $sql_meth = $sql_name) =~ s/\s/_/g;
# spent 60µs making 13 calls to Ima::DBI::CORE:subst, avg 5µs/call
357 $sql_meth = "sql_$sql_meth";
358
359 # Remember the name of this handle for the class.
360 my $handles = $class->__Statement_Names || [];
# spent 369µs making 13 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 28µs/call
361 push @$handles, $sql_name;
362 $class->__Statement_Names($handles);
# spent 710µs making 13 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 55µs/call
363
3643994µs196µs no strict 'refs';
# spent 96µs making 1 call to strict::unimport
365 *{ $class . "::$sql_meth" } =
# spent 380µs making 13 calls to Ima::DBI::_mk_sql_closure, avg 29µs/call
366 $class->_mk_sql_closure($sql_name, $statement, $db_meth, $cache);
367
368 return 1;
369}
370
371
# spent 380µs within Ima::DBI::_mk_sql_closure which was called 13 times, avg 29µs/call: # 13 times (380µs+0s) by Ima::DBI::set_sql at line 365, avg 29µs/call
sub _mk_sql_closure {
37226418µs my ($class, $sql_name, $statement, $db_meth, $cache) = @_;
373
374
# spent 6.79ms (245µs+6.55) within Ima::DBI::__ANON__[/project/perl/lib/Ima/DBI.pm:384] which was called 2 times, avg 3.40ms/call: # once (145µs+4.54ms) by Class::DBI::Plugin::RetrieveAll::__ANON__[/project/perl/lib/Class/DBI/Plugin/RetrieveAll.pm:77] at line 76 of Class/DBI/Plugin/RetrieveAll.pm # once (100µs+2.01ms) by Class::DBI::_flesh at line 857 of Class/DBI.pm
return sub {
3758233µs my $class = shift;
376 my $dbh = $class->$db_meth();
# spent 844µs making 2 calls to Ima::DBI::__ANON__[Ima/DBI.pm:316], avg 422µs/call
377
378 # Everything must pass through sprintf, even if @_ is empty.
379 # This is to do proper '%%' translation.
380 my $sql = $class->transform_sql($statement => @_);
# spent 4.75ms making 2 calls to Class::DBI::transform_sql, avg 2.37ms/call
3811144µs2957µs return $cache
# spent 957µs making 2 calls to DBI::db::prepare_cached, avg 479µs/call
382 ? $dbh->prepare_cached($sql)
383 : $dbh->prepare($sql);
384 };
385}
386
387=head2 transform_sql
388
389To make up for the limitations of bind parameters, $statement can contain
390sprintf() style formatting (ie. %s and such) to allow dynamically
391generated SQL statements (so to get a real percent sign, use '%%').
392
393The translation of the SQL happens in transform_sql(), which can be
394overridden to do more complex transformations. See L<Class::DBI> for an
395example.
396
397=cut
398
399
# spent 51µs within Ima::DBI::transform_sql which was called 2 times, avg 26µs/call: # 2 times (51µs+0s) by Class::DBI::transform_sql at line 154 of Class/DBI.pm, avg 26µs/call
sub transform_sql {
400460µs my ($class, $sql, @args) = @_;
401 return sprintf $sql, @args;
402}
403
404=head2 db_names / db_handles
405
406 my @database_names = Foo->db_names;
407 my @database_handles = Foo->db_handles;
408 my @database_handles = Foo->db_handles(@db_names);
409
410Returns a list of the database handles set up for this class using
411set_db(). This includes all inherited handles.
412
413db_names() simply returns the name of the handle, from which it is
414possible to access it by converting it to a method name and calling
415that db method...
416
417 my @db_names = Foo->db_names;
418 my $db_meth = 'db_'.$db_names[0];
419 my $dbh = $foo->$db_meth;
420
421Icky, eh? Fortunately, db_handles() does this for you and returns a
422list of database handles in the same order as db_names(). B<Use this
423sparingly> as it will connect you to the database if you weren't
424already connected.
425
426If given @db_names, db_handles() will return only the handles for
427those connections.
428
429These both work as either class or object methods.
430
431=cut
432
433sub db_names { @{ $_[0]->__Database_Names || [] } }
434
435sub db_handles {
436 my ($self, @db_names) = @_;
437 @db_names = $self->db_names unless @db_names;
438 return map $self->$_(), map "db_$_", @db_names;
439}
440
441=head2 sql_names
442
443 my @statement_names = Foo->sql_names;
444
445Similar to db_names() this returns the names of all SQL statements set
446up for this class using set_sql(), inherited or otherwise.
447
448There is no corresponding sql_handles() because we can't know what
449arguments to pass in.
450
451=cut
452
453sub sql_names { @{ $_[0]->__Statement_Names || [] } }
454
455=head1 Object Methods
456
457=head2 db_*
458
459 $dbh = $obj->db_*;
460
461This is how you directly access a database handle you set up with set_db.
462
463The actual particular method name is derived from what you told set_db.
464
465db_* will handle all the issues of making sure you're already
466connected to the database.
467
468=head2 sql_*
469
470 $sth = $obj->sql_*;
471 $sth = $obj->sql_*(@sql_pieces);
472
473sql_*() is a catch-all name for the methods you set up with set_sql().
474For instance, if you did:
475
476 Foo->set_sql('GetAllFoo', 'Select * From Foo', 'SomeDb');
477
478you'd run that statement with sql_GetAllFoo().
479
480sql_* will handle all the issues of making sure the database is
481already connected, and the statement handle is prepared. It returns a
482prepared statement handle for you to use. (You're expected to
483execute() it)
484
485If sql_*() is given a list of @sql_pieces it will use them to fill in
486your statement, assuming you have sprintf() formatting tags in your
487statement. For example:
488
489 Foo->set_sql('GetTable', 'Select * From %s', 'Things');
490
491 # Assuming we have created an object... this will prepare the
492 # statement 'Select * From Bar'
493 $sth = $obj->sql_Search('Bar');
494
495Be B<very careful> with what you feed this function. It cannot
496do any quoting or escaping for you, so it is totally up to you
497to take care of that. Fortunately if you have tainting on you
498will be spared the worst.
499
500It is recommended you only use this in cases where bind parameters
501will not work.
502
503=head2 DBIwarn
504
505 $obj->DBIwarn($what, $doing);
506
507Produces a useful error for exceptions with DBI.
508
509B<I'm not particularly happy with this interface>
510
511Most useful like this:
512
513 eval {
514 $self->sql_Something->execute($self->{ID}, @stuff);
515 };
516 if($@) {
517 $self->DBIwarn($self->{ID}, 'Something');
518 return;
519 }
520
521
522=cut
523
524sub DBIwarn {
525 my ($self, $thing, $doing) = @_;
526 my $errstr = "Failure while doing '$doing' with '$thing'\n";
527 $errstr .= $@ if $@;
528
529 require Carp;
530 Carp::carp $errstr;
531
532 return 1;
533}
534
535=head1 Modified database handle methods
536
537Ima::DBI makes some of the methods available to your object that are
538normally only available via the database handle. In addition, it
539spices up the API a bit.
540
541=head2 commit
542
543 $rc = $obj->commit;
544 $rc = $obj->commit(@db_names);
545
546Derived from $dbh->commit() and basically does the same thing.
547
548If called with no arguments, it causes commit() to be called on all
549database handles associated with $obj. Otherwise it commits all
550database handles whose names are listed in @db_names.
551
552Alternatively, you may like to do: $rc = $obj->db_Name->commit;
553
554If all the commits succeeded it returns true, false otherwise.
555
556=cut
557
558sub commit {
559 my ($self, @db_names) = @_;
560 return grep(!$_, map $_->commit, $self->db_handles(@db_names)) ? 0 : 1;
561}
562
563=head2 rollback
564
565 $rc = $obj->rollback;
566 $rc = $obj->rollback(@db_names);
567
568Derived from $dbh->rollback, this acts just like Ima::DBI->commit,
569except that it calls rollback().
570
571Alternatively, you may like to do: $rc = $obj->db_Name->rollback;
572
573If all the rollbacks succeeded it returns true, false otherwise.
574
575=cut
576
577sub rollback {
578 my ($self, @db_names) = @_;
579 return grep(!$_, map $_->rollback, $self->db_handles(@db_names)) ? 0 : 1;
580}
581
582=head1 EXAMPLE
583
584 package Foo;
585 use base qw(Ima::DBI);
586
587 # Set up database connections (but don't connect yet)
588 Foo->set_db('Users', 'dbi:Oracle:Foo', 'admin', 'passwd');
589 Foo->set_db('Customers', 'dbi:Oracle:Foo', 'Staff', 'passwd');
590
591 # Set up SQL statements to be used through out the program.
592 Foo->set_sql('FindUser', <<"SQL", 'Users');
593 SELECT *
594 FROM Users
595 WHERE Name LIKE ?
596 SQL
597
598 Foo->set_sql('ChangeLanguage', <<"SQL", 'Customers');
599 UPDATE Customers
600 SET Language = ?
601 WHERE Country = ?
602 SQL
603
604 # rest of the class as usual.
605
606 package main;
607
608 $obj = Foo->new;
609
610 eval {
611 # Does connect & prepare
612 my $sth = $obj->sql_FindUser;
613 # bind_params, execute & bind_columns
614 $sth->execute(['Likmi%'], [\($name)]);
615 while( $sth->fetch ) {
616 print $name;
617 }
618
619 # Uses cached database and statement handles
620 $sth = $obj->sql_FindUser;
621 # bind_params & execute.
622 $sth->execute('%Hock');
623 @names = $sth->fetchall;
624
625 # connects, prepares
626 $rows_altered = $obj->sql_ChangeLanguage->execute(qw(es_MX mx));
627 };
628 unless ($@) {
629 # Everything went okay, commit the changes to the customers.
630 $obj->commit('Customers');
631 }
632 else {
633 $obj->rollback('Customers');
634 warn "DBI failure: $@";
635 }
636
637
638=head1 TODO, Caveat, BUGS, etc....
639
640=over 4
641
642=item I seriously doubt that it's thread safe.
643
644You can bet cupcackes to sno-cones that much havoc will be wrought if
645Ima::DBI is used in a threaded Perl.
646
647=item Should make use of private_* handle method to store information
648
649=item The docs stink.
650
651The docs were originally written when I didn't have a good handle on
652the module and how it will be used in practical cases. I need to
653rewrite the docs from the ground up.
654
655=item Need to add debugging hooks.
656
657The thing which immediately comes to mind is a Verbose flag to print
658out SQL statements as they are made as well as mention when database
659connections are made, etc...
660
661=back
662
663=head1 MAINTAINER
664
665Tony Bowden <tony@tmtm.com>
666
667=head1 ORIGINAL AUTHOR
668
669Michael G Schwern <schwern@pobox.com>
670
671=head1 LICENSE
672
673This module is free software. You may distribute under the same terms
674as Perl itself. IT COMES WITHOUT WARRANTY OF ANY KIND.
675
676=head1 THANKS MUCHLY
677
678Tim Bunce, for enduring many DBI questions and adding Taint,
679prepare_cached and connect_cached methods to DBI, simplifying this
680greatly!
681
682Arena Networks, for effectively paying for Mike to write most of this
683module.
684
685=head1 SEE ALSO
686
687L<DBI>.
688
689You may also choose to check out L<Class::DBI> which hides most of this
690from view.
691
692=cut
693
694116µsreturn 1001001;
# spent 180µs within Ima::DBI::CORE:subst which was called 27 times, avg 7µs/call: # 13 times (112µs+0s) by Ima::DBI::set_sql at line 353 of Ima/DBI.pm, avg 9µs/call # 13 times (60µs+0s) by Ima::DBI::set_sql at line 356 of Ima/DBI.pm, avg 5µs/call # once (8µs+0s) by Ima::DBI::set_db at line 267 of Ima/DBI.pm
sub Ima::DBI::CORE:subst; # xsub