1 package DBIx::Class::Schema;
6 use DBIx::Class::Exception;
7 use Carp::Clan qw/^DBIx::Class/;
8 use Scalar::Util qw/weaken/;
13 use base qw/DBIx::Class/;
15 __PACKAGE__->mk_classdata('class_mappings' => {});
16 __PACKAGE__->mk_classdata('source_registrations' => {});
17 __PACKAGE__->mk_classdata('storage_type' => '::DBI');
18 __PACKAGE__->mk_classdata('storage');
19 __PACKAGE__->mk_classdata('exception_action');
20 __PACKAGE__->mk_classdata('stacktrace' => $ENV{DBIC_TRACE} || 0);
21 __PACKAGE__->mk_classdata('default_resultset_attributes' => {});
25 DBIx::Class::Schema - composable schemas
29 package Library::Schema;
30 use base qw/DBIx::Class::Schema/;
32 # load all Result classes in Library/Schema/Result/
33 __PACKAGE__->load_namespaces();
35 package Library::Schema::Result::CD;
36 use base qw/DBIx::Class/;
37 __PACKAGE__->load_components(qw/Core/); # for example
38 __PACKAGE__->table('cd');
40 # Elsewhere in your code:
41 my $schema1 = Library::Schema->connect(
48 my $schema2 = Library::Schema->connect($coderef_returning_dbh);
50 # fetch objects using Library::Schema::Result::DVD
51 my $resultset = $schema1->resultset('DVD')->search( ... );
52 my @dvd_objects = $schema2->resultset('DVD')->search( ... );
56 Creates database classes based on a schema. This is the recommended way to
57 use L<DBIx::Class> and allows you to use more than one concurrent connection
60 NB: If you're used to L<Class::DBI> it's worth reading the L</SYNOPSIS>
61 carefully, as DBIx::Class does things a little differently. Note in
62 particular which module inherits off which.
66 =head2 load_namespaces
70 =item Arguments: %options?
74 __PACKAGE__->load_namespaces();
76 __PACKAGE__->load_namespaces(
77 result_namespace => 'Res',
78 resultset_namespace => 'RSet',
79 default_resultset_class => '+MyDB::Othernamespace::RSet',
82 With no arguments, this method uses L<Module::Find> to load all your
83 Result classes from a sub-namespace F<Result> under your Schema class'
84 namespace. Eg. With a Schema of I<MyDB::Schema> all files in
85 I<MyDB::Schema::Result> are assumed to be Result classes.
87 It also finds all ResultSet classes in the namespace F<ResultSet> and
88 loads them into the appropriate Result classes using for you. The
89 matching is done by assuming the package name of the ResultSet class
90 is the same as that of the Result class.
92 You will be warned if ResultSet classes are discovered for which there
93 are no matching Result classes like this:
95 load_namespaces found ResultSet class $classname with no corresponding Result class
97 If a Result class is found to already have a ResultSet class set using
98 L</resultset_class> to some other class, you will be warned like this:
100 We found ResultSet class '$rs_class' for '$result', but it seems
101 that you had already set '$result' to use '$rs_set' instead
103 Both of the sub-namespaces are configurable if you don't like the defaults,
104 via the options C<result_namespace> and C<resultset_namespace>.
106 If (and only if) you specify the option C<default_resultset_class>, any found
107 Result classes for which we do not find a corresponding
108 ResultSet class will have their C<resultset_class> set to
109 C<default_resultset_class>.
111 All of the namespace and classname options to this method are relative to
112 the schema classname by default. To specify a fully-qualified name, prefix
113 it with a literal C<+>.
117 # load My::Schema::Result::CD, My::Schema::Result::Artist,
118 # My::Schema::ResultSet::CD, etc...
119 My::Schema->load_namespaces;
121 # Override everything to use ugly names.
122 # In this example, if there is a My::Schema::Res::Foo, but no matching
123 # My::Schema::RSets::Foo, then Foo will have its
124 # resultset_class set to My::Schema::RSetBase
125 My::Schema->load_namespaces(
126 result_namespace => 'Res',
127 resultset_namespace => 'RSets',
128 default_resultset_class => 'RSetBase',
131 # Put things in other namespaces
132 My::Schema->load_namespaces(
133 result_namespace => '+Some::Place::Results',
134 resultset_namespace => '+Another::Place::RSets',
137 If you'd like to use multiple namespaces of each type, simply use an arrayref
138 of namespaces for that option. In the case that the same result
139 (or resultset) class exists in multiple namespaces, the latter entries in
140 your list of namespaces will override earlier ones.
142 My::Schema->load_namespaces(
143 # My::Schema::Results_C::Foo takes precedence over My::Schema::Results_B::Foo :
144 result_namespace => [ 'Results_A', 'Results_B', 'Results_C' ],
145 resultset_namespace => [ '+Some::Place::RSets', 'RSets' ],
150 # Pre-pends our classname to the given relative classname or
151 # class namespace, unless there is a '+' prefix, which will
153 sub _expand_relative_name {
154 my ($class, $name) = @_;
156 $name = $class . '::' . $name if ! ($name =~ s/^\+//);
160 # returns a hash of $shortname => $fullname for every package
161 # found in the given namespaces ($shortname is with the $fullname's
162 # namespace stripped off)
163 sub _map_namespaces {
164 my ($class, @namespaces) = @_;
167 foreach my $namespace (@namespaces) {
170 map { (substr($_, length "${namespace}::"), $_) }
171 Module::Find::findallmod($namespace)
178 sub load_namespaces {
179 my ($class, %args) = @_;
181 my $result_namespace = delete $args{result_namespace} || 'Result';
182 my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
183 my $default_resultset_class = delete $args{default_resultset_class};
185 $class->throw_exception('load_namespaces: unknown option(s): '
186 . join(q{,}, map { qq{'$_'} } keys %args))
187 if scalar keys %args;
189 $default_resultset_class
190 = $class->_expand_relative_name($default_resultset_class);
192 for my $arg ($result_namespace, $resultset_namespace) {
193 $arg = [ $arg ] if !ref($arg) && $arg;
195 $class->throw_exception('load_namespaces: namespace arguments must be '
196 . 'a simple string or an arrayref')
197 if ref($arg) ne 'ARRAY';
199 $_ = $class->_expand_relative_name($_) for (@$arg);
202 my %results = $class->_map_namespaces(@$result_namespace);
203 my %resultsets = $class->_map_namespaces(@$resultset_namespace);
207 no warnings 'redefine';
208 local *Class::C3::reinitialize = sub { };
209 use warnings 'redefine';
211 # ensure classes are loaded and fetch properly sorted classes
212 $class->ensure_class_loaded($_) foreach(values %results);
213 my @subclass_last = sort { $results{$a}->isa($results{$b}) } keys(%results);
215 foreach my $result (@subclass_last) {
216 my $result_class = $results{$result};
218 my $rs_class = delete $resultsets{$result};
219 my $rs_set = $result_class->resultset_class;
221 if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
222 if($rs_class && $rs_class ne $rs_set) {
223 warn "We found ResultSet class '$rs_class' for '$result', but it seems "
224 . "that you had already set '$result' to use '$rs_set' instead";
227 elsif($rs_class ||= $default_resultset_class) {
228 $class->ensure_class_loaded($rs_class);
229 $result_class->resultset_class($rs_class);
232 my $source_name = $result_class->source_name || $result;
234 push(@to_register, [ $source_name, $result_class ]);
238 foreach (sort keys %resultsets) {
239 warn "load_namespaces found ResultSet class $_ with no "
240 . 'corresponding Result class';
243 Class::C3->reinitialize;
244 $class->register_class(@$_) for (@to_register);
253 =item Arguments: @classes?, { $namespace => [ @classes ] }+
257 Alternative method to L</load_namespaces> which you should look at
260 With no arguments, this method uses L<Module::Find> to find all classes under
261 the schema's namespace. Otherwise, this method loads the classes you specify
262 (using L<use>), and registers them (using L</"register_class">).
264 It is possible to comment out classes with a leading C<#>, but note that perl
265 will think it's a mistake (trying to use a comment in a qw list), so you'll
266 need to add C<no warnings 'qw';> before your load_classes call.
268 If any classes found do not appear to be Result class files, you will
269 get the following warning:
271 Failed to load $comp_class. Can't find source_name method. Is
272 $comp_class really a full DBIC result class? Fix it, move it elsewhere,
273 or make your load_classes call more specific.
277 My::Schema->load_classes(); # loads My::Schema::CD, My::Schema::Artist,
278 # etc. (anything under the My::Schema namespace)
280 # loads My::Schema::CD, My::Schema::Artist, Other::Namespace::Producer but
281 # not Other::Namespace::LinerNotes nor My::Schema::Track
282 My::Schema->load_classes(qw/ CD Artist #Track /, {
283 Other::Namespace => [qw/ Producer #LinerNotes /],
289 my ($class, @params) = @_;
294 foreach my $param (@params) {
295 if (ref $param eq 'ARRAY') {
296 # filter out commented entries
297 my @modules = grep { $_ !~ /^#/ } @$param;
299 push (@{$comps_for{$class}}, @modules);
301 elsif (ref $param eq 'HASH') {
302 # more than one namespace possible
303 for my $comp ( keys %$param ) {
304 # filter out commented entries
305 my @modules = grep { $_ !~ /^#/ } @{$param->{$comp}};
307 push (@{$comps_for{$comp}}, @modules);
311 # filter out commented entries
312 push (@{$comps_for{$class}}, $param) if $param !~ /^#/;
316 my @comp = map { substr $_, length "${class}::" }
317 Module::Find::findallmod($class);
318 $comps_for{$class} = \@comp;
323 no warnings qw/redefine/;
324 local *Class::C3::reinitialize = sub { };
325 foreach my $prefix (keys %comps_for) {
326 foreach my $comp (@{$comps_for{$prefix}||[]}) {
327 my $comp_class = "${prefix}::${comp}";
328 { # try to untaint module name. mods where this fails
329 # are left alone so we don't have to change the old behavior
330 no locale; # localized \w doesn't untaint expression
331 if ( $comp_class =~ m/^( (?:\w+::)* \w+ )$/x ) {
335 $class->ensure_class_loaded($comp_class);
337 my $snsub = $comp_class->can('source_name');
339 warn "Failed to load $comp_class. Can't find source_name method. Is $comp_class really a full DBIC result class? Fix it, move it elsewhere, or make your load_classes call more specific.";
342 $comp = $snsub->($comp_class) || $comp;
344 push(@to_register, [ $comp, $comp_class ]);
348 Class::C3->reinitialize;
350 foreach my $to (@to_register) {
351 $class->register_class(@$to);
352 # if $class->can('result_source_instance');
360 =item Arguments: $storage_type|{$storage_type, \%args}
362 =item Return value: $storage_type|{$storage_type, \%args}
364 =item Default value: DBIx::Class::Storage::DBI
368 Set the storage class that will be instantiated when L</connect> is called.
369 If the classname starts with C<::>, the prefix C<DBIx::Class::Storage> is
370 assumed by L</connect>.
372 You want to use this to set subclasses of L<DBIx::Class::Storage::DBI>
373 in cases where the appropriate subclass is not autodetected, such as
374 when dealing with MSSQL via L<DBD::Sybase>, in which case you'd set it
375 to C<::DBI::Sybase::MSSQL>.
377 If your storage type requires instantiation arguments, those are
378 defined as a second argument in the form of a hashref and the entire
379 value needs to be wrapped into an arrayref or a hashref. We support
380 both types of refs here in order to play nice with your
381 Config::[class] or your choice. See
382 L<DBIx::Class::Storage::DBI::Replicated> for an example of this.
384 =head2 exception_action
388 =item Arguments: $code_reference
390 =item Return value: $code_reference
392 =item Default value: None
396 If C<exception_action> is set for this class/object, L</throw_exception>
397 will prefer to call this code reference with the exception as an argument,
398 rather than L<DBIx::Class::Exception/throw>.
400 Your subroutine should probably just wrap the error in the exception
401 object/class of your choosing and rethrow. If, against all sage advice,
402 you'd like your C<exception_action> to suppress a particular exception
403 completely, simply have it return true.
408 use base qw/DBIx::Class::Schema/;
409 use My::ExceptionClass;
410 __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
411 __PACKAGE__->load_classes;
414 my $schema_obj = My::Schema->connect( .... );
415 $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
417 # suppress all exceptions, like a moron:
418 $schema_obj->exception_action(sub { 1 });
424 =item Arguments: boolean
428 Whether L</throw_exception> should include stack trace information.
429 Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
432 =head2 sqlt_deploy_hook
436 =item Arguments: $sqlt_schema
440 An optional sub which you can declare in your own Schema class that will get
441 passed the L<SQL::Translator::Schema> object when you deploy the schema via
442 L</create_ddl_dir> or L</deploy>.
444 For an example of what you can do with this, see
445 L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
447 Note that sqlt_deploy_hook is called by L</deployment_statements>, which in turn
448 is called before L</deploy>. Therefore the hook can be used only to manipulate
449 the L<SQL::Translator::Schema> object before it is turned into SQL fed to the
450 database. If you want to execute post-deploy statements which can not be generated
451 by L<SQL::Translator>, the currently suggested method is to overload L</deploy>
452 and use L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
460 =item Arguments: @connectinfo
462 =item Return Value: $new_schema
466 Creates and returns a new Schema object. The connection info set on it
467 is used to create a new instance of the storage backend and set it on
470 See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific
471 syntax on the C<@connectinfo> argument, or L<DBIx::Class::Storage> in
474 Note that C<connect_info> expects an arrayref of arguments, but
475 C<connect> does not. C<connect> wraps it's arguments in an arrayref
476 before passing them to C<connect_info>.
480 sub connect { shift->clone->connection(@_) }
486 =item Arguments: $source_name
488 =item Return Value: $resultset
492 my $rs = $schema->resultset('DVD');
494 Returns the L<DBIx::Class::ResultSet> object for the registered source
500 my ($self, $moniker) = @_;
501 return $self->source($moniker)->resultset;
508 =item Return Value: @source_names
512 my @source_names = $schema->sources;
514 Lists names of all the sources registered on this Schema object.
518 sub sources { return keys %{shift->source_registrations}; }
524 =item Arguments: $source_name
526 =item Return Value: $result_source
530 my $source = $schema->source('Book');
532 Returns the L<DBIx::Class::ResultSource> object for the registered
538 my ($self, $moniker) = @_;
539 my $sreg = $self->source_registrations;
540 return $sreg->{$moniker} if exists $sreg->{$moniker};
542 # if we got here, they probably passed a full class name
543 my $mapped = $self->class_mappings->{$moniker};
544 $self->throw_exception("Can't find source for ${moniker}")
545 unless $mapped && exists $sreg->{$mapped};
546 return $sreg->{$mapped};
553 =item Arguments: $source_name
555 =item Return Value: $classname
559 my $class = $schema->class('CD');
561 Retrieves the Result class name for the given source name.
566 my ($self, $moniker) = @_;
567 return $self->source($moniker)->result_class;
574 =item Arguments: C<$coderef>, @coderef_args?
576 =item Return Value: The return value of $coderef
580 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
581 returning its result (if any). Equivalent to calling $schema->storage->txn_do.
582 See L<DBIx::Class::Storage/"txn_do"> for more information.
584 This interface is preferred over using the individual methods L</txn_begin>,
585 L</txn_commit>, and L</txn_rollback> below.
587 WARNING: If you are connected with C<AutoCommit => 0> the transaction is
588 considered nested, and you will still need to call L</txn_commit> to write your
589 changes when appropriate. You will also want to connect with C<auto_savepoint =>
590 1> to get partial rollback to work, if the storage driver for your database
593 Connecting with C<AutoCommit => 1> is recommended.
600 $self->storage or $self->throw_exception
601 ('txn_do called on $schema without storage');
603 $self->storage->txn_do(@_);
606 =head2 txn_scope_guard (EXPERIMENTAL)
608 Runs C<txn_scope_guard> on the schema's storage. See
609 L<DBIx::Class::Storage/txn_scope_guard>.
613 sub txn_scope_guard {
616 $self->storage or $self->throw_exception
617 ('txn_scope_guard called on $schema without storage');
619 $self->storage->txn_scope_guard(@_);
624 Begins a transaction (does nothing if AutoCommit is off). Equivalent to
625 calling $schema->storage->txn_begin. See
626 L<DBIx::Class::Storage::DBI/"txn_begin"> for more information.
633 $self->storage or $self->throw_exception
634 ('txn_begin called on $schema without storage');
636 $self->storage->txn_begin;
641 Commits the current transaction. Equivalent to calling
642 $schema->storage->txn_commit. See L<DBIx::Class::Storage::DBI/"txn_commit">
643 for more information.
650 $self->storage or $self->throw_exception
651 ('txn_commit called on $schema without storage');
653 $self->storage->txn_commit;
658 Rolls back the current transaction. Equivalent to calling
659 $schema->storage->txn_rollback. See
660 L<DBIx::Class::Storage::DBI/"txn_rollback"> for more information.
667 $self->storage or $self->throw_exception
668 ('txn_rollback called on $schema without storage');
670 $self->storage->txn_rollback;
675 my $storage = $schema->storage;
677 Returns the L<DBIx::Class::Storage> object for this Schema. Grab this
678 if you want to turn on SQL statement debugging at runtime, or set the
679 quote character. For the default storage, the documentation can be
680 found in L<DBIx::Class::Storage::DBI>.
686 =item Arguments: $source_name, \@data;
688 =item Return value: \@$objects | nothing
692 Pass this method a resultsource name, and an arrayref of
693 arrayrefs. The arrayrefs should contain a list of column names,
694 followed by one or many sets of matching data for the given columns.
696 In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
697 to insert the data, as this is a fast method. However, insert_bulk currently
698 assumes that your datasets all contain the same type of values, using scalar
699 references in a column in one row, and not in another will probably not work.
701 Otherwise, each set of data is inserted into the database using
702 L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
707 $schema->populate('Artist', [
708 [ qw/artistid name/ ],
709 [ 1, 'Popular Band' ],
714 Since wantarray context is basically the same as looping over $rs->create(...)
715 you won't see any performance benefits and in this case the method is more for
716 convenience. Void context sends the column information directly to storage
717 using <DBI>s bulk insert method. So the performance will be much better for
718 storages that support this method.
720 Because of this difference in the way void context inserts rows into your
721 database you need to note how this will effect any loaded components that
722 override or augment insert. For example if you are using a component such
723 as L<DBIx::Class::UUIDColumns> to populate your primary keys you MUST use
724 wantarray context if you want the PKs automatically created.
729 my ($self, $name, $data) = @_;
730 if(my $rs = $self->resultset($name)) {
731 if(defined wantarray) {
732 return $rs->populate($data);
734 $rs->populate($data);
737 $self->throw_exception("$name is not a resultset");
745 =item Arguments: @args
747 =item Return Value: $new_schema
751 Similar to L</connect> except sets the storage object and connection
752 data in-place on the Schema class. You should probably be calling
753 L</connect> to get a proper Schema object instead.
759 my ($self, @info) = @_;
760 return $self if !@info && $self->storage;
762 my ($storage_class, $args) = ref $self->storage_type ?
763 ($self->_normalize_storage_type($self->storage_type),{}) : ($self->storage_type, {});
765 $storage_class = 'DBIx::Class::Storage'.$storage_class
766 if $storage_class =~ m/^::/;
767 eval "require ${storage_class};";
768 $self->throw_exception(
769 "No arguments to load_classes and couldn't load ${storage_class} ($@)"
771 my $storage = $storage_class->new($self=>$args);
772 $storage->connect_info(\@info);
773 $self->storage($storage);
777 sub _normalize_storage_type {
778 my ($self, $storage_type) = @_;
779 if(ref $storage_type eq 'ARRAY') {
780 return @$storage_type;
781 } elsif(ref $storage_type eq 'HASH') {
782 return %$storage_type;
784 $self->throw_exception('Unsupported REFTYPE given: '. ref $storage_type);
788 =head2 compose_namespace
792 =item Arguments: $target_namespace, $additional_base_class?
794 =item Retur Value: $new_schema
798 For each L<DBIx::Class::ResultSource> in the schema, this method creates a
799 class in the target namespace (e.g. $target_namespace::CD,
800 $target_namespace::Artist) that inherits from the corresponding classes
801 attached to the current schema.
803 It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
804 new $schema object. If C<$additional_base_class> is given, the new composed
805 classes will inherit from first the corresponding classe from the current
806 schema then the base class.
808 For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
810 $schema->compose_namespace('My::DB', 'Base::Class');
811 print join (', ', @My::DB::CD::ISA) . "\n";
812 print join (', ', @My::DB::Artist::ISA) ."\n";
814 will produce the output
816 My::Schema::CD, Base::Class
817 My::Schema::Artist, Base::Class
821 # this might be oversimplified
822 # sub compose_namespace {
823 # my ($self, $target, $base) = @_;
825 # my $schema = $self->clone;
826 # foreach my $moniker ($schema->sources) {
827 # my $source = $schema->source($moniker);
828 # my $target_class = "${target}::${moniker}";
829 # $self->inject_base(
830 # $target_class => $source->result_class, ($base ? $base : ())
832 # $source->result_class($target_class);
833 # $target_class->result_source_instance($source)
834 # if $target_class->can('result_source_instance');
835 # $schema->register_source($moniker, $source);
840 sub compose_namespace {
841 my ($self, $target, $base) = @_;
842 my $schema = $self->clone;
844 no warnings qw/redefine/;
845 # local *Class::C3::reinitialize = sub { };
846 foreach my $moniker ($schema->sources) {
847 my $source = $schema->source($moniker);
848 my $target_class = "${target}::${moniker}";
850 $target_class => $source->result_class, ($base ? $base : ())
852 $source->result_class($target_class);
853 $target_class->result_source_instance($source)
854 if $target_class->can('result_source_instance');
855 $schema->register_source($moniker, $source);
858 # Class::C3->reinitialize();
861 no warnings 'redefine';
862 foreach my $meth (qw/class source resultset/) {
863 *{"${target}::${meth}"} =
864 sub { shift->schema->$meth(@_) };
870 sub setup_connection_class {
871 my ($class, $target, @info) = @_;
872 $class->inject_base($target => 'DBIx::Class::DB');
873 #$target->load_components('DB');
874 $target->connection(@info);
879 Creates a new savepoint (does nothing outside a transaction).
880 Equivalent to calling $schema->storage->svp_begin. See
881 L<DBIx::Class::Storage::DBI/"svp_begin"> for more information.
886 my ($self, $name) = @_;
888 $self->storage or $self->throw_exception
889 ('svp_begin called on $schema without storage');
891 $self->storage->svp_begin($name);
896 Releases a savepoint (does nothing outside a transaction).
897 Equivalent to calling $schema->storage->svp_release. See
898 L<DBIx::Class::Storage::DBI/"svp_release"> for more information.
903 my ($self, $name) = @_;
905 $self->storage or $self->throw_exception
906 ('svp_release called on $schema without storage');
908 $self->storage->svp_release($name);
913 Rollback to a savepoint (does nothing outside a transaction).
914 Equivalent to calling $schema->storage->svp_rollback. See
915 L<DBIx::Class::Storage::DBI/"svp_rollback"> for more information.
920 my ($self, $name) = @_;
922 $self->storage or $self->throw_exception
923 ('svp_rollback called on $schema without storage');
925 $self->storage->svp_rollback($name);
932 =item Return Value: $new_schema
936 Clones the schema and its associated result_source objects and returns the
943 my $clone = { (ref $self ? %$self : ()) };
944 bless $clone, (ref $self || $self);
946 $clone->class_mappings({ %{$clone->class_mappings} });
947 $clone->source_registrations({ %{$clone->source_registrations} });
948 foreach my $moniker ($self->sources) {
949 my $source = $self->source($moniker);
950 my $new = $source->new($source);
951 # we use extra here as we want to leave the class_mappings as they are
952 # but overwrite the source_registrations entry with the new source
953 $clone->register_extra_source($moniker => $new);
955 $clone->storage->set_schema($clone) if $clone->storage;
959 =head2 throw_exception
963 =item Arguments: $message
967 Throws an exception. Defaults to using L<Carp::Clan> to report errors from
968 user's perspective. See L</exception_action> for details on overriding
969 this method's behavior. If L</stacktrace> is turned on, C<throw_exception>'s
970 default behavior will provide a detailed stack trace.
974 sub throw_exception {
977 DBIx::Class::Exception->throw($_[0], $self->stacktrace)
978 if !$self->exception_action || !$self->exception_action->(@_);
985 =item Arguments: $sqlt_args, $dir
989 Attempts to deploy the schema to the current storage using L<SQL::Translator>.
991 See L<SQL::Translator/METHODS> for a list of values for C<$sqlt_args>. The most
992 common value for this would be C<< { add_drop_table => 1, } >> to have the SQL
993 produced include a DROP TABLE statement for each table created.
995 Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
996 ref or an array ref, containing a list of source to deploy. If present, then
997 only the sources listed will get deployed. Furthermore, you can use the
998 C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1004 my ($self, $sqltargs, $dir) = @_;
1005 $self->throw_exception("Can't deploy without storage") unless $self->storage;
1006 $self->storage->deploy($self, undef, $sqltargs, $dir);
1009 =head2 deployment_statements
1013 =item Arguments: $rdbms_type, $sqlt_args, $dir
1015 =item Return value: $listofstatements
1019 A convenient shortcut to storage->deployment_statements(). Returns the
1020 SQL statements used by L</deploy> and
1021 L<DBIx::Class::Schema::Storage/deploy>. C<$rdbms_type> provides the
1022 (optional) SQLT (not DBI) database driver name for which the SQL
1023 statements are produced. If not supplied, the type is determined by
1024 interrogating the current connection. The other two arguments are
1025 identical to those of L</deploy>.
1029 sub deployment_statements {
1032 $self->throw_exception("Can't generate deployment statements without a storage")
1033 if not $self->storage;
1035 $self->storage->deployment_statements($self, @_);
1038 =head2 create_ddl_dir (EXPERIMENTAL)
1042 =item Arguments: \@databases, $version, $directory, $preversion, $sqlt_args
1046 Creates an SQL file based on the Schema, for each of the specified
1047 database types, in the given directory. Given a previous version number,
1048 this will also create a file containing the ALTER TABLE statements to
1049 transform the previous schema into the current one. Note that these
1050 statements may contain DROP TABLE or DROP COLUMN statements that can
1051 potentially destroy data.
1053 The file names are created using the C<ddl_filename> method below, please
1054 override this method in your schema if you would like a different file
1055 name format. For the ALTER file, the same format is used, replacing
1056 $version in the name with "$preversion-$version".
1058 See L<DBIx::Class::Schema/deploy> for details of $sqlt_args.
1060 If no arguments are passed, then the following default values are used:
1064 =item databases - ['MySQL', 'SQLite', 'PostgreSQL']
1066 =item version - $schema->schema_version
1068 =item directory - './'
1070 =item preversion - <none>
1074 Note that this feature is currently EXPERIMENTAL and may not work correctly
1075 across all databases, or fully handle complex relationships.
1077 WARNING: Please check all SQL files created, before applying them.
1081 sub create_ddl_dir {
1084 $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1085 $self->storage->create_ddl_dir($self, @_);
1092 =item Arguments: $database-type, $version, $directory, $preversion
1094 =item Return value: $normalised_filename
1098 my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
1100 This method is called by C<create_ddl_dir> to compose a file name out of
1101 the supplied directory, database type and version number. The default file
1102 name format is: C<$dir$schema-$version-$type.sql>.
1104 You may override this method in your schema if you wish to use a different
1110 my ($self, $type, $version, $dir, $preversion) = @_;
1112 my $filename = ref($self);
1113 $filename =~ s/::/-/g;
1114 $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
1115 $filename =~ s/$version/$preversion-$version/ if($preversion);
1122 Provided as the recommended way of thawing schema objects. You can call
1123 C<Storable::thaw> directly if you wish, but the thawed objects will not have a
1124 reference to any schema, so are rather useless
1129 my ($self, $obj) = @_;
1130 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1131 return Storable::thaw($obj);
1136 This doesn't actualy do anything more than call L<Storable/freeze>, it is just
1137 provided here for symetry.
1142 return Storable::freeze($_[1]);
1147 Recommeneded way of dcloning objects. This is needed to properly maintain
1148 references to the schema object (which itself is B<not> cloned.)
1153 my ($self, $obj) = @_;
1154 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1155 return Storable::dclone($obj);
1158 =head2 schema_version
1160 Returns the current schema class' $VERSION in a normalised way.
1164 sub schema_version {
1166 my $class = ref($self)||$self;
1168 # does -not- use $schema->VERSION
1169 # since that varies in results depending on if version.pm is installed, and if
1170 # so the perl or XS versions. If you want this to change, bug the version.pm
1171 # author to make vpp and vxs behave the same.
1176 $version = ${"${class}::VERSION"};
1182 =head2 register_class
1186 =item Arguments: $moniker, $component_class
1190 This method is called by L</load_namespaces> and L</load_classes> to install the found classes into your Schema. You should be using those instead of this one.
1192 You will only need this method if you have your Result classes in
1193 files which are not named after the packages (or all in the same
1194 file). You may also need it to register classes at runtime.
1196 Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
1199 $schema->register_source($moniker, $component_class->result_source_instance);
1203 sub register_class {
1204 my ($self, $moniker, $to_register) = @_;
1205 $self->register_source($moniker => $to_register->result_source_instance);
1208 =head2 register_source
1212 =item Arguments: $moniker, $result_source
1216 This method is called by L</register_class>.
1218 Registers the L<DBIx::Class::ResultSource> in the schema with the given
1223 sub register_source {
1226 $self->_register_source(@_);
1229 =head2 register_extra_source
1233 =item Arguments: $moniker, $result_source
1237 As L</register_source> but should be used if the result class already
1238 has a source and you want to register an extra one.
1242 sub register_extra_source {
1245 $self->_register_source(@_, { extra => 1 });
1248 sub _register_source {
1249 my ($self, $moniker, $source, $params) = @_;
1251 $source = $source->new({ %$source, source_name => $moniker });
1253 my %reg = %{$self->source_registrations};
1254 $reg{$moniker} = $source;
1255 $self->source_registrations(\%reg);
1257 $source->schema($self);
1258 weaken($source->{schema}) if ref($self);
1259 return if ($params->{extra});
1261 if ($source->result_class) {
1262 my %map = %{$self->class_mappings};
1263 if (exists $map{$source->result_class}) {
1264 warn $source->result_class . ' already has a source, use register_extra_source for additional sources';
1266 $map{$source->result_class} = $moniker;
1267 $self->class_mappings(\%map);
1271 sub _unregister_source {
1272 my ($self, $moniker) = @_;
1273 my %reg = %{$self->source_registrations};
1275 my $source = delete $reg{$moniker};
1276 $self->source_registrations(\%reg);
1277 if ($source->result_class) {
1278 my %map = %{$self->class_mappings};
1279 delete $map{$source->result_class};
1280 $self->class_mappings(\%map);
1285 =head2 compose_connection (DEPRECATED)
1289 =item Arguments: $target_namespace, @db_info
1291 =item Return Value: $new_schema
1295 DEPRECATED. You probably wanted compose_namespace.
1297 Actually, you probably just wanted to call connect.
1301 (hidden due to deprecation)
1303 Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
1304 calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
1305 then injects the L<DBix::Class::ResultSetProxy> component and a
1306 resultset_instance classdata entry on all the new classes, in order to support
1307 $target_namespaces::$class->search(...) method calls.
1309 This is primarily useful when you have a specific need for class method access
1310 to a connection. In normal usage it is preferred to call
1311 L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
1312 on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
1322 sub compose_connection {
1323 my ($self, $target, @info) = @_;
1325 warn "compose_connection deprecated as of 0.08000"
1326 unless ($INC{"DBIx/Class/CDBICompat.pm"} || $warn++);
1328 my $base = 'DBIx::Class::ResultSetProxy';
1329 eval "require ${base};";
1330 $self->throw_exception
1331 ("No arguments to load_classes and couldn't load ${base} ($@)")
1334 if ($self eq $target) {
1335 # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
1336 foreach my $moniker ($self->sources) {
1337 my $source = $self->source($moniker);
1338 my $class = $source->result_class;
1339 $self->inject_base($class, $base);
1340 $class->mk_classdata(resultset_instance => $source->resultset);
1341 $class->mk_classdata(class_resolver => $self);
1343 $self->connection(@info);
1347 my $schema = $self->compose_namespace($target, $base);
1350 my $name = join '::', $target, 'schema';
1351 *$name = Sub::Name::subname $name, sub { $schema };
1354 $schema->connection(@info);
1355 foreach my $moniker ($schema->sources) {
1356 my $source = $schema->source($moniker);
1357 my $class = $source->result_class;
1358 #warn "$moniker $class $source ".$source->storage;
1359 $class->mk_classdata(result_source_instance => $source);
1360 $class->mk_classdata(resultset_instance => $source->resultset);
1361 $class->mk_classdata(class_resolver => $schema);
1371 Matt S. Trout <mst@shadowcatsystems.co.uk>
1375 You may distribute this code under the same terms as Perl itself.