| File | /project/perl/lib/Class/DBI.pm |
| Statements Executed | 22583 |
| Statement Execution Time | 445ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 13 | 6 | 3 | 101ms | 173ms | Class::DBI::_require_class |
| 461 | 1 | 1 | 62.1ms | 180ms | Class::DBI::_live_object_key |
| 461 | 1 | 1 | 45.1ms | 78.1ms | Class::DBI::_fresh_init |
| 925 | 2 | 2 | 42.6ms | 79.6ms | Class::DBI::_attrs |
| 463 | 1 | 1 | 39.6ms | 213ms | Class::DBI::get |
| 461 | 1 | 1 | 26.7ms | 771ms | Class::DBI::construct |
| 463 | 1 | 1 | 25.7ms | 86.3ms | Class::DBI::_find_columns |
| 461 | 1 | 1 | 24.8ms | 283ms | Class::DBI::_init |
| 464 | 3 | 2 | 23.9ms | 64.4ms | Class::DBI::primary_column |
| 467 | 2 | 1 | 21.4ms | 38.9ms | Class::DBI::_attribute_exists |
| 463 | 3 | 2 | 16.7ms | 16.7ms | Class::DBI::_attribute_store |
| 1 | 1 | 1 | 10.2ms | 863ms | Class::DBI::sth_to_objects |
| 461 | 1 | 1 | 8.41ms | 8.41ms | Class::DBI::is_changed |
| 1 | 1 | 1 | 7.21ms | 778ms | Class::DBI::_ids_to_objects |
| 4 | 1 | 1 | 2.81ms | 8.65ms | Class::DBI::_mk_column_accessors |
| 461 | 1 | 2 | 2.61ms | 2.61ms | Class::DBI::CORE:sort (opcode) |
| 36 | 2 | 1 | 1.99ms | 2.75ms | Class::DBI::_make_method |
| 4 | 1 | 1 | 1.35ms | 15.8ms | Class::DBI::_set_columns |
| 13 | 13 | 4 | 1.21ms | 5.54ms | Class::DBI::set_sql |
| 15 | 2 | 2 | 759µs | 2.46ms | Class::DBI::add_trigger |
| 10 | 1 | 1 | 607µs | 982µs | Class::DBI::accessor_name_for |
| 1 | 1 | 1 | 539µs | 10.6ms | Class::DBI::_flesh |
| 10 | 1 | 1 | 538µs | 538µs | Class::DBI::_generate_search_sql |
| 5 | 1 | 1 | 530µs | 2.03ms | Class::DBI::_extend_meta |
| 10 | 1 | 1 | 486µs | 861µs | Class::DBI::mutator_name_for |
| 5 | 2 | 2 | 449µs | 1.22ms | Class::DBI::_extend_class_data |
| 2 | 1 | 1 | 412µs | 4.75ms | Class::DBI::transform_sql |
| 4 | 2 | 2 | 271µs | 735µs | Class::DBI::table |
| 5 | 5 | 3 | 241µs | 170ms | Class::DBI::__ANON__[:1034] |
| 1 | 1 | 1 | 239µs | 11.6ms | Class::DBI::add_relationship_type |
| 4 | 2 | 1 | 199µs | 16.0ms | Class::DBI::columns |
| 3 | 1 | 1 | 149µs | 519µs | Class::DBI::find_column |
| 9 | 1 | 2 | 136µs | 136µs | Class::DBI::CORE:subst (opcode) |
| 1 | 1 | 1 | 130µs | 1.02ms | Class::DBI::set_db |
| 14 | 2 | 2 | 127µs | 127µs | Class::DBI::CORE:match (opcode) |
| 1 | 1 | 1 | 123µs | 3.53ms | Class::DBI::add_searcher |
| 10 | 1 | 1 | 115µs | 115µs | Class::DBI::_column_class |
| 1 | 1 | 1 | 110µs | 213µs | Class::DBI::meta_info |
| 1 | 1 | 1 | 78µs | 120µs | Class::DBI::_default_attributes |
| 5 | 1 | 1 | 66µs | 66µs | Class::DBI::clear_object_index |
| 1 | 1 | 1 | 49µs | 287µs | Class::DBI::_essential |
| 1 | 1 | 1 | 45µs | 1.07ms | Class::DBI::connection |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::BEGIN |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::DESTROY |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__::Base::BEGIN |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:1008] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:1095] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:1127] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:38] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:39] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:416] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:436] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:437] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:74] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:948] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:966] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:968] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::__ANON__[:971] |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_add_data_type |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_as_hash |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_attribute_delete |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_attribute_set |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_auto_increment_value |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_bind_param |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_carp |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_check_classes |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_class_autoupdate |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_column_placeholder |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_croak |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_data_hash |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_db_error |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_deflated_column |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_do_search |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_insert |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_insert_row |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_invalid_object_method |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_my_iterator |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_next_in_sequence |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_obj_autoupdate |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_prepopulate_id |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_search_delete |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_simple_bless |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_single_row_select |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_single_value_select |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_undefined_primary |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_unique_entries |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_update_line |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::_update_vals |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::add_constraint |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::add_constructor |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::all_columns |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::any_changed |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::autoupdate |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::constrain_column |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::copy |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::count_all |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::data_type |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::dbi_commit |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::dbi_rollback |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::delete |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::discard_changes |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::find_or_create |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::has_real_column |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::id |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::insert |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::make_read_only |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::maximum_value_of |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::minimum_value_of |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::move |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::normalize_column_values |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::purge_dead_from_object_index |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::remove_from_object_index |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::retrieve |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::retrieve_all |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::retrieve_from_sql |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::search_like |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::set |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::stringify_self |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::table_alias |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::update |
| 0 | 0 | 0 | 0s | 0s | Class::DBI::validate_column_values |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Class::DBI::__::Base; | ||||
| 2 | |||||
| 3 | 1 | 5µs | require 5.006; | ||
| 4 | |||||
| 5 | 3 | 16.6ms | 2 | 101µs | use Class::Trigger 0.07; # spent 88µs making 1 call to Class::Trigger::import
# spent 13µs making 1 call to UNIVERSAL::VERSION |
| 6 | 3 | 109µs | 1 | 0s | use base qw(Class::Accessor Class::Data::Inheritable Ima::DBI); # spent 92.7ms making 1 call to base::import, recursion: max depth 3, time 92.7ms |
| 7 | |||||
| 8 | package Class::DBI; | ||||
| 9 | |||||
| 10 | 4 | 353µs | 2 | 279µs | use version; $VERSION = qv('3.0.17'); # spent 236µs making 1 call to version::__ANON__[version.pm:32]
# spent 43µs making 1 call to version::import |
| 11 | |||||
| 12 | 3 | 78µs | 1 | 23µs | use strict; # spent 23µs making 1 call to strict::import |
| 13 | 3 | 85µs | 1 | 112µs | use warnings; # spent 112µs making 1 call to warnings::import |
| 14 | |||||
| 15 | 3 | 106µs | 1 | 0s | use base "Class::DBI::__::Base"; # spent 26.6ms making 1 call to base::import, recursion: max depth 3, time 26.6ms |
| 16 | |||||
| 17 | 3 | 22.1ms | use Class::DBI::ColumnGrouper; | ||
| 18 | 3 | 1.43ms | use Class::DBI::Query; | ||
| 19 | 3 | 58µs | use Carp (); | ||
| 20 | 3 | 101µs | 1 | 163µs | use List::Util; # spent 163µs making 1 call to Exporter::import |
| 21 | 3 | 5.27ms | use Clone (); | ||
| 22 | 3 | 4.25ms | use UNIVERSAL::moniker; | ||
| 23 | |||||
| 24 | 3 | 164µs | 1 | 143µs | use vars qw($Weaken_Is_Available); # spent 143µs making 1 call to vars::import |
| 25 | |||||
| 26 | BEGIN { | ||||
| 27 | 1 | 5µs | $Weaken_Is_Available = 1; | ||
| 28 | 1 | 10µs | eval { | ||
| 29 | 1 | 5µs | require Scalar::Util; | ||
| 30 | 1 | 31µs | 1 | 421µs | import Scalar::Util qw(weaken); # spent 421µs making 1 call to Exporter::import |
| 31 | }; | ||||
| 32 | 1 | 6µs | if ($@) { | ||
| 33 | $Weaken_Is_Available = 0; | ||||
| 34 | } | ||||
| 35 | 1 | 166µs | } | ||
| 36 | |||||
| 37 | use overload | ||||
| 38 | '""' => sub { shift->stringify_self }, | ||||
| 39 | bool => sub { not shift->_undefined_primary }, | ||||
| 40 | 3 | 337µs | 1 | 209µs | fallback => 1; # spent 209µs making 1 call to overload::import |
| 41 | |||||
| 42 | sub stringify_self { | ||||
| 43 | my $self = shift; | ||||
| 44 | return (ref $self || $self) unless $self; # empty PK | ||||
| 45 | my @cols = $self->columns('Stringify'); | ||||
| 46 | @cols = $self->primary_columns unless @cols; | ||||
| 47 | return join "/", $self->get(@cols); | ||||
| 48 | } | ||||
| 49 | |||||
| 50 | sub _undefined_primary { | ||||
| 51 | my $self = shift; | ||||
| 52 | return grep !defined, $self->_attrs($self->primary_columns); | ||||
| 53 | } | ||||
| 54 | |||||
| 55 | #---------------------------------------------------------------------- | ||||
| 56 | # Deprecations | ||||
| 57 | #---------------------------------------------------------------------- | ||||
| 58 | |||||
| 59 | 1 | 41µs | 1 | 73µs | __PACKAGE__->mk_classdata('__hasa_rels' => {}); # spent 73µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 60 | |||||
| 61 | { | ||||
| 62 | 2 | 16µs | my %deprecated = ( | ||
| 63 | # accessor_name => 'accessor_name_for', # 3.0.7 | ||||
| 64 | # mutator_name => 'accessor_name_for', # 3.0.7 | ||||
| 65 | ); | ||||
| 66 | |||||
| 67 | 3 | 2.99ms | 1 | 98µs | no strict 'refs'; # spent 98µs making 1 call to strict::unimport |
| 68 | 1 | 12µs | while (my ($old, $new) = each %deprecated) { | ||
| 69 | *$old = sub { | ||||
| 70 | my @caller = caller; | ||||
| 71 | warn | ||||
| 72 | "Use of '$old' is deprecated at $caller[1] line $caller[2]. Use '$new' instead\n"; | ||||
| 73 | goto &$new; | ||||
| 74 | }; | ||||
| 75 | } | ||||
| 76 | } | ||||
| 77 | |||||
| 78 | #---------------------------------------------------------------------- | ||||
| 79 | # Our Class Data | ||||
| 80 | #---------------------------------------------------------------------- | ||||
| 81 | 1 | 27µs | 1 | 60µs | __PACKAGE__->mk_classdata('__AutoCommit'); # spent 60µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 82 | 1 | 23µs | 1 | 54µs | __PACKAGE__->mk_classdata('__hasa_list'); # spent 54µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 83 | 1 | 22µs | 1 | 52µs | __PACKAGE__->mk_classdata('_table'); # spent 52µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 84 | 1 | 23µs | 1 | 52µs | __PACKAGE__->mk_classdata('_table_alias'); # spent 52µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 85 | 1 | 22µs | 1 | 53µs | __PACKAGE__->mk_classdata('sequence'); # spent 53µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 86 | 1 | 38µs | 2 | 89µs | __PACKAGE__->mk_classdata('__grouper' => Class::DBI::ColumnGrouper->new()); # spent 53µs making 1 call to Class::Data::Inheritable::mk_classdata
# spent 36µs making 1 call to Class::DBI::ColumnGrouper::new |
| 87 | 1 | 38µs | 1 | 53µs | __PACKAGE__->mk_classdata('__data_type' => {}); # spent 53µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 88 | 1 | 22µs | 1 | 48µs | __PACKAGE__->mk_classdata('__driver'); # spent 48µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 89 | 1 | 24µs | 1 | 52µs | __PACKAGE__->mk_classdata('iterator_class' => 'Class::DBI::Iterator'); # spent 52µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 90 | 1 | 23µs | 1 | 69µs | __PACKAGE__->mk_classdata('purge_object_index_every' => 1000); # spent 69µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 91 | 1 | 18µs | 1 | 3.53ms | __PACKAGE__->add_searcher(search => "Class::DBI::Search::Basic",); # spent 3.53ms making 1 call to Class::DBI::add_searcher |
| 92 | |||||
| 93 | 1 | 20µs | 1 | 11.6ms | __PACKAGE__->add_relationship_type( # spent 11.6ms making 1 call to Class::DBI::add_relationship_type |
| 94 | has_a => "Class::DBI::Relationship::HasA", | ||||
| 95 | has_many => "Class::DBI::Relationship::HasMany", | ||||
| 96 | might_have => "Class::DBI::Relationship::MightHave", | ||||
| 97 | ); | ||||
| 98 | 1 | 41µs | 1 | 65µs | __PACKAGE__->mk_classdata('__meta_info' => {}); # spent 65µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 99 | |||||
| 100 | #---------------------------------------------------------------------- | ||||
| 101 | # SQL we'll need | ||||
| 102 | #---------------------------------------------------------------------- | ||||
| 103 | 1 | 19µs | 1 | 531µs | __PACKAGE__->set_sql(MakeNewObj => <<''); # spent 531µs making 1 call to Class::DBI::set_sql |
| 104 | INSERT INTO __TABLE__ (%s) | ||||
| 105 | VALUES (%s) | ||||
| 106 | |||||
| 107 | 1 | 19µs | 1 | 318µs | __PACKAGE__->set_sql(update => <<""); # spent 318µs making 1 call to Class::DBI::set_sql |
| 108 | UPDATE __TABLE__ | ||||
| 109 | SET %s | ||||
| 110 | WHERE __IDENTIFIER__ | ||||
| 111 | |||||
| 112 | 1 | 19µs | 1 | 451µs | __PACKAGE__->set_sql(Nextval => <<''); # spent 451µs making 1 call to Class::DBI::set_sql |
| 113 | SELECT NEXTVAL ('%s') | ||||
| 114 | |||||
| 115 | 1 | 18µs | 1 | 393µs | __PACKAGE__->set_sql(SearchSQL => <<''); # spent 393µs making 1 call to Class::DBI::set_sql |
| 116 | SELECT %s | ||||
| 117 | FROM %s | ||||
| 118 | WHERE %s | ||||
| 119 | |||||
| 120 | 1 | 17µs | 1 | 370µs | __PACKAGE__->set_sql(RetrieveAll => <<''); # spent 370µs making 1 call to Class::DBI::set_sql |
| 121 | SELECT __ESSENTIAL__ | ||||
| 122 | FROM __TABLE__ | ||||
| 123 | |||||
| 124 | 1 | 17µs | 1 | 378µs | __PACKAGE__->set_sql(Retrieve => <<''); # spent 378µs making 1 call to Class::DBI::set_sql |
| 125 | SELECT __ESSENTIAL__ | ||||
| 126 | FROM __TABLE__ | ||||
| 127 | WHERE %s | ||||
| 128 | |||||
| 129 | 1 | 17µs | 1 | 376µs | __PACKAGE__->set_sql(Flesh => <<''); # spent 376µs making 1 call to Class::DBI::set_sql |
| 130 | SELECT %s | ||||
| 131 | FROM __TABLE__ | ||||
| 132 | WHERE __IDENTIFIER__ | ||||
| 133 | |||||
| 134 | 1 | 18µs | 1 | 384µs | __PACKAGE__->set_sql(single => <<''); # spent 384µs making 1 call to Class::DBI::set_sql |
| 135 | SELECT %s | ||||
| 136 | FROM __TABLE__ | ||||
| 137 | |||||
| 138 | 1 | 19µs | 1 | 301µs | __PACKAGE__->set_sql(DeleteMe => <<""); # spent 301µs making 1 call to Class::DBI::set_sql |
| 139 | DELETE | ||||
| 140 | FROM __TABLE__ | ||||
| 141 | WHERE __IDENTIFIER__ | ||||
| 142 | |||||
| 143 | |||||
| 144 | 1 | 27µs | 1 | 53µs | __PACKAGE__->mk_classdata('sql_transformer_class'); # spent 53µs making 1 call to Class::Data::Inheritable::mk_classdata |
| 145 | 1 | 18µs | 1 | 27µs | __PACKAGE__->sql_transformer_class('Class::DBI::SQL::Transformer'); # spent 27µs making 1 call to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23] |
| 146 | |||||
| 147 | # Override transform_sql from Ima::DBI to provide some extra | ||||
| 148 | # transformations | ||||
| 149 | # spent 4.75ms (412µs+4.34) within Class::DBI::transform_sql which was called 2 times, avg 2.37ms/call:
# 2 times (412µs+4.34ms) by Ima::DBI::__ANON__[/project/perl/lib/Ima/DBI.pm:384] at line 380 of Ima/DBI.pm, avg 2.37ms/call | ||||
| 150 | 2 | 18µs | my ($self, $sql, @args) = @_; | ||
| 151 | 2 | 51µs | 2 | 58µs | my $tclass = $self->sql_transformer_class; # spent 58µs making 2 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 29µs/call |
| 152 | 2 | 48µs | 2 | 2.45ms | $self->_require_class($tclass); # spent 2.45ms making 2 calls to Class::DBI::_require_class, avg 1.23ms/call |
| 153 | 2 | 53µs | 2 | 93µs | my $T = $tclass->new($self, $sql, @args); # spent 93µs making 2 calls to Class::DBI::SQL::Transformer::new, avg 46µs/call |
| 154 | 2 | 183µs | 6 | 1.73ms | return $self->SUPER::transform_sql($T->sql => $T->args); # spent 1.64ms making 2 calls to Class::DBI::SQL::Transformer::sql, avg 818µs/call
# spent 51µs making 2 calls to Ima::DBI::transform_sql, avg 26µs/call
# spent 45µs making 2 calls to Class::DBI::SQL::Transformer::args, avg 22µs/call |
| 155 | } | ||||
| 156 | |||||
| 157 | #---------------------------------------------------------------------- | ||||
| 158 | # EXCEPTIONS | ||||
| 159 | #---------------------------------------------------------------------- | ||||
| 160 | |||||
| 161 | sub _carp { | ||||
| 162 | my ($self, $msg) = @_; | ||||
| 163 | Carp::carp($msg || $self); | ||||
| 164 | return; | ||||
| 165 | } | ||||
| 166 | |||||
| 167 | sub _croak { | ||||
| 168 | my ($self, $msg) = @_; | ||||
| 169 | Carp::croak($msg || $self); | ||||
| 170 | } | ||||
| 171 | |||||
| 172 | sub _db_error { | ||||
| 173 | my ($self, %info) = @_; | ||||
| 174 | my $msg = delete $info{msg}; | ||||
| 175 | return $self->_croak($msg, %info); | ||||
| 176 | } | ||||
| 177 | |||||
| 178 | #---------------------------------------------------------------------- | ||||
| 179 | # SET UP | ||||
| 180 | #---------------------------------------------------------------------- | ||||
| 181 | |||||
| 182 | # spent 1.07ms (45µs+1.02) within Class::DBI::connection which was called
# once (45µs+1.02ms) by base::import at line 13 of K2/DB2.pm | ||||
| 183 | 1 | 7µs | my $class = shift; | ||
| 184 | 1 | 35µs | 1 | 1.02ms | $class->set_db(Main => @_); # spent 1.02ms making 1 call to Class::DBI::set_db |
| 185 | } | ||||
| 186 | |||||
| 187 | { | ||||
| 188 | 2 | 22µs | my %Per_DB_Attr_Defaults = ( | ||
| 189 | pg => { AutoCommit => 0 }, | ||||
| 190 | oracle => { AutoCommit => 0 }, | ||||
| 191 | ); | ||||
| 192 | |||||
| 193 | # spent 120µs (78+42) within Class::DBI::_default_attributes which was called
# once (78µs+42µs) by Ima::DBI::_add_default_attributes at line 286 of Ima/DBI.pm | ||||
| 194 | 1 | 5µs | my $class = shift; | ||
| 195 | return ( | ||||
| 196 | $class->SUPER::_default_attributes, | ||||
| 197 | FetchHashKeyName => 'NAME_lc', | ||||
| 198 | ShowErrorStatement => 1, | ||||
| 199 | AutoCommit => 1, | ||||
| 200 | ChopBlanks => 1, | ||||
| 201 | 1 | 67µs | 2 | 42µs | %{ $Per_DB_Attr_Defaults{ lc $class->__driver } || {} }, # spent 26µs making 1 call to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23]
# spent 16µs making 1 call to Ima::DBI::_default_attributes |
| 202 | ); | ||||
| 203 | } | ||||
| 204 | } | ||||
| 205 | |||||
| 206 | # spent 1.02ms (130µs+893µs) within Class::DBI::set_db which was called
# once (130µs+893µs) by Class::DBI::connection at line 184 | ||||
| 207 | 1 | 9µs | my ($class, $db_name, $data_source, $user, $password, $attr) = @_; | ||
| 208 | |||||
| 209 | # 'dbi:Pg:dbname=foo' we want 'Pg'. I think this is enough. | ||||
| 210 | 1 | 37µs | 1 | 12µs | my ($driver) = $data_source =~ /^dbi:(\w+)/i; # spent 12µs making 1 call to Class::DBI::CORE:match |
| 211 | 1 | 31µs | 1 | 155µs | $class->__driver($driver); # spent 155µs making 1 call to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23] |
| 212 | 1 | 61µs | 1 | 726µs | $class->SUPER::set_db('Main', $data_source, $user, $password, $attr); # spent 726µs making 1 call to Ima::DBI::set_db |
| 213 | } | ||||
| 214 | |||||
| 215 | # spent 735µs (271+464) within Class::DBI::table which was called 4 times, avg 184µs/call:
# 2 times (166µs+410µs) by Class::DBI::Pg::set_up_table at line 80 of Class/DBI/Pg.pm, avg 288µs/call
# 2 times (105µs+54µs) by Class::DBI::SQL::Transformer::_expand_table at line 71 of Class/DBI/SQL/Transformer.pm, avg 80µs/call | ||||
| 216 | 4 | 27µs | my ($proto, $table, $alias) = @_; | ||
| 217 | 4 | 22µs | my $class = ref $proto || $proto; | ||
| 218 | 4 | 68µs | 2 | 359µs | $class->_table($table) if $table; # spent 359µs making 2 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 180µs/call |
| 219 | 4 | 17µs | $class->table_alias($alias) if $alias; | ||
| 220 | 4 | 117µs | 4 | 105µs | return $class->_table || $class->_table($class->table_alias); # spent 105µs making 4 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 26µs/call |
| 221 | } | ||||
| 222 | |||||
| 223 | sub table_alias { | ||||
| 224 | my ($proto, $alias) = @_; | ||||
| 225 | my $class = ref $proto || $proto; | ||||
| 226 | $class->_table_alias($alias) if $alias; | ||||
| 227 | return $class->_table_alias || $class->_table_alias($class->moniker); | ||||
| 228 | } | ||||
| 229 | |||||
| 230 | # spent 16.0ms (199µs+15.8) within Class::DBI::columns which was called 4 times, avg 4.00ms/call:
# 2 times (98µs+10.9ms) by Class::DBI::Pg::set_up_table at line 82 of Class/DBI/Pg.pm, avg 5.51ms/call
# 2 times (101µs+4.89ms) by Class::DBI::Pg::set_up_table at line 81 of Class/DBI/Pg.pm, avg 2.49ms/call | ||||
| 231 | 4 | 24µs | my $proto = shift; | ||
| 232 | 4 | 18µs | my $class = ref $proto || $proto; | ||
| 233 | 4 | 20µs | my $group = shift || "All"; | ||
| 234 | 4 | 140µs | 4 | 15.8ms | return $class->_set_columns($group => @_) if @_; # spent 15.8ms making 4 calls to Class::DBI::_set_columns, avg 3.95ms/call |
| 235 | return $class->all_columns if $group eq "All"; | ||||
| 236 | return $class->primary_column if $group eq "Primary"; | ||||
| 237 | return $class->_essential if $group eq "Essential"; | ||||
| 238 | return $class->__grouper->group_cols($group); | ||||
| 239 | } | ||||
| 240 | |||||
| 241 | 10 | 140µs | # spent 115µs within Class::DBI::_column_class which was called 10 times, avg 12µs/call:
# 10 times (115µs+0s) by Class::DBI::_set_columns at line 246, avg 12µs/call | ||
| 242 | |||||
| 243 | # spent 15.8ms (1.35+14.5) within Class::DBI::_set_columns which was called 4 times, avg 3.95ms/call:
# 4 times (1.35ms+14.5ms) by Class::DBI::columns at line 234, avg 3.95ms/call | ||||
| 244 | 4 | 33µs | my ($class, $group, @columns) = @_; | ||
| 245 | |||||
| 246 | 4 | 350µs | 20 | 1.93ms | my @cols = map ref $_ ? $_ : $class->_column_class->new($_), @columns; # spent 1.81ms making 10 calls to Class::DBI::Column::new, avg 182µs/call
# spent 115µs making 10 calls to Class::DBI::_column_class, avg 12µs/call |
| 247 | |||||
| 248 | # Careful to take copy | ||||
| 249 | 4 | 302µs | 16 | 3.88ms | $class->__grouper(Class::DBI::ColumnGrouper->clone($class->__grouper) # spent 2.45ms making 4 calls to Class::DBI::ColumnGrouper::add_group, avg 613µs/call
# spent 903µs making 4 calls to Class::DBI::ColumnGrouper::clone, avg 226µs/call
# spent 525µs making 8 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 66µs/call |
| 250 | ->add_group($group => @cols)); | ||||
| 251 | 4 | 126µs | 4 | 8.65ms | $class->_mk_column_accessors(@cols); # spent 8.65ms making 4 calls to Class::DBI::_mk_column_accessors, avg 2.16ms/call |
| 252 | 4 | 462µs | return @columns; | ||
| 253 | } | ||||
| 254 | |||||
| 255 | sub all_columns { shift->__grouper->all_columns } | ||||
| 256 | |||||
| 257 | sub id { | ||||
| 258 | my $self = shift; | ||||
| 259 | my $class = ref($self) | ||||
| 260 | or return $self->_croak("Can't call id() as a class method"); | ||||
| 261 | |||||
| 262 | # we don't use get() here because all objects should have | ||||
| 263 | # exisitng values for PK columns, or else loop endlessly | ||||
| 264 | my @pk_values = $self->_attrs($self->primary_columns); | ||||
| 265 | UNIVERSAL::can($_ => 'id') and $_ = $_->id for @pk_values; | ||||
| 266 | return @pk_values if wantarray; | ||||
| 267 | $self->_croak( | ||||
| 268 | "id called in scalar context for class with multiple primary key columns") | ||||
| 269 | if @pk_values > 1; | ||||
| 270 | return $pk_values[0]; | ||||
| 271 | } | ||||
| 272 | |||||
| 273 | # spent 64.4ms (23.9+40.5) within Class::DBI::primary_column which was called 464 times, avg 139µs/call:
# 461 times (23.7ms+40.2ms) by Class::DBI::_live_object_key at line 521, avg 139µs/call
# 2 times (138µs+186µs) by Class::DBI::_make_method at line 368, avg 162µs/call
# once (55µs+89µs) by Class::DBI::SQL::Transformer::_do_transformation at line 120 of Class/DBI/SQL/Transformer.pm | ||||
| 274 | 464 | 2.27ms | my $self = shift; | ||
| 275 | 464 | 13.8ms | 928 | 40.5ms | my @primary_columns = $self->__grouper->primary; # spent 28.8ms making 464 calls to Class::DBI::ColumnGrouper::primary, avg 62µs/call
# spent 11.7ms making 464 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 25µs/call |
| 276 | 464 | 5.86ms | return @primary_columns if wantarray; | ||
| 277 | $self->_carp( | ||||
| 278 | ref($self) | ||||
| 279 | . " has multiple primary columns, but fetching in scalar context") | ||||
| 280 | if @primary_columns > 1; | ||||
| 281 | return $primary_columns[0]; | ||||
| 282 | } | ||||
| 283 | 1 | 7µs | *primary_columns = \&primary_column; | ||
| 284 | |||||
| 285 | 1 | 42µs | 2 | 238µs | # spent 287µs (49+238) within Class::DBI::_essential which was called
# once (49µs+238µs) by Class::DBI::SQL::Transformer::_do_transformation at line 116 of Class/DBI/SQL/Transformer.pm # spent 211µs making 1 call to Class::DBI::ColumnGrouper::essential
# spent 27µs making 1 call to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23] |
| 286 | |||||
| 287 | # spent 519µs (149+370) within Class::DBI::find_column which was called 3 times, avg 173µs/call:
# 3 times (149µs+370µs) by Class::DBI::Relationship::HasA::remap_arguments at line 11 of Class/DBI/Relationship/HasA.pm, avg 173µs/call | ||||
| 288 | 3 | 17µs | my ($class, $want) = @_; | ||
| 289 | 3 | 127µs | 6 | 370µs | return $class->__grouper->find_column($want); # spent 291µs making 3 calls to Class::DBI::ColumnGrouper::find_column, avg 97µs/call
# spent 79µs making 3 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 26µs/call |
| 290 | } | ||||
| 291 | |||||
| 292 | # spent 86.3ms (25.7+60.7) within Class::DBI::_find_columns which was called 463 times, avg 186µs/call:
# 463 times (25.7ms+60.7ms) by Class::DBI::get at line 841, avg 186µs/call | ||||
| 293 | 463 | 2.18ms | my $class = shift; | ||
| 294 | 463 | 8.27ms | 463 | 13.1ms | my $cg = $class->__grouper; # spent 13.1ms making 463 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 28µs/call |
| 295 | 463 | 12.9ms | 463 | 47.6ms | return map $cg->find_column($_), @_; # spent 47.6ms making 463 calls to Class::DBI::ColumnGrouper::find_column, avg 103µs/call |
| 296 | } | ||||
| 297 | |||||
| 298 | sub has_real_column { # is really in the database | ||||
| 299 | my ($class, $want) = @_; | ||||
| 300 | return ($class->find_column($want) || return)->in_database; | ||||
| 301 | } | ||||
| 302 | |||||
| 303 | sub data_type { | ||||
| 304 | my $class = shift; | ||||
| 305 | my %datatype = @_; | ||||
| 306 | while (my ($col, $type) = each %datatype) { | ||||
| 307 | $class->_add_data_type($col, $type); | ||||
| 308 | } | ||||
| 309 | } | ||||
| 310 | |||||
| 311 | sub _add_data_type { | ||||
| 312 | my ($class, $col, $type) = @_; | ||||
| 313 | my $datatype = $class->__data_type; | ||||
| 314 | $datatype->{$col} = $type; | ||||
| 315 | $class->__data_type($datatype); | ||||
| 316 | } | ||||
| 317 | |||||
| 318 | # Make a set of accessors for each of a list of columns. We construct | ||||
| 319 | # the method name by calling accessor_name_for() and mutator_name_for() | ||||
| 320 | # with the normalized column name. | ||||
| 321 | |||||
| 322 | # mutator name will be the same as accessor name unless you override it. | ||||
| 323 | |||||
| 324 | # If both the accessor and mutator are to have the same method name, | ||||
| 325 | # (which will always be true unless you override mutator_name_for), a | ||||
| 326 | # read-write method is constructed for it. If they differ we create both | ||||
| 327 | # a read-only accessor and a write-only mutator. | ||||
| 328 | |||||
| 329 | # spent 8.65ms (2.81+5.84) within Class::DBI::_mk_column_accessors which was called 4 times, avg 2.16ms/call:
# 4 times (2.81ms+5.84ms) by Class::DBI::_set_columns at line 251, avg 2.16ms/call | ||||
| 330 | 4 | 23µs | my $class = shift; | ||
| 331 | 4 | 80µs | foreach my $col (@_) { | ||
| 332 | |||||
| 333 | 10 | 179µs | 10 | 148µs | my $default_accessor = $col->accessor; # spent 148µs making 10 calls to Class::Accessor::Fast::__ANON__[Class/Accessor/Fast.pm:41], avg 15µs/call |
| 334 | |||||
| 335 | 10 | 239µs | 10 | 982µs | my $acc = $class->accessor_name_for($col); # spent 982µs making 10 calls to Class::DBI::accessor_name_for, avg 98µs/call |
| 336 | 10 | 237µs | 10 | 861µs | my $mut = $class->mutator_name_for($col); # spent 861µs making 10 calls to Class::DBI::mutator_name_for, avg 86µs/call |
| 337 | |||||
| 338 | 10 | 56µs | my %method = (); | ||
| 339 | |||||
| 340 | 10 | 95µs | if ( | ||
| 341 | ($acc eq $mut) # if they are the same | ||||
| 342 | or ($mut eq $default_accessor) | ||||
| 343 | ) { # or only the accessor was customized | ||||
| 344 | 10 | 63µs | %method = ('_' => $acc); # make the accessor the mutator too | ||
| 345 | 10 | 161µs | 10 | 230µs | $col->accessor($acc); # spent 230µs making 10 calls to Class::Accessor::Fast::__ANON__[Class/Accessor/Fast.pm:41], avg 23µs/call |
| 346 | 10 | 159µs | 10 | 223µs | $col->mutator($acc); # spent 223µs making 10 calls to Class::Accessor::Fast::__ANON__[Class/Accessor/Fast.pm:41], avg 22µs/call |
| 347 | } else { | ||||
| 348 | %method = ( | ||||
| 349 | _ro_ => $acc, | ||||
| 350 | _wo_ => $mut, | ||||
| 351 | ); | ||||
| 352 | $col->accessor($acc); | ||||
| 353 | $col->mutator($mut); | ||||
| 354 | } | ||||
| 355 | |||||
| 356 | 10 | 216µs | foreach my $type (keys %method) { | ||
| 357 | 10 | 53µs | my $name = $method{$type}; | ||
| 358 | 10 | 58µs | my $acc_type = "make${type}accessor"; | ||
| 359 | 10 | 422µs | 20 | 650µs | my $accessor = $class->$acc_type($col->name_lc); # spent 395µs making 10 calls to Class::DBI::Column::name_lc, avg 40µs/call
# spent 255µs making 10 calls to Class::Accessor::make_accessor, avg 26µs/call |
| 360 | 20 | 612µs | 20 | 2.75ms | $class->_make_method($_, $accessor) for ($name, "_${name}_accessor"); # spent 2.75ms making 20 calls to Class::DBI::_make_method, avg 137µs/call |
| 361 | } | ||||
| 362 | } | ||||
| 363 | } | ||||
| 364 | |||||
| 365 | sub _make_method { | ||||
| 366 | 36 | 199µs | my ($class, $name, $method) = @_; | ||
| 367 | 36 | 476µs | return if defined &{"$class\::$name"}; | ||
| 368 | 16 | 902µs | 18 | 677µs | $class->_carp("Column '$name' in $class clashes with built-in method") # spent 353µs making 16 calls to UNIVERSAL::can, avg 22µs/call
# spent 324µs making 2 calls to Class::DBI::primary_column, avg 162µs/call |
| 369 | if Class::DBI->can($name) | ||||
| 370 | and not($name eq "id" and join(" ", $class->primary_columns) eq "id"); | ||||
| 371 | 3 | 6.65ms | 1 | 100µs | no strict 'refs'; # spent 100µs making 1 call to strict::unimport |
| 372 | 16 | 203µs | *{"$class\::$name"} = $method; | ||
| 373 | 16 | 517µs | 16 | 0s | $class->_make_method(lc $name => $method); # spent 338µs making 16 calls to Class::DBI::_make_method, avg 21µs/call, recursion: max depth 1, time 338µs |
| 374 | } | ||||
| 375 | |||||
| 376 | # spent 982µs (607+375) within Class::DBI::accessor_name_for which was called 10 times, avg 98µs/call:
# 10 times (607µs+375µs) by Class::DBI::_mk_column_accessors at line 335, avg 98µs/call | ||||
| 377 | 10 | 53µs | my ($class, $column) = @_; | ||
| 378 | 10 | 521µs | 10 | 219µs | if ($class->can('accessor_name')) { # spent 219µs making 10 calls to UNIVERSAL::can, avg 22µs/call |
| 379 | warn "Use of 'accessor_name' is deprecated. Use 'accessor_name_for' instead\n"; | ||||
| 380 | return $class->accessor_name($column) | ||||
| 381 | } | ||||
| 382 | 10 | 237µs | 10 | 156µs | return $column->accessor; # spent 156µs making 10 calls to Class::Accessor::Fast::__ANON__[Class/Accessor/Fast.pm:41], avg 16µs/call |
| 383 | } | ||||
| 384 | |||||
| 385 | # spent 861µs (486+375) within Class::DBI::mutator_name_for which was called 10 times, avg 86µs/call:
# 10 times (486µs+375µs) by Class::DBI::_mk_column_accessors at line 336, avg 86µs/call | ||||
| 386 | 10 | 54µs | my ($class, $column) = @_; | ||
| 387 | 10 | 361µs | 10 | 218µs | if ($class->can('mutator_name')) { # spent 218µs making 10 calls to UNIVERSAL::can, avg 22µs/call |
| 388 | warn "Use of 'mutator_name' is deprecated. Use 'mutator_name_for' instead\n"; | ||||
| 389 | return $class->mutator_name($column) | ||||
| 390 | } | ||||
| 391 | 10 | 291µs | 10 | 157µs | return $column->mutator; # spent 157µs making 10 calls to Class::Accessor::Fast::__ANON__[Class/Accessor/Fast.pm:41], avg 16µs/call |
| 392 | } | ||||
| 393 | |||||
| 394 | sub autoupdate { | ||||
| 395 | my $proto = shift; | ||||
| 396 | ref $proto ? $proto->_obj_autoupdate(@_) : $proto->_class_autoupdate(@_); | ||||
| 397 | } | ||||
| 398 | |||||
| 399 | sub _obj_autoupdate { | ||||
| 400 | my ($self, $set) = @_; | ||||
| 401 | my $class = ref $self; | ||||
| 402 | $self->{__AutoCommit} = $set if defined $set; | ||||
| 403 | defined $self->{__AutoCommit} | ||||
| 404 | ? $self->{__AutoCommit} | ||||
| 405 | : $class->_class_autoupdate; | ||||
| 406 | } | ||||
| 407 | |||||
| 408 | sub _class_autoupdate { | ||||
| 409 | my ($class, $set) = @_; | ||||
| 410 | $class->__AutoCommit($set) if defined $set; | ||||
| 411 | return $class->__AutoCommit; | ||||
| 412 | } | ||||
| 413 | |||||
| 414 | sub make_read_only { | ||||
| 415 | my $proto = shift; | ||||
| 416 | $proto->add_trigger("before_$_" => sub { _croak "$proto is read only" }) | ||||
| 417 | foreach qw/create delete update/; | ||||
| 418 | return $proto; | ||||
| 419 | } | ||||
| 420 | |||||
| 421 | sub find_or_create { | ||||
| 422 | my $class = shift; | ||||
| 423 | my $hash = ref $_[0] eq "HASH" ? shift: {@_}; | ||||
| 424 | my ($exists) = $class->search($hash); | ||||
| 425 | return defined($exists) ? $exists : $class->insert($hash); | ||||
| 426 | } | ||||
| 427 | |||||
| 428 | sub insert { | ||||
| 429 | my $class = shift; | ||||
| 430 | return $class->_croak("insert needs a hashref") unless ref $_[0] eq 'HASH'; | ||||
| 431 | my $info = { %{ +shift } }; # make sure we take a copy | ||||
| 432 | |||||
| 433 | my $data; | ||||
| 434 | while (my ($k, $v) = each %$info) { | ||||
| 435 | my $col = $class->find_column($k) | ||||
| 436 | || (List::Util::first { $_->mutator eq $k } $class->columns) | ||||
| 437 | || (List::Util::first { $_->accessor eq $k } $class->columns) | ||||
| 438 | || $class->_croak("$k is not a column of $class"); | ||||
| 439 | $data->{$col} = $v; | ||||
| 440 | } | ||||
| 441 | |||||
| 442 | $class->normalize_column_values($data); | ||||
| 443 | $class->validate_column_values($data); | ||||
| 444 | return $class->_insert($data); | ||||
| 445 | } | ||||
| 446 | |||||
| 447 | 1 | 5µs | *create = \&insert; | ||
| 448 | |||||
| 449 | #---------------------------------------------------------------------- | ||||
| 450 | # Low Level Data Access | ||||
| 451 | #---------------------------------------------------------------------- | ||||
| 452 | |||||
| 453 | # spent 79.6ms (42.6+36.9) within Class::DBI::_attrs which was called 925 times, avg 86µs/call:
# 463 times (21.0ms+17.2ms) by Class::DBI::get at line 848, avg 83µs/call
# 462 times (21.6ms+19.7ms) by Class::DBI::Relationship::HasA::__ANON__[/project/perl/lib/Class/DBI/Relationship/HasA.pm:77] at line 36 of Class/DBI/Relationship/HasA.pm, avg 89µs/call | ||||
| 454 | 925 | 5.09ms | my ($self, @atts) = @_; | ||
| 455 | 925 | 21.4ms | return @{$self}{@atts}; | ||
| 456 | } | ||||
| 457 | 1 | 6µs | *_attr = \&_attrs; | ||
| 458 | |||||
| 459 | # spent 16.7ms (16.7+47µs) within Class::DBI::_attribute_store which was called 463 times, avg 36µs/call:
# 461 times (16.5ms+0s) by Class::DBI::_fresh_init at line 505, avg 36µs/call
# once (74µs+47µs) by Class::DBI::Relationship::HasA::__ANON__[/project/perl/lib/Class/DBI/Relationship/HasA.pm:77] at line 55 of Class/DBI/Relationship/HasA.pm
# once (70µs+0s) by Class::DBI::_flesh at line 858 | ||||
| 460 | 463 | 2.17ms | my $self = shift; | ||
| 461 | 463 | 3.45ms | my $vals = @_ == 1 ? shift: {@_}; | ||
| 462 | 463 | 3.15ms | my (@cols) = keys %$vals; | ||
| 463 | 463 | 9.16ms | @{$self}{@cols} = @{$vals}{@cols}; | ||
| 464 | } | ||||
| 465 | |||||
| 466 | # If you override this method, you must use the same mechanism to log changes | ||||
| 467 | # for future updates, as other parts of Class::DBI depend on it. | ||||
| 468 | sub _attribute_set { | ||||
| 469 | my $self = shift; | ||||
| 470 | my $vals = @_ == 1 ? shift: {@_}; | ||||
| 471 | |||||
| 472 | # We increment instead of setting to 1 because it might be useful to | ||||
| 473 | # someone to know how many times a value has changed between updates. | ||||
| 474 | for my $col (keys %$vals) { $self->{__Changed}{$col}++; } | ||||
| 475 | $self->_attribute_store($vals); | ||||
| 476 | } | ||||
| 477 | |||||
| 478 | sub _attribute_delete { | ||||
| 479 | my ($self, @attributes) = @_; | ||||
| 480 | delete @{$self}{@attributes}; | ||||
| 481 | } | ||||
| 482 | |||||
| 483 | sub _attribute_exists { | ||||
| 484 | 467 | 2.50ms | my ($self, $attribute) = @_; | ||
| 485 | 467 | 10.7ms | exists $self->{$attribute}; | ||
| 486 | } | ||||
| 487 | |||||
| 488 | #---------------------------------------------------------------------- | ||||
| 489 | # Live Object Index (using weak refs if available) | ||||
| 490 | #---------------------------------------------------------------------- | ||||
| 491 | |||||
| 492 | 1 | 4µs | my %Live_Objects; | ||
| 493 | 1 | 5µs | my $Init_Count = 0; | ||
| 494 | |||||
| 495 | # spent 283ms (24.8+259) within Class::DBI::_init which was called 461 times, avg 615µs/call:
# 461 times (24.8ms+259ms) by Class::DBI::construct at line 716, avg 615µs/call | ||||
| 496 | 461 | 2.32ms | my $class = shift; | ||
| 497 | 461 | 2.13ms | my $data = shift || {}; | ||
| 498 | 461 | 7.72ms | 461 | 180ms | my $key = $class->_live_object_key($data); # spent 180ms making 461 calls to Class::DBI::_live_object_key, avg 391µs/call |
| 499 | 461 | 11.9ms | 461 | 78.1ms | return $Live_Objects{$key} || $class->_fresh_init($key => $data); # spent 78.1ms making 461 calls to Class::DBI::_fresh_init, avg 169µs/call |
| 500 | } | ||||
| 501 | |||||
| 502 | # spent 78.1ms (45.1+33.1) within Class::DBI::_fresh_init which was called 461 times, avg 169µs/call:
# 461 times (45.1ms+33.1ms) by Class::DBI::_init at line 499, avg 169µs/call | ||||
| 503 | 461 | 2.68ms | my ($class, $key, $data) = @_; | ||
| 504 | 461 | 5.12ms | my $obj = bless {}, $class; | ||
| 505 | 461 | 8.56ms | 461 | 16.5ms | $obj->_attribute_store(%$data); # spent 16.5ms making 461 calls to Class::DBI::_attribute_store, avg 36µs/call |
| 506 | |||||
| 507 | # don't store it unless all keys are present | ||||
| 508 | 461 | 4.57ms | if ($key && $Weaken_Is_Available) { | ||
| 509 | 461 | 11.8ms | 461 | 4.37ms | weaken($Live_Objects{$key} = $obj); # spent 4.37ms making 461 calls to Scalar::Util::weaken, avg 9µs/call |
| 510 | |||||
| 511 | # time to clean up your room? | ||||
| 512 | 461 | 8.88ms | 461 | 12.2ms | $class->purge_dead_from_object_index # spent 12.2ms making 461 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 26µs/call |
| 513 | if ++$Init_Count % $class->purge_object_index_every == 0; | ||||
| 514 | } | ||||
| 515 | 461 | 5.63ms | return $obj; | ||
| 516 | } | ||||
| 517 | |||||
| 518 | # spent 180ms (62.1+118) within Class::DBI::_live_object_key which was called 461 times, avg 391µs/call:
# 461 times (62.1ms+118ms) by Class::DBI::_init at line 498, avg 391µs/call | ||||
| 519 | 461 | 2.27ms | my ($me, $data) = @_; | ||
| 520 | 461 | 2.07ms | my $class = ref($me) || $me; | ||
| 521 | 461 | 7.94ms | 461 | 63.9ms | my @primary = $class->primary_columns; # spent 63.9ms making 461 calls to Class::DBI::primary_column, avg 139µs/call |
| 522 | |||||
| 523 | # no key unless all PK columns are defined | ||||
| 524 | 461 | 7.49ms | return "" unless @primary == grep defined $data->{$_}, @primary; | ||
| 525 | |||||
| 526 | # create single unique key for this object | ||||
| 527 | 461 | 21.7ms | 461 | 2.61ms | return join "\030", $class, map $_ . "\032" . $data->{$_}, sort @primary; # spent 2.61ms making 461 calls to Class::DBI::CORE:sort, avg 6µs/call |
| 528 | } | ||||
| 529 | |||||
| 530 | sub purge_dead_from_object_index { | ||||
| 531 | delete @Live_Objects{ grep !defined $Live_Objects{$_}, keys %Live_Objects }; | ||||
| 532 | } | ||||
| 533 | |||||
| 534 | sub remove_from_object_index { | ||||
| 535 | my $self = shift; | ||||
| 536 | my $obj_key = $self->_live_object_key({ $self->_as_hash }); | ||||
| 537 | delete $Live_Objects{$obj_key}; | ||||
| 538 | } | ||||
| 539 | |||||
| 540 | # spent 66µs within Class::DBI::clear_object_index which was called 5 times, avg 13µs/call:
# 5 times (66µs+0s) by Class::DBI::Relationship::_init at line 23 of Class/DBI/Relationship.pm, avg 13µs/call | ||||
| 541 | 5 | 78µs | %Live_Objects = (); | ||
| 542 | } | ||||
| 543 | |||||
| 544 | #---------------------------------------------------------------------- | ||||
| 545 | |||||
| 546 | sub _prepopulate_id { | ||||
| 547 | my $self = shift; | ||||
| 548 | my @primary_columns = $self->primary_columns; | ||||
| 549 | return $self->_croak( | ||||
| 550 | sprintf "Can't create %s object with null primary key columns (%s)", | ||||
| 551 | ref $self, $self->_undefined_primary) | ||||
| 552 | if @primary_columns > 1; | ||||
| 553 | $self->_attribute_store($primary_columns[0] => $self->_next_in_sequence) | ||||
| 554 | if $self->sequence; | ||||
| 555 | } | ||||
| 556 | |||||
| 557 | sub _insert { | ||||
| 558 | my ($proto, $data) = @_; | ||||
| 559 | my $class = ref $proto || $proto; | ||||
| 560 | |||||
| 561 | my $self = $class->_init($data); | ||||
| 562 | $self->call_trigger('before_create'); | ||||
| 563 | $self->call_trigger('deflate_for_create'); | ||||
| 564 | |||||
| 565 | $self->_prepopulate_id if $self->_undefined_primary; | ||||
| 566 | |||||
| 567 | # Reinstate data | ||||
| 568 | my ($real, $temp) = ({}, {}); | ||||
| 569 | foreach my $col (grep $self->_attribute_exists($_), $self->all_columns) { | ||||
| 570 | ($class->has_real_column($col) ? $real : $temp)->{$col} = | ||||
| 571 | $self->_attrs($col); | ||||
| 572 | } | ||||
| 573 | $self->_insert_row($real); | ||||
| 574 | |||||
| 575 | my @primary_columns = $class->primary_columns; | ||||
| 576 | $self->_attribute_store( | ||||
| 577 | $primary_columns[0] => $real->{ $primary_columns[0] }) | ||||
| 578 | if @primary_columns == 1; | ||||
| 579 | |||||
| 580 | delete $self->{__Changed}; | ||||
| 581 | |||||
| 582 | my %primary_columns; | ||||
| 583 | @primary_columns{@primary_columns} = (); | ||||
| 584 | my @discard_columns = grep !exists $primary_columns{$_}, keys %$real; | ||||
| 585 | $self->call_trigger('create', discard_columns => \@discard_columns); # XXX | ||||
| 586 | |||||
| 587 | # Empty everything back out again! | ||||
| 588 | $self->_attribute_delete(@discard_columns); | ||||
| 589 | $self->call_trigger('after_create'); | ||||
| 590 | return $self; | ||||
| 591 | } | ||||
| 592 | |||||
| 593 | sub _next_in_sequence { | ||||
| 594 | my $self = shift; | ||||
| 595 | return $self->sql_Nextval($self->sequence)->select_val; | ||||
| 596 | } | ||||
| 597 | |||||
| 598 | sub _auto_increment_value { | ||||
| 599 | my $self = shift; | ||||
| 600 | my $dbh = $self->db_Main; | ||||
| 601 | |||||
| 602 | # Try to do this in a standard method. Fall back to MySQL/SQLite | ||||
| 603 | # specific versions. TODO remove these when last_insert_id is more | ||||
| 604 | # widespread. | ||||
| 605 | # Note: I don't believe the last_insert_id can be zero. We need to | ||||
| 606 | # switch to defined() checks if it can. | ||||
| 607 | my $id = $dbh->last_insert_id(undef, undef, $self->table, undef) # std | ||||
| 608 | || $dbh->{mysql_insertid} # mysql | ||||
| 609 | || eval { $dbh->func('last_insert_rowid') } | ||||
| 610 | or $self->_croak("Can't get last insert id"); | ||||
| 611 | return $id; | ||||
| 612 | } | ||||
| 613 | |||||
| 614 | sub _insert_row { | ||||
| 615 | my $self = shift; | ||||
| 616 | my $data = shift; | ||||
| 617 | eval { | ||||
| 618 | my @columns = keys %$data; | ||||
| 619 | my $sth = $self->sql_MakeNewObj( | ||||
| 620 | join(', ', @columns), | ||||
| 621 | join(', ', map $self->_column_placeholder($_), @columns), | ||||
| 622 | ); | ||||
| 623 | $self->_bind_param($sth, \@columns); | ||||
| 624 | $sth->execute(values %$data); | ||||
| 625 | my @primary_columns = $self->primary_columns; | ||||
| 626 | $data->{ $primary_columns[0] } = $self->_auto_increment_value | ||||
| 627 | if @primary_columns == 1 | ||||
| 628 | && !defined $data->{ $primary_columns[0] }; | ||||
| 629 | }; | ||||
| 630 | if ($@) { | ||||
| 631 | my $class = ref $self; | ||||
| 632 | return $self->_db_error( | ||||
| 633 | msg => "Can't insert new $class: $@", | ||||
| 634 | err => $@, | ||||
| 635 | method => 'insert' | ||||
| 636 | ); | ||||
| 637 | } | ||||
| 638 | return 1; | ||||
| 639 | } | ||||
| 640 | |||||
| 641 | sub _bind_param { | ||||
| 642 | my ($class, $sth, $keys) = @_; | ||||
| 643 | my $datatype = $class->__data_type or return; | ||||
| 644 | for my $i (0 .. $#$keys) { | ||||
| 645 | if (my $type = $datatype->{ $keys->[$i] }) { | ||||
| 646 | $sth->bind_param($i + 1, undef, $type); | ||||
| 647 | } | ||||
| 648 | } | ||||
| 649 | } | ||||
| 650 | |||||
| 651 | sub retrieve { | ||||
| 652 | my $class = shift; | ||||
| 653 | my @primary_columns = $class->primary_columns | ||||
| 654 | or return $class->_croak( | ||||
| 655 | "Can't retrieve unless primary columns are defined"); | ||||
| 656 | my %key_value; | ||||
| 657 | if (@_ == 1 && @primary_columns == 1) { | ||||
| 658 | my $id = shift; | ||||
| 659 | return unless defined $id; | ||||
| 660 | return $class->_croak("Can't retrieve a reference") if ref($id); | ||||
| 661 | $key_value{ $primary_columns[0] } = $id; | ||||
| 662 | } else { | ||||
| 663 | %key_value = @_; | ||||
| 664 | $class->_croak( | ||||
| 665 | "$class->retrieve(@_) parameters don't include values for all primary key columns (@primary_columns)" | ||||
| 666 | ) | ||||
| 667 | if keys %key_value < @primary_columns; | ||||
| 668 | } | ||||
| 669 | my @rows = $class->search(%key_value); | ||||
| 670 | $class->_carp("$class->retrieve(@_) selected " . @rows . " rows") | ||||
| 671 | if @rows > 1; | ||||
| 672 | return $rows[0]; | ||||
| 673 | } | ||||
| 674 | |||||
| 675 | # Get the data, as a hash, but setting certain values to whatever | ||||
| 676 | # we pass. Used by copy() and move(). | ||||
| 677 | # This can take either a primary key, or a hashref of all the columns | ||||
| 678 | # to change. | ||||
| 679 | sub _data_hash { | ||||
| 680 | my $self = shift; | ||||
| 681 | my %data = $self->_as_hash; | ||||
| 682 | my @primary_columns = $self->primary_columns; | ||||
| 683 | delete @data{@primary_columns}; | ||||
| 684 | if (@_) { | ||||
| 685 | my $arg = shift; | ||||
| 686 | unless (ref $arg) { | ||||
| 687 | $self->_croak("Need hash-ref to edit copied column values") | ||||
| 688 | unless @primary_columns == 1; | ||||
| 689 | $arg = { $primary_columns[0] => $arg }; | ||||
| 690 | } | ||||
| 691 | @data{ keys %$arg } = values %$arg; | ||||
| 692 | } | ||||
| 693 | return \%data; | ||||
| 694 | } | ||||
| 695 | |||||
| 696 | sub _as_hash { | ||||
| 697 | my $self = shift; | ||||
| 698 | my @columns = $self->all_columns; | ||||
| 699 | my %data; | ||||
| 700 | @data{@columns} = $self->get(@columns); | ||||
| 701 | return %data; | ||||
| 702 | } | ||||
| 703 | |||||
| 704 | sub copy { | ||||
| 705 | my $self = shift; | ||||
| 706 | return $self->insert($self->_data_hash(@_)); | ||||
| 707 | } | ||||
| 708 | |||||
| 709 | #---------------------------------------------------------------------- | ||||
| 710 | # CONSTRUCT | ||||
| 711 | #---------------------------------------------------------------------- | ||||
| 712 | |||||
| 713 | # spent 771ms (26.7+744) within Class::DBI::construct which was called 461 times, avg 1.67ms/call:
# 461 times (26.7ms+744ms) by Class::DBI::_ids_to_objects at line 1159, avg 1.67ms/call | ||||
| 714 | 461 | 2.64ms | my ($proto, $data) = @_; | ||
| 715 | 461 | 2.25ms | my $class = ref $proto || $proto; | ||
| 716 | 461 | 7.50ms | 461 | 283ms | my $self = $class->_init($data); # spent 283ms making 461 calls to Class::DBI::_init, avg 615µs/call |
| 717 | 461 | 7.75ms | 461 | 461ms | $self->call_trigger('select'); # spent 461ms making 461 calls to Class::Trigger::call_trigger, avg 1000µs/call |
| 718 | 461 | 6.20ms | return $self; | ||
| 719 | } | ||||
| 720 | |||||
| 721 | sub move { | ||||
| 722 | my ($class, $old_obj, @data) = @_; | ||||
| 723 | $class->_carp("move() is deprecated. If you really need it, " | ||||
| 724 | . "you should tell me quickly so I can abandon my plan to remove it."); | ||||
| 725 | return $old_obj->_croak("Can't move to an unrelated class") | ||||
| 726 | unless $class->isa(ref $old_obj) | ||||
| 727 | or $old_obj->isa($class); | ||||
| 728 | return $class->insert($old_obj->_data_hash(@data)); | ||||
| 729 | } | ||||
| 730 | |||||
| 731 | sub delete { | ||||
| 732 | my $self = shift; | ||||
| 733 | return $self->_search_delete(@_) if not ref $self; | ||||
| 734 | $self->remove_from_object_index; | ||||
| 735 | $self->call_trigger('before_delete'); | ||||
| 736 | |||||
| 737 | eval { $self->sql_DeleteMe->execute($self->id) }; | ||||
| 738 | if ($@) { | ||||
| 739 | return $self->_db_error( | ||||
| 740 | msg => "Can't delete $self: $@", | ||||
| 741 | err => $@, | ||||
| 742 | method => 'delete' | ||||
| 743 | ); | ||||
| 744 | } | ||||
| 745 | $self->call_trigger('after_delete'); | ||||
| 746 | undef %$self; | ||||
| 747 | bless $self, 'Class::DBI::Object::Has::Been::Deleted'; | ||||
| 748 | return 1; | ||||
| 749 | } | ||||
| 750 | |||||
| 751 | sub _search_delete { | ||||
| 752 | my ($class, @args) = @_; | ||||
| 753 | $class->_carp( | ||||
| 754 | "Delete as class method is deprecated. Use search and delete_all instead." | ||||
| 755 | ); | ||||
| 756 | my $it = $class->search_like(@args); | ||||
| 757 | while (my $obj = $it->next) { $obj->delete } | ||||
| 758 | return 1; | ||||
| 759 | } | ||||
| 760 | |||||
| 761 | # Return the placeholder to be used in UPDATE and INSERT queries. | ||||
| 762 | # Overriding this is deprecated in favour of | ||||
| 763 | # __PACKAGE__->find_column('entered')->placeholder('IF(1, CURDATE(), ?)); | ||||
| 764 | |||||
| 765 | sub _column_placeholder { | ||||
| 766 | my ($self, $column) = @_; | ||||
| 767 | return $self->find_column($column)->placeholder; | ||||
| 768 | } | ||||
| 769 | |||||
| 770 | sub update { | ||||
| 771 | my $self = shift; | ||||
| 772 | my $class = ref($self) | ||||
| 773 | or return $self->_croak("Can't call update as a class method"); | ||||
| 774 | |||||
| 775 | $self->call_trigger('before_update'); | ||||
| 776 | return -1 unless my @changed_cols = $self->is_changed; | ||||
| 777 | $self->call_trigger('deflate_for_update'); | ||||
| 778 | my @primary_columns = $self->primary_columns; | ||||
| 779 | my $sth = $self->sql_update($self->_update_line); | ||||
| 780 | $class->_bind_param($sth, \@changed_cols); | ||||
| 781 | my $rows = eval { $sth->execute($self->_update_vals, $self->id); }; | ||||
| 782 | if ($@) { | ||||
| 783 | return $self->_db_error( | ||||
| 784 | msg => "Can't update $self: $@", | ||||
| 785 | err => $@, | ||||
| 786 | method => 'update' | ||||
| 787 | ); | ||||
| 788 | } | ||||
| 789 | |||||
| 790 | # enable this once new fixed DBD::SQLite is released: | ||||
| 791 | if (0 and $rows != 1) { # should always only update one row | ||||
| 792 | $self->_croak("Can't update $self: row not found") if $rows == 0; | ||||
| 793 | $self->_croak("Can't update $self: updated more than one row"); | ||||
| 794 | } | ||||
| 795 | |||||
| 796 | $self->call_trigger('after_update', discard_columns => \@changed_cols); | ||||
| 797 | |||||
| 798 | # delete columns that changed (in case adding to DB modifies them again) | ||||
| 799 | $self->_attribute_delete(@changed_cols); | ||||
| 800 | delete $self->{__Changed}; | ||||
| 801 | return 1; | ||||
| 802 | } | ||||
| 803 | |||||
| 804 | sub _update_line { | ||||
| 805 | my $self = shift; | ||||
| 806 | join(', ', map "$_ = " . $self->_column_placeholder($_), $self->is_changed); | ||||
| 807 | } | ||||
| 808 | |||||
| 809 | sub _update_vals { | ||||
| 810 | my $self = shift; | ||||
| 811 | $self->_attrs($self->is_changed); | ||||
| 812 | } | ||||
| 813 | |||||
| 814 | sub DESTROY { | ||||
| 815 | 461 | 2.26ms | my ($self) = shift; | ||
| 816 | 461 | 8.16ms | 461 | 8.41ms | if (my @changed = $self->is_changed) { # spent 8.41ms making 461 calls to Class::DBI::is_changed, avg 18µs/call |
| 817 | my $class = ref $self; | ||||
| 818 | $self->_carp("$class $self destroyed without saving changes to " | ||||
| 819 | . join(', ', @changed)); | ||||
| 820 | } | ||||
| 821 | } | ||||
| 822 | |||||
| 823 | sub discard_changes { | ||||
| 824 | my $self = shift; | ||||
| 825 | return $self->_croak("Can't discard_changes while autoupdate is on") | ||||
| 826 | if $self->autoupdate; | ||||
| 827 | $self->_attribute_delete($self->is_changed); | ||||
| 828 | delete $self->{__Changed}; | ||||
| 829 | return 1; | ||||
| 830 | } | ||||
| 831 | |||||
| 832 | # We override the get() method from Class::Accessor to fetch the data for | ||||
| 833 | # the column (and associated) columns from the database, using the _flesh() | ||||
| 834 | # method. We also allow get to be called with a list of keys, instead of | ||||
| 835 | # just one. | ||||
| 836 | |||||
| 837 | # spent 213ms (39.6+174) within Class::DBI::get which was called 463 times, avg 460µs/call:
# 463 times (39.6ms+174ms) by Class::Accessor::__ANON__[/project/perl/lib/Class/Accessor.pm:395] at line 393 of Class/Accessor.pm, avg 460µs/call | ||||
| 838 | 463 | 2.15ms | my $self = shift; | ||
| 839 | 463 | 2.56ms | return $self->_croak("Can't fetch data as class method") unless ref $self; | ||
| 840 | |||||
| 841 | 463 | 8.86ms | 463 | 86.3ms | my @cols = $self->_find_columns(@_); # spent 86.3ms making 463 calls to Class::DBI::_find_columns, avg 186µs/call |
| 842 | 463 | 2.28ms | return $self->_croak("Can't get() nothing!") unless @cols; | ||
| 843 | |||||
| 844 | 463 | 10.2ms | 466 | 49.3ms | if (my @fetch_cols = grep !$self->_attribute_exists($_), @cols) { # spent 38.6ms making 463 calls to Class::DBI::_attribute_exists, avg 83µs/call
# spent 10.6ms making 1 call to Class::DBI::_flesh
# spent 114µs making 1 call to Class::DBI::ColumnGrouper::groups_for
# spent 25µs making 1 call to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23] |
| 845 | $self->_flesh($self->__grouper->groups_for(@fetch_cols)); | ||||
| 846 | } | ||||
| 847 | |||||
| 848 | 463 | 12.5ms | 463 | 38.3ms | return $self->_attrs(@cols); # spent 38.3ms making 463 calls to Class::DBI::_attrs, avg 83µs/call |
| 849 | } | ||||
| 850 | |||||
| 851 | # spent 10.6ms (539µs+10.1) within Class::DBI::_flesh which was called
# once (539µs+10.1ms) by Class::DBI::get at line 844 | ||||
| 852 | 1 | 7µs | my ($self, @groups) = @_; | ||
| 853 | 1 | 7µs | my @real = grep $_ ne "TEMP", @groups; | ||
| 854 | 1 | 102µs | 6 | 1.04ms | if (my @want = grep !$self->_attribute_exists($_), # spent 699µs making 1 call to Class::DBI::ColumnGrouper::columns_in
# spent 316µs making 4 calls to Class::DBI::_attribute_exists, avg 79µs/call
# spent 27µs making 1 call to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23] |
| 855 | $self->__grouper->columns_in(@real)) { | ||||
| 856 | 1 | 4µs | my %row; | ||
| 857 | 1 | 166µs | 3 | 4.52ms | @row{@want} = $self->sql_Flesh(join ", ", @want)->select_row($self->id); # spent 2.11ms making 1 call to Ima::DBI::__ANON__[Ima/DBI.pm:384]
# spent 1.96ms making 1 call to DBIx::ContextualFetch::st::select_row
# spent 458µs making 1 call to Class::Accessor::__ANON__[Class/Accessor.pm:395] |
| 858 | 1 | 35µs | 1 | 70µs | $self->_attribute_store(\%row); # spent 70µs making 1 call to Class::DBI::_attribute_store |
| 859 | 1 | 37µs | 1 | 4.21ms | $self->call_trigger('select'); # spent 4.21ms making 1 call to Class::Trigger::call_trigger |
| 860 | } | ||||
| 861 | 1 | 22µs | return 1; | ||
| 862 | } | ||||
| 863 | |||||
| 864 | # We also override set() from Class::Accessor so we can keep track of | ||||
| 865 | # changes, and either write to the database now (if autoupdate is on), | ||||
| 866 | # or when update() is called. | ||||
| 867 | sub set { | ||||
| 868 | my $self = shift; | ||||
| 869 | my $column_values = {@_}; | ||||
| 870 | |||||
| 871 | $self->normalize_column_values($column_values); | ||||
| 872 | $self->validate_column_values($column_values); | ||||
| 873 | |||||
| 874 | while (my ($column, $value) = each %$column_values) { | ||||
| 875 | my $col = $self->find_column($column) or die "No such column: $column\n"; | ||||
| 876 | $self->_attribute_set($col => $value); | ||||
| 877 | |||||
| 878 | # $self->SUPER::set($column, $value); | ||||
| 879 | |||||
| 880 | eval { $self->call_trigger("after_set_$column") }; # eg inflate | ||||
| 881 | if ($@) { | ||||
| 882 | $self->_attribute_delete($column); | ||||
| 883 | return $self->_croak("after_set_$column trigger error: $@", err => $@); | ||||
| 884 | } | ||||
| 885 | } | ||||
| 886 | |||||
| 887 | $self->update if $self->autoupdate; | ||||
| 888 | return 1; | ||||
| 889 | } | ||||
| 890 | |||||
| 891 | # spent 8.41ms within Class::DBI::is_changed which was called 461 times, avg 18µs/call:
# 461 times (8.41ms+0s) by Class::DBI::DESTROY at line 816, avg 18µs/call | ||||
| 892 | 461 | 2.14ms | my $self = shift; | ||
| 893 | 461 | 7.05ms | grep $self->has_real_column($_), keys %{ $self->{__Changed} }; | ||
| 894 | } | ||||
| 895 | |||||
| 896 | sub any_changed { keys %{ shift->{__Changed} } } | ||||
| 897 | |||||
| 898 | # By default do nothing. Subclasses should override if required. | ||||
| 899 | # | ||||
| 900 | # Given a hash ref of column names and proposed new values, | ||||
| 901 | # edit the values in the hash if required. | ||||
| 902 | # For insert $self is the class name (not an object ref). | ||||
| 903 | sub normalize_column_values { | ||||
| 904 | my ($self, $column_values) = @_; | ||||
| 905 | } | ||||
| 906 | |||||
| 907 | # Given a hash ref of column names and proposed new values | ||||
| 908 | # validate that the whole set of new values in the hash | ||||
| 909 | # is valid for the object in relation to its current values | ||||
| 910 | # For insert $self is the class name (not an object ref). | ||||
| 911 | sub validate_column_values { | ||||
| 912 | my ($self, $column_values) = @_; | ||||
| 913 | my @errors; | ||||
| 914 | foreach my $column (keys %$column_values) { | ||||
| 915 | eval { | ||||
| 916 | $self->call_trigger("before_set_$column", $column_values->{$column}, | ||||
| 917 | $column_values); | ||||
| 918 | }; | ||||
| 919 | push @errors, $column => $@ if $@; | ||||
| 920 | } | ||||
| 921 | return unless @errors; | ||||
| 922 | $self->_croak( | ||||
| 923 | "validate_column_values error: " . join(" ", @errors), | ||||
| 924 | method => 'validate_column_values', | ||||
| 925 | data => {@errors} | ||||
| 926 | ); | ||||
| 927 | } | ||||
| 928 | |||||
| 929 | # We override set_sql() from Ima::DBI so it has a default database connection. | ||||
| 930 | # spent 5.54ms (1.21+4.33) within Class::DBI::set_sql which was called 13 times, avg 426µs/call:
# once (110µs+483µs) by Class::DBI::Plugin::RetrieveAll::import at line 69 of Class/DBI/Plugin/RetrieveAll.pm
# once (117µs+472µs) by main::BEGIN at line 29 of Wiki/DB/Wiki.pm
# once (97µs+434µs) by base::import at line 103
# once (91µs+360µs) by base::import at line 112
# once (113µs+316µs) by main::BEGIN at line 35 of Wiki/DB/Wiki.pm
# once (100µs+327µs) by Class::DBI::Plugin::AbstractCount::init at line 13 of Class/DBI/Plugin/AbstractCount.pm
# once (89µs+304µs) by base::import at line 115
# once (99µs+285µs) by base::import at line 134
# once (83µs+295µs) by base::import at line 124
# once (87µs+289µs) by base::import at line 129
# once (86µs+284µs) by base::import at line 120
# once (69µs+249µs) by base::import at line 107
# once (71µs+230µs) by base::import at line 138 | ||||
| 931 | 13 | 106µs | my ($class, $name, $sql, $db, @others) = @_; | ||
| 932 | 13 | 61µs | $db ||= 'Main'; | ||
| 933 | 13 | 471µs | 13 | 3.67ms | $class->SUPER::set_sql($name, $sql, $db, @others); # spent 3.67ms making 13 calls to Ima::DBI::set_sql, avg 283µs/call |
| 934 | 13 | 468µs | 23 | 653µs | $class->_generate_search_sql($name) if $sql =~ /select/i; # spent 538µs making 10 calls to Class::DBI::_generate_search_sql, avg 54µs/call
# spent 115µs making 13 calls to Class::DBI::CORE:match, avg 9µs/call |
| 935 | 13 | 216µs | return 1; | ||
| 936 | } | ||||
| 937 | |||||
| 938 | # spent 538µs within Class::DBI::_generate_search_sql which was called 10 times, avg 54µs/call:
# 10 times (538µs+0s) by Class::DBI::set_sql at line 934, avg 54µs/call | ||||
| 939 | 10 | 75µs | my ($class, $name) = @_; | ||
| 940 | 10 | 53µs | my $method = "search_$name"; | ||
| 941 | 10 | 80µs | defined &{"$class\::$method"} | ||
| 942 | and return $class->_carp("$method() already exists"); | ||||
| 943 | 10 | 50µs | my $sql_method = "sql_$name"; | ||
| 944 | 3 | 1.38ms | 1 | 105µs | no strict 'refs'; # spent 105µs making 1 call to strict::unimport |
| 945 | *{"$class\::$method"} = sub { | ||||
| 946 | my ($class, @args) = @_; | ||||
| 947 | return $class->sth_to_objects($name, \@args); | ||||
| 948 | 10 | 310µs | }; | ||
| 949 | } | ||||
| 950 | |||||
| 951 | sub dbi_commit { my $proto = shift; $proto->SUPER::commit(@_); } | ||||
| 952 | sub dbi_rollback { my $proto = shift; $proto->SUPER::rollback(@_); } | ||||
| 953 | |||||
| 954 | #---------------------------------------------------------------------- | ||||
| 955 | # Constraints / Triggers | ||||
| 956 | #---------------------------------------------------------------------- | ||||
| 957 | |||||
| 958 | sub constrain_column { | ||||
| 959 | my $class = shift; | ||||
| 960 | my $col = $class->find_column(+shift) | ||||
| 961 | or return $class->_croak("constraint_column needs a valid column"); | ||||
| 962 | my $how = shift | ||||
| 963 | or return $class->_croak("constrain_column needs a constraint"); | ||||
| 964 | if (ref $how eq "ARRAY") { | ||||
| 965 | my %hash = map { $_ => 1 } @$how; | ||||
| 966 | $class->add_constraint(list => $col => sub { exists $hash{ +shift } }); | ||||
| 967 | } elsif (ref $how eq "Regexp") { | ||||
| 968 | $class->add_constraint(regexp => $col => sub { shift =~ $how }); | ||||
| 969 | } elsif (ref $how eq "CODE") { | ||||
| 970 | $class->add_constraint( | ||||
| 971 | code => $col => sub { local $_ = $_[0]; $how->($_) }); | ||||
| 972 | } else { | ||||
| 973 | my $try_method = sprintf '_constrain_by_%s', $how->moniker; | ||||
| 974 | if (my $dispatch = $class->can($try_method)) { | ||||
| 975 | $class->$dispatch($col => ($how, @_)); | ||||
| 976 | } else { | ||||
| 977 | $class->_croak("Don't know how to constrain $col with $how"); | ||||
| 978 | } | ||||
| 979 | } | ||||
| 980 | } | ||||
| 981 | |||||
| 982 | sub add_constraint { | ||||
| 983 | my $class = shift; | ||||
| 984 | $class->_invalid_object_method('add_constraint()') if ref $class; | ||||
| 985 | my $name = shift or return $class->_croak("Constraint needs a name"); | ||||
| 986 | my $column = $class->find_column(+shift) | ||||
| 987 | or return $class->_croak("Constraint $name needs a valid column"); | ||||
| 988 | my $code = shift | ||||
| 989 | or return $class->_croak("Constraint $name needs a code reference"); | ||||
| 990 | return $class->_croak("Constraint $name '$code' is not a code reference") | ||||
| 991 | unless ref($code) eq "CODE"; | ||||
| 992 | |||||
| 993 | $column->is_constrained(1); | ||||
| 994 | $class->add_trigger( | ||||
| 995 | "before_set_$column" => sub { | ||||
| 996 | my ($self, $value, $column_values) = @_; | ||||
| 997 | $code->($value, $self, $column, $column_values) | ||||
| 998 | or return $self->_croak( | ||||
| 999 | "$class $column fails '$name' constraint with '$value'", | ||||
| 1000 | method => "before_set_$column", | ||||
| 1001 | exception_type => 'constraint_failure', | ||||
| 1002 | data => { | ||||
| 1003 | column => $column, | ||||
| 1004 | value => $value, | ||||
| 1005 | constraint_name => $name, | ||||
| 1006 | } | ||||
| 1007 | ); | ||||
| 1008 | } | ||||
| 1009 | ); | ||||
| 1010 | } | ||||
| 1011 | |||||
| 1012 | # spent 2.46ms (759µs+1.70) within Class::DBI::add_trigger which was called 15 times, avg 164µs/call:
# 14 times (689µs+1.59ms) by Class::DBI::Relationship::_add_triggers at line 53 of Class/DBI/Relationship.pm, avg 163µs/call
# once (70µs+112µs) by main::BEGIN at line 11 of Wiki/DB/Wiki.pm | ||||
| 1013 | 15 | 110µs | my ($self, $name, @args) = @_; | ||
| 1014 | 15 | 74µs | return $self->_croak("on_setting trigger no longer exists") | ||
| 1015 | if $name eq "on_setting"; | ||||
| 1016 | 15 | 69µs | $self->_carp( | ||
| 1017 | "$name trigger deprecated: use before_$name or after_$name instead") | ||||
| 1018 | if ($name eq "create" or $name eq "delete"); | ||||
| 1019 | 15 | 492µs | 15 | 1.70ms | $self->SUPER::add_trigger($name => @args); # spent 1.70ms making 15 calls to Class::Trigger::add_trigger, avg 113µs/call |
| 1020 | } | ||||
| 1021 | |||||
| 1022 | #---------------------------------------------------------------------- | ||||
| 1023 | # Inflation | ||||
| 1024 | #---------------------------------------------------------------------- | ||||
| 1025 | |||||
| 1026 | # spent 11.6ms (239µs+11.4) within Class::DBI::add_relationship_type which was called
# once (239µs+11.4ms) by base::import at line 93 | ||||
| 1027 | 1 | 12µs | my ($self, %rels) = @_; | ||
| 1028 | 1 | 31µs | while (my ($name, $class) = each %rels) { | ||
| 1029 | 3 | 63µs | 3 | 11.4ms | $self->_require_class($class); # spent 11.4ms making 3 calls to Class::DBI::_require_class, avg 3.80ms/call |
| 1030 | 3 | 1.06ms | 1 | 101µs | no strict 'refs'; # spent 101µs making 1 call to strict::unimport |
| 1031 | # spent 170ms (241µs+170) within Class::DBI::__ANON__[/project/perl/lib/Class/DBI.pm:1034] which was called 5 times, avg 34.0ms/call:
# once (63µs+114ms) by K2::DB2::has_a_datetime at line 50 of K2/DB2.pm
# once (45µs+47.5ms) by main::BEGIN at line 8 of Wiki/DB/Wiki.pm
# once (58µs+3.12ms) by Class::DBI::_require_class at line 8 of Wiki/DB/WikiCategories.pm
# once (35µs+2.93ms) by Class::DBI::_require_class at line 9 of Wiki/DB/WikiCategories.pm
# once (40µs+2.35ms) by main::BEGIN at line 9 of Wiki/DB/Wiki.pm | ||||
| 1032 | 5 | 31µs | my $proto = shift; | ||
| 1033 | 5 | 188µs | 5 | 164ms | $class->set_up($name => $proto => @_); # spent 170ms making 5 calls to Class::DBI::Relationship::set_up, avg 34.0ms/call, recursion: max depth 1, time 6.05ms |
| 1034 | 3 | 109µs | }; | ||
| 1035 | } | ||||
| 1036 | } | ||||
| 1037 | |||||
| 1038 | # spent 2.03ms (530µs+1.50) within Class::DBI::_extend_meta which was called 5 times, avg 407µs/call:
# 5 times (530µs+1.50ms) by Class::DBI::Relationship::_set_up_class_data at line 42 of Class/DBI/Relationship.pm, avg 407µs/call | ||||
| 1039 | 5 | 34µs | my ($class, $type, $subtype, $val) = @_; | ||
| 1040 | 5 | 1.02ms | 10 | 965µs | my %hash = %{ Clone::clone($class->__meta_info || {}) }; # spent 833µs making 5 calls to Clone::clone, avg 167µs/call
# spent 132µs making 5 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 26µs/call |
| 1041 | 5 | 69µs | $hash{$type}->{$subtype} = $val; | ||
| 1042 | 5 | 137µs | 5 | 410µs | $class->__meta_info(\%hash); # spent 410µs making 5 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 82µs/call |
| 1043 | } | ||||
| 1044 | |||||
| 1045 | # spent 213µs (110+103) within Class::DBI::meta_info which was called
# once (110µs+103µs) by Class::DBI::Relationship::HasA::__ANON__[/project/perl/lib/Class/DBI/Relationship/HasA.pm:77] at line 37 of Class/DBI/Relationship/HasA.pm | ||||
| 1046 | 1 | 6µs | my ($class, $type, $subtype) = @_; | ||
| 1047 | 1 | 19µs | 1 | 28µs | my $meta = $class->__meta_info; # spent 28µs making 1 call to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23] |
| 1048 | 1 | 5µs | return $meta unless $type; | ||
| 1049 | 1 | 11µs | return $meta->{$type} unless $subtype; | ||
| 1050 | 1 | 24µs | return $meta->{$type}->{$subtype}; | ||
| 1051 | } | ||||
| 1052 | |||||
| 1053 | sub _simple_bless { | ||||
| 1054 | my ($class, $pri) = @_; | ||||
| 1055 | return $class->_init({ $class->primary_column => $pri }); | ||||
| 1056 | } | ||||
| 1057 | |||||
| 1058 | sub _deflated_column { | ||||
| 1059 | my ($self, $col, $val) = @_; | ||||
| 1060 | $val ||= $self->_attrs($col) if ref $self; | ||||
| 1061 | return $val unless ref $val; | ||||
| 1062 | my $meta = $self->meta_info(has_a => $col) or return $val; | ||||
| 1063 | my ($a_class, %meths) = ($meta->foreign_class, %{ $meta->args }); | ||||
| 1064 | if (my $deflate = $meths{'deflate'}) { | ||||
| 1065 | $val = $val->$deflate(ref $deflate eq 'CODE' ? $self : ()); | ||||
| 1066 | return $val unless ref $val; | ||||
| 1067 | } | ||||
| 1068 | return $self->_croak("Can't deflate $col: $val is not a $a_class") | ||||
| 1069 | unless UNIVERSAL::isa($val, $a_class); | ||||
| 1070 | return $val->id if UNIVERSAL::isa($val => 'Class::DBI'); | ||||
| 1071 | return "$val"; | ||||
| 1072 | } | ||||
| 1073 | |||||
| 1074 | #---------------------------------------------------------------------- | ||||
| 1075 | # SEARCH | ||||
| 1076 | #---------------------------------------------------------------------- | ||||
| 1077 | |||||
| 1078 | sub retrieve_all { shift->sth_to_objects('RetrieveAll') } | ||||
| 1079 | |||||
| 1080 | sub retrieve_from_sql { | ||||
| 1081 | my ($class, $sql, @vals) = @_; | ||||
| 1082 | $sql =~ s/^\s*(WHERE)\s*//i; | ||||
| 1083 | return $class->sth_to_objects($class->sql_Retrieve($sql), \@vals); | ||||
| 1084 | } | ||||
| 1085 | |||||
| 1086 | # spent 3.53ms (123µs+3.41) within Class::DBI::add_searcher which was called
# once (123µs+3.41ms) by base::import at line 91 | ||||
| 1087 | 1 | 9µs | my ($self, %rels) = @_; | ||
| 1088 | 1 | 30µs | while (my ($name, $class) = each %rels) { | ||
| 1089 | 1 | 17µs | 1 | 3.39ms | $self->_require_class($class); # spent 3.39ms making 1 call to Class::DBI::_require_class |
| 1090 | 1 | 50µs | 1 | 11µs | $self->_croak("$class is not a valid Searcher") # spent 11µs making 1 call to UNIVERSAL::can |
| 1091 | unless $class->can('run_search'); | ||||
| 1092 | 3 | 428µs | 1 | 96µs | no strict 'refs'; # spent 96µs making 1 call to strict::unimport |
| 1093 | *{"$self\::$name"} = sub { | ||||
| 1094 | $class->new(@_)->run_search; | ||||
| 1095 | 1 | 26µs | }; | ||
| 1096 | } | ||||
| 1097 | } | ||||
| 1098 | |||||
| 1099 | # This should really be its own Search subclass. But the _do_search | ||||
| 1100 | # version has been publicised as the way to do this. We need to | ||||
| 1101 | # deprecate this eventually. | ||||
| 1102 | |||||
| 1103 | sub search_like { shift->_do_search(LIKE => @_) } | ||||
| 1104 | |||||
| 1105 | sub _do_search { | ||||
| 1106 | my ($class, $type, @args) = @_; | ||||
| 1107 | $class->_require_class('Class::DBI::Search::Basic'); | ||||
| 1108 | my $search = Class::DBI::Search::Basic->new($class, @args); | ||||
| 1109 | $search->type($type); | ||||
| 1110 | $search->run_search; | ||||
| 1111 | } | ||||
| 1112 | |||||
| 1113 | #---------------------------------------------------------------------- | ||||
| 1114 | # CONSTRUCTORS | ||||
| 1115 | #---------------------------------------------------------------------- | ||||
| 1116 | |||||
| 1117 | sub add_constructor { | ||||
| 1118 | my ($class, $method, $fragment) = @_; | ||||
| 1119 | return $class->_croak("constructors needs a name") unless $method; | ||||
| 1120 | 3 | 1.65ms | 1 | 91µs | no strict 'refs'; # spent 91µs making 1 call to strict::unimport |
| 1121 | my $meth = "$class\::$method"; | ||||
| 1122 | return $class->_carp("$method already exists in $class") | ||||
| 1123 | if *$meth{CODE}; | ||||
| 1124 | *$meth = sub { | ||||
| 1125 | my $self = shift; | ||||
| 1126 | $self->sth_to_objects($self->sql_Retrieve($fragment), \@_); | ||||
| 1127 | }; | ||||
| 1128 | } | ||||
| 1129 | |||||
| 1130 | # spent 863ms (10.2+853) within Class::DBI::sth_to_objects which was called
# once (10.2ms+853ms) by Class::DBI::Plugin::RetrieveAll::__ANON__[/project/perl/lib/Class/DBI/Plugin/RetrieveAll.pm:77] at line 76 of Class/DBI/Plugin/RetrieveAll.pm | ||||
| 1131 | 1 | 9µs | my ($class, $sth, $args) = @_; | ||
| 1132 | 1 | 4µs | $class->_croak("sth_to_objects needs a statement handle") unless $sth; | ||
| 1133 | 1 | 37µs | 1 | 19µs | unless (UNIVERSAL::isa($sth => "DBI::st")) { # spent 19µs making 1 call to UNIVERSAL::isa |
| 1134 | my $meth = "sql_$sth"; | ||||
| 1135 | $sth = $class->$meth(); | ||||
| 1136 | } | ||||
| 1137 | 1 | 5µs | my (%data, @rows); | ||
| 1138 | 1 | 10µs | eval { | ||
| 1139 | 1 | 83µs | 2 | 56.3ms | $sth->execute(@$args) unless $sth->{Active}; # spent 56.3ms making 1 call to DBIx::ContextualFetch::st::execute
# spent 14µs making 1 call to DBI::common::FETCH |
| 1140 | 1 | 183µs | 3 | 286µs | $sth->bind_columns(\(@data{ @{ $sth->{NAME_lc} } })); # spent 155µs making 1 call to DBI::st::bind_columns
# spent 131µs making 2 calls to DBI::common::FETCH, avg 66µs/call |
| 1141 | 1 | 9.73ms | 462 | 17.9ms | push @rows, {%data} while $sth->fetch; # spent 17.9ms making 462 calls to DBIx::ContextualFetch::st::fetch, avg 39µs/call |
| 1142 | }; | ||||
| 1143 | 1 | 5µs | return $class->_croak("$class can't $sth->{Statement}: $@", err => $@) | ||
| 1144 | if $@; | ||||
| 1145 | 1 | 62µs | 1 | 778ms | return $class->_ids_to_objects(\@rows); # spent 778ms making 1 call to Class::DBI::_ids_to_objects |
| 1146 | } | ||||
| 1147 | 1 | 6µs | *_sth_to_objects = \&sth_to_objects; | ||
| 1148 | |||||
| 1149 | sub _my_iterator { | ||||
| 1150 | my $self = shift; | ||||
| 1151 | my $class = $self->iterator_class; | ||||
| 1152 | $self->_require_class($class); | ||||
| 1153 | return $class; | ||||
| 1154 | } | ||||
| 1155 | |||||
| 1156 | # spent 778ms (7.21+771) within Class::DBI::_ids_to_objects which was called
# once (7.21ms+771ms) by Class::DBI::sth_to_objects at line 1145 | ||||
| 1157 | 1 | 6µs | my ($class, $data) = @_; | ||
| 1158 | 1 | 5µs | return $#$data + 1 unless defined wantarray; | ||
| 1159 | 1 | 6.66ms | 461 | 771ms | return map $class->construct($_), @$data if wantarray; # spent 771ms making 461 calls to Class::DBI::construct, avg 1.67ms/call |
| 1160 | return $class->_my_iterator->new($class => $data); | ||||
| 1161 | } | ||||
| 1162 | |||||
| 1163 | #---------------------------------------------------------------------- | ||||
| 1164 | # SINGLE VALUE SELECTS | ||||
| 1165 | #---------------------------------------------------------------------- | ||||
| 1166 | |||||
| 1167 | sub _single_row_select { | ||||
| 1168 | my ($self, $sth, @args) = @_; | ||||
| 1169 | Carp::confess("_single_row_select is deprecated in favour of select_row"); | ||||
| 1170 | return $sth->select_row(@args); | ||||
| 1171 | } | ||||
| 1172 | |||||
| 1173 | sub _single_value_select { | ||||
| 1174 | my ($self, $sth, @args) = @_; | ||||
| 1175 | $self->_carp("_single_value_select is deprecated in favour of select_val"); | ||||
| 1176 | return $sth->select_val(@args); | ||||
| 1177 | } | ||||
| 1178 | |||||
| 1179 | sub count_all { shift->sql_single("COUNT(*)")->select_val } | ||||
| 1180 | |||||
| 1181 | sub maximum_value_of { | ||||
| 1182 | my ($class, $col) = @_; | ||||
| 1183 | $class->sql_single("MAX($col)")->select_val; | ||||
| 1184 | } | ||||
| 1185 | |||||
| 1186 | sub minimum_value_of { | ||||
| 1187 | my ($class, $col) = @_; | ||||
| 1188 | $class->sql_single("MIN($col)")->select_val; | ||||
| 1189 | } | ||||
| 1190 | |||||
| 1191 | sub _unique_entries { | ||||
| 1192 | my ($class, %tmp) = shift; | ||||
| 1193 | return grep !$tmp{$_}++, @_; | ||||
| 1194 | } | ||||
| 1195 | |||||
| 1196 | sub _invalid_object_method { | ||||
| 1197 | my ($self, $method) = @_; | ||||
| 1198 | $self->_carp( | ||||
| 1199 | "$method should be called as a class method not an object method"); | ||||
| 1200 | } | ||||
| 1201 | |||||
| 1202 | #---------------------------------------------------------------------- | ||||
| 1203 | # misc stuff | ||||
| 1204 | #---------------------------------------------------------------------- | ||||
| 1205 | |||||
| 1206 | # spent 1.22ms (449µs+774µs) within Class::DBI::_extend_class_data which was called 5 times, avg 245µs/call:
# 3 times (306µs+540µs) by Class::DBI::Relationship::HasA::_set_up_class_data at line 94 of Class/DBI/Relationship/HasA.pm, avg 282µs/call
# 2 times (143µs+234µs) by Class::DBI::Relationship::HasMany::_set_up_class_data at line 57 of Class/DBI/Relationship/HasMany.pm, avg 189µs/call | ||||
| 1207 | 5 | 39µs | my ($class, $struct, $key, $value) = @_; | ||
| 1208 | 5 | 136µs | 5 | 132µs | my %hash = %{ $class->$struct() || {} }; # spent 132µs making 5 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 26µs/call |
| 1209 | 5 | 57µs | $hash{$key} = $value; | ||
| 1210 | 5 | 135µs | 5 | 524µs | $class->$struct(\%hash); # spent 524µs making 5 calls to Class::Data::Inheritable::__ANON__[Class/Data/Inheritable.pm:23], avg 105µs/call |
| 1211 | } | ||||
| 1212 | |||||
| 1213 | 1 | 5µs | my %required_classes; # { required_class => class_that_last_required_it, ... } | ||
| 1214 | |||||
| 1215 | # spent 173ms (101+72.0) within Class::DBI::_require_class which was called 13 times, avg 13.3ms/call:
# 3 times (71.1ms+39.4ms) by Class::DBI::Relationship::HasA::triggers at line 19 of Class/DBI/Relationship/HasA.pm, avg 36.9ms/call
# 3 times (6.72ms+4.66ms) by Class::DBI::add_relationship_type at line 1029, avg 3.80ms/call
# 2 times (12.8ms+24.8ms) by Class::DBI::Relationship::HasMany::remap_arguments at line 26 of Class/DBI/Relationship/HasMany.pm, avg 18.8ms/call
# 2 times (5.81ms+1.52ms) by Class::DBI::Relationship::HasMany::triggers at line 71 of Class/DBI/Relationship/HasMany.pm, avg 3.66ms/call
# 2 times (2.28ms+173µs) by Class::DBI::transform_sql at line 152, avg 1.23ms/call
# once (2.05ms+1.35ms) by Class::DBI::add_searcher at line 1089 | ||||
| 1216 | 13 | 84µs | my ($self, $load_class) = @_; | ||
| 1217 | 13 | 101µs | $required_classes{$load_class} ||= my $for_class = ref($self) || $self; | ||
| 1218 | |||||
| 1219 | # return quickly if class already exists | ||||
| 1220 | 3 | 511µs | 1 | 105µs | no strict 'refs'; # spent 105µs making 1 call to strict::unimport |
| 1221 | 13 | 214µs | return if exists ${"$load_class\::"}{ISA}; | ||
| 1222 | 9 | 288µs | 9 | 136µs | (my $load_module = $load_class) =~ s!::!/!g; # spent 136µs making 9 calls to Class::DBI::CORE:subst, avg 15µs/call |
| 1223 | 18 | 46.6ms | return if eval { require "$load_module.pm" }; | ||
| 1224 | |||||
| 1225 | # Only ignore "Can't locate" errors for the specific module we're loading | ||||
| 1226 | return if $@ =~ /^Can't locate \Q$load_module\E\.pm /; | ||||
| 1227 | |||||
| 1228 | # Other fatal errors (syntax etc) must be reported (as per base.pm). | ||||
| 1229 | chomp $@; | ||||
| 1230 | |||||
| 1231 | # This error message prefix is especially handy when dealing with | ||||
| 1232 | # classes that are being loaded by other classes recursively. | ||||
| 1233 | # The final message shows the path, e.g.: | ||||
| 1234 | # Foo can't load Bar: Bar can't load Baz: syntax error at line ... | ||||
| 1235 | $self->_croak("$for_class can't load $load_class: $@"); | ||||
| 1236 | } | ||||
| 1237 | |||||
| 1238 | sub _check_classes { # may automatically call from CHECK block in future | ||||
| 1239 | while (my ($load_class, $by_class) = each %required_classes) { | ||||
| 1240 | next if $load_class->isa("Class::DBI"); | ||||
| 1241 | $by_class->_croak( | ||||
| 1242 | "Class $load_class used by $by_class has not been loaded"); | ||||
| 1243 | } | ||||
| 1244 | } | ||||
| 1245 | |||||
| 1246 | 1 | 62µs | 1; | ||
| 1247 | |||||
| 1248 | __END__ | ||||
| 1249 | |||||
| 1250 | =head1 NAME | ||||
| 1251 | |||||
| 1252 | Class::DBI - Simple Database Abstraction | ||||
| 1253 | |||||
| 1254 | =head1 SYNOPSIS | ||||
| 1255 | |||||
| 1256 | package Music::DBI; | ||||
| 1257 | use base 'Class::DBI'; | ||||
| 1258 | Music::DBI->connection('dbi:mysql:dbname', 'username', 'password'); | ||||
| 1259 | |||||
| 1260 | package Music::Artist; | ||||
| 1261 | use base 'Music::DBI'; | ||||
| 1262 | Music::Artist->table('artist'); | ||||
| 1263 | Music::Artist->columns(All => qw/artistid name/); | ||||
| 1264 | Music::Artist->has_many(cds => 'Music::CD'); | ||||
| 1265 | |||||
| 1266 | package Music::CD; | ||||
| 1267 | use base 'Music::DBI'; | ||||
| 1268 | Music::CD->table('cd'); | ||||
| 1269 | Music::CD->columns(All => qw/cdid artist title year reldate/); | ||||
| 1270 | Music::CD->has_many(tracks => 'Music::Track'); | ||||
| 1271 | Music::CD->has_a(artist => 'Music::Artist'); | ||||
| 1272 | Music::CD->has_a(reldate => 'Time::Piece', | ||||
| 1273 | inflate => sub { Time::Piece->strptime(shift, "%Y-%m-%d") }, | ||||
| 1274 | deflate => 'ymd', | ||||
| 1275 | ); | ||||
| 1276 | |||||
| 1277 | Music::CD->might_have(liner_notes => LinerNotes => qw/notes/); | ||||
| 1278 | |||||
| 1279 | package Music::Track; | ||||
| 1280 | use base 'Music::DBI'; | ||||
| 1281 | Music::Track->table('track'); | ||||
| 1282 | Music::Track->columns(All => qw/trackid cd position title/); | ||||
| 1283 | |||||
| 1284 | #-- Meanwhile, in a nearby piece of code! --# | ||||
| 1285 | |||||
| 1286 | my $artist = Music::Artist->insert({ artistid => 1, name => 'U2' }); | ||||
| 1287 | |||||
| 1288 | my $cd = $artist->add_to_cds({ | ||||
| 1289 | cdid => 1, | ||||
| 1290 | title => 'October', | ||||
| 1291 | year => 1980, | ||||
| 1292 | }); | ||||
| 1293 | |||||
| 1294 | # Oops, got it wrong. | ||||
| 1295 | $cd->year(1981); | ||||
| 1296 | $cd->update; | ||||
| 1297 | |||||
| 1298 | # etc. | ||||
| 1299 | |||||
| 1300 | foreach my $track ($cd->tracks) { | ||||
| 1301 | print $track->position, $track->title | ||||
| 1302 | } | ||||
| 1303 | |||||
| 1304 | $cd->delete; # also deletes the tracks | ||||
| 1305 | |||||
| 1306 | my $cd = Music::CD->retrieve(1); | ||||
| 1307 | my @cds = Music::CD->retrieve_all; | ||||
| 1308 | my @cds = Music::CD->search(year => 1980); | ||||
| 1309 | my @cds = Music::CD->search_like(title => 'October%'); | ||||
| 1310 | |||||
| 1311 | =head1 INTRODUCTION | ||||
| 1312 | |||||
| 1313 | Class::DBI provides a convenient abstraction layer to a database. | ||||
| 1314 | |||||
| 1315 | It not only provides a simple database to object mapping layer, but can | ||||
| 1316 | be used to implement several higher order database functions (triggers, | ||||
| 1317 | referential integrity, cascading delete etc.), at the application level, | ||||
| 1318 | rather than at the database. | ||||
| 1319 | |||||
| 1320 | This is particularly useful when using a database which doesn't support | ||||
| 1321 | these (such as MySQL), or when you would like your code to be portable | ||||
| 1322 | across multiple databases which might implement these things in different | ||||
| 1323 | ways. | ||||
| 1324 | |||||
| 1325 | In short, Class::DBI aims to make it simple to introduce 'best | ||||
| 1326 | practice' when dealing with data stored in a relational database. | ||||
| 1327 | |||||
| 1328 | =head2 How to set it up | ||||
| 1329 | |||||
| 1330 | =over 4 | ||||
| 1331 | |||||
| 1332 | =item I<Set up a database.> | ||||
| 1333 | |||||
| 1334 | You must have an existing database set up, have DBI.pm installed and | ||||
| 1335 | the necessary DBD:: driver module for that database. See L<DBI> and | ||||
| 1336 | the documentation of your particular database and driver for details. | ||||
| 1337 | |||||
| 1338 | =item I<Set up a table for your objects to be stored in.> | ||||
| 1339 | |||||
| 1340 | Class::DBI works on a simple one class/one table model. It is your | ||||
| 1341 | responsibility to have your database tables already set up. Automating that | ||||
| 1342 | process is outside the scope of Class::DBI. | ||||
| 1343 | |||||
| 1344 | Using our CD example, you might declare a table something like this: | ||||
| 1345 | |||||
| 1346 | CREATE TABLE cd ( | ||||
| 1347 | cdid INTEGER PRIMARY KEY, | ||||
| 1348 | artist INTEGER, # references 'artist' | ||||
| 1349 | title VARCHAR(255), | ||||
| 1350 | year CHAR(4), | ||||
| 1351 | ); | ||||
| 1352 | |||||
| 1353 | =item I<Set up an application base class> | ||||
| 1354 | |||||
| 1355 | It's usually wise to set up a "top level" class for your entire | ||||
| 1356 | application to inherit from, rather than have each class inherit | ||||
| 1357 | directly from Class::DBI. This gives you a convenient point to | ||||
| 1358 | place system-wide overrides and enhancements to Class::DBI's behavior. | ||||
| 1359 | |||||
| 1360 | package Music::DBI; | ||||
| 1361 | use base 'Class::DBI'; | ||||
| 1362 | |||||
| 1363 | =item I<Give it a database connection> | ||||
| 1364 | |||||
| 1365 | Class::DBI needs to know how to access the database. It does this | ||||
| 1366 | through a DBI connection which you set up by calling the connection() | ||||
| 1367 | method. | ||||
| 1368 | |||||
| 1369 | Music::DBI->connection('dbi:mysql:dbname', 'user', 'password'); | ||||
| 1370 | |||||
| 1371 | By setting the connection up in your application base class all the | ||||
| 1372 | table classes that inherit from it will share the same connection. | ||||
| 1373 | |||||
| 1374 | =item I<Set up each Class> | ||||
| 1375 | |||||
| 1376 | package Music::CD; | ||||
| 1377 | use base 'Music::DBI'; | ||||
| 1378 | |||||
| 1379 | Each class will inherit from your application base class, so you don't | ||||
| 1380 | need to repeat the information on how to connect to the database. | ||||
| 1381 | |||||
| 1382 | =item I<Declare the name of your table> | ||||
| 1383 | |||||
| 1384 | Inform Class::DBI what table you are using for this class: | ||||
| 1385 | |||||
| 1386 | Music::CD->table('cd'); | ||||
| 1387 | |||||
| 1388 | =item I<Declare your columns.> | ||||
| 1389 | |||||
| 1390 | This is done using the columns() method. In the simplest form, you tell | ||||
| 1391 | it the name of all your columns (with the single primary key first): | ||||
| 1392 | |||||
| 1393 | Music::CD->columns(All => qw/cdid artist title year/); | ||||
| 1394 | |||||
| 1395 | If the primary key of your table spans multiple columns then | ||||
| 1396 | declare them using a separate call to columns() like this: | ||||
| 1397 | |||||
| 1398 | Music::CD->columns(Primary => qw/pk1 pk2/); | ||||
| 1399 | Music::CD->columns(Others => qw/foo bar baz/); | ||||
| 1400 | |||||
| 1401 | For more information about how you can more efficiently use subsets of | ||||
| 1402 | your columns, see L</"LAZY POPULATION"> | ||||
| 1403 | |||||
| 1404 | =item I<Done.> | ||||
| 1405 | |||||
| 1406 | That's it! You now have a class with methods to L<"insert">, | ||||
| 1407 | L<"retrieve">, L<"search"> for, L<"update"> and L<"delete"> objects | ||||
| 1408 | from your table, as well as accessors and mutators for each of the | ||||
| 1409 | columns in that object (row). | ||||
| 1410 | |||||
| 1411 | =back | ||||
| 1412 | |||||
| 1413 | Let's look at all that in more detail: | ||||
| 1414 | |||||
| 1415 | =head1 CLASS METHODS | ||||
| 1416 | |||||
| 1417 | =head2 connection | ||||
| 1418 | |||||
| 1419 | __PACKAGE__->connection($data_source, $user, $password, \%attr); | ||||
| 1420 | |||||
| 1421 | This sets up a database connection with the given information. | ||||
| 1422 | |||||
| 1423 | This uses L<Ima::DBI> to set up an inheritable connection (named Main). It is | ||||
| 1424 | therefore usual to only set up a connection() in your application base class | ||||
| 1425 | and let the 'table' classes inherit from it. | ||||
| 1426 | |||||
| 1427 | package Music::DBI; | ||||
| 1428 | use base 'Class::DBI'; | ||||
| 1429 | |||||
| 1430 | Music::DBI->connection('dbi:foo:dbname', 'user', 'password'); | ||||
| 1431 | |||||
| 1432 | package My::Other::Table; | ||||
| 1433 | use base 'Music::DBI'; | ||||
| 1434 | |||||
| 1435 | Class::DBI helps you along a bit to set up the database connection. | ||||
| 1436 | connection() provides its own default attributes depending on the driver | ||||
| 1437 | name in the data_source parameter. The connection() method provides defaults | ||||
| 1438 | for these attributes: | ||||
| 1439 | |||||
| 1440 | FetchHashKeyName => 'NAME_lc', | ||||
| 1441 | ShowErrorStatement => 1, | ||||
| 1442 | ChopBlanks => 1, | ||||
| 1443 | AutoCommit => 1, | ||||
| 1444 | |||||
| 1445 | (Except for Oracle and Pg, where AutoCommit defaults 0, placing the | ||||
| 1446 | database in transactional mode). | ||||
| 1447 | |||||
| 1448 | The defaults can always be extended (or overridden if you know what | ||||
| 1449 | you're doing) by supplying your own \%attr parameter. For example: | ||||
| 1450 | |||||
| 1451 | Music::DBI->connection(dbi:foo:dbname','user','pass',{ChopBlanks=>0}); | ||||
| 1452 | |||||
| 1453 | The RootClass of L<DBIx::ContextualFetch> in also inherited from L<Ima::DBI>, | ||||
| 1454 | and you should be very careful not to change this unless you know what | ||||
| 1455 | you're doing! | ||||
| 1456 | |||||
| 1457 | =head3 Dynamic Database Connections / db_Main | ||||
| 1458 | |||||
| 1459 | It is sometimes desirable to generate your database connection information | ||||
| 1460 | dynamically, for example, to allow multiple databases with the same | ||||
| 1461 | schema to not have to duplicate an entire class hierarchy. | ||||
| 1462 | |||||
| 1463 | The preferred method for doing this is to supply your own db_Main() | ||||
| 1464 | method rather than calling L<"connection">. This method should return a | ||||
| 1465 | valid database handle, and should ensure it sets the standard attributes | ||||
| 1466 | described above, preferably by combining $class->_default_attributes() | ||||
| 1467 | with your own. Note, this handle *must* have its RootClass set to | ||||
| 1468 | L<DBIx::ContextualFetch>, so it is usually not possible to just supply a | ||||
| 1469 | $dbh obtained elsewhere. | ||||
| 1470 | |||||
| 1471 | Note that connection information is class data, and that changing it | ||||
| 1472 | at run time may have unexpected behaviour for instances of the class | ||||
| 1473 | already in existence. | ||||
| 1474 | |||||
| 1475 | =head2 table | ||||
| 1476 | |||||
| 1477 | __PACKAGE__->table($table); | ||||
| 1478 | |||||
| 1479 | $table = Class->table; | ||||
| 1480 | $table = $obj->table; | ||||
| 1481 | |||||
| 1482 | An accessor to get/set the name of the database table in which this | ||||
| 1483 | class is stored. It -must- be set. | ||||
| 1484 | |||||
| 1485 | Table information is inherited by subclasses, but can be overridden. | ||||
| 1486 | |||||
| 1487 | =head2 table_alias | ||||
| 1488 | |||||
| 1489 | package Shop::Order; | ||||
| 1490 | __PACKAGE__->table('orders'); | ||||
| 1491 | __PACKAGE__->table_alias('orders'); | ||||
| 1492 | |||||
| 1493 | When Class::DBI constructs SQL, it aliases your table name to a name | ||||
| 1494 | representing your class. However, if your class's name is an SQL reserved | ||||
| 1495 | word (such as 'Order') this will cause SQL errors. In such cases you | ||||
| 1496 | should supply your own alias for your table name (which can, of course, | ||||
| 1497 | be the same as the actual table name). | ||||
| 1498 | |||||
| 1499 | This can also be passed as a second argument to 'table': | ||||
| 1500 | |||||
| 1501 | __PACKAGE__->table('orders', 'orders'); | ||||
| 1502 | |||||
| 1503 | As with table, this is inherited but can be overridden. | ||||
| 1504 | |||||
| 1505 | =head2 sequence / auto_increment | ||||
| 1506 | |||||
| 1507 | __PACKAGE__->sequence($sequence_name); | ||||
| 1508 | |||||
| 1509 | $sequence_name = Class->sequence; | ||||
| 1510 | $sequence_name = $obj->sequence; | ||||
| 1511 | |||||
| 1512 | If you are using a database which supports sequences and you want to use | ||||
| 1513 | a sequence to automatically supply values for the primary key of a table, | ||||
| 1514 | then you should declare this using the sequence() method: | ||||
| 1515 | |||||
| 1516 | __PACKAGE__->columns(Primary => 'id'); | ||||
| 1517 | __PACKAGE__->sequence('class_id_seq'); | ||||
| 1518 | |||||
| 1519 | Class::DBI will use the sequence to generate a primary key value when | ||||
| 1520 | objects are inserted without one. | ||||
| 1521 | |||||
| 1522 | *NOTE* This method does not work for Oracle. However, L<Class::DBI::Oracle> | ||||
| 1523 | (which can be downloaded separately from CPAN) provides a suitable | ||||
| 1524 | replacement sequence() method. | ||||
| 1525 | |||||
| 1526 | If you are using a database with AUTO_INCREMENT (e.g. MySQL) then you do | ||||
| 1527 | not need this, and any call to insert() without a primary key specified | ||||
| 1528 | will fill this in automagically. | ||||
| 1529 | |||||
| 1530 | Sequence and auto-increment mechanisms only apply to tables that have | ||||
| 1531 | a single column primary key. For tables with multi-column primary keys | ||||
| 1532 | you need to supply the key values manually. | ||||
| 1533 | |||||
| 1534 | =head1 CONSTRUCTORS and DESTRUCTORS | ||||
| 1535 | |||||
| 1536 | The following are methods provided for convenience to insert, retrieve | ||||
| 1537 | and delete stored objects. It's not entirely one-size fits all and you | ||||
| 1538 | might find it necessary to override them. | ||||
| 1539 | |||||
| 1540 | =head2 insert | ||||
| 1541 | |||||
| 1542 | my $obj = Class->insert(\%data); | ||||
| 1543 | |||||
| 1544 | This is a constructor to insert new data into the database and create an | ||||
| 1545 | object representing the newly inserted row. | ||||
| 1546 | |||||
| 1547 | %data consists of the initial information to place in your object and | ||||
| 1548 | the database. The keys of %data match up with the columns of your | ||||
| 1549 | objects and the values are the initial settings of those fields. | ||||
| 1550 | |||||
| 1551 | my $cd = Music::CD->insert({ | ||||
| 1552 | cdid => 1, | ||||
| 1553 | artist => $artist, | ||||
| 1554 | title => 'October', | ||||
| 1555 | year => 1980, | ||||
| 1556 | }); | ||||
| 1557 | |||||
| 1558 | If the table has a single primary key column and that column value | ||||
| 1559 | is not defined in %data, insert() will assume it is to be generated. | ||||
| 1560 | If a sequence() has been specified for this Class, it will use that. | ||||
| 1561 | Otherwise, it will assume the primary key can be generated by | ||||
| 1562 | AUTO_INCREMENT and attempt to use that. | ||||
| 1563 | |||||
| 1564 | The C<before_create> trigger is invoked directly after storing the | ||||
| 1565 | supplied values into the new object and before inserting the record | ||||
| 1566 | into the database. The object stored in $self may not have all the | ||||
| 1567 | functionality of the final object after_creation, particularly if the | ||||
| 1568 | database is going to be providing the primary key value. | ||||
| 1569 | |||||
| 1570 | For tables with multi-column primary keys you need to supply all | ||||
| 1571 | the key values, either in the arguments to the insert() method, or | ||||
| 1572 | by setting the values in a C<before_create> trigger. | ||||
| 1573 | |||||
| 1574 | If the class has declared relationships with foreign classes via | ||||
| 1575 | has_a(), you can pass an object to insert() for the value of that key. | ||||
| 1576 | Class::DBI will Do The Right Thing. | ||||
| 1577 | |||||
| 1578 | After the new record has been inserted into the database the data | ||||
| 1579 | for non-primary key columns is discarded from the object. If those | ||||
| 1580 | columns are accessed again they'll simply be fetched as needed. | ||||
| 1581 | This ensures that the data in the application is consistent with | ||||
| 1582 | what the database I<actually> stored. | ||||
| 1583 | |||||
| 1584 | The C<after_create> trigger is invoked after the database insert | ||||
| 1585 | has executed. | ||||
| 1586 | |||||
| 1587 | =head2 find_or_create | ||||
| 1588 | |||||
| 1589 | my $cd = Music::CD->find_or_create({ artist => 'U2', title => 'Boy' }); | ||||
| 1590 | |||||
| 1591 | This checks if a CD can be found to match the information passed, and | ||||
| 1592 | if not inserts it. | ||||
| 1593 | |||||
| 1594 | =head2 delete | ||||
| 1595 | |||||
| 1596 | $obj->delete; | ||||
| 1597 | Music::CD->search(year => 1980, title => 'Greatest %')->delete_all; | ||||
| 1598 | |||||
| 1599 | Deletes this object from the database and from memory. If you have set up | ||||
| 1600 | any relationships using C<has_many> or C<might_have>, this will delete | ||||
| 1601 | the foreign elements also, recursively (cascading delete). $obj is no | ||||
| 1602 | longer usable after this call. | ||||
| 1603 | |||||
| 1604 | Multiple objects can be deleted by calling delete_all on the Iterator | ||||
| 1605 | returned from a search. Each object found will be deleted in turn, | ||||
| 1606 | so cascading delete and other triggers will be honoured. | ||||
| 1607 | |||||
| 1608 | The C<before_delete> trigger is when an object instance is about to be | ||||
| 1609 | deleted. It is invoked before any cascaded deletes. The C<after_delete> | ||||
| 1610 | trigger is invoked after the record has been deleted from the database | ||||
| 1611 | and just before the contents in memory are discarded. | ||||
| 1612 | |||||
| 1613 | =head1 RETRIEVING OBJECTS | ||||
| 1614 | |||||
| 1615 | Class::DBI provides a few very simple search methods. | ||||
| 1616 | |||||
| 1617 | It is not the goal of Class::DBI to replace the need for using SQL. Users | ||||
| 1618 | are expected to write their own searches for more complex cases. | ||||
| 1619 | |||||
| 1620 | L<Class::DBI::AbstractSearch>, available on CPAN, provides a much more | ||||
| 1621 | complex search interface than Class::DBI provides itself. | ||||
| 1622 | |||||
| 1623 | =head2 retrieve | ||||
| 1624 | |||||
| 1625 | $obj = Class->retrieve( $id ); | ||||
| 1626 | $obj = Class->retrieve( %key_values ); | ||||
| 1627 | |||||
| 1628 | Given key values it will retrieve the object with that key from the | ||||
| 1629 | database. For tables with a single column primary key a single | ||||
| 1630 | parameter can be used, otherwise a hash of key-name key-value pairs | ||||
| 1631 | must be given. | ||||
| 1632 | |||||
| 1633 | my $cd = Music::CD->retrieve(1) or die "No such cd"; | ||||
| 1634 | |||||
| 1635 | =head2 retrieve_all | ||||
| 1636 | |||||
| 1637 | my @objs = Class->retrieve_all; | ||||
| 1638 | my $iterator = Class->retrieve_all; | ||||
| 1639 | |||||
| 1640 | Retrieves objects for all rows in the database. This is probably a | ||||
| 1641 | bad idea if your table is big, unless you use the iterator version. | ||||
| 1642 | |||||
| 1643 | =head2 search | ||||
| 1644 | |||||
| 1645 | @objs = Class->search(column1 => $value, column2 => $value ...); | ||||
| 1646 | |||||
| 1647 | This is a simple search for all objects where the columns specified are | ||||
| 1648 | equal to the values specified e.g.: | ||||
| 1649 | |||||
| 1650 | @cds = Music::CD->search(year => 1990); | ||||
| 1651 | @cds = Music::CD->search(title => "Greatest Hits", year => 1990); | ||||
| 1652 | |||||
| 1653 | You may also specify the sort order of the results by adding a final | ||||
| 1654 | hash of arguments with the key 'order_by': | ||||
| 1655 | |||||
| 1656 | @cds = Music::CD->search(year => 1990, { order_by=>'artist' }); | ||||
| 1657 | |||||
| 1658 | This is passed through 'as is', enabling order_by clauses such | ||||
| 1659 | as 'year DESC, title'. | ||||
| 1660 | |||||
| 1661 | =head2 search_like | ||||
| 1662 | |||||
| 1663 | @objs = Class->search_like(column1 => $like_pattern, ....); | ||||
| 1664 | |||||
| 1665 | This is a simple search for all objects where the columns specified are | ||||
| 1666 | like the values specified. $like_pattern is a pattern given in SQL LIKE | ||||
| 1667 | predicate syntax. '%' means "any zero or more characters", '_' means | ||||
| 1668 | "any single character". | ||||
| 1669 | |||||
| 1670 | @cds = Music::CD->search_like(title => 'October%'); | ||||
| 1671 | @cds = Music::CD->search_like(title => 'Hits%', artist => 'Various%'); | ||||
| 1672 | |||||
| 1673 | You can also use 'order_by' with these, as with search(). | ||||
| 1674 | |||||
| 1675 | =head1 ITERATORS | ||||
| 1676 | |||||
| 1677 | my $it = Music::CD->search_like(title => 'October%'); | ||||
| 1678 | while (my $cd = $it->next) { | ||||
| 1679 | print $cd->title; | ||||
| 1680 | } | ||||
| 1681 | |||||
| 1682 | Any of the above searches (as well as those defined by has_many) can also | ||||
| 1683 | be used as an iterator. Rather than creating a list of objects matching | ||||
| 1684 | your criteria, this will return a Class::DBI::Iterator instance, which | ||||
| 1685 | can return the objects required one at a time. | ||||
| 1686 | |||||
| 1687 | Currently the iterator initially fetches all the matching row data into | ||||
| 1688 | memory, and defers only the creation of the objects from that data until | ||||
| 1689 | the iterator is asked for the next object. So using an iterator will | ||||
| 1690 | only save significant memory if your objects will inflate substantially | ||||
| 1691 | when used. | ||||
| 1692 | |||||
| 1693 | In the case of has_many relationships with a mapping method, the mapping | ||||
| 1694 | method is not called until each time you call 'next'. This means that | ||||
| 1695 | if your mapping is not a one-to-one, the results will probably not be | ||||
| 1696 | what you expect. | ||||
| 1697 | |||||
| 1698 | =head2 Subclassing the Iterator | ||||
| 1699 | |||||
| 1700 | Music::CD->iterator_class('Music::CD::Iterator'); | ||||
| 1701 | |||||
| 1702 | You can also subclass the default iterator class to override its | ||||
| 1703 | functionality. This is done via class data, and so is inherited into | ||||
| 1704 | your subclasses. | ||||
| 1705 | |||||
| 1706 | =head2 QUICK RETRIEVAL | ||||
| 1707 | |||||
| 1708 | my $obj = Class->construct(\%data); | ||||
| 1709 | |||||
| 1710 | This is used to turn data from the database into objects, and should | ||||
| 1711 | thus only be used when writing constructors. It is very handy for | ||||
| 1712 | cheaply setting up lots of objects from data for without going back to | ||||
| 1713 | the database. | ||||
| 1714 | |||||
| 1715 | For example, instead of doing one SELECT to get a bunch of IDs and then | ||||
| 1716 | feeding those individually to retrieve() (and thus doing more SELECT | ||||
| 1717 | calls), you can do one SELECT to get the essential data of many objects | ||||
| 1718 | and feed that data to construct(): | ||||
| 1719 | |||||
| 1720 | return map $class->construct($_), $sth->fetchall_hash; | ||||
| 1721 | |||||
| 1722 | The construct() method creates a new empty object, loads in the column | ||||
| 1723 | values, and then invokes the C<select> trigger. | ||||
| 1724 | |||||
| 1725 | =head1 COPY AND MOVE | ||||
| 1726 | |||||
| 1727 | =head2 copy | ||||
| 1728 | |||||
| 1729 | $new_obj = $obj->copy; | ||||
| 1730 | $new_obj = $obj->copy($new_id); | ||||
| 1731 | $new_obj = $obj->copy({ title => 'new_title', rating => 18 }); | ||||
| 1732 | |||||
| 1733 | This creates a copy of the given $obj, removes the primary key, | ||||
| 1734 | sets any supplied column values and calls insert() to make a new | ||||
| 1735 | record in the database. | ||||
| 1736 | |||||
| 1737 | For tables with a single column primary key, copy() can be called | ||||
| 1738 | with no parameters and the new object will be assigned a key | ||||
| 1739 | automatically. Or a single parameter can be supplied and will be | ||||
| 1740 | used as the new key. | ||||
| 1741 | |||||
| 1742 | For tables with a multi-column primary key, copy() must be called with | ||||
| 1743 | parameters which supply new values for all primary key columns, unless | ||||
| 1744 | a C<before_create> trigger will supply them. The insert() method will | ||||
| 1745 | fail if any primary key columns are not defined. | ||||
| 1746 | |||||
| 1747 | my $blrunner_dc = $blrunner->copy("Bladerunner: Director's Cut"); | ||||
| 1748 | my $blrunner_unrated = $blrunner->copy({ | ||||
| 1749 | Title => "Bladerunner: Director's Cut", | ||||
| 1750 | Rating => 'Unrated', | ||||
| 1751 | }); | ||||
| 1752 | |||||
| 1753 | =head2 move | ||||
| 1754 | |||||
| 1755 | my $new_obj = Sub::Class->move($old_obj); | ||||
| 1756 | my $new_obj = Sub::Class->move($old_obj, $new_id); | ||||
| 1757 | my $new_obj = Sub::Class->move($old_obj, \%changes); | ||||
| 1758 | |||||
| 1759 | For transferring objects from one class to another. Similar to copy(), an | ||||
| 1760 | instance of Sub::Class is inserted using the data in $old_obj (Sub::Class | ||||
| 1761 | is a subclass of $old_obj's subclass). Like copy(), you can supply | ||||
| 1762 | $new_id as the primary key of $new_obj (otherwise the usual sequence or | ||||
| 1763 | autoincrement is used), or a hashref of multiple new values. | ||||
| 1764 | |||||
| 1765 | =head1 TRIGGERS | ||||
| 1766 | |||||
| 1767 | __PACKAGE__->add_trigger(trigger_point_name => \&code_to_execute); | ||||
| 1768 | |||||
| 1769 | # e.g. | ||||
| 1770 | |||||
| 1771 | __PACKAGE__->add_trigger(after_create => \&call_after_create); | ||||
| 1772 | |||||
| 1773 | It is possible to set up triggers that will be called at various | ||||
| 1774 | points in the life of an object. Valid trigger points are: | ||||
| 1775 | |||||
| 1776 | before_create (also used for deflation) | ||||
| 1777 | after_create | ||||
| 1778 | before_set_$column (also used by add_constraint) | ||||
| 1779 | after_set_$column (also used for inflation and by has_a) | ||||
| 1780 | before_update (also used for deflation and by might_have) | ||||
| 1781 | after_update | ||||
| 1782 | before_delete | ||||
| 1783 | after_delete | ||||
| 1784 | select (also used for inflation and by construct and _flesh) | ||||
| 1785 | |||||
| 1786 | |||||
| 1787 | You can create any number of triggers for each point, but you cannot | ||||
| 1788 | specify the order in which they will be run. | ||||
| 1789 | |||||
| 1790 | All triggers are passed the object they are being fired for, except | ||||
| 1791 | when C<before_set_$column> is fired during L<"insert">, in which case | ||||
| 1792 | the class is passed in place of the object, which does not yet exist. | ||||
| 1793 | You may change object values if required. | ||||
| 1794 | |||||
| 1795 | Some triggers are also passed extra parameters as name-value | ||||
| 1796 | pairs. The individual triggers are further documented with the methods | ||||
| 1797 | that trigger them. | ||||
| 1798 | |||||
| 1799 | =head1 CONSTRAINTS | ||||
| 1800 | |||||
| 1801 | __PACKAGE__->add_constraint('name', column => \&check_sub); | ||||
| 1802 | |||||
| 1803 | # e.g. | ||||
| 1804 | |||||
| 1805 | __PACKAGE__->add_constraint('over18', age => \&check_age); | ||||
| 1806 | |||||
| 1807 | # Simple version | ||||
| 1808 | sub check_age { | ||||
| 1809 | my ($value) = @_; | ||||
| 1810 | return $value >= 18; | ||||
| 1811 | } | ||||
| 1812 | |||||
| 1813 | # Cross-field checking - must have SSN if age < 18 | ||||
| 1814 | sub check_age { | ||||
| 1815 | my ($value, $self, $column_name, $changing) = @_; | ||||
| 1816 | return 1 if $value >= 18; # We're old enough. | ||||
| 1817 | return 1 if $changing->{SSN}; # We're also being given an SSN | ||||
| 1818 | return 0 if !ref($self); # This is an insert, so we can't have an SSN | ||||
| 1819 | return 1 if $self->ssn; # We already have one in the database | ||||
| 1820 | return 0; # We can't find an SSN anywhere | ||||
| 1821 | } | ||||
| 1822 | |||||
| 1823 | It is also possible to set up constraints on the values that can be set | ||||
| 1824 | on a column. The constraint on a column is triggered whenever an object | ||||
| 1825 | is created and whenever the value in that column is being changed. | ||||
| 1826 | |||||
| 1827 | The constraint code is called with four parameters: | ||||
| 1828 | |||||
| 1829 | - The new value to be assigned | ||||
| 1830 | - The object it will be assigned to | ||||
| 1831 | (or class name when initially creating an object) | ||||
| 1832 | - The name of the column | ||||
| 1833 | (useful if many constraints share the same code) | ||||
| 1834 | - A hash ref of all new column values being assigned | ||||
| 1835 | (useful for cross-field validation) | ||||
| 1836 | |||||
| 1837 | The constraints are applied to all the columns being set before the | ||||
| 1838 | object data is changed. Attempting to create or modify an object | ||||
| 1839 | where one or more constraint fail results in an exception and the object | ||||
| 1840 | remains unchanged. | ||||
| 1841 | |||||
| 1842 | The exception thrown has its data set to a hashref of the column being | ||||
| 1843 | changed and the value being changed to. | ||||
| 1844 | |||||
| 1845 | Note 1: Constraints are implemented using before_set_$column triggers. | ||||
| 1846 | This will only prevent you from setting these values through a | ||||
| 1847 | the provided insert() or set() methods. It will always be possible to | ||||
| 1848 | bypass this if you try hard enough. | ||||
| 1849 | |||||
| 1850 | Note 2: When an object is created constraints are currently only | ||||
| 1851 | checked for column names included in the parameters to insert(). | ||||
| 1852 | This is probably a bug and is likely to change in future. | ||||
| 1853 | |||||
| 1854 | =head2 constrain_column | ||||
| 1855 | |||||
| 1856 | Film->constrain_column(year => qr/^\d{4}$/); | ||||
| 1857 | Film->constrain_column(rating => [qw/U Uc PG 12 15 18/]); | ||||
| 1858 | Film->constrain_column(title => sub { length() <= 20 }); | ||||
| 1859 | |||||
| 1860 | Simple anonymous constraints can also be added to a column using the | ||||
| 1861 | constrain_column() method. By default this takes either a regex which | ||||
| 1862 | must match, a reference to a list of possible values, or a subref which | ||||
| 1863 | will have $_ aliased to the value being set, and should return a | ||||
| 1864 | true or false value. | ||||
| 1865 | |||||
| 1866 | However, this behaviour can be extended (or replaced) by providing a | ||||
| 1867 | constraint handler for the type of argument passed to constrain_column. | ||||
| 1868 | This behavior should be provided in a method named "_constrain_by_$type", | ||||
| 1869 | where $type is the moniker of the argument. For example, the | ||||
| 1870 | year example above could be provided by _constrain_by_array(). | ||||
| 1871 | |||||
| 1872 | =head1 DATA NORMALIZATION | ||||
| 1873 | |||||
| 1874 | Before an object is assigned data from the application (via insert or | ||||
| 1875 | a set accessor) the normalize_column_values() method is called with | ||||
| 1876 | a reference to a hash containing the column names and the new values | ||||
| 1877 | which are to be assigned (after any validation and constraint checking, | ||||
| 1878 | as described below). | ||||
| 1879 | |||||
| 1880 | Currently Class::DBI does not offer any per-column mechanism here. | ||||
| 1881 | The default method is empty. You can override it in your own classes | ||||
| 1882 | to normalize (edit) the data in any way you need. For example the values | ||||
| 1883 | in the hash for certain columns could be made lowercase. | ||||
| 1884 | |||||
| 1885 | The method is called as an instance method when the values of an existing | ||||
| 1886 | object are being changed, and as a class method when a new object is | ||||
| 1887 | being created. | ||||
| 1888 | |||||
| 1889 | =head1 DATA VALIDATION | ||||
| 1890 | |||||
| 1891 | Before an object is assigned data from the application (via insert or | ||||
| 1892 | a set accessor) the validate_column_values() method is called with a | ||||
| 1893 | reference to a hash containing the column names and the new values which | ||||
| 1894 | are to be assigned. | ||||
| 1895 | |||||
| 1896 | The method is called as an instance method when the values of an existing | ||||
| 1897 | object are being changed, and as a class method when a new object is | ||||
| 1898 | being inserted. | ||||
| 1899 | |||||
| 1900 | The default method calls the before_set_$column trigger for each column | ||||
| 1901 | name in the hash. Each trigger is called inside an eval. Any failures | ||||
| 1902 | result in an exception after all have been checked. The exception data | ||||
| 1903 | is a reference to a hash which holds the column name and error text for | ||||
| 1904 | each trigger error. | ||||
| 1905 | |||||
| 1906 | When using this mechanism for form data validation, for example, | ||||
| 1907 | this exception data can be stored in an exception object, via a | ||||
| 1908 | custom _croak() method, and then caught and used to redisplay the | ||||
| 1909 | form with error messages next to each field which failed validation. | ||||
| 1910 | |||||
| 1911 | =head1 EXCEPTIONS | ||||
| 1912 | |||||
| 1913 | All errors that are generated, or caught and propagated, by Class::DBI | ||||
| 1914 | are handled by calling the _croak() method (as an instance method | ||||
| 1915 | if possible, or else as a class method). | ||||
| 1916 | |||||
| 1917 | The _croak() method is passed an error message and in some cases | ||||
| 1918 | some extra information as described below. The default behaviour | ||||
| 1919 | is simply to call Carp::croak($message). | ||||
| 1920 | |||||
| 1921 | Applications that require custom behaviour should override the | ||||
| 1922 | _croak() method in their application base class (or table classes | ||||
| 1923 | for table-specific behaviour). For example: | ||||
| 1924 | |||||
| 1925 | use Error; | ||||
| 1926 | |||||
| 1927 | sub _croak { | ||||
| 1928 | my ($self, $message, %info) = @_; | ||||
| 1929 | # convert errors into exception objects | ||||
| 1930 | # except for duplicate insert errors which we'll ignore | ||||
| 1931 | Error->throw(-text => $message, %info) | ||||
| 1932 | unless $message =~ /^Can't insert .* duplicate/; | ||||
| 1933 | return; | ||||
| 1934 | } | ||||
| 1935 | |||||
| 1936 | The _croak() method is expected to trigger an exception and not | ||||
| 1937 | return. If it does return then it should use C<return;> so that an | ||||
| 1938 | undef or empty list is returned as required depending on the calling | ||||
| 1939 | context. You should only return other values if you are prepared to | ||||
| 1940 | deal with the (unsupported) consequences. | ||||
| 1941 | |||||
| 1942 | For exceptions that are caught and propagated by Class::DBI, $message | ||||
| 1943 | includes the text of $@ and the original $@ value is available in $info{err}. | ||||
| 1944 | That allows you to correctly propagate exception objects that may have | ||||
| 1945 | been thrown 'below' Class::DBI (using L<Exception::Class::DBI> for example). | ||||
| 1946 | |||||
| 1947 | Exceptions generated by some methods may provide additional data in | ||||
| 1948 | $info{data} and, if so, also store the method name in $info{method}. | ||||
| 1949 | For example, the validate_column_values() method stores details of | ||||
| 1950 | failed validations in $info{data}. See individual method documentation | ||||
| 1951 | for what additional data they may store, if any. | ||||
| 1952 | |||||
| 1953 | =head1 WARNINGS | ||||
| 1954 | |||||
| 1955 | All warnings are handled by calling the _carp() method (as | ||||
| 1956 | an instance method if possible, or else as a class method). | ||||
| 1957 | The default behaviour is simply to call Carp::carp(). | ||||
| 1958 | |||||
| 1959 | =head1 INSTANCE METHODS | ||||
| 1960 | |||||
| 1961 | =head2 accessors | ||||
| 1962 | |||||
| 1963 | Class::DBI inherits from L<Class::Accessor> and thus provides individual | ||||
| 1964 | accessor methods for every column in your subclass. It also overrides | ||||
| 1965 | the get() and set() methods provided by Accessor to automagically handle | ||||
| 1966 | database reading and writing. (Note that as it doesn't make sense to | ||||
| 1967 | store a list of values in a column, set() takes a hash of column => | ||||
| 1968 | value pairs, rather than the single key => values of Class::Accessor). | ||||
| 1969 | |||||
| 1970 | =head2 the fundamental set() and get() methods | ||||
| 1971 | |||||
| 1972 | $value = $obj->get($column_name); | ||||
| 1973 | @values = $obj->get(@column_names); | ||||
| 1974 | |||||
| 1975 | $obj->set($column_name => $value); | ||||
| 1976 | $obj->set($col1 => $value1, $col2 => $value2 ... ); | ||||
| 1977 | |||||
| 1978 | These methods are the fundamental entry points for getting and setting | ||||
| 1979 | column values. The extra accessor methods automatically generated for | ||||
| 1980 | each column of your table are simple wrappers that call these get() | ||||
| 1981 | and set() methods. | ||||
| 1982 | |||||
| 1983 | The set() method calls normalize_column_values() then | ||||
| 1984 | validate_column_values() before storing the values. The | ||||
| 1985 | C<before_set_$column> trigger is invoked by validate_column_values(), | ||||
| 1986 | checking any constraints that may have been set up. | ||||
| 1987 | |||||
| 1988 | The C<after_set_$column> trigger is invoked after the new value has | ||||
| 1989 | been stored. | ||||
| 1990 | |||||
| 1991 | It is possible for an object to not have all its column data in memory | ||||
| 1992 | (due to lazy inflation). If the get() method is called for such a column | ||||
| 1993 | then it will select the corresponding group of columns and then invoke | ||||
| 1994 | the C<select> trigger. | ||||
| 1995 | |||||
| 1996 | =head1 Changing Your Column Accessor Method Names | ||||
| 1997 | |||||
| 1998 | =head2 accessor_name_for / mutator_name_for | ||||
| 1999 | |||||
| 2000 | It is possible to change the name of the accessor method created for a | ||||
| 2001 | column either declaratively or programmatically. | ||||
| 2002 | |||||
| 2003 | If, for example, you have a column with a name that clashes with a | ||||
| 2004 | method otherwise created by Class::DBI, such as 'meta_info', you could | ||||
| 2005 | create that Column explicitly with a different accessor (and/or | ||||
| 2006 | mutator) when setting up your columns: | ||||
| 2007 | |||||
| 2008 | my $meta_col = Class::DBI::Column->new(meta_info => { | ||||
| 2009 | accessor => 'metadata', | ||||
| 2010 | }); | ||||
| 2011 | |||||
| 2012 | __PACKAGE__->columns(All => qw/id name/, $meta_col); | ||||
| 2013 | |||||
| 2014 | If you want to change the name of all your accessors, or all that match | ||||
| 2015 | a certain pattern, you need to provide an accessor_name_for($col) method, | ||||
| 2016 | which will convert a column name to a method name. | ||||
| 2017 | |||||
| 2018 | e.g: if your local database naming convention was to prepend the word | ||||
| 2019 | 'customer' to each column in the 'customer' table, so that you had the | ||||
| 2020 | columns 'customerid', 'customername' and 'customerage', but you wanted | ||||
| 2021 | your methods to just be $customer->name and $customer->age rather than | ||||
| 2022 | $customer->customername etc., you could create a | ||||
| 2023 | |||||
| 2024 | sub accessor_name_for { | ||||
| 2025 | my ($class, $column) = @_; | ||||
| 2026 | $column =~ s/^customer//; | ||||
| 2027 | return $column; | ||||
| 2028 | } | ||||
| 2029 | |||||
| 2030 | Similarly, if you wanted to have distinct accessor and mutator methods, | ||||
| 2031 | you could provide a mutator_name_for($col) method which would return | ||||
| 2032 | the name of the method to change the value: | ||||
| 2033 | |||||
| 2034 | sub mutator_name_for { | ||||
| 2035 | my ($class, $column) = @_; | ||||
| 2036 | return "set_" . $column->accessor; | ||||
| 2037 | } | ||||
| 2038 | |||||
| 2039 | If you override the mutator name, then the accessor method will be | ||||
| 2040 | enforced as read-only, and the mutator as write-only. | ||||
| 2041 | |||||
| 2042 | =head2 update vs auto update | ||||
| 2043 | |||||
| 2044 | There are two modes for the accessors to work in: manual update and | ||||
| 2045 | autoupdate. When in autoupdate mode, every time one calls an accessor | ||||
| 2046 | to make a change an UPDATE will immediately be sent to the database. | ||||
| 2047 | Otherwise, if autoupdate is off, no changes will be written until update() | ||||
| 2048 | is explicitly called. | ||||
| 2049 | |||||
| 2050 | This is an example of manual updating: | ||||
| 2051 | |||||
| 2052 | # The calls to NumExplodingSheep() and Rating() will only make the | ||||
| 2053 | # changes in memory, not in the database. Once update() is called | ||||
| 2054 | # it writes to the database in one swell foop. | ||||
| 2055 | $gone->NumExplodingSheep(5); | ||||
| 2056 | $gone->Rating('NC-17'); | ||||
| 2057 | $gone->update; | ||||
| 2058 | |||||
| 2059 | And of autoupdating: | ||||
| 2060 | |||||
| 2061 | # Turn autoupdating on for this object. | ||||
| 2062 | $gone->autoupdate(1); | ||||
| 2063 | |||||
| 2064 | # Each accessor call causes the new value to immediately be written. | ||||
| 2065 | $gone->NumExplodingSheep(5); | ||||
| 2066 | $gone->Rating('NC-17'); | ||||
| 2067 | |||||
| 2068 | Manual updating is probably more efficient than autoupdating and | ||||
| 2069 | it provides the extra safety of a discard_changes() option to clear out all | ||||
| 2070 | unsaved changes. Autoupdating can be more convenient for the programmer. | ||||
| 2071 | Autoupdating is I<off> by default. | ||||
| 2072 | |||||
| 2073 | If changes are neither updated nor rolled back when the object is | ||||
| 2074 | destroyed (falls out of scope or the program ends) then Class::DBI's | ||||
| 2075 | DESTROY method will print a warning about unsaved changes. | ||||
| 2076 | |||||
| 2077 | =head2 autoupdate | ||||
| 2078 | |||||
| 2079 | __PACKAGE__->autoupdate($on_or_off); | ||||
| 2080 | $update_style = Class->autoupdate; | ||||
| 2081 | |||||
| 2082 | $obj->autoupdate($on_or_off); | ||||
| 2083 | $update_style = $obj->autoupdate; | ||||
| 2084 | |||||
| 2085 | This is an accessor to the current style of auto-updating. When called | ||||
| 2086 | with no arguments it returns the current auto-updating state, true for on, | ||||
| 2087 | false for off. When given an argument it turns auto-updating on and off: | ||||
| 2088 | a true value turns it on, a false one off. | ||||
| 2089 | |||||
| 2090 | When called as a class method it will control the updating style for | ||||
| 2091 | every instance of the class. When called on an individual object it | ||||
| 2092 | will control updating for just that object, overriding the choice for | ||||
| 2093 | the class. | ||||
| 2094 | |||||
| 2095 | __PACKAGE__->autoupdate(1); # Autoupdate is now on for the class. | ||||
| 2096 | |||||
| 2097 | $obj = Class->retrieve('Aliens Cut My Hair'); | ||||
| 2098 | $obj->autoupdate(0); # Shut off autoupdating for this object. | ||||
| 2099 | |||||
| 2100 | The update setting for an object is not stored in the database. | ||||
| 2101 | |||||
| 2102 | =head2 update | ||||
| 2103 | |||||
| 2104 | $obj->update; | ||||
| 2105 | |||||
| 2106 | If L<"autoupdate"> is not enabled then changes you make to your object are | ||||
| 2107 | not reflected in the database until you call update(). It is harmless | ||||
| 2108 | to call update() if there are no changes to be saved. (If autoupdate | ||||
| 2109 | is on there'll never be anything to save.) | ||||
| 2110 | |||||
| 2111 | Note: If you have transactions turned on for your database (but see | ||||
| 2112 | L<"TRANSACTIONS"> below) you will also need to call dbi_commit(), as | ||||
| 2113 | update() merely issues the UPDATE to the database). | ||||
| 2114 | |||||
| 2115 | After the database update has been executed, the data for columns | ||||
| 2116 | that have been updated are deleted from the object. If those columns | ||||
| 2117 | are accessed again they'll simply be fetched as needed. This ensures | ||||
| 2118 | that the data in the application is consistent with what the database | ||||
| 2119 | I<actually> stored. | ||||
| 2120 | |||||
| 2121 | When update() is called the C<before_update>($self) trigger is | ||||
| 2122 | always invoked immediately. | ||||
| 2123 | |||||
| 2124 | If any columns have been updated then the C<after_update> trigger | ||||
| 2125 | is invoked after the database update has executed and is passed: | ||||
| 2126 | ($self, discard_columns => \@discard_columns) | ||||
| 2127 | |||||
| 2128 | The trigger code can modify the discard_columns array to affect | ||||
| 2129 | which columns are discarded. | ||||
| 2130 | |||||
| 2131 | For example: | ||||
| 2132 | |||||
| 2133 | Class->add_trigger(after_update => sub { | ||||
| 2134 | my ($self, %args) = @_; | ||||
| 2135 | my $discard_columns = $args{discard_columns}; | ||||
| 2136 | # discard the md5_hash column if any field starting with 'foo' | ||||
| 2137 | # has been updated - because the md5_hash will have been changed | ||||
| 2138 | # by a trigger. | ||||
| 2139 | push @$discard_columns, 'md5_hash' if grep { /^foo/ } @$discard_columns; | ||||
| 2140 | }); | ||||
| 2141 | |||||
| 2142 | Take care to not delete a primary key column unless you know what | ||||
| 2143 | you're doing. | ||||
| 2144 | |||||
| 2145 | The update() method returns the number of rows updated. If the object | ||||
| 2146 | had not changed and thus did not need to issue an UPDATE statement, | ||||
| 2147 | the update() call will have a return value of -1. | ||||
| 2148 | |||||
| 2149 | If the record in the database has been deleted, or its primary key value | ||||
| 2150 | changed, then the update will not affect any records and so the update() | ||||
| 2151 | method will return 0. | ||||
| 2152 | |||||
| 2153 | =head2 discard_changes | ||||
| 2154 | |||||
| 2155 | $obj->discard_changes; | ||||
| 2156 | |||||
| 2157 | Removes any changes you've made to this object since the last update. | ||||
| 2158 | Currently this simply discards the column values from the object. | ||||
| 2159 | |||||
| 2160 | If you're using autoupdate this method will throw an exception. | ||||
| 2161 | |||||
| 2162 | =head2 is_changed | ||||
| 2163 | |||||
| 2164 | my $changed = $obj->is_changed; | ||||
| 2165 | my @changed_keys = $obj->is_changed; | ||||
| 2166 | |||||
| 2167 | Indicates if the given $obj has changes since the last update. Returns | ||||
| 2168 | a list of keys which have changed. (If autoupdate is on, this method | ||||
| 2169 | will return an empty list, unless called inside a before_update or | ||||
| 2170 | after_set_$column trigger) | ||||
| 2171 | |||||
| 2172 | =head2 id | ||||
| 2173 | |||||
| 2174 | $id = $obj->id; | ||||
| 2175 | @id = $obj->id; | ||||
| 2176 | |||||
| 2177 | Returns a unique identifier for this object based on the values in the | ||||
| 2178 | database. It's the equivalent of $obj->get($self->columns('Primary')), | ||||
| 2179 | with inflated values reduced to their ids. | ||||
| 2180 | |||||
| 2181 | A warning will be generated if this method is used in scalar context on | ||||
| 2182 | a table with a multi-column primary key. | ||||
| 2183 | |||||
| 2184 | =head2 LOW-LEVEL DATA ACCESS | ||||
| 2185 | |||||
| 2186 | On some occasions, such as when you're writing triggers or constraint | ||||
| 2187 | routines, you'll want to manipulate data in a Class::DBI object without | ||||
| 2188 | using the usual get() and set() accessors, which may themselves call | ||||
| 2189 | triggers, fetch information from the database, etc. | ||||
| 2190 | |||||
| 2191 | Rather than interacting directly with the data hash stored in a Class::DBI | ||||
| 2192 | object (the exact implementation of which may change in future releases) | ||||
| 2193 | you could use Class::DBI's low-level accessors. These appear 'private' | ||||
| 2194 | to make you think carefully about using them - they should not be a | ||||
| 2195 | common means of dealing with the object. | ||||
| 2196 | |||||
| 2197 | The data within the object is modelled as a set of key-value pairs, | ||||
| 2198 | where the keys are normalized column names (returned by find_column()), | ||||
| 2199 | and the values are the data from the database row represented by the | ||||
| 2200 | object. Access is via these functions: | ||||
| 2201 | |||||
| 2202 | =over 4 | ||||
| 2203 | |||||
| 2204 | =item _attrs | ||||
| 2205 | |||||
| 2206 | @values = $object->_attrs(@cols); | ||||
| 2207 | |||||
| 2208 | Returns the values for one or more keys. | ||||
| 2209 | |||||
| 2210 | =item _attribute_store | ||||
| 2211 | |||||
| 2212 | $object->_attribute_store( { $col0 => $val0, $col1 => $val1 } ); | ||||
| 2213 | $object->_attribute_store($col0, $val0, $col1, $val1); | ||||
| 2214 | |||||
| 2215 | Stores values in the object. They key-value pairs may be passed in | ||||
| 2216 | either as a simple list or as a hash reference. This only updates | ||||
| 2217 | values in the object itself; changes will not be propagated to the | ||||
| 2218 | database. | ||||
| 2219 | |||||
| 2220 | =item _attribute_set | ||||
| 2221 | |||||
| 2222 | $object->_attribute_set( { $col0 => $val0, $col1 => $val1 } ); | ||||
| 2223 | $object->_attribute_set($col0, $val0, $col1, $val1); | ||||
| 2224 | |||||
| 2225 | Updates values in the object via _attribute_store(), but also logs | ||||
| 2226 | the changes so that they are propagated to the database with the next | ||||
| 2227 | update. (Unlike set(), however, _attribute_set() will not trigger an | ||||
| 2228 | update if autoupdate is turned on.) | ||||
| 2229 | |||||
| 2230 | =item _attribute_delete | ||||
| 2231 | |||||
| 2232 | @values = $object->_attribute_delete(@cols); | ||||
| 2233 | |||||
| 2234 | Deletes values from the object, and returns the deleted values. | ||||
| 2235 | |||||
| 2236 | =item _attribute_exists | ||||
| 2237 | |||||
| 2238 | $bool = $object->_attribute_exists($col); | ||||
| 2239 | |||||
| 2240 | Returns a true value if the object contains a value for the specified | ||||
| 2241 | column, and a false value otherwise. | ||||
| 2242 | |||||
| 2243 | =back | ||||
| 2244 | |||||
| 2245 | By default, Class::DBI uses simple hash references to store object | ||||
| 2246 | data, but all access is via these routines, so if you want to | ||||
| 2247 | implement a different data model, just override these functions. | ||||
| 2248 | |||||
| 2249 | =head2 OVERLOADED OPERATORS | ||||
| 2250 | |||||
| 2251 | Class::DBI and its subclasses overload the perl builtin I<stringify> | ||||
| 2252 | and I<bool> operators. This is a significant convenience. | ||||
| 2253 | |||||
| 2254 | The perl builtin I<bool> operator is overloaded so that a Class::DBI | ||||
| 2255 | object reference is true so long as all its key columns have defined | ||||
| 2256 | values. (This means an object with an id() of zero is not considered | ||||
| 2257 | false.) | ||||
| 2258 | |||||
| 2259 | When a Class::DBI object reference is used in a string context it will, | ||||
| 2260 | by default, return the value of the primary key. (Composite primary key | ||||
| 2261 | values will be separated by a slash). | ||||
| 2262 | |||||
| 2263 | You can also specify the column(s) to be used for stringification via | ||||
| 2264 | the special 'Stringify' column group. So, for example, if you're using | ||||
| 2265 | an auto-incremented primary key, you could use this to provide a more | ||||
| 2266 | meaningful display string: | ||||
| 2267 | |||||
| 2268 | Widget->columns(Stringify => qw/name/); | ||||
| 2269 | |||||
| 2270 | If you need to do anything more complex, you can provide an stringify_self() | ||||
| 2271 | method which stringification will call: | ||||
| 2272 | |||||
| 2273 | sub stringify_self { | ||||
| 2274 | my $self = shift; | ||||
| 2275 | return join ":", $self->id, $self->name; | ||||
| 2276 | } | ||||
| 2277 | |||||
| 2278 | This overloading behaviour can be useful for columns that have has_a() | ||||
| 2279 | relationships. For example, consider a table that has price and currency | ||||
| 2280 | fields: | ||||
| 2281 | |||||
| 2282 | package Widget; | ||||
| 2283 | use base 'My::Class::DBI'; | ||||
| 2284 | Widget->table('widget'); | ||||
| 2285 | Widget->columns(All => qw/widgetid name price currency_code/); | ||||
| 2286 | |||||
| 2287 | $obj = Widget->retrieve($id); | ||||
| 2288 | print $obj->price . " " . $obj->currency_code; | ||||
| 2289 | |||||
| 2290 | The would print something like "C<42.07 USD>". If the currency_code | ||||
| 2291 | field is later changed to be a foreign key to a new currency table then | ||||
| 2292 | $obj->currency_code will return an object reference instead of a plain | ||||
| 2293 | string. Without overloading the stringify operator the example would now | ||||
| 2294 | print something like "C<42.07 Widget=HASH(0x1275}>" and the fix would | ||||
| 2295 | be to change the code to add a call to id(): | ||||
| 2296 | |||||
| 2297 | print $obj->price . " " . $obj->currency_code->id; | ||||
| 2298 | |||||
| 2299 | However, with overloaded stringification, the original code continues | ||||
| 2300 | to work as before, with no code changes needed. | ||||
| 2301 | |||||
| 2302 | This makes it much simpler and safer to add relationships to existing | ||||
| 2303 | applications, or remove them later. | ||||
| 2304 | |||||
| 2305 | =head1 TABLE RELATIONSHIPS | ||||
| 2306 | |||||
| 2307 | Databases are all about relationships. Thus Class::DBI provides a way | ||||
| 2308 | for you to set up descriptions of your relationhips. | ||||
| 2309 | |||||
| 2310 | Class::DBI provides three such relationships: 'has_a', 'has_many', and | ||||
| 2311 | 'might_have'. Others are available from CPAN. | ||||
| 2312 | |||||
| 2313 | =head2 has_a | ||||
| 2314 | |||||
| 2315 | Music::CD->has_a(column => 'Foreign::Class'); | ||||
| 2316 | |||||
| 2317 | Music::CD->has_a(artist => 'Music::Artist'); | ||||
| 2318 | print $cd->artist->name; | ||||
| 2319 | |||||
| 2320 | 'has_a' is most commonly used to supply lookup information for a foreign | ||||
| 2321 | key. If a column is declared as storing the primary key of another | ||||
| 2322 | table, then calling the method for that column does not return the id, | ||||
| 2323 | but instead the relevant object from that foreign class. | ||||
| 2324 | |||||
| 2325 | It is also possible to use has_a to inflate the column value to a non | ||||
| 2326 | Class::DBI based. A common usage would be to inflate a date field to a | ||||
| 2327 | date/time object: | ||||
| 2328 | |||||
| 2329 | Music::CD->has_a(reldate => 'Date::Simple'); | ||||
| 2330 | print $cd->reldate->format("%d %b, %Y"); | ||||
| 2331 | |||||
| 2332 | Music::CD->has_a(reldate => 'Time::Piece', | ||||
| 2333 | inflate => sub { Time::Piece->strptime(shift, "%Y-%m-%d") }, | ||||
| 2334 | deflate => 'ymd', | ||||
| 2335 | ); | ||||
| 2336 | print $cd->reldate->strftime("%d %b, %Y"); | ||||
| 2337 | |||||
| 2338 | If the foreign class is another Class::DBI representation retrieve is | ||||
| 2339 | called on that class with the column value. Any other object will be | ||||
| 2340 | instantiated either by calling new($value) or using the given 'inflate' | ||||
| 2341 | method. If the inflate method name is a subref, it will be executed, | ||||
| 2342 | and will be passed the value and the Class::DBI object as arguments. | ||||
| 2343 | |||||
| 2344 | When the object is being written to the database the object will be | ||||
| 2345 | deflated either by calling the 'deflate' method (if given), or by | ||||
| 2346 | attempting to stringify the object. If the deflate method is a subref, | ||||
| 2347 | it will be passed the Class::DBI object as an argument. | ||||
| 2348 | |||||
| 2349 | *NOTE* You should not attempt to make your primary key column inflate | ||||
| 2350 | using has_a() as bad things will happen. If you have two tables which | ||||
| 2351 | share a primary key, consider using might_have() instead. | ||||
| 2352 | |||||
| 2353 | =head2 has_many | ||||
| 2354 | |||||
| 2355 | Class->has_many(method_to_create => "Foreign::Class"); | ||||
| 2356 | |||||
| 2357 | Music::CD->has_many(tracks => 'Music::Track'); | ||||
| 2358 | |||||
| 2359 | my @tracks = $cd->tracks; | ||||
| 2360 | |||||
| 2361 | my $track6 = $cd->add_to_tracks({ | ||||
| 2362 | position => 6, | ||||
| 2363 | title => 'Tomorrow', | ||||
| 2364 | }); | ||||
| 2365 | |||||
| 2366 | This method declares that another table is referencing us (i.e. storing | ||||
| 2367 | our primary key in its table). | ||||
| 2368 | |||||
| 2369 | It creates a named accessor method in our class which returns a list of | ||||
| 2370 | all the matching Foreign::Class objects. | ||||
| 2371 | |||||
| 2372 | In addition it creates another method which allows a new associated object | ||||
| 2373 | to be constructed, taking care of the linking automatically. This method | ||||
| 2374 | is the same as the accessor method with "add_to_" prepended. | ||||
| 2375 | |||||
| 2376 | The add_to_tracks example above is exactly equivalent to: | ||||
| 2377 | |||||
| 2378 | my $track6 = Music::Track->insert({ | ||||
| 2379 | cd => $cd, | ||||
| 2380 | position => 6, | ||||
| 2381 | title => 'Tomorrow', | ||||
| 2382 | }); | ||||
| 2383 | |||||
| 2384 | When setting up the relationship the foreign class's has_a() declarations | ||||
| 2385 | are examined to discover which of its columns reference our class. (Note | ||||
| 2386 | that because this happens at compile time, if the foreign class is defined | ||||
| 2387 | in the same file, the class with the has_a() must be defined earlier than | ||||
| 2388 | the class with the has_many(). If the classes are in different files, | ||||
| 2389 | Class::DBI should usually be able to do the right things, as long as all | ||||
| 2390 | classes inherit Class::DBI before 'use'ing any other classes.) | ||||
| 2391 | |||||
| 2392 | If the foreign class has no has_a() declarations linking to this class, | ||||
| 2393 | it is assumed that the foreign key in that class is named after the | ||||
| 2394 | moniker() of this class. | ||||
| 2395 | |||||
| 2396 | If this is not true you can pass an additional third argument to | ||||
| 2397 | the has_many() declaration stating which column of the foreign class | ||||
| 2398 | is the foreign key to this class. | ||||
| 2399 | |||||
| 2400 | =head3 Limiting | ||||
| 2401 | |||||
| 2402 | Music::Artist->has_many(cds => 'Music::CD'); | ||||
| 2403 | my @cds = $artist->cds(year => 1980); | ||||
| 2404 | |||||
| 2405 | When calling the method created by has_many, you can also supply any | ||||
| 2406 | additional key/value pairs for restricting the search. The above example | ||||
| 2407 | will only return the CDs with a year of 1980. | ||||
| 2408 | |||||
| 2409 | =head3 Ordering | ||||
| 2410 | |||||
| 2411 | Music::CD->has_many(tracks => 'Music::Track', { order_by => 'playorder' }); | ||||
| 2412 | |||||
| 2413 | has_many takes an optional final hashref of options. If an 'order_by' | ||||
| 2414 | option is set, its value will be set in an ORDER BY clause in the SQL | ||||
| 2415 | issued. This is passed through 'as is', enabling order_by clauses such | ||||
| 2416 | as 'length DESC, position'. | ||||
| 2417 | |||||
| 2418 | =head3 Mapping | ||||
| 2419 | |||||
| 2420 | Music::CD->has_many(styles => [ 'Music::StyleRef' => 'style' ]); | ||||
| 2421 | |||||
| 2422 | If the second argument to has_many is turned into a listref of the | ||||
| 2423 | Classname and an additional method, then that method will be called in | ||||
| 2424 | turn on each of the objects being returned. | ||||
| 2425 | |||||
| 2426 | The above is exactly equivalent to: | ||||
| 2427 | |||||
| 2428 | Music::CD->has_many(_style_refs => 'Music::StyleRef'); | ||||
| 2429 | |||||
| 2430 | sub styles { | ||||
| 2431 | my $self = shift; | ||||
| 2432 | return map $_->style, $self->_style_refs; | ||||
| 2433 | } | ||||
| 2434 | |||||
| 2435 | For an example of where this is useful see L<"MANY TO MANY RELATIONSHIPS"> | ||||
| 2436 | below. | ||||
| 2437 | |||||
| 2438 | =head3 Cascading Delete | ||||
| 2439 | |||||
| 2440 | Music::Artist->has_many(cds => 'Music::CD', { cascade => 'Fail' }); | ||||
| 2441 | |||||
| 2442 | It is also possible to control what happens to the 'child' objects when | ||||
| 2443 | the 'parent' object is deleted. By default this is set to 'Delete' - so, | ||||
| 2444 | for example, when you delete an artist, you also delete all their CDs, | ||||
| 2445 | leaving no orphaned records. However you could also set this to 'None', | ||||
| 2446 | which would leave all those orphaned records (although this generally | ||||
| 2447 | isn't a good idea), or 'Fail', which will throw an exception when you | ||||
| 2448 | try to delete an artist that still has any CDs. | ||||
| 2449 | |||||
| 2450 | You can also write your own Cascade strategies by supplying a Class | ||||
| 2451 | Name here. | ||||
| 2452 | |||||
| 2453 | For example you could write a Class::DBI::Cascade::Plugin::Nullify | ||||
| 2454 | which would set all related foreign keys to be NULL, and plug it into | ||||
| 2455 | your relationship: | ||||
| 2456 | |||||
| 2457 | Music::Artist->has_many(cds => 'Music::CD', { | ||||
| 2458 | cascade => 'Class::DBI::Cascade::Plugin::Nullify' | ||||
| 2459 | }); | ||||
| 2460 | |||||
| 2461 | =head2 might_have | ||||
| 2462 | |||||
| 2463 | Music::CD->might_have(method_name => Class => (@fields_to_import)); | ||||
| 2464 | |||||
| 2465 | Music::CD->might_have(liner_notes => LinerNotes => qw/notes/); | ||||
| 2466 | |||||
| 2467 | my $liner_notes_object = $cd->liner_notes; | ||||
| 2468 | my $notes = $cd->notes; # equivalent to $cd->liner_notes->notes; | ||||
| 2469 | |||||
| 2470 | might_have() is similar to has_many() for relationships that can have | ||||
| 2471 | at most one associated objects. For example, if you have a CD database | ||||
| 2472 | to which you want to add liner notes information, you might not want | ||||
| 2473 | to add a 'liner_notes' column to your main CD table even though there | ||||
| 2474 | is no multiplicity of relationship involved (each CD has at most one | ||||
| 2475 | 'liner notes' field). So, you create another table with the same primary | ||||
| 2476 | key as this one, with which you can cross-reference. | ||||
| 2477 | |||||
| 2478 | But you don't want to have to keep writing methods to turn the the | ||||
| 2479 | 'list' of liner_notes objects you'd get back from has_many into the | ||||
| 2480 | single object you'd need. So, might_have() does this work for you. It | ||||
| 2481 | creates an accessor to fetch the single object back if it exists, and | ||||
| 2482 | it also allows you import any of its methods into your namespace. So, | ||||
| 2483 | in the example above, the LinerNotes class can be mostly invisible - | ||||
| 2484 | you can just call $cd->notes and it will call the notes method on the | ||||
| 2485 | correct LinerNotes object transparently for you. | ||||
| 2486 | |||||
| 2487 | Making sure you don't have namespace clashes is up to you, as is correctly | ||||
| 2488 | creating the objects, but this may be made simpler in later versions. | ||||
| 2489 | (Particularly if someone asks for this!) | ||||
| 2490 | |||||
| 2491 | =head2 Notes | ||||
| 2492 | |||||
| 2493 | has_a(), might_have() and has_many() check that the relevant class has | ||||
| 2494 | already been loaded. If it hasn't then they try to load the module of | ||||
| 2495 | the same name using require. If the require fails because it can't | ||||
| 2496 | find the module then it will assume it's not a simple require (i.e., | ||||
| 2497 | Foreign::Class isn't in Foreign/Class.pm) and that you will take care | ||||
| 2498 | of it and ignore the warning. Any other error, such as a syntax error, | ||||
| 2499 | triggers an exception. | ||||
| 2500 | |||||
| 2501 | NOTE: The two classes in a relationship do not have to be in the same | ||||
| 2502 | database, on the same machine, or even in the same type of database! It | ||||
| 2503 | is quite acceptable for a table in a MySQL database to be connected to | ||||
| 2504 | a different table in an Oracle database, and for cascading delete etc | ||||
| 2505 | to work across these. This should assist greatly if you need to migrate | ||||
| 2506 | a database gradually. | ||||
| 2507 | |||||
| 2508 | =head1 MANY TO MANY RELATIONSHIPS | ||||
| 2509 | |||||
| 2510 | Class::DBI does not currently support Many to Many relationships, per se. | ||||
| 2511 | However, by combining the relationships that already exist it is possible | ||||
| 2512 | to set these up. | ||||
| 2513 | |||||
| 2514 | Consider the case of Films and Actors, with a linking Role table with a | ||||
| 2515 | multi-column Primary Key. First of all set up the Role class: | ||||
| 2516 | |||||
| 2517 | Role->table('role'); | ||||
| 2518 | Role->columns(Primary => qw/film actor/); | ||||
| 2519 | Role->has_a(film => 'Film'); | ||||
| 2520 | Role->has_a(actor => 'Actor'); | ||||
| 2521 | |||||
| 2522 | Then, set up the Film and Actor classes to use this linking table: | ||||
| 2523 | |||||
| 2524 | Film->table('film'); | ||||
| 2525 | Film->columns(All => qw/id title rating/); | ||||
| 2526 | Film->has_many(stars => [ Role => 'actor' ]); | ||||
| 2527 | |||||
| 2528 | Actor->table('actor'); | ||||
| 2529 | Actor->columns(All => qw/id name/); | ||||
| 2530 | Actor->has_many(films => [ Role => 'film' ]); | ||||
| 2531 | |||||
| 2532 | In each case the 'mapping method' variation of has_many() is used to | ||||
| 2533 | call the lookup method on the Role object returned. As these methods are | ||||
| 2534 | the 'has_a' relationships on the Role, these will return the actual | ||||
| 2535 | Actor and Film objects, providing a cheap many-to-many relationship. | ||||
| 2536 | |||||
| 2537 | In the case of Film, this is equivalent to the more long-winded: | ||||
| 2538 | |||||
| 2539 | Film->has_many(roles => "Role"); | ||||
| 2540 | |||||
| 2541 | sub actors { | ||||
| 2542 | my $self = shift; | ||||
| 2543 | return map $_->actor, $self->roles | ||||
| 2544 | } | ||||
| 2545 | |||||
| 2546 | As this is almost exactly what is created internally, add_to_stars and | ||||
| 2547 | add_to_films will generally do the right thing as they are actually | ||||
| 2548 | doing the equivalent of add_to_roles: | ||||
| 2549 | |||||
| 2550 | $film->add_to_actors({ actor => $actor }); | ||||
| 2551 | |||||
| 2552 | Similarly a cascading delete will also do the right thing as it will | ||||
| 2553 | only delete the relationship from the linking table. | ||||
| 2554 | |||||
| 2555 | If the Role table were to contain extra information, such as the name | ||||
| 2556 | of the character played, then you would usually need to skip these | ||||
| 2557 | short-cuts and set up each of the relationships, and associated helper | ||||
| 2558 | methods, manually. | ||||
| 2559 | |||||
| 2560 | =head1 ADDING NEW RELATIONSHIP TYPES | ||||
| 2561 | |||||
| 2562 | =head2 add_relationship_type | ||||
| 2563 | |||||
| 2564 | The relationships described above are implemented through | ||||
| 2565 | Class::DBI::Relationship subclasses. These are then plugged into | ||||
| 2566 | Class::DBI through an add_relationship_type() call: | ||||
| 2567 | |||||
| 2568 | __PACKAGE__->add_relationship_type( | ||||
| 2569 | has_a => "Class::DBI::Relationship::HasA", | ||||
| 2570 | has_many => "Class::DBI::Relationship::HasMany", | ||||
| 2571 | might_have => "Class::DBI::Relationship::MightHave", | ||||
| 2572 | ); | ||||
| 2573 | |||||
| 2574 | If is thus possible to add new relationship types, or modify the behaviour | ||||
| 2575 | of the existing types. See L<Class::DBI::Relationship> for more information | ||||
| 2576 | on what is required. | ||||
| 2577 | |||||
| 2578 | =head1 DEFINING SQL STATEMENTS | ||||
| 2579 | |||||
| 2580 | There are several main approaches to setting up your own SQL queries: | ||||
| 2581 | |||||
| 2582 | For queries which could be used to create a list of matching objects | ||||
| 2583 | you can create a constructor method associated with this SQL and let | ||||
| 2584 | Class::DBI do the work for you, or just inline the entire query. | ||||
| 2585 | |||||
| 2586 | For more complex queries you need to fall back on the underlying Ima::DBI | ||||
| 2587 | query mechanism. (Caveat: since Ima::DBI uses sprintf-style interpolation, | ||||
| 2588 | you need to be careful to double any "wildcard" % signs in your queries). | ||||
| 2589 | |||||
| 2590 | =head2 add_constructor | ||||
| 2591 | |||||
| 2592 | __PACKAGE__->add_constructor(method_name => 'SQL_where_clause'); | ||||
| 2593 | |||||
| 2594 | The SQL can be of arbitrary complexity and will be turned into: | ||||
| 2595 | |||||
| 2596 | SELECT (essential columns) | ||||
| 2597 | FROM (table name) | ||||
| 2598 | WHERE <your SQL> | ||||
| 2599 | |||||
| 2600 | This will then create a method of the name you specify, which returns | ||||
| 2601 | a list of objects as with any built in query. | ||||
| 2602 | |||||
| 2603 | For example: | ||||
| 2604 | |||||
| 2605 | Music::CD->add_constructor(new_music => 'year > 2000'); | ||||
| 2606 | my @recent = Music::CD->new_music; | ||||
| 2607 | |||||
| 2608 | You can also supply placeholders in your SQL, which must then be | ||||
| 2609 | specified at query time: | ||||
| 2610 | |||||
| 2611 | Music::CD->add_constructor(new_music => 'year > ?'); | ||||
| 2612 | my @recent = Music::CD->new_music(2000); | ||||
| 2613 | |||||
| 2614 | =head2 retrieve_from_sql | ||||
| 2615 | |||||
| 2616 | On occasions where you want to execute arbitrary SQL, but don't want | ||||
| 2617 | to go to the trouble of setting up a constructor method, you can inline | ||||
| 2618 | the entire WHERE clause, and just get the objects back directly: | ||||
| 2619 | |||||
| 2620 | my @cds = Music::CD->retrieve_from_sql(qq{ | ||||
| 2621 | artist = 'Ozzy Osbourne' AND | ||||
| 2622 | title like "%Crazy" AND | ||||
| 2623 | year <= 1986 | ||||
| 2624 | ORDER BY year | ||||
| 2625 | LIMIT 2,3 | ||||
| 2626 | }); | ||||
| 2627 | |||||
| 2628 | =head2 Ima::DBI queries | ||||
| 2629 | |||||
| 2630 | When you can't use 'add_constructor', e.g. when using aggregate functions, | ||||
| 2631 | you can fall back on the fact that Class::DBI inherits from Ima::DBI | ||||
| 2632 | and prefers to use its style of dealing with statements, via set_sql(). | ||||
| 2633 | |||||
| 2634 | The Class::DBI set_sql() method defaults to using prepare_cached() | ||||
| 2635 | unless the $cache parameter is defined and false (see L<Ima::DBI> docs for | ||||
| 2636 | more information). | ||||
| 2637 | |||||
| 2638 | To assist with writing SQL that is inheritable into subclasses, several | ||||
| 2639 | additional substitutions are available here: __TABLE__, __ESSENTIAL__ | ||||
| 2640 | and __IDENTIFIER__. These represent the table name associated with the | ||||
| 2641 | class, its essential columns, and the primary key of the current object, | ||||
| 2642 | in the case of an instance method on it. | ||||
| 2643 | |||||
| 2644 | For example, the SQL for the internal 'update' method is implemented as: | ||||
| 2645 | |||||
| 2646 | __PACKAGE__->set_sql('update', <<""); | ||||
| 2647 | UPDATE __TABLE__ | ||||
| 2648 | SET %s | ||||
| 2649 | WHERE __IDENTIFIER__ | ||||
| 2650 | |||||
| 2651 | The 'longhand' version of the new_music constructor shown above would | ||||
| 2652 | similarly be: | ||||
| 2653 | |||||
| 2654 | Music::CD->set_sql(new_music => qq{ | ||||
| 2655 | SELECT __ESSENTIAL__ | ||||
| 2656 | FROM __TABLE__ | ||||
| 2657 | WHERE year > ? | ||||
| 2658 | }); | ||||
| 2659 | |||||
| 2660 | For such 'SELECT' queries L<Ima::DBI>'s set_sql() method is extended to | ||||
| 2661 | create a helper shortcut method, named by prefixing the name of the | ||||
| 2662 | SQL fragment with 'search_'. Thus, the above call to set_sql() will | ||||
| 2663 | automatically set up the method Music::CD->search_new_music(), which | ||||
| 2664 | will execute this search and return the relevant objects or Iterator. | ||||
| 2665 | (If there are placeholders in the query, you must pass the relevant | ||||
| 2666 | arguments when calling your search method.) | ||||
| 2667 | |||||
| 2668 | This does the equivalent of: | ||||
| 2669 | |||||
| 2670 | sub search_new_music { | ||||
| 2671 | my ($class, @args) = @_; | ||||
| 2672 | my $sth = $class->sql_new_music; | ||||
| 2673 | $sth->execute(@args); | ||||
| 2674 | return $class->sth_to_objects($sth); | ||||
| 2675 | } | ||||
| 2676 | |||||
| 2677 | The $sth which is used to return the objects here is a normal DBI-style | ||||
| 2678 | statement handle, so if the results can't be turned into objects easily, | ||||
| 2679 | it is still possible to call $sth->fetchrow_array etc and return whatever | ||||
| 2680 | data you choose. | ||||
| 2681 | |||||
| 2682 | Of course, any query can be added via set_sql, including joins. So, | ||||
| 2683 | to add a query that returns the 10 Artists with the most CDs, you could | ||||
| 2684 | write (with MySQL): | ||||
| 2685 | |||||
| 2686 | Music::Artist->set_sql(most_cds => qq{ | ||||
| 2687 | SELECT artist.id, COUNT(cd.id) AS cds | ||||
| 2688 | FROM artist, cd | ||||
| 2689 | WHERE artist.id = cd.artist | ||||
| 2690 | GROUP BY artist.id | ||||
| 2691 | ORDER BY cds DESC | ||||
| 2692 | LIMIT 10 | ||||
| 2693 | }); | ||||
| 2694 | |||||
| 2695 | my @artists = Music::Artist->search_most_cds(); | ||||
| 2696 | |||||
| 2697 | If you also need to access the 'cds' value returned from this query, | ||||
| 2698 | the best approach is to declare 'cds' to be a TEMP column. (See | ||||
| 2699 | L<"Non-Persistent Fields"> below). | ||||
| 2700 | |||||
| 2701 | =head2 Class::DBI::AbstractSearch | ||||
| 2702 | |||||
| 2703 | my @music = Music::CD->search_where( | ||||
| 2704 | artist => [ 'Ozzy', 'Kelly' ], | ||||
| 2705 | status => { '!=', 'outdated' }, | ||||
| 2706 | ); | ||||
| 2707 | |||||
| 2708 | The L<Class::DBI::AbstractSearch> module, available from CPAN, is a | ||||
| 2709 | plugin for Class::DBI that allows you to write arbitrarily complex | ||||
| 2710 | searches using perl data structures, rather than SQL. | ||||
| 2711 | |||||
| 2712 | =head2 Single Value SELECTs | ||||
| 2713 | |||||
| 2714 | =head3 select_val | ||||
| 2715 | |||||
| 2716 | Selects which only return a single value can couple Class::DBI's | ||||
| 2717 | sql_single() SQL, with the $sth->select_val() call which we get from | ||||
| 2718 | DBIx::ContextualFetch. | ||||
| 2719 | |||||
| 2720 | __PACKAGE__->set_sql(count_all => "SELECT COUNT(*) FROM __TABLE__"); | ||||
| 2721 | # .. then .. | ||||
| 2722 | my $count = $class->sql_count_all->select_val; | ||||
| 2723 | |||||
| 2724 | This can also take placeholders and/or do column interpolation if required: | ||||
| 2725 | |||||
| 2726 | __PACKAGE__->set_sql(count_above => q{ | ||||
| 2727 | SELECT COUNT(*) FROM __TABLE__ WHERE %s > ? | ||||
| 2728 | }); | ||||
| 2729 | # .. then .. | ||||
| 2730 | my $count = $class->sql_count_above('year')->select_val(2001); | ||||
| 2731 | |||||
| 2732 | =head3 sql_single | ||||
| 2733 | |||||
| 2734 | Internally Class::DBI defines a very simple SQL fragment called 'single': | ||||
| 2735 | |||||
| 2736 | "SELECT %s FROM __TABLE__". | ||||
| 2737 | |||||
| 2738 | This is used to implement the above Class->count_all(): | ||||
| 2739 | |||||
| 2740 | $class->sql_single("COUNT(*)")->select_val; | ||||
| 2741 | |||||
| 2742 | This interpolates the COUNT(*) into the %s of the SQL, and then executes | ||||
| 2743 | the query, returning a single value. | ||||
| 2744 | |||||
| 2745 | Any SQL set up via set_sql() can of course be supplied here, and | ||||
| 2746 | select_val can take arguments for any placeholders there. | ||||
| 2747 | |||||
| 2748 | Internally several helper methods are defined using this approach: | ||||
| 2749 | |||||
| 2750 | =over 4 | ||||
| 2751 | |||||
| 2752 | =item - count_all | ||||
| 2753 | |||||
| 2754 | =item - maximum_value_of($column) | ||||
| 2755 | |||||
| 2756 | =item - minimum_value_of($column) | ||||
| 2757 | |||||
| 2758 | =back | ||||
| 2759 | |||||
| 2760 | =head1 LAZY POPULATION | ||||
| 2761 | |||||
| 2762 | In the tradition of Perl, Class::DBI is lazy about how it loads your | ||||
| 2763 | objects. Often, you find yourself using only a small number of the | ||||
| 2764 | available columns and it would be a waste of memory to load all of them | ||||
| 2765 | just to get at two, especially if you're dealing with large numbers of | ||||
| 2766 | objects simultaneously. | ||||
| 2767 | |||||
| 2768 | You should therefore group together your columns by typical usage, as | ||||
| 2769 | fetching one value from a group can also pre-fetch all the others in | ||||
| 2770 | that group for you, for more efficient access. | ||||
| 2771 | |||||
| 2772 | So for example, if we usually fetch the artist and title, but don't use | ||||
| 2773 | the 'year' so much, then we could say the following: | ||||
| 2774 | |||||
| 2775 | Music::CD->columns(Primary => qw/cdid/); | ||||
| 2776 | Music::CD->columns(Essential => qw/artist title/); | ||||
| 2777 | Music::CD->columns(Others => qw/year runlength/); | ||||
| 2778 | |||||
| 2779 | Now when you fetch back a CD it will come pre-loaded with the 'cdid', | ||||
| 2780 | 'artist' and 'title' fields. Fetching the 'year' will mean another visit | ||||
| 2781 | to the database, but will bring back the 'runlength' whilst it's there. | ||||
| 2782 | |||||
| 2783 | This can potentially increase performance. | ||||
| 2784 | |||||
| 2785 | If you don't like this behavior, then just add all your columns to the | ||||
| 2786 | Essential group, and Class::DBI will load everything at once. If you | ||||
| 2787 | have a single column primary key you can do this all in one shot with | ||||
| 2788 | one single column declaration: | ||||
| 2789 | |||||
| 2790 | Music::CD->columns(Essential => qw/cdid artist title year runlength/); | ||||
| 2791 | |||||
| 2792 | =head2 columns | ||||
| 2793 | |||||
| 2794 | my @all_columns = $class->columns; | ||||
| 2795 | my @columns = $class->columns($group); | ||||
| 2796 | |||||
| 2797 | my @primary = $class->primary_columns; | ||||
| 2798 | my $primary = $class->primary_column; | ||||
| 2799 | my @essential = $class->_essential; | ||||
| 2800 | |||||
| 2801 | There are four 'reserved' groups: 'All', 'Essential', 'Primary' and | ||||
| 2802 | 'TEMP'. | ||||
| 2803 | |||||
| 2804 | B<'All'> are all columns used by the class. If not set it will be | ||||
| 2805 | created from all the other groups. | ||||
| 2806 | |||||
| 2807 | B<'Primary'> is the primary key columns for this class. It I<must> | ||||
| 2808 | be set before objects can be used. | ||||
| 2809 | |||||
| 2810 | If 'All' is given but not 'Primary' it will assume the first column in | ||||
| 2811 | 'All' is the primary key. | ||||
| 2812 | |||||
| 2813 | B<'Essential'> are the minimal set of columns needed to load and use the | ||||
| 2814 | object. Only the columns in this group will be loaded when an object | ||||
| 2815 | is retrieve()'d. It is typically used to save memory on a class that | ||||
| 2816 | has a lot of columns but where only use a few of them are commonly | ||||
| 2817 | used. It will automatically be set to B<'Primary'> if not explicitly set. | ||||
| 2818 | The 'Primary' column is always part of the 'Essential' group. | ||||
| 2819 | |||||
| 2820 | For simplicity primary_columns(), primary_column(), and _essential() | ||||
| 2821 | methods are provided to return these. The primary_column() method should | ||||
| 2822 | only be used for tables that have a single primary key column. | ||||
| 2823 | |||||
| 2824 | =head2 Non-Persistent Fields | ||||
| 2825 | |||||
| 2826 | Music::CD->columns(TEMP => qw/nonpersistent/); | ||||
| 2827 | |||||
| 2828 | If you wish to have fields that act like columns in every other way, but | ||||
| 2829 | that don't actually exist in the database (and thus will not persist), | ||||
| 2830 | you can declare them as part of a column group of 'TEMP'. | ||||
| 2831 | |||||
| 2832 | =head2 find_column | ||||
| 2833 | |||||
| 2834 | Class->find_column($column); | ||||
| 2835 | $obj->find_column($column); | ||||
| 2836 | |||||
| 2837 | The columns of a class are stored as Class::DBI::Column objects. This | ||||
| 2838 | method will return you the object for the given column, if it exists. | ||||
| 2839 | This is most useful either in a boolean context to discover if the column | ||||
| 2840 | exists, or to 'normalize' a user-entered column name to an actual Column. | ||||
| 2841 | |||||
| 2842 | The interface of the Column object itself is still under development, | ||||
| 2843 | so you shouldn't really rely on anything internal to it. | ||||
| 2844 | |||||
| 2845 | =head1 TRANSACTIONS | ||||
| 2846 | |||||
| 2847 | Class::DBI suffers from the usual problems when dealing with transactions. | ||||
| 2848 | In particular, you should be very wary when committing your changes that | ||||
| 2849 | you may actually be in a wider scope than expected and that your caller | ||||
| 2850 | may not be expecting you to commit. | ||||
| 2851 | |||||
| 2852 | However, as long as you are aware of this, and try to keep the scope | ||||
| 2853 | of your transactions small, ideally always within the scope of a single | ||||
| 2854 | method, you should be able to work with transactions with few problems. | ||||
| 2855 | |||||
| 2856 | =head2 dbi_commit / dbi_rollback | ||||
| 2857 | |||||
| 2858 | $obj->dbi_commit(); | ||||
| 2859 | $obj->dbi_rollback(); | ||||
| 2860 | |||||
| 2861 | These are thin aliases through to the DBI's commit() and rollback() | ||||
| 2862 | commands to commit or rollback all changes to this object. | ||||
| 2863 | |||||
| 2864 | =head2 Localised Transactions | ||||
| 2865 | |||||
| 2866 | A nice idiom for turning on a transaction locally (with AutoCommit turned | ||||
| 2867 | on globally) (courtesy of Dominic Mitchell) is: | ||||
| 2868 | |||||
| 2869 | sub do_transaction { | ||||
| 2870 | my $class = shift; | ||||
| 2871 | my ( $code ) = @_; | ||||
| 2872 | # Turn off AutoCommit for this scope. | ||||
| 2873 | # A commit will occur at the exit of this block automatically, | ||||
| 2874 | # when the local AutoCommit goes out of scope. | ||||
| 2875 | local $class->db_Main->{ AutoCommit }; | ||||
| 2876 | |||||
| 2877 | # Execute the required code inside the transaction. | ||||
| 2878 | eval { $code->() }; | ||||
| 2879 | if ( $@ ) { | ||||
| 2880 | my $commit_error = $@; | ||||
| 2881 | eval { $class->dbi_rollback }; # might also die! | ||||
| 2882 | die $commit_error; | ||||
| 2883 | } | ||||
| 2884 | } | ||||
| 2885 | |||||
| 2886 | And then you just call: | ||||
| 2887 | |||||
| 2888 | Music::DBI->do_transaction( sub { | ||||
| 2889 | my $artist = Music::Artist->insert({ name => 'Pink Floyd' }); | ||||
| 2890 | my $cd = $artist->add_to_cds({ | ||||
| 2891 | title => 'Dark Side Of The Moon', | ||||
| 2892 | year => 1974, | ||||
| 2893 | }); | ||||
| 2894 | }); | ||||
| 2895 | |||||
| 2896 | Now either both will get added, or the entire transaction will be | ||||
| 2897 | rolled back. | ||||
| 2898 | |||||
| 2899 | =head1 UNIQUENESS OF OBJECTS IN MEMORY | ||||
| 2900 | |||||
| 2901 | Class::DBI supports uniqueness of objects in memory. In a given perl | ||||
| 2902 | interpreter there will only be one instance of any given object at | ||||
| 2903 | one time. Many variables may reference that object, but there can be | ||||
| 2904 | only one. | ||||
| 2905 | |||||
| 2906 | Here's an example to illustrate: | ||||
| 2907 | |||||
| 2908 | my $artist1 = Music::Artist->insert({ artistid => 7, name => 'Polysics' }); | ||||
| 2909 | my $artist2 = Music::Artist->retrieve(7); | ||||
| 2910 | my $artist3 = Music::Artist->search( name => 'Polysics' )->first; | ||||
| 2911 | |||||
| 2912 | Now $artist1, $artist2, and $artist3 all point to the same object. If you | ||||
| 2913 | update a property on one of them, all of them will reflect the update. | ||||
| 2914 | |||||
| 2915 | This is implemented using a simple object lookup index for all live | ||||
| 2916 | objects in memory. It is not a traditional cache - when your objects | ||||
| 2917 | go out of scope, they will be destroyed normally, and a future retrieve | ||||
| 2918 | will instantiate an entirely new object. | ||||
| 2919 | |||||
| 2920 | The ability to perform this magic for you replies on your perl having | ||||
| 2921 | access to the Scalar::Util::weaken function. Although this is part of | ||||
| 2922 | the core perl distribution, some vendors do not compile support for it. | ||||
| 2923 | To find out if your perl has support for it, you can run this on the | ||||
| 2924 | command line: | ||||
| 2925 | |||||
| 2926 | perl -e 'use Scalar::Util qw(weaken)' | ||||
| 2927 | |||||
| 2928 | If you get an error message about weak references not being implemented, | ||||
| 2929 | Class::DBI will not maintain this lookup index, but give you a separate | ||||
| 2930 | instances for each retrieve. | ||||
| 2931 | |||||
| 2932 | A few new tools are offered for adjusting the behavior of the object | ||||
| 2933 | index. These are still somewhat experimental and may change in a | ||||
| 2934 | future release. | ||||
| 2935 | |||||
| 2936 | =head2 remove_from_object_index | ||||
| 2937 | |||||
| 2938 | $artist->remove_from_object_index(); | ||||
| 2939 | |||||
| 2940 | This is an object method for removing a single object from the live | ||||
| 2941 | objects index. You can use this if you want to have multiple distinct | ||||
| 2942 | copies of the same object in memory. | ||||
| 2943 | |||||
| 2944 | =head2 clear_object_index | ||||
| 2945 | |||||
| 2946 | Music::DBI->clear_object_index(); | ||||
| 2947 | |||||
| 2948 | You can call this method on any class or instance of Class::DBI, but | ||||
| 2949 | the effect is universal: it removes all objects from the index. | ||||
| 2950 | |||||
| 2951 | =head2 purge_object_index_every | ||||
| 2952 | |||||
| 2953 | Music::Artist->purge_object_index_every(2000); | ||||
| 2954 | |||||
| 2955 | Weak references are not removed from the index when an object goes | ||||
| 2956 | out of scope. This means that over time the index will grow in memory. | ||||
| 2957 | This is really only an issue for long-running environments like mod_perl, | ||||
| 2958 | but every so often dead references are cleaned out to prevent this. By | ||||
| 2959 | default, this happens every 1000 object loads, but you can change that | ||||
| 2960 | default for your class by setting the 'purge_object_index_every' value. | ||||
| 2961 | |||||
| 2962 | (Eventually this may handled in the DESTROY method instead.) | ||||
| 2963 | |||||
| 2964 | As a final note, keep in mind that you can still have multiple distinct | ||||
| 2965 | copies of an object in memory if you have multiple perl interpreters | ||||
| 2966 | running. CGI, mod_perl, and many other common usage situations run | ||||
| 2967 | multiple interpreters, meaning that each one of them may have an instance | ||||
| 2968 | of an object representing the same data. However, this is no worse | ||||
| 2969 | than it was before, and is entirely normal for database applications in | ||||
| 2970 | multi-process environments. | ||||
| 2971 | |||||
| 2972 | =head1 SUBCLASSING | ||||
| 2973 | |||||
| 2974 | The preferred method of interacting with Class::DBI is for you to write | ||||
| 2975 | a subclass for your database connection, with each table-class inheriting | ||||
| 2976 | in turn from it. | ||||
| 2977 | |||||
| 2978 | As well as encapsulating the connection information in one place, | ||||
| 2979 | this also allows you to override default behaviour or add additional | ||||
| 2980 | functionality across all of your classes. | ||||
| 2981 | |||||
| 2982 | As the innards of Class::DBI are still in flux, you must exercise extreme | ||||
| 2983 | caution in overriding private methods of Class::DBI (those starting with | ||||
| 2984 | an underscore), unless they are explicitly mentioned in this documentation | ||||
| 2985 | as being safe to override. If you find yourself needing to do this, | ||||
| 2986 | then I would suggest that you ask on the mailing list about it, and | ||||
| 2987 | we'll see if we can either come up with a better approach, or provide | ||||
| 2988 | a new means to do whatever you need to do. | ||||
| 2989 | |||||
| 2990 | =head1 CAVEATS | ||||
| 2991 | |||||
| 2992 | =head2 Multi-Column Foreign Keys are not supported | ||||
| 2993 | |||||
| 2994 | You can't currently add a relationship keyed on multiple columns. | ||||
| 2995 | You could, however, write a Relationship plugin to do this, and the | ||||
| 2996 | world would be eternally grateful... | ||||
| 2997 | |||||
| 2998 | =head2 Don't change or inflate the value of your primary columns | ||||
| 2999 | |||||
| 3000 | Altering your primary key column currently causes Bad Things to happen. | ||||
| 3001 | I should really protect against this. | ||||
| 3002 | |||||
| 3003 | =head1 SUPPORTED DATABASES | ||||
| 3004 | |||||
| 3005 | Theoretically Class::DBI should work with almost any standard RDBMS. Of | ||||
| 3006 | course, in the real world, we know that that's not true. It is known | ||||
| 3007 | to work with MySQL, PostgreSQL, Oracle and SQLite, each of which have | ||||
| 3008 | their own additional subclass on CPAN that you should explore if you're | ||||
| 3009 | using them: | ||||
| 3010 | |||||
| 3011 | L<Class::DBI::mysql>, L<Class::DBI::Pg>, L<Class::DBI::Oracle>, | ||||
| 3012 | L<Class::DBI::SQLite> | ||||
| 3013 | |||||
| 3014 | For the most part it's been reported to work with Sybase, although there | ||||
| 3015 | are some issues with multi-case column/table names. Beyond that lies | ||||
| 3016 | The Great Unknown(tm). If you have access to other databases, please | ||||
| 3017 | give this a test run, and let me know the results. | ||||
| 3018 | |||||
| 3019 | L<Ima::DBI> (and hence Class::DBI) requires a database that supports | ||||
| 3020 | table aliasing and a DBI driver that supports placeholders. This means | ||||
| 3021 | it won't work with older releases of L<DBD::AnyData> (and any releases | ||||
| 3022 | of its predecessor L<DBD::RAM>), and L<DBD::Sybase> + FreeTDS may or | ||||
| 3023 | may not work depending on your FreeTDS version. | ||||
| 3024 | |||||
| 3025 | =head1 CURRENT AUTHOR | ||||
| 3026 | |||||
| 3027 | Tony Bowden | ||||
| 3028 | |||||
| 3029 | =head1 AUTHOR EMERITUS | ||||
| 3030 | |||||
| 3031 | Michael G Schwern | ||||
| 3032 | |||||
| 3033 | =head1 THANKS TO | ||||
| 3034 | |||||
| 3035 | Tim Bunce, Tatsuhiko Miyagawa, Perrin Harkins, Alexander Karelas, Barry | ||||
| 3036 | Hoggard, Bart Lateur, Boris Mouzykantskii, Brad Bowman, Brian Parker, | ||||
| 3037 | Casey West, Charles Bailey, Christopher L. Everett Damian Conway, Dan | ||||
| 3038 | Thill, Dave Cash, David Jack Olrik, Dominic Mitchell, Drew Taylor, | ||||
| 3039 | Drew Wilson, Jay Strauss, Jesse Sheidlower, Jonathan Swartz, Marty | ||||
| 3040 | Pauley, Michael Styer, Mike Lambert, Paul Makepeace, Phil Crow, Richard | ||||
| 3041 | Piacentini, Simon Cozens, Simon Wilcox, Thomas Klausner, Tom Renfro, | ||||
| 3042 | Uri Gutman, William McKee, the Class::DBI mailing list, the POOP group, | ||||
| 3043 | and all the others who've helped, but that I've forgetten to mention. | ||||
| 3044 | |||||
| 3045 | =head1 RELEASE PHILOSOPHY | ||||
| 3046 | |||||
| 3047 | Class::DBI now uses a three-level versioning system. This release, for | ||||
| 3048 | example, is version 3.0.17 | ||||
| 3049 | |||||
| 3050 | The general approach to releases will be that users who like a degree of | ||||
| 3051 | stability can hold off on upgrades until the major sub-version increases | ||||
| 3052 | (e.g. 3.1.0). Those who like living more on the cutting edge can keep up | ||||
| 3053 | to date with minor sub-version releases. | ||||
| 3054 | |||||
| 3055 | Functionality which was introduced during a minor sub-version release may | ||||
| 3056 | disappear without warning in a later minor sub-version release. I'll try | ||||
| 3057 | to avoid doing this, and will aim to have a deprecation cycle of at least | ||||
| 3058 | a few minor sub-versions, but you should keep a close eye on the CHANGES | ||||
| 3059 | file, and have good tests in place. (This is good advice generally, | ||||
| 3060 | of course.) Anything that is in a major sub-version release will go | ||||
| 3061 | through a deprecation cycle of at least one further major sub-version | ||||
| 3062 | before it is removed (and usually longer). | ||||
| 3063 | |||||
| 3064 | =head2 Getting changes accepted | ||||
| 3065 | |||||
| 3066 | There is an active Class::DBI community, however I am not part of it. | ||||
| 3067 | I am not on the mailing list, and I don't follow the wiki. I also do | ||||
| 3068 | not follow Perl Monks or CPAN reviews or annoCPAN or whatever the tool | ||||
| 3069 | du jour happens to be. | ||||
| 3070 | |||||
| 3071 | If you find a problem with Class::DBI, by all means discuss it in any of | ||||
| 3072 | these places, but don't expect anything to happen unless you actually | ||||
| 3073 | tell me about it. | ||||
| 3074 | |||||
| 3075 | The preferred method for doing this is via the CPAN RT interface, which | ||||
| 3076 | you can access at http://rt.cpan.org/ or by emailing | ||||
| 3077 | bugs-Class-DBI@rt.cpan.org | ||||
| 3078 | |||||
| 3079 | If you email me personally about Class::DBI issues, then I will | ||||
| 3080 | probably bounce them on to there, unless you specifically ask me not to. | ||||
| 3081 | Otherwise I can't keep track of what all needs fixed. (This of course | ||||
| 3082 | means that if you ask me not to send your mail to RT, there's a much | ||||
| 3083 | higher chance that nothing will every happen about your problem). | ||||
| 3084 | |||||
| 3085 | =head2 Bug Reports | ||||
| 3086 | |||||
| 3087 | If you're reporting a bug then it has a much higher chance of getting | ||||
| 3088 | fixed quicker if you can include a failing test case. This should be | ||||
| 3089 | a completely stand-alone test that could be added to the Class::DBI | ||||
| 3090 | distribution. That is, it should use L<Test::Simple> or L<Test::More>, | ||||
| 3091 | fail with the current code, but pass when I fix the problem. If it | ||||
| 3092 | needs to have a working database to show the problem, then this should | ||||
| 3093 | preferably use SQLite, and come with all the code to set this up. The | ||||
| 3094 | nice people on the mailing list will probably help you out if you need | ||||
| 3095 | assistance putting this together. | ||||
| 3096 | |||||
| 3097 | You don't need to include code for actually fixing the problem, but of | ||||
| 3098 | course it's often nice if you can. I may choose to fix it in a different | ||||
| 3099 | way, however, so it's often better to ask first whether I'd like a | ||||
| 3100 | patch, particularly before spending a lot of time hacking. | ||||
| 3101 | |||||
| 3102 | =head2 Patches | ||||
| 3103 | |||||
| 3104 | If you are sending patches, then please send either the entire code | ||||
| 3105 | that is being changed or the output of 'diff -Bub'. Please also note | ||||
| 3106 | what version the patch is against. I tend to apply all patches manually, | ||||
| 3107 | so I'm more interested in being able to see what you're doing than in | ||||
| 3108 | being able to apply the patch cleanly. Code formatting isn't an issue, | ||||
| 3109 | as I automagically run perltidy against the source after any changes, | ||||
| 3110 | so please format for clarity. | ||||
| 3111 | |||||
| 3112 | Patches have a much better chance of being applied if they are small. | ||||
| 3113 | People often think that it's better for me to get one patch with a bunch | ||||
| 3114 | of fixes. It's not. I'd much rather get 100 small patches that can be | ||||
| 3115 | applied one by one. A change that I can make and release in five minutes | ||||
| 3116 | is always better than one that needs a couple of hours to ponder and work | ||||
| 3117 | through. | ||||
| 3118 | |||||
| 3119 | I often reject patches that I don't like. Please don't take it personally. | ||||
| 3120 | I also like time to think about the wider implications of changes. Often | ||||
| 3121 | a I<lot> of time. Feel free to remind me about things that I may have | ||||
| 3122 | forgotten about, but as long as they're on rt.cpan.org I will get around | ||||
| 3123 | to them eventually. | ||||
| 3124 | |||||
| 3125 | =head2 Feature Requests | ||||
| 3126 | |||||
| 3127 | Wish-list requests are fine, although you should probably discuss them | ||||
| 3128 | on the mailing list (or equivalent) with others first. There's quite | ||||
| 3129 | often a plugin somewhere that already does what you want. | ||||
| 3130 | |||||
| 3131 | In general I am much more open to discussion on how best to provide the | ||||
| 3132 | flexibility for you to make your Cool New Feature(tm) a plugin rather | ||||
| 3133 | than adding it to Class::DBI itself. | ||||
| 3134 | |||||
| 3135 | For the most part the core of Class::DBI already has most of the | ||||
| 3136 | functionality that I believe it will ever need (and some more besides, | ||||
| 3137 | that will probably be split off at some point). Most other things are much | ||||
| 3138 | better off as plugins, with a separate life on CPAN or elsewhere (and with | ||||
| 3139 | me nowhere near the critical path). Most of the ongoing work on Class::DBI | ||||
| 3140 | is about making life easier for people to write extensions - whether | ||||
| 3141 | they're local to your own codebase or released for wider consumption. | ||||
| 3142 | |||||
| 3143 | =head1 SUPPORT | ||||
| 3144 | |||||
| 3145 | Support for Class::DBI is mostly via the mailing list. | ||||
| 3146 | |||||
| 3147 | To join the list, or read the archives, visit | ||||
| 3148 | http://lists.digitalcraftsmen.net/mailman/listinfo/classdbi | ||||
| 3149 | |||||
| 3150 | There is also a Class::DBI wiki at | ||||
| 3151 | http://www.class-dbi.com/ | ||||
| 3152 | |||||
| 3153 | The wiki contains much information that should probably be in these docs | ||||
| 3154 | but isn't yet. (See above if you want to help to rectify this.) | ||||
| 3155 | |||||
| 3156 | As mentioned above, I don't follow the list or the wiki, so if you want | ||||
| 3157 | to contact me individually, then you'll have to track me down personally. | ||||
| 3158 | |||||
| 3159 | There are lots of 3rd party subclasses and plugins available. | ||||
| 3160 | For a list of the ones on CPAN see: | ||||
| 3161 | http://search.cpan.org/search?query=Class%3A%3ADBI&mode=module | ||||
| 3162 | |||||
| 3163 | An article on Class::DBI was published on Perl.com a while ago. It's | ||||
| 3164 | slightly out of date , but it's a good introduction: | ||||
| 3165 | http://www.perl.com/pub/a/2002/11/27/classdbi.html | ||||
| 3166 | |||||
| 3167 | The wiki has numerous references to other articles, presentations etc. | ||||
| 3168 | |||||
| 3169 | http://poop.sourceforge.net/ provides a document comparing a variety | ||||
| 3170 | of different approaches to database persistence, such as Class::DBI, | ||||
| 3171 | Alazabo, Tangram, SPOPS etc. | ||||
| 3172 | |||||
| 3173 | =head1 LICENSE | ||||
| 3174 | |||||
| 3175 | This library is free software; you can redistribute it and/or modify | ||||
| 3176 | it under the same terms as Perl itself. | ||||
| 3177 | |||||
| 3178 | =head1 SEE ALSO | ||||
| 3179 | |||||
| 3180 | Class::DBI is built on top of L<Ima::DBI>, L<DBIx::ContextualFetch>, | ||||
| 3181 | L<Class::Accessor> and L<Class::Data::Inheritable>. The innards and | ||||
| 3182 | much of the interface are easier to understand if you have an idea of | ||||
| 3183 | how they all work as well. | ||||
| 3184 | |||||
| 3185 | =cut | ||||
| 3186 | |||||
# spent 127µs within Class::DBI::CORE:match which was called 14 times, avg 9µs/call:
# 13 times (115µs+0s) by Class::DBI::set_sql at line 934 of Class/DBI.pm, avg 9µs/call
# once (12µs+0s) by Class::DBI::set_db at line 210 of Class/DBI.pm | |||||
# spent 2.61ms within Class::DBI::CORE:sort which was called 461 times, avg 6µs/call:
# 461 times (2.61ms+0s) by Class::DBI::_live_object_key at line 527 of Class/DBI.pm, avg 6µs/call | |||||
# spent 136µs within Class::DBI::CORE:subst which was called 9 times, avg 15µs/call:
# 9 times (136µs+0s) by Class::DBI::_require_class at line 1222 of Class/DBI.pm, avg 15µs/call |