Implemented "add_unique_constraints".
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSource.pm
1 package DBIx::Class::ResultSource;
2
3 use strict;
4 use warnings;
5
6 use DBIx::Class::ResultSet;
7 use DBIx::Class::ResultSourceHandle;
8
9 use DBIx::Class::Exception;
10 use Carp::Clan qw/^DBIx::Class/;
11 use Try::Tiny;
12 use List::Util 'first';
13 use namespace::clean;
14
15 use base qw/DBIx::Class/;
16
17 __PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
18   _columns _primaries _unique_constraints name resultset_attributes
19   schema from _relationships column_info_from_storage source_info
20   source_name sqlt_deploy_callback/);
21
22 __PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
23   result_class/);
24
25 =head1 NAME
26
27 DBIx::Class::ResultSource - Result source object
28
29 =head1 SYNOPSIS
30
31   # Create a table based result source, in a result class.
32
33   package MyDB::Schema::Result::Artist;
34   use base qw/DBIx::Class::Core/;
35
36   __PACKAGE__->table('artist');
37   __PACKAGE__->add_columns(qw/ artistid name /);
38   __PACKAGE__->set_primary_key('artistid');
39   __PACKAGE__->has_many(cds => 'MyDB::Schema::Result::CD');
40
41   1;
42
43   # Create a query (view) based result source, in a result class
44   package MyDB::Schema::Result::Year2000CDs;
45   use base qw/DBIx::Class::Core/;
46
47   __PACKAGE__->load_components('InflateColumn::DateTime');
48   __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
49
50   __PACKAGE__->table('year2000cds');
51   __PACKAGE__->result_source_instance->is_virtual(1);
52   __PACKAGE__->result_source_instance->view_definition(
53       "SELECT cdid, artist, title FROM cd WHERE year ='2000'"
54       );
55
56
57 =head1 DESCRIPTION
58
59 A ResultSource is an object that represents a source of data for querying.
60
61 This class is a base class for various specialised types of result
62 sources, for example L<DBIx::Class::ResultSource::Table>. Table is the
63 default result source type, so one is created for you when defining a
64 result class as described in the synopsis above.
65
66 More specifically, the L<DBIx::Class::Core> base class pulls in the
67 L<DBIx::Class::ResultSourceProxy::Table> component, which defines
68 the L<table|DBIx::Class::ResultSourceProxy::Table/table> method.
69 When called, C<table> creates and stores an instance of
70 L<DBIx::Class::ResultSoure::Table>. Luckily, to use tables as result
71 sources, you don't need to remember any of this.
72
73 Result sources representing select queries, or views, can also be
74 created, see L<DBIx::Class::ResultSource::View> for full details.
75
76 =head2 Finding result source objects
77
78 As mentioned above, a result source instance is created and stored for
79 you when you define a L<Result Class|DBIx::Class::Manual::Glossary/Result Class>.
80
81 You can retrieve the result source at runtime in the following ways:
82
83 =over
84
85 =item From a Schema object:
86
87    $schema->source($source_name);
88
89 =item From a Row object:
90
91    $row->result_source;
92
93 =item From a ResultSet object:
94
95    $rs->result_source;
96
97 =back
98
99 =head1 METHODS
100
101 =pod
102
103 =cut
104
105 sub new {
106   my ($class, $attrs) = @_;
107   $class = ref $class if ref $class;
108
109   my $new = bless { %{$attrs || {}} }, $class;
110   $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
111   $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
112   $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
113   $new->{_columns} = { %{$new->{_columns}||{}} };
114   $new->{_relationships} = { %{$new->{_relationships}||{}} };
115   $new->{name} ||= "!!NAME NOT SET!!";
116   $new->{_columns_info_loaded} ||= 0;
117   $new->{sqlt_deploy_callback} ||= "default_sqlt_deploy_hook";
118   return $new;
119 }
120
121 =pod
122
123 =head2 add_columns
124
125 =over
126
127 =item Arguments: @columns
128
129 =item Return value: The ResultSource object
130
131 =back
132
133   $source->add_columns(qw/col1 col2 col3/);
134
135   $source->add_columns('col1' => \%col1_info, 'col2' => \%col2_info, ...);
136
137 Adds columns to the result source. If supplied colname => hashref
138 pairs, uses the hashref as the L</column_info> for that column. Repeated
139 calls of this method will add more columns, not replace them.
140
141 The column names given will be created as accessor methods on your
142 L<DBIx::Class::Row> objects. You can change the name of the accessor
143 by supplying an L</accessor> in the column_info hash.
144
145 If a column name beginning with a plus sign ('+col1') is provided, the
146 attributes provided will be merged with any existing attributes for the
147 column, with the new attributes taking precedence in the case that an
148 attribute already exists. Using this without a hashref
149 (C<< $source->add_columns(qw/+col1 +col2/) >>) is legal, but useless --
150 it does the same thing it would do without the plus.
151
152 The contents of the column_info are not set in stone. The following
153 keys are currently recognised/used by DBIx::Class:
154
155 =over 4
156
157 =item accessor
158
159    { accessor => '_name' }
160
161    # example use, replace standard accessor with one of your own:
162    sub name {
163        my ($self, $value) = @_;
164
165        die "Name cannot contain digits!" if($value =~ /\d/);
166        $self->_name($value);
167
168        return $self->_name();
169    }
170
171 Use this to set the name of the accessor method for this column. If unset,
172 the name of the column will be used.
173
174 =item data_type
175
176    { data_type => 'integer' }
177
178 This contains the column type. It is automatically filled if you use the
179 L<SQL::Translator::Producer::DBIx::Class::File> producer, or the
180 L<DBIx::Class::Schema::Loader> module.
181
182 Currently there is no standard set of values for the data_type. Use
183 whatever your database supports.
184
185 =item size
186
187    { size => 20 }
188
189 The length of your column, if it is a column type that can have a size
190 restriction. This is currently only used to create tables from your
191 schema, see L<DBIx::Class::Schema/deploy>.
192
193 =item is_nullable
194
195    { is_nullable => 1 }
196
197 Set this to a true value for a columns that is allowed to contain NULL
198 values, default is false. This is currently only used to create tables
199 from your schema, see L<DBIx::Class::Schema/deploy>.
200
201 =item is_auto_increment
202
203    { is_auto_increment => 1 }
204
205 Set this to a true value for a column whose value is somehow
206 automatically set, defaults to false. This is used to determine which
207 columns to empty when cloning objects using
208 L<DBIx::Class::Row/copy>. It is also used by
209 L<DBIx::Class::Schema/deploy>.
210
211 =item is_numeric
212
213    { is_numeric => 1 }
214
215 Set this to a true or false value (not C<undef>) to explicitly specify
216 if this column contains numeric data. This controls how set_column
217 decides whether to consider a column dirty after an update: if
218 C<is_numeric> is true a numeric comparison C<< != >> will take place
219 instead of the usual C<eq>
220
221 If not specified the storage class will attempt to figure this out on
222 first access to the column, based on the column C<data_type>. The
223 result will be cached in this attribute.
224
225 =item is_foreign_key
226
227    { is_foreign_key => 1 }
228
229 Set this to a true value for a column that contains a key from a
230 foreign table, defaults to false. This is currently only used to
231 create tables from your schema, see L<DBIx::Class::Schema/deploy>.
232
233 =item default_value
234
235    { default_value => \'now()' }
236
237 Set this to the default value which will be inserted into a column by
238 the database. Can contain either a value or a function (use a
239 reference to a scalar e.g. C<\'now()'> if you want a function). This
240 is currently only used to create tables from your schema, see
241 L<DBIx::Class::Schema/deploy>.
242
243 See the note on L<DBIx::Class::Row/new> for more information about possible
244 issues related to db-side default values.
245
246 =item sequence
247
248    { sequence => 'my_table_seq' }
249
250 Set this on a primary key column to the name of the sequence used to
251 generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
252 will attempt to retrieve the name of the sequence from the database
253 automatically.
254
255 =item auto_nextval
256
257 Set this to a true value for a column whose value is retrieved automatically
258 from a sequence or function (if supported by your Storage driver.) For a
259 sequence, if you do not use a trigger to get the nextval, you have to set the
260 L</sequence> value as well.
261
262 Also set this for MSSQL columns with the 'uniqueidentifier'
263 L<data_type|DBIx::Class::ResultSource/data_type> whose values you want to
264 automatically generate using C<NEWID()>, unless they are a primary key in which
265 case this will be done anyway.
266
267 =item extra
268
269 This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
270 to add extra non-generic data to the column. For example: C<< extra
271 => { unsigned => 1} >> is used by the MySQL producer to set an integer
272 column to unsigned. For more details, see
273 L<SQL::Translator::Producer::MySQL>.
274
275 =back
276
277 =head2 add_column
278
279 =over
280
281 =item Arguments: $colname, \%columninfo?
282
283 =item Return value: 1/0 (true/false)
284
285 =back
286
287   $source->add_column('col' => \%info);
288
289 Add a single column and optional column info. Uses the same column
290 info keys as L</add_columns>.
291
292 =cut
293
294 sub add_columns {
295   my ($self, @cols) = @_;
296   $self->_ordered_columns(\@cols) unless $self->_ordered_columns;
297
298   my @added;
299   my $columns = $self->_columns;
300   while (my $col = shift @cols) {
301     my $column_info = {};
302     if ($col =~ s/^\+//) {
303       $column_info = $self->column_info($col);
304     }
305
306     # If next entry is { ... } use that for the column info, if not
307     # use an empty hashref
308     if (ref $cols[0]) {
309       my $new_info = shift(@cols);
310       %$column_info = (%$column_info, %$new_info);
311     }
312     push(@added, $col) unless exists $columns->{$col};
313     $columns->{$col} = $column_info;
314   }
315   push @{ $self->_ordered_columns }, @added;
316   return $self;
317 }
318
319 sub add_column { shift->add_columns(@_); } # DO NOT CHANGE THIS TO GLOB
320
321 =head2 has_column
322
323 =over
324
325 =item Arguments: $colname
326
327 =item Return value: 1/0 (true/false)
328
329 =back
330
331   if ($source->has_column($colname)) { ... }
332
333 Returns true if the source has a column of this name, false otherwise.
334
335 =cut
336
337 sub has_column {
338   my ($self, $column) = @_;
339   return exists $self->_columns->{$column};
340 }
341
342 =head2 column_info
343
344 =over
345
346 =item Arguments: $colname
347
348 =item Return value: Hashref of info
349
350 =back
351
352   my $info = $source->column_info($col);
353
354 Returns the column metadata hashref for a column, as originally passed
355 to L</add_columns>. See L</add_columns> above for information on the
356 contents of the hashref.
357
358 =cut
359
360 sub column_info {
361   my ($self, $column) = @_;
362   $self->throw_exception("No such column $column")
363     unless exists $self->_columns->{$column};
364   #warn $self->{_columns_info_loaded}, "\n";
365   if ( ! $self->_columns->{$column}{data_type}
366        and $self->column_info_from_storage
367        and ! $self->{_columns_info_loaded}
368        and $self->schema and $self->storage )
369   {
370     $self->{_columns_info_loaded}++;
371     my $info = {};
372     my $lc_info = {};
373
374     # try for the case of storage without table
375     try {
376       $info = $self->storage->columns_info_for( $self->from );
377       for my $realcol ( keys %{$info} ) {
378         $lc_info->{lc $realcol} = $info->{$realcol};
379       }
380       foreach my $col ( keys %{$self->_columns} ) {
381         $self->_columns->{$col} = {
382           %{ $self->_columns->{$col} },
383           %{ $info->{$col} || $lc_info->{lc $col} || {} }
384         };
385       }
386     };
387   }
388   return $self->_columns->{$column};
389 }
390
391 =head2 columns
392
393 =over
394
395 =item Arguments: None
396
397 =item Return value: Ordered list of column names
398
399 =back
400
401   my @column_names = $source->columns;
402
403 Returns all column names in the order they were declared to L</add_columns>.
404
405 =cut
406
407 sub columns {
408   my $self = shift;
409   $self->throw_exception(
410     "columns() is a read-only accessor, did you mean add_columns()?"
411   ) if @_;
412   return @{$self->{_ordered_columns}||[]};
413 }
414
415 =head2 remove_columns
416
417 =over
418
419 =item Arguments: @colnames
420
421 =item Return value: undefined
422
423 =back
424
425   $source->remove_columns(qw/col1 col2 col3/);
426
427 Removes the given list of columns by name, from the result source.
428
429 B<Warning>: Removing a column that is also used in the sources primary
430 key, or in one of the sources unique constraints, B<will> result in a
431 broken result source.
432
433 =head2 remove_column
434
435 =over
436
437 =item Arguments: $colname
438
439 =item Return value: undefined
440
441 =back
442
443   $source->remove_column('col');
444
445 Remove a single column by name from the result source, similar to
446 L</remove_columns>.
447
448 B<Warning>: Removing a column that is also used in the sources primary
449 key, or in one of the sources unique constraints, B<will> result in a
450 broken result source.
451
452 =cut
453
454 sub remove_columns {
455   my ($self, @to_remove) = @_;
456
457   my $columns = $self->_columns
458     or return;
459
460   my %to_remove;
461   for (@to_remove) {
462     delete $columns->{$_};
463     ++$to_remove{$_};
464   }
465
466   $self->_ordered_columns([ grep { not $to_remove{$_} } @{$self->_ordered_columns} ]);
467 }
468
469 sub remove_column { shift->remove_columns(@_); } # DO NOT CHANGE THIS TO GLOB
470
471 =head2 set_primary_key
472
473 =over 4
474
475 =item Arguments: @cols
476
477 =item Return value: undefined
478
479 =back
480
481 Defines one or more columns as primary key for this source. Must be
482 called after L</add_columns>.
483
484 Additionally, defines a L<unique constraint|add_unique_constraint>
485 named C<primary>.
486
487 Note: you normally do want to define a primary key on your sources
488 B<even if the underlying database table does not have a primary key>.
489 See
490 L<DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
491 for more info.
492
493 =cut
494
495 sub set_primary_key {
496   my ($self, @cols) = @_;
497   # check if primary key columns are valid columns
498   foreach my $col (@cols) {
499     $self->throw_exception("No such column $col on table " . $self->name)
500       unless $self->has_column($col);
501   }
502   $self->_primaries(\@cols);
503
504   $self->add_unique_constraint(primary => \@cols);
505 }
506
507 =head2 primary_columns
508
509 =over 4
510
511 =item Arguments: None
512
513 =item Return value: Ordered list of primary column names
514
515 =back
516
517 Read-only accessor which returns the list of primary keys, supplied by
518 L</set_primary_key>.
519
520 =cut
521
522 sub primary_columns {
523   return @{shift->_primaries||[]};
524 }
525
526 # a helper method that will automatically die with a descriptive message if
527 # no pk is defined on the source in question. For internal use to save
528 # on if @pks... boilerplate
529 sub _pri_cols {
530   my $self = shift;
531   my @pcols = $self->primary_columns
532     or $self->throw_exception (sprintf(
533       "Operation requires a primary key to be declared on '%s' via set_primary_key",
534       $self->source_name,
535     ));
536   return @pcols;
537 }
538
539 =head2 add_unique_constraint
540
541 =over 4
542
543 =item Arguments: $name?, \@colnames
544
545 =item Return value: undefined
546
547 =back
548
549 Declare a unique constraint on this source. Call once for each unique
550 constraint.
551
552   # For UNIQUE (column1, column2)
553   __PACKAGE__->add_unique_constraint(
554     constraint_name => [ qw/column1 column2/ ],
555   );
556
557 Alternatively, you can specify only the columns:
558
559   __PACKAGE__->add_unique_constraint([ qw/column1 column2/ ]);
560
561 This will result in a unique constraint named
562 C<table_column1_column2>, where C<table> is replaced with the table
563 name.
564
565 Unique constraints are used, for example, when you pass the constraint
566 name as the C<key> attribute to L<DBIx::Class::ResultSet/find>. Then
567 only columns in the constraint are searched.
568
569 Throws an error if any of the given column names do not yet exist on
570 the result source.
571
572 =cut
573
574 sub add_unique_constraint {
575   my $self = shift;
576
577   if (@_ > 2) {
578     $self->throw_exception(
579         'add_unique_constraint() does not accept multiple constraints, use '
580       . 'add_unique_constraints() instead'
581     );
582   }
583
584   my $cols = pop @_;
585   if (ref $cols ne 'ARRAY') {
586     $self->throw_exception (
587       'Expecting an arrayref of constraint columns, got ' . ($cols||'NOTHING')
588     );
589   }
590
591   my $name = shift @_;
592
593   $name ||= $self->name_unique_constraint($cols);
594
595   foreach my $col (@$cols) {
596     $self->throw_exception("No such column $col on table " . $self->name)
597       unless $self->has_column($col);
598   }
599
600   my %unique_constraints = $self->unique_constraints;
601   $unique_constraints{$name} = $cols;
602   $self->_unique_constraints(\%unique_constraints);
603 }
604
605 =head2 add_unique_constraints
606
607 =over 4
608
609 =item Arguments: @constraints
610
611 =item Return value: undefined
612
613 =back
614
615 Declare multiple unique constraints on this source.
616
617   __PACKAGE__->add_unique_constraints(
618     constraint_name1 => [ qw/column1 column2/ ],
619     constraint_name2 => [ qw/column2 column3/ ],
620   );
621
622 Alternatively, you can specify only the columns:
623
624   __PACKAGE__->add_unique_constraints(
625     [ qw/column1 column2/ ],
626     [ qw/column3 column4/ ]
627   );
628
629 This will result in unique constraints named C<table_column1_column2> and
630 C<table_column3_column4>, where C<table> is replaced with the table name.
631
632 Throws an error if any of the given column names do not yet exist on
633 the result source.
634
635 See also L</add_unique_constraint>.
636
637 =cut
638
639 sub add_unique_constraints {
640   my $self = shift;
641   my @constraints = @_;
642
643   if ( !(@constraints % 2) && first { ref $_ ne 'ARRAY' } @constraints ) {
644     # with constraint name
645     while (my ($name, $constraint) = splice @constraints, 0, 2) {
646       $self->add_unique_constraint($name => $constraint);
647     }
648   }
649   else {
650     # no constraint name
651     foreach my $constraint (@constraints) {
652       $self->add_unique_constraint($constraint);
653     }
654   }
655 }
656
657 =head2 name_unique_constraint
658
659 =over 4
660
661 =item Arguments: \@colnames
662
663 =item Return value: Constraint name
664
665 =back
666
667   $source->table('mytable');
668   $source->name_unique_constraint(['col1', 'col2']);
669   # returns
670   'mytable_col1_col2'
671
672 Return a name for a unique constraint containing the specified
673 columns. The name is created by joining the table name and each column
674 name, using an underscore character.
675
676 For example, a constraint on a table named C<cd> containing the columns
677 C<artist> and C<title> would result in a constraint name of C<cd_artist_title>.
678
679 This is used by L</add_unique_constraint> if you do not specify the
680 optional constraint name.
681
682 =cut
683
684 sub name_unique_constraint {
685   my ($self, $cols) = @_;
686
687   my $name = $self->name;
688   $name = $$name if (ref $name eq 'SCALAR');
689
690   return join '_', $name, @$cols;
691 }
692
693 =head2 unique_constraints
694
695 =over 4
696
697 =item Arguments: None
698
699 =item Return value: Hash of unique constraint data
700
701 =back
702
703   $source->unique_constraints();
704
705 Read-only accessor which returns a hash of unique constraints on this
706 source.
707
708 The hash is keyed by constraint name, and contains an arrayref of
709 column names as values.
710
711 =cut
712
713 sub unique_constraints {
714   return %{shift->_unique_constraints||{}};
715 }
716
717 =head2 unique_constraint_names
718
719 =over 4
720
721 =item Arguments: None
722
723 =item Return value: Unique constraint names
724
725 =back
726
727   $source->unique_constraint_names();
728
729 Returns the list of unique constraint names defined on this source.
730
731 =cut
732
733 sub unique_constraint_names {
734   my ($self) = @_;
735
736   my %unique_constraints = $self->unique_constraints;
737
738   return keys %unique_constraints;
739 }
740
741 =head2 unique_constraint_columns
742
743 =over 4
744
745 =item Arguments: $constraintname
746
747 =item Return value: List of constraint columns
748
749 =back
750
751   $source->unique_constraint_columns('myconstraint');
752
753 Returns the list of columns that make up the specified unique constraint.
754
755 =cut
756
757 sub unique_constraint_columns {
758   my ($self, $constraint_name) = @_;
759
760   my %unique_constraints = $self->unique_constraints;
761
762   $self->throw_exception(
763     "Unknown unique constraint $constraint_name on '" . $self->name . "'"
764   ) unless exists $unique_constraints{$constraint_name};
765
766   return @{ $unique_constraints{$constraint_name} };
767 }
768
769 =head2 sqlt_deploy_callback
770
771 =over
772
773 =item Arguments: $callback
774
775 =back
776
777   __PACKAGE__->sqlt_deploy_callback('mycallbackmethod');
778
779 An accessor to set a callback to be called during deployment of
780 the schema via L<DBIx::Class::Schema/create_ddl_dir> or
781 L<DBIx::Class::Schema/deploy>.
782
783 The callback can be set as either a code reference or the name of a
784 method in the current result class.
785
786 If not set, the L</default_sqlt_deploy_hook> is called.
787
788 Your callback will be passed the $source object representing the
789 ResultSource instance being deployed, and the
790 L<SQL::Translator::Schema::Table> object being created from it. The
791 callback can be used to manipulate the table object or add your own
792 customised indexes. If you need to manipulate a non-table object, use
793 the L<DBIx::Class::Schema/sqlt_deploy_hook>.
794
795 See L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To
796 Your SQL> for examples.
797
798 This sqlt deployment callback can only be used to manipulate
799 SQL::Translator objects as they get turned into SQL. To execute
800 post-deploy statements which SQL::Translator does not currently
801 handle, override L<DBIx::Class::Schema/deploy> in your Schema class
802 and call L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
803
804 =head2 default_sqlt_deploy_hook
805
806 =over
807
808 =item Arguments: $source, $sqlt_table
809
810 =item Return value: undefined
811
812 =back
813
814 This is the sensible default for L</sqlt_deploy_callback>.
815
816 If a method named C<sqlt_deploy_hook> exists in your Result class, it
817 will be called and passed the current C<$source> and the
818 C<$sqlt_table> being deployed.
819
820 =cut
821
822 sub default_sqlt_deploy_hook {
823   my $self = shift;
824
825   my $class = $self->result_class;
826
827   if ($class and $class->can('sqlt_deploy_hook')) {
828     $class->sqlt_deploy_hook(@_);
829   }
830 }
831
832 sub _invoke_sqlt_deploy_hook {
833   my $self = shift;
834   if ( my $hook = $self->sqlt_deploy_callback) {
835     $self->$hook(@_);
836   }
837 }
838
839 =head2 resultset
840
841 =over 4
842
843 =item Arguments: None
844
845 =item Return value: $resultset
846
847 =back
848
849 Returns a resultset for the given source. This will initially be created
850 on demand by calling
851
852   $self->resultset_class->new($self, $self->resultset_attributes)
853
854 but is cached from then on unless resultset_class changes.
855
856 =head2 resultset_class
857
858 =over 4
859
860 =item Arguments: $classname
861
862 =item Return value: $classname
863
864 =back
865
866   package My::Schema::ResultSet::Artist;
867   use base 'DBIx::Class::ResultSet';
868   ...
869
870   # In the result class
871   __PACKAGE__->resultset_class('My::Schema::ResultSet::Artist');
872
873   # Or in code
874   $source->resultset_class('My::Schema::ResultSet::Artist');
875
876 Set the class of the resultset. This is useful if you want to create your
877 own resultset methods. Create your own class derived from
878 L<DBIx::Class::ResultSet>, and set it here. If called with no arguments,
879 this method returns the name of the existing resultset class, if one
880 exists.
881
882 =head2 resultset_attributes
883
884 =over 4
885
886 =item Arguments: \%attrs
887
888 =item Return value: \%attrs
889
890 =back
891
892   # In the result class
893   __PACKAGE__->resultset_attributes({ order_by => [ 'id' ] });
894
895   # Or in code
896   $source->resultset_attributes({ order_by => [ 'id' ] });
897
898 Store a collection of resultset attributes, that will be set on every
899 L<DBIx::Class::ResultSet> produced from this result source. For a full
900 list see L<DBIx::Class::ResultSet/ATTRIBUTES>.
901
902 =cut
903
904 sub resultset {
905   my $self = shift;
906   $self->throw_exception(
907     'resultset does not take any arguments. If you want another resultset, '.
908     'call it on the schema instead.'
909   ) if scalar @_;
910
911   return $self->resultset_class->new(
912     $self,
913     {
914       %{$self->{resultset_attributes}},
915       %{$self->schema->default_resultset_attributes}
916     },
917   );
918 }
919
920 =head2 source_name
921
922 =over 4
923
924 =item Arguments: $source_name
925
926 =item Result value: $source_name
927
928 =back
929
930 Set an alternate name for the result source when it is loaded into a schema.
931 This is useful if you want to refer to a result source by a name other than
932 its class name.
933
934   package ArchivedBooks;
935   use base qw/DBIx::Class/;
936   __PACKAGE__->table('books_archive');
937   __PACKAGE__->source_name('Books');
938
939   # from your schema...
940   $schema->resultset('Books')->find(1);
941
942 =head2 from
943
944 =over 4
945
946 =item Arguments: None
947
948 =item Return value: FROM clause
949
950 =back
951
952   my $from_clause = $source->from();
953
954 Returns an expression of the source to be supplied to storage to specify
955 retrieval from this source. In the case of a database, the required FROM
956 clause contents.
957
958 =head2 schema
959
960 =over 4
961
962 =item Arguments: None
963
964 =item Return value: A schema object
965
966 =back
967
968   my $schema = $source->schema();
969
970 Returns the L<DBIx::Class::Schema> object that this result source
971 belongs to.
972
973 =head2 storage
974
975 =over 4
976
977 =item Arguments: None
978
979 =item Return value: A Storage object
980
981 =back
982
983   $source->storage->debug(1);
984
985 Returns the storage handle for the current schema.
986
987 See also: L<DBIx::Class::Storage>
988
989 =cut
990
991 sub storage { shift->schema->storage; }
992
993 =head2 add_relationship
994
995 =over 4
996
997 =item Arguments: $relname, $related_source_name, \%cond, [ \%attrs ]
998
999 =item Return value: 1/true if it succeeded
1000
1001 =back
1002
1003   $source->add_relationship('relname', 'related_source', $cond, $attrs);
1004
1005 L<DBIx::Class::Relationship> describes a series of methods which
1006 create pre-defined useful types of relationships. Look there first
1007 before using this method directly.
1008
1009 The relationship name can be arbitrary, but must be unique for each
1010 relationship attached to this result source. 'related_source' should
1011 be the name with which the related result source was registered with
1012 the current schema. For example:
1013
1014   $schema->source('Book')->add_relationship('reviews', 'Review', {
1015     'foreign.book_id' => 'self.id',
1016   });
1017
1018 The condition C<$cond> needs to be an L<SQL::Abstract>-style
1019 representation of the join between the tables. For example, if you're
1020 creating a relation from Author to Book,
1021
1022   { 'foreign.author_id' => 'self.id' }
1023
1024 will result in the JOIN clause
1025
1026   author me JOIN book foreign ON foreign.author_id = me.id
1027
1028 You can specify as many foreign => self mappings as necessary.
1029
1030 Valid attributes are as follows:
1031
1032 =over 4
1033
1034 =item join_type
1035
1036 Explicitly specifies the type of join to use in the relationship. Any
1037 SQL join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in
1038 the SQL command immediately before C<JOIN>.
1039
1040 =item proxy
1041
1042 An arrayref containing a list of accessors in the foreign class to proxy in
1043 the main class. If, for example, you do the following:
1044
1045   CD->might_have(liner_notes => 'LinerNotes', undef, {
1046     proxy => [ qw/notes/ ],
1047   });
1048
1049 Then, assuming LinerNotes has an accessor named notes, you can do:
1050
1051   my $cd = CD->find(1);
1052   # set notes -- LinerNotes object is created if it doesn't exist
1053   $cd->notes('Notes go here');
1054
1055 =item accessor
1056
1057 Specifies the type of accessor that should be created for the
1058 relationship. Valid values are C<single> (for when there is only a single
1059 related object), C<multi> (when there can be many), and C<filter> (for
1060 when there is a single related object, but you also want the relationship
1061 accessor to double as a column accessor). For C<multi> accessors, an
1062 add_to_* method is also created, which calls C<create_related> for the
1063 relationship.
1064
1065 =back
1066
1067 Throws an exception if the condition is improperly supplied, or cannot
1068 be resolved.
1069
1070 =cut
1071
1072 sub add_relationship {
1073   my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
1074   $self->throw_exception("Can't create relationship without join condition")
1075     unless $cond;
1076   $attrs ||= {};
1077
1078   # Check foreign and self are right in cond
1079   if ( (ref $cond ||'') eq 'HASH') {
1080     for (keys %$cond) {
1081       $self->throw_exception("Keys of condition should be of form 'foreign.col', not '$_'")
1082         if /\./ && !/^foreign\./;
1083     }
1084   }
1085
1086   my %rels = %{ $self->_relationships };
1087   $rels{$rel} = { class => $f_source_name,
1088                   source => $f_source_name,
1089                   cond  => $cond,
1090                   attrs => $attrs };
1091   $self->_relationships(\%rels);
1092
1093   return $self;
1094
1095 # XXX disabled. doesn't work properly currently. skip in tests.
1096
1097   my $f_source = $self->schema->source($f_source_name);
1098   unless ($f_source) {
1099     $self->ensure_class_loaded($f_source_name);
1100     $f_source = $f_source_name->result_source;
1101     #my $s_class = ref($self->schema);
1102     #$f_source_name =~ m/^${s_class}::(.*)$/;
1103     #$self->schema->register_class(($1 || $f_source_name), $f_source_name);
1104     #$f_source = $self->schema->source($f_source_name);
1105   }
1106   return unless $f_source; # Can't test rel without f_source
1107
1108   try { $self->_resolve_join($rel, 'me', {}, []) }
1109   catch {
1110     # If the resolve failed, back out and re-throw the error
1111     delete $rels{$rel};
1112     $self->_relationships(\%rels);
1113     $self->throw_exception("Error creating relationship $rel: $_");
1114   };
1115
1116   1;
1117 }
1118
1119 =head2 relationships
1120
1121 =over 4
1122
1123 =item Arguments: None
1124
1125 =item Return value: List of relationship names
1126
1127 =back
1128
1129   my @relnames = $source->relationships();
1130
1131 Returns all relationship names for this source.
1132
1133 =cut
1134
1135 sub relationships {
1136   return keys %{shift->_relationships};
1137 }
1138
1139 =head2 relationship_info
1140
1141 =over 4
1142
1143 =item Arguments: $relname
1144
1145 =item Return value: Hashref of relation data,
1146
1147 =back
1148
1149 Returns a hash of relationship information for the specified relationship
1150 name. The keys/values are as specified for L</add_relationship>.
1151
1152 =cut
1153
1154 sub relationship_info {
1155   my ($self, $rel) = @_;
1156   return $self->_relationships->{$rel};
1157 }
1158
1159 =head2 has_relationship
1160
1161 =over 4
1162
1163 =item Arguments: $rel
1164
1165 =item Return value: 1/0 (true/false)
1166
1167 =back
1168
1169 Returns true if the source has a relationship of this name, false otherwise.
1170
1171 =cut
1172
1173 sub has_relationship {
1174   my ($self, $rel) = @_;
1175   return exists $self->_relationships->{$rel};
1176 }
1177
1178 =head2 reverse_relationship_info
1179
1180 =over 4
1181
1182 =item Arguments: $relname
1183
1184 =item Return value: Hashref of relationship data
1185
1186 =back
1187
1188 Looks through all the relationships on the source this relationship
1189 points to, looking for one whose condition is the reverse of the
1190 condition on this relationship.
1191
1192 A common use of this is to find the name of the C<belongs_to> relation
1193 opposing a C<has_many> relation. For definition of these look in
1194 L<DBIx::Class::Relationship>.
1195
1196 The returned hashref is keyed by the name of the opposing
1197 relationship, and contains its data in the same manner as
1198 L</relationship_info>.
1199
1200 =cut
1201
1202 sub reverse_relationship_info {
1203   my ($self, $rel) = @_;
1204   my $rel_info = $self->relationship_info($rel);
1205   my $ret = {};
1206
1207   return $ret unless ((ref $rel_info->{cond}) eq 'HASH');
1208
1209   my @cond = keys(%{$rel_info->{cond}});
1210   my @refkeys = map {/^\w+\.(\w+)$/} @cond;
1211   my @keys = map {$rel_info->{cond}->{$_} =~ /^\w+\.(\w+)$/} @cond;
1212
1213   # Get the related result source for this relationship
1214   my $othertable = $self->related_source($rel);
1215
1216   # Get all the relationships for that source that related to this source
1217   # whose foreign column set are our self columns on $rel and whose self
1218   # columns are our foreign columns on $rel.
1219   my @otherrels = $othertable->relationships();
1220   my $otherrelationship;
1221   foreach my $otherrel (@otherrels) {
1222     my $otherrel_info = $othertable->relationship_info($otherrel);
1223
1224     my $back = $othertable->related_source($otherrel);
1225     next unless $back->source_name eq $self->source_name;
1226
1227     my @othertestconds;
1228
1229     if (ref $otherrel_info->{cond} eq 'HASH') {
1230       @othertestconds = ($otherrel_info->{cond});
1231     }
1232     elsif (ref $otherrel_info->{cond} eq 'ARRAY') {
1233       @othertestconds = @{$otherrel_info->{cond}};
1234     }
1235     else {
1236       next;
1237     }
1238
1239     foreach my $othercond (@othertestconds) {
1240       my @other_cond = keys(%$othercond);
1241       my @other_refkeys = map {/^\w+\.(\w+)$/} @other_cond;
1242       my @other_keys = map {$othercond->{$_} =~ /^\w+\.(\w+)$/} @other_cond;
1243       next if (!$self->_compare_relationship_keys(\@refkeys, \@other_keys) ||
1244                !$self->_compare_relationship_keys(\@other_refkeys, \@keys));
1245       $ret->{$otherrel} =  $otherrel_info;
1246     }
1247   }
1248   return $ret;
1249 }
1250
1251 sub compare_relationship_keys {
1252   carp 'compare_relationship_keys is a private method, stop calling it';
1253   my $self = shift;
1254   $self->_compare_relationship_keys (@_);
1255 }
1256
1257 # Returns true if both sets of keynames are the same, false otherwise.
1258 sub _compare_relationship_keys {
1259   my ($self, $keys1, $keys2) = @_;
1260
1261   # Make sure every keys1 is in keys2
1262   my $found;
1263   foreach my $key (@$keys1) {
1264     $found = 0;
1265     foreach my $prim (@$keys2) {
1266       if ($prim eq $key) {
1267         $found = 1;
1268         last;
1269       }
1270     }
1271     last unless $found;
1272   }
1273
1274   # Make sure every key2 is in key1
1275   if ($found) {
1276     foreach my $prim (@$keys2) {
1277       $found = 0;
1278       foreach my $key (@$keys1) {
1279         if ($prim eq $key) {
1280           $found = 1;
1281           last;
1282         }
1283       }
1284       last unless $found;
1285     }
1286   }
1287
1288   return $found;
1289 }
1290
1291 # Returns the {from} structure used to express JOIN conditions
1292 sub _resolve_join {
1293   my ($self, $join, $alias, $seen, $jpath, $parent_force_left) = @_;
1294
1295   # we need a supplied one, because we do in-place modifications, no returns
1296   $self->throw_exception ('You must supply a seen hashref as the 3rd argument to _resolve_join')
1297     unless ref $seen eq 'HASH';
1298
1299   $self->throw_exception ('You must supply a joinpath arrayref as the 4th argument to _resolve_join')
1300     unless ref $jpath eq 'ARRAY';
1301
1302   $jpath = [@$jpath]; # copy
1303
1304   if (not defined $join) {
1305     return ();
1306   }
1307   elsif (ref $join eq 'ARRAY') {
1308     return
1309       map {
1310         $self->_resolve_join($_, $alias, $seen, $jpath, $parent_force_left);
1311       } @$join;
1312   }
1313   elsif (ref $join eq 'HASH') {
1314
1315     my @ret;
1316     for my $rel (keys %$join) {
1317
1318       my $rel_info = $self->relationship_info($rel)
1319         or $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1320
1321       my $force_left = $parent_force_left;
1322       $force_left ||= lc($rel_info->{attrs}{join_type}||'') eq 'left';
1323
1324       # the actual seen value will be incremented by the recursion
1325       my $as = $self->storage->relname_to_table_alias(
1326         $rel, ($seen->{$rel} && $seen->{$rel} + 1)
1327       );
1328
1329       push @ret, (
1330         $self->_resolve_join($rel, $alias, $seen, [@$jpath], $force_left),
1331         $self->related_source($rel)->_resolve_join(
1332           $join->{$rel}, $as, $seen, [@$jpath, { $rel => $as }], $force_left
1333         )
1334       );
1335     }
1336     return @ret;
1337
1338   }
1339   elsif (ref $join) {
1340     $self->throw_exception("No idea how to resolve join reftype ".ref $join);
1341   }
1342   else {
1343     my $count = ++$seen->{$join};
1344     my $as = $self->storage->relname_to_table_alias(
1345       $join, ($count > 1 && $count)
1346     );
1347
1348     my $rel_info = $self->relationship_info($join)
1349       or $self->throw_exception("No such relationship $join on " . $self->source_name);
1350
1351     my $rel_src = $self->related_source($join);
1352     return [ { $as => $rel_src->from,
1353                -source_handle => $rel_src->handle,
1354                -join_type => $parent_force_left
1355                   ? 'left'
1356                   : $rel_info->{attrs}{join_type}
1357                 ,
1358                -join_path => [@$jpath, { $join => $as } ],
1359                -is_single => (
1360                   $rel_info->{attrs}{accessor}
1361                     &&
1362                   first { $rel_info->{attrs}{accessor} eq $_ } (qw/single filter/)
1363                 ),
1364                -alias => $as,
1365                -relation_chain_depth => $seen->{-relation_chain_depth} || 0,
1366              },
1367              $self->_resolve_condition($rel_info->{cond}, $as, $alias) ];
1368   }
1369 }
1370
1371 sub pk_depends_on {
1372   carp 'pk_depends_on is a private method, stop calling it';
1373   my $self = shift;
1374   $self->_pk_depends_on (@_);
1375 }
1376
1377 # Determines whether a relation is dependent on an object from this source
1378 # having already been inserted. Takes the name of the relationship and a
1379 # hashref of columns of the related object.
1380 sub _pk_depends_on {
1381   my ($self, $relname, $rel_data) = @_;
1382
1383   my $relinfo = $self->relationship_info($relname);
1384
1385   # don't assume things if the relationship direction is specified
1386   return $relinfo->{attrs}{is_foreign_key_constraint}
1387     if exists ($relinfo->{attrs}{is_foreign_key_constraint});
1388
1389   my $cond = $relinfo->{cond};
1390   return 0 unless ref($cond) eq 'HASH';
1391
1392   # map { foreign.foo => 'self.bar' } to { bar => 'foo' }
1393   my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond };
1394
1395   # assume anything that references our PK probably is dependent on us
1396   # rather than vice versa, unless the far side is (a) defined or (b)
1397   # auto-increment
1398   my $rel_source = $self->related_source($relname);
1399
1400   foreach my $p ($self->primary_columns) {
1401     if (exists $keyhash->{$p}) {
1402       unless (defined($rel_data->{$keyhash->{$p}})
1403               || $rel_source->column_info($keyhash->{$p})
1404                             ->{is_auto_increment}) {
1405         return 0;
1406       }
1407     }
1408   }
1409
1410   return 1;
1411 }
1412
1413 sub resolve_condition {
1414   carp 'resolve_condition is a private method, stop calling it';
1415   my $self = shift;
1416   $self->_resolve_condition (@_);
1417 }
1418
1419 # Resolves the passed condition to a concrete query fragment. If given an alias,
1420 # returns a join condition; if given an object, inverts that object to produce
1421 # a related conditional from that object.
1422 our $UNRESOLVABLE_CONDITION = \'1 = 0';
1423
1424 sub _resolve_condition {
1425   my ($self, $cond, $as, $for) = @_;
1426   if (ref $cond eq 'HASH') {
1427     my %ret;
1428     foreach my $k (keys %{$cond}) {
1429       my $v = $cond->{$k};
1430       # XXX should probably check these are valid columns
1431       $k =~ s/^foreign\.// ||
1432         $self->throw_exception("Invalid rel cond key ${k}");
1433       $v =~ s/^self\.// ||
1434         $self->throw_exception("Invalid rel cond val ${v}");
1435       if (ref $for) { # Object
1436         #warn "$self $k $for $v";
1437         unless ($for->has_column_loaded($v)) {
1438           if ($for->in_storage) {
1439             $self->throw_exception(sprintf
1440               "Unable to resolve relationship '%s' from object %s: column '%s' not "
1441             . 'loaded from storage (or not passed to new() prior to insert()). You '
1442             . 'probably need to call ->discard_changes to get the server-side defaults '
1443             . 'from the database.',
1444               $as,
1445               $for,
1446               $v,
1447             );
1448           }
1449           return $UNRESOLVABLE_CONDITION;
1450         }
1451         $ret{$k} = $for->get_column($v);
1452         #$ret{$k} = $for->get_column($v) if $for->has_column_loaded($v);
1453         #warn %ret;
1454       } elsif (!defined $for) { # undef, i.e. "no object"
1455         $ret{$k} = undef;
1456       } elsif (ref $as eq 'HASH') { # reverse hashref
1457         $ret{$v} = $as->{$k};
1458       } elsif (ref $as) { # reverse object
1459         $ret{$v} = $as->get_column($k);
1460       } elsif (!defined $as) { # undef, i.e. "no reverse object"
1461         $ret{$v} = undef;
1462       } else {
1463         $ret{"${as}.${k}"} = "${for}.${v}";
1464       }
1465     }
1466     return \%ret;
1467   } elsif (ref $cond eq 'ARRAY') {
1468     return [ map { $self->_resolve_condition($_, $as, $for) } @$cond ];
1469   } else {
1470    die("Can't handle condition $cond yet :(");
1471   }
1472 }
1473
1474
1475 # Accepts one or more relationships for the current source and returns an
1476 # array of column names for each of those relationships. Column names are
1477 # prefixed relative to the current source, in accordance with where they appear
1478 # in the supplied relationships.
1479
1480 sub _resolve_prefetch {
1481   my ($self, $pre, $alias, $alias_map, $order, $collapse, $pref_path) = @_;
1482   $pref_path ||= [];
1483
1484   if (not defined $pre) {
1485     return ();
1486   }
1487   elsif( ref $pre eq 'ARRAY' ) {
1488     return
1489       map { $self->_resolve_prefetch( $_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ) }
1490         @$pre;
1491   }
1492   elsif( ref $pre eq 'HASH' ) {
1493     my @ret =
1494     map {
1495       $self->_resolve_prefetch($_, $alias, $alias_map, $order, $collapse, [ @$pref_path ] ),
1496       $self->related_source($_)->_resolve_prefetch(
1497                $pre->{$_}, "${alias}.$_", $alias_map, $order, $collapse, [ @$pref_path, $_] )
1498     } keys %$pre;
1499     return @ret;
1500   }
1501   elsif( ref $pre ) {
1502     $self->throw_exception(
1503       "don't know how to resolve prefetch reftype ".ref($pre));
1504   }
1505   else {
1506     my $p = $alias_map;
1507     $p = $p->{$_} for (@$pref_path, $pre);
1508
1509     $self->throw_exception (
1510       "Unable to resolve prefetch '$pre' - join alias map does not contain an entry for path: "
1511       . join (' -> ', @$pref_path, $pre)
1512     ) if (ref $p->{-join_aliases} ne 'ARRAY' or not @{$p->{-join_aliases}} );
1513
1514     my $as = shift @{$p->{-join_aliases}};
1515
1516     my $rel_info = $self->relationship_info( $pre );
1517     $self->throw_exception( $self->source_name . " has no such relationship '$pre'" )
1518       unless $rel_info;
1519     my $as_prefix = ($alias =~ /^.*?\.(.+)$/ ? $1.'.' : '');
1520     my $rel_source = $self->related_source($pre);
1521
1522     if ($rel_info->{attrs}{accessor} && $rel_info->{attrs}{accessor} eq 'multi') {
1523       $self->throw_exception(
1524         "Can't prefetch has_many ${pre} (join cond too complex)")
1525         unless ref($rel_info->{cond}) eq 'HASH';
1526       my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
1527       if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
1528                          keys %{$collapse}) {
1529         my ($last) = ($fail =~ /([^\.]+)$/);
1530         carp (
1531           "Prefetching multiple has_many rels ${last} and ${pre} "
1532           .(length($as_prefix)
1533             ? "at the same level (${as_prefix}) "
1534             : "at top level "
1535           )
1536           . 'will explode the number of row objects retrievable via ->next or ->all. '
1537           . 'Use at your own risk.'
1538         );
1539       }
1540       #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
1541       #              values %{$rel_info->{cond}};
1542       $collapse->{".${as_prefix}${pre}"} = [ $rel_source->_pri_cols ];
1543         # action at a distance. prepending the '.' allows simpler code
1544         # in ResultSet->_collapse_result
1545       my @key = map { (/^foreign\.(.+)$/ ? ($1) : ()); }
1546                     keys %{$rel_info->{cond}};
1547       my @ord = (ref($rel_info->{attrs}{order_by}) eq 'ARRAY'
1548                    ? @{$rel_info->{attrs}{order_by}}
1549
1550                 : (defined $rel_info->{attrs}{order_by}
1551                        ? ($rel_info->{attrs}{order_by})
1552                        : ()));
1553       push(@$order, map { "${as}.$_" } (@key, @ord));
1554     }
1555
1556     return map { [ "${as}.$_", "${as_prefix}${pre}.$_", ] }
1557       $rel_source->columns;
1558   }
1559 }
1560
1561 =head2 related_source
1562
1563 =over 4
1564
1565 =item Arguments: $relname
1566
1567 =item Return value: $source
1568
1569 =back
1570
1571 Returns the result source object for the given relationship.
1572
1573 =cut
1574
1575 sub related_source {
1576   my ($self, $rel) = @_;
1577   if( !$self->has_relationship( $rel ) ) {
1578     $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1579   }
1580   return $self->schema->source($self->relationship_info($rel)->{source});
1581 }
1582
1583 =head2 related_class
1584
1585 =over 4
1586
1587 =item Arguments: $relname
1588
1589 =item Return value: $classname
1590
1591 =back
1592
1593 Returns the class name for objects in the given relationship.
1594
1595 =cut
1596
1597 sub related_class {
1598   my ($self, $rel) = @_;
1599   if( !$self->has_relationship( $rel ) ) {
1600     $self->throw_exception("No such relationship '$rel' on " . $self->source_name);
1601   }
1602   return $self->schema->class($self->relationship_info($rel)->{source});
1603 }
1604
1605 =head2 handle
1606
1607 Obtain a new handle to this source. Returns an instance of a
1608 L<DBIx::Class::ResultSourceHandle>.
1609
1610 =cut
1611
1612 sub handle {
1613     return DBIx::Class::ResultSourceHandle->new({
1614         schema         => $_[0]->schema,
1615         source_moniker => $_[0]->source_name
1616     });
1617 }
1618
1619 =head2 throw_exception
1620
1621 See L<DBIx::Class::Schema/"throw_exception">.
1622
1623 =cut
1624
1625 sub throw_exception {
1626   my $self = shift;
1627
1628   if (defined $self->schema) {
1629     $self->schema->throw_exception(@_);
1630   }
1631   else {
1632     DBIx::Class::Exception->throw(@_);
1633   }
1634 }
1635
1636 =head2 source_info
1637
1638 Stores a hashref of per-source metadata.  No specific key names
1639 have yet been standardized, the examples below are purely hypothetical
1640 and don't actually accomplish anything on their own:
1641
1642   __PACKAGE__->source_info({
1643     "_tablespace" => 'fast_disk_array_3',
1644     "_engine" => 'InnoDB',
1645   });
1646
1647 =head2 new
1648
1649   $class->new();
1650
1651   $class->new({attribute_name => value});
1652
1653 Creates a new ResultSource object.  Not normally called directly by end users.
1654
1655 =head2 column_info_from_storage
1656
1657 =over
1658
1659 =item Arguments: 1/0 (default: 0)
1660
1661 =item Return value: 1/0
1662
1663 =back
1664
1665   __PACKAGE__->column_info_from_storage(1);
1666
1667 Enables the on-demand automatic loading of the above column
1668 metadata from storage as necessary.  This is *deprecated*, and
1669 should not be used.  It will be removed before 1.0.
1670
1671
1672 =head1 AUTHORS
1673
1674 Matt S. Trout <mst@shadowcatsystems.co.uk>
1675
1676 =head1 LICENSE
1677
1678 You may distribute this code under the same terms as Perl itself.
1679
1680 =cut
1681
1682 1;