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 # Finds all modules in the supplied namespace, or if omitted in the
161 # namespace of $class. Untaints all findings as they can be assumed
165 my $ns = shift || ref $proto || $proto;
167 my @mods = Module::Find::findallmod($ns);
169 # try to untaint module names. mods where this fails
170 # are left alone so we don't have to change the old behavior
171 no locale; # localized \w doesn't untaint expression
172 return map { $_ =~ m/^( (?:\w+::)* \w+ )$/x ? $1 : $_ } @mods;
175 # returns a hash of $shortname => $fullname for every package
176 # found in the given namespaces ($shortname is with the $fullname's
177 # namespace stripped off)
178 sub _map_namespaces {
179 my ($class, @namespaces) = @_;
182 foreach my $namespace (@namespaces) {
185 map { (substr($_, length "${namespace}::"), $_) }
186 $class->_findallmod($namespace)
193 # returns the result_source_instance for the passed class/object,
194 # or dies with an informative message (used by load_namespaces)
195 sub _ns_get_rsrc_instance {
197 my $rs = ref ($_[0]) || $_[0];
199 if ($rs->can ('result_source_instance') ) {
200 return $rs->result_source_instance;
203 $class->throw_exception (
204 "Attempt to load_namespaces() class $rs failed - are you sure this is a real Result Class?"
209 sub load_namespaces {
210 my ($class, %args) = @_;
212 my $result_namespace = delete $args{result_namespace} || 'Result';
213 my $resultset_namespace = delete $args{resultset_namespace} || 'ResultSet';
214 my $default_resultset_class = delete $args{default_resultset_class};
216 $class->throw_exception('load_namespaces: unknown option(s): '
217 . join(q{,}, map { qq{'$_'} } keys %args))
218 if scalar keys %args;
220 $default_resultset_class
221 = $class->_expand_relative_name($default_resultset_class);
223 for my $arg ($result_namespace, $resultset_namespace) {
224 $arg = [ $arg ] if !ref($arg) && $arg;
226 $class->throw_exception('load_namespaces: namespace arguments must be '
227 . 'a simple string or an arrayref')
228 if ref($arg) ne 'ARRAY';
230 $_ = $class->_expand_relative_name($_) for (@$arg);
233 my %results = $class->_map_namespaces(@$result_namespace);
234 my %resultsets = $class->_map_namespaces(@$resultset_namespace);
238 no warnings 'redefine';
239 local *Class::C3::reinitialize = sub { };
240 use warnings 'redefine';
242 # ensure classes are loaded and fetch properly sorted classes
243 $class->ensure_class_loaded($_) foreach(values %results);
244 my @subclass_last = sort { $results{$a}->isa($results{$b}) } keys(%results);
246 foreach my $result (@subclass_last) {
247 my $result_class = $results{$result};
249 my $rs_class = delete $resultsets{$result};
250 my $rs_set = $class->_ns_get_rsrc_instance ($result_class)->resultset_class;
252 if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
253 if($rs_class && $rs_class ne $rs_set) {
254 carp "We found ResultSet class '$rs_class' for '$result', but it seems "
255 . "that you had already set '$result' to use '$rs_set' instead";
258 elsif($rs_class ||= $default_resultset_class) {
259 $class->ensure_class_loaded($rs_class);
260 $class->_ns_get_rsrc_instance ($result_class)->resultset_class($rs_class);
263 my $source_name = $class->_ns_get_rsrc_instance ($result_class)->source_name || $result;
265 push(@to_register, [ $source_name, $result_class ]);
269 foreach (sort keys %resultsets) {
270 carp "load_namespaces found ResultSet class $_ with no "
271 . 'corresponding Result class';
274 Class::C3->reinitialize;
275 $class->register_class(@$_) for (@to_register);
284 =item Arguments: @classes?, { $namespace => [ @classes ] }+
288 L</load_classes> is an alternative method to L</load_namespaces>, both of
289 which serve similar purposes, each with different advantages and disadvantages.
290 In the general case you should use L</load_namespaces>, unless you need to
291 be able to specify that only specific classes are loaded at runtime.
293 With no arguments, this method uses L<Module::Find> to find all classes under
294 the schema's namespace. Otherwise, this method loads the classes you specify
295 (using L<use>), and registers them (using L</"register_class">).
297 It is possible to comment out classes with a leading C<#>, but note that perl
298 will think it's a mistake (trying to use a comment in a qw list), so you'll
299 need to add C<no warnings 'qw';> before your load_classes call.
301 If any classes found do not appear to be Result class files, you will
302 get the following warning:
304 Failed to load $comp_class. Can't find source_name method. Is
305 $comp_class really a full DBIC result class? Fix it, move it elsewhere,
306 or make your load_classes call more specific.
310 My::Schema->load_classes(); # loads My::Schema::CD, My::Schema::Artist,
311 # etc. (anything under the My::Schema namespace)
313 # loads My::Schema::CD, My::Schema::Artist, Other::Namespace::Producer but
314 # not Other::Namespace::LinerNotes nor My::Schema::Track
315 My::Schema->load_classes(qw/ CD Artist #Track /, {
316 Other::Namespace => [qw/ Producer #LinerNotes /],
322 my ($class, @params) = @_;
327 foreach my $param (@params) {
328 if (ref $param eq 'ARRAY') {
329 # filter out commented entries
330 my @modules = grep { $_ !~ /^#/ } @$param;
332 push (@{$comps_for{$class}}, @modules);
334 elsif (ref $param eq 'HASH') {
335 # more than one namespace possible
336 for my $comp ( keys %$param ) {
337 # filter out commented entries
338 my @modules = grep { $_ !~ /^#/ } @{$param->{$comp}};
340 push (@{$comps_for{$comp}}, @modules);
344 # filter out commented entries
345 push (@{$comps_for{$class}}, $param) if $param !~ /^#/;
349 my @comp = map { substr $_, length "${class}::" }
351 $comps_for{$class} = \@comp;
356 no warnings qw/redefine/;
357 local *Class::C3::reinitialize = sub { };
358 foreach my $prefix (keys %comps_for) {
359 foreach my $comp (@{$comps_for{$prefix}||[]}) {
360 my $comp_class = "${prefix}::${comp}";
361 $class->ensure_class_loaded($comp_class);
363 my $snsub = $comp_class->can('source_name');
365 carp "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.";
368 $comp = $snsub->($comp_class) || $comp;
370 push(@to_register, [ $comp, $comp_class ]);
374 Class::C3->reinitialize;
376 foreach my $to (@to_register) {
377 $class->register_class(@$to);
378 # if $class->can('result_source_instance');
386 =item Arguments: $storage_type|{$storage_type, \%args}
388 =item Return value: $storage_type|{$storage_type, \%args}
390 =item Default value: DBIx::Class::Storage::DBI
394 Set the storage class that will be instantiated when L</connect> is called.
395 If the classname starts with C<::>, the prefix C<DBIx::Class::Storage> is
396 assumed by L</connect>.
398 You want to use this to set subclasses of L<DBIx::Class::Storage::DBI>
399 in cases where the appropriate subclass is not autodetected, such as
400 when dealing with MSSQL via L<DBD::Sybase>, in which case you'd set it
401 to C<::DBI::Sybase::MSSQL>.
403 If your storage type requires instantiation arguments, those are
404 defined as a second argument in the form of a hashref and the entire
405 value needs to be wrapped into an arrayref or a hashref. We support
406 both types of refs here in order to play nice with your
407 Config::[class] or your choice. See
408 L<DBIx::Class::Storage::DBI::Replicated> for an example of this.
410 =head2 exception_action
414 =item Arguments: $code_reference
416 =item Return value: $code_reference
418 =item Default value: None
422 If C<exception_action> is set for this class/object, L</throw_exception>
423 will prefer to call this code reference with the exception as an argument,
424 rather than L<DBIx::Class::Exception/throw>.
426 Your subroutine should probably just wrap the error in the exception
427 object/class of your choosing and rethrow. If, against all sage advice,
428 you'd like your C<exception_action> to suppress a particular exception
429 completely, simply have it return true.
434 use base qw/DBIx::Class::Schema/;
435 use My::ExceptionClass;
436 __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
437 __PACKAGE__->load_classes;
440 my $schema_obj = My::Schema->connect( .... );
441 $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
443 # suppress all exceptions, like a moron:
444 $schema_obj->exception_action(sub { 1 });
450 =item Arguments: boolean
454 Whether L</throw_exception> should include stack trace information.
455 Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
458 =head2 sqlt_deploy_hook
462 =item Arguments: $sqlt_schema
466 An optional sub which you can declare in your own Schema class that will get
467 passed the L<SQL::Translator::Schema> object when you deploy the schema via
468 L</create_ddl_dir> or L</deploy>.
470 For an example of what you can do with this, see
471 L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
473 Note that sqlt_deploy_hook is called by L</deployment_statements>, which in turn
474 is called before L</deploy>. Therefore the hook can be used only to manipulate
475 the L<SQL::Translator::Schema> object before it is turned into SQL fed to the
476 database. If you want to execute post-deploy statements which can not be generated
477 by L<SQL::Translator>, the currently suggested method is to overload L</deploy>
478 and use L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
486 =item Arguments: @connectinfo
488 =item Return Value: $new_schema
492 Creates and returns a new Schema object. The connection info set on it
493 is used to create a new instance of the storage backend and set it on
496 See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific
497 syntax on the C<@connectinfo> argument, or L<DBIx::Class::Storage> in
500 Note that C<connect_info> expects an arrayref of arguments, but
501 C<connect> does not. C<connect> wraps it's arguments in an arrayref
502 before passing them to C<connect_info>.
506 C<connect> is a convenience method. It is equivalent to calling
507 $schema->clone->connection(@connectinfo). To write your own overloaded
508 version, overload L</connection> instead.
512 sub connect { shift->clone->connection(@_) }
518 =item Arguments: $source_name
520 =item Return Value: $resultset
524 my $rs = $schema->resultset('DVD');
526 Returns the L<DBIx::Class::ResultSet> object for the registered source
532 my ($self, $moniker) = @_;
533 return $self->source($moniker)->resultset;
540 =item Return Value: @source_names
544 my @source_names = $schema->sources;
546 Lists names of all the sources registered on this Schema object.
550 sub sources { return keys %{shift->source_registrations}; }
556 =item Arguments: $source_name
558 =item Return Value: $result_source
562 my $source = $schema->source('Book');
564 Returns the L<DBIx::Class::ResultSource> object for the registered
570 my ($self, $moniker) = @_;
571 my $sreg = $self->source_registrations;
572 return $sreg->{$moniker} if exists $sreg->{$moniker};
574 # if we got here, they probably passed a full class name
575 my $mapped = $self->class_mappings->{$moniker};
576 $self->throw_exception("Can't find source for ${moniker}")
577 unless $mapped && exists $sreg->{$mapped};
578 return $sreg->{$mapped};
585 =item Arguments: $source_name
587 =item Return Value: $classname
591 my $class = $schema->class('CD');
593 Retrieves the Result class name for the given source name.
598 my ($self, $moniker) = @_;
599 return $self->source($moniker)->result_class;
606 =item Arguments: C<$coderef>, @coderef_args?
608 =item Return Value: The return value of $coderef
612 Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
613 returning its result (if any). Equivalent to calling $schema->storage->txn_do.
614 See L<DBIx::Class::Storage/"txn_do"> for more information.
616 This interface is preferred over using the individual methods L</txn_begin>,
617 L</txn_commit>, and L</txn_rollback> below.
619 WARNING: If you are connected with C<AutoCommit => 0> the transaction is
620 considered nested, and you will still need to call L</txn_commit> to write your
621 changes when appropriate. You will also want to connect with C<auto_savepoint =>
622 1> to get partial rollback to work, if the storage driver for your database
625 Connecting with C<AutoCommit => 1> is recommended.
632 $self->storage or $self->throw_exception
633 ('txn_do called on $schema without storage');
635 $self->storage->txn_do(@_);
638 =head2 txn_scope_guard
640 Runs C<txn_scope_guard> on the schema's storage. See
641 L<DBIx::Class::Storage/txn_scope_guard>.
645 sub txn_scope_guard {
648 $self->storage or $self->throw_exception
649 ('txn_scope_guard called on $schema without storage');
651 $self->storage->txn_scope_guard(@_);
656 Begins a transaction (does nothing if AutoCommit is off). Equivalent to
657 calling $schema->storage->txn_begin. See
658 L<DBIx::Class::Storage::DBI/"txn_begin"> for more information.
665 $self->storage or $self->throw_exception
666 ('txn_begin called on $schema without storage');
668 $self->storage->txn_begin;
673 Commits the current transaction. Equivalent to calling
674 $schema->storage->txn_commit. See L<DBIx::Class::Storage::DBI/"txn_commit">
675 for more information.
682 $self->storage or $self->throw_exception
683 ('txn_commit called on $schema without storage');
685 $self->storage->txn_commit;
690 Rolls back the current transaction. Equivalent to calling
691 $schema->storage->txn_rollback. See
692 L<DBIx::Class::Storage::DBI/"txn_rollback"> for more information.
699 $self->storage or $self->throw_exception
700 ('txn_rollback called on $schema without storage');
702 $self->storage->txn_rollback;
707 my $storage = $schema->storage;
709 Returns the L<DBIx::Class::Storage> object for this Schema. Grab this
710 if you want to turn on SQL statement debugging at runtime, or set the
711 quote character. For the default storage, the documentation can be
712 found in L<DBIx::Class::Storage::DBI>.
718 =item Arguments: $source_name, \@data;
720 =item Return value: \@$objects | nothing
724 Pass this method a resultsource name, and an arrayref of
725 arrayrefs. The arrayrefs should contain a list of column names,
726 followed by one or many sets of matching data for the given columns.
728 In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
729 to insert the data, as this is a fast method. However, insert_bulk currently
730 assumes that your datasets all contain the same type of values, using scalar
731 references in a column in one row, and not in another will probably not work.
733 Otherwise, each set of data is inserted into the database using
734 L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
739 $schema->populate('Artist', [
740 [ qw/artistid name/ ],
741 [ 1, 'Popular Band' ],
746 Since wantarray context is basically the same as looping over $rs->create(...)
747 you won't see any performance benefits and in this case the method is more for
748 convenience. Void context sends the column information directly to storage
749 using <DBI>s bulk insert method. So the performance will be much better for
750 storages that support this method.
752 Because of this difference in the way void context inserts rows into your
753 database you need to note how this will effect any loaded components that
754 override or augment insert. For example if you are using a component such
755 as L<DBIx::Class::UUIDColumns> to populate your primary keys you MUST use
756 wantarray context if you want the PKs automatically created.
761 my ($self, $name, $data) = @_;
762 if(my $rs = $self->resultset($name)) {
763 if(defined wantarray) {
764 return $rs->populate($data);
766 $rs->populate($data);
769 $self->throw_exception("$name is not a resultset");
777 =item Arguments: @args
779 =item Return Value: $new_schema
783 Similar to L</connect> except sets the storage object and connection
784 data in-place on the Schema class. You should probably be calling
785 L</connect> to get a proper Schema object instead.
789 Overload C<connection> to change the behaviour of C<connect>.
794 my ($self, @info) = @_;
795 return $self if !@info && $self->storage;
797 my ($storage_class, $args) = ref $self->storage_type ?
798 ($self->_normalize_storage_type($self->storage_type),{}) : ($self->storage_type, {});
800 $storage_class = 'DBIx::Class::Storage'.$storage_class
801 if $storage_class =~ m/^::/;
802 eval "require ${storage_class};";
803 $self->throw_exception(
804 "No arguments to load_classes and couldn't load ${storage_class} ($@)"
806 my $storage = $storage_class->new($self=>$args);
807 $storage->connect_info(\@info);
808 $self->storage($storage);
812 sub _normalize_storage_type {
813 my ($self, $storage_type) = @_;
814 if(ref $storage_type eq 'ARRAY') {
815 return @$storage_type;
816 } elsif(ref $storage_type eq 'HASH') {
817 return %$storage_type;
819 $self->throw_exception('Unsupported REFTYPE given: '. ref $storage_type);
823 =head2 compose_namespace
827 =item Arguments: $target_namespace, $additional_base_class?
829 =item Retur Value: $new_schema
833 For each L<DBIx::Class::ResultSource> in the schema, this method creates a
834 class in the target namespace (e.g. $target_namespace::CD,
835 $target_namespace::Artist) that inherits from the corresponding classes
836 attached to the current schema.
838 It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
839 new $schema object. If C<$additional_base_class> is given, the new composed
840 classes will inherit from first the corresponding classe from the current
841 schema then the base class.
843 For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
845 $schema->compose_namespace('My::DB', 'Base::Class');
846 print join (', ', @My::DB::CD::ISA) . "\n";
847 print join (', ', @My::DB::Artist::ISA) ."\n";
849 will produce the output
851 My::Schema::CD, Base::Class
852 My::Schema::Artist, Base::Class
856 # this might be oversimplified
857 # sub compose_namespace {
858 # my ($self, $target, $base) = @_;
860 # my $schema = $self->clone;
861 # foreach my $moniker ($schema->sources) {
862 # my $source = $schema->source($moniker);
863 # my $target_class = "${target}::${moniker}";
864 # $self->inject_base(
865 # $target_class => $source->result_class, ($base ? $base : ())
867 # $source->result_class($target_class);
868 # $target_class->result_source_instance($source)
869 # if $target_class->can('result_source_instance');
870 # $schema->register_source($moniker, $source);
875 sub compose_namespace {
876 my ($self, $target, $base) = @_;
877 my $schema = $self->clone;
879 no warnings qw/redefine/;
880 # local *Class::C3::reinitialize = sub { };
881 foreach my $moniker ($schema->sources) {
882 my $source = $schema->source($moniker);
883 my $target_class = "${target}::${moniker}";
885 $target_class => $source->result_class, ($base ? $base : ())
887 $source->result_class($target_class);
888 $target_class->result_source_instance($source)
889 if $target_class->can('result_source_instance');
890 $schema->register_source($moniker, $source);
893 # Class::C3->reinitialize();
896 no warnings 'redefine';
897 foreach my $meth (qw/class source resultset/) {
898 *{"${target}::${meth}"} =
899 sub { shift->schema->$meth(@_) };
905 sub setup_connection_class {
906 my ($class, $target, @info) = @_;
907 $class->inject_base($target => 'DBIx::Class::DB');
908 #$target->load_components('DB');
909 $target->connection(@info);
914 Creates a new savepoint (does nothing outside a transaction).
915 Equivalent to calling $schema->storage->svp_begin. See
916 L<DBIx::Class::Storage::DBI/"svp_begin"> for more information.
921 my ($self, $name) = @_;
923 $self->storage or $self->throw_exception
924 ('svp_begin called on $schema without storage');
926 $self->storage->svp_begin($name);
931 Releases a savepoint (does nothing outside a transaction).
932 Equivalent to calling $schema->storage->svp_release. See
933 L<DBIx::Class::Storage::DBI/"svp_release"> for more information.
938 my ($self, $name) = @_;
940 $self->storage or $self->throw_exception
941 ('svp_release called on $schema without storage');
943 $self->storage->svp_release($name);
948 Rollback to a savepoint (does nothing outside a transaction).
949 Equivalent to calling $schema->storage->svp_rollback. See
950 L<DBIx::Class::Storage::DBI/"svp_rollback"> for more information.
955 my ($self, $name) = @_;
957 $self->storage or $self->throw_exception
958 ('svp_rollback called on $schema without storage');
960 $self->storage->svp_rollback($name);
967 =item Return Value: $new_schema
971 Clones the schema and its associated result_source objects and returns the
978 my $clone = { (ref $self ? %$self : ()) };
979 bless $clone, (ref $self || $self);
981 $clone->class_mappings({ %{$clone->class_mappings} });
982 $clone->source_registrations({ %{$clone->source_registrations} });
983 foreach my $moniker ($self->sources) {
984 my $source = $self->source($moniker);
985 my $new = $source->new($source);
986 # we use extra here as we want to leave the class_mappings as they are
987 # but overwrite the source_registrations entry with the new source
988 $clone->register_extra_source($moniker => $new);
990 $clone->storage->set_schema($clone) if $clone->storage;
994 =head2 throw_exception
998 =item Arguments: $message
1002 Throws an exception. Defaults to using L<Carp::Clan> to report errors from
1003 user's perspective. See L</exception_action> for details on overriding
1004 this method's behavior. If L</stacktrace> is turned on, C<throw_exception>'s
1005 default behavior will provide a detailed stack trace.
1009 sub throw_exception {
1012 DBIx::Class::Exception->throw($_[0], $self->stacktrace)
1013 if !$self->exception_action || !$self->exception_action->(@_);
1020 =item Arguments: \%sqlt_args, $dir
1024 Attempts to deploy the schema to the current storage using L<SQL::Translator>.
1026 See L<SQL::Translator/METHODS> for a list of values for C<\%sqlt_args>.
1027 The most common value for this would be C<< { add_drop_table => 1 } >>
1028 to have the SQL produced include a C<DROP TABLE> statement for each table
1029 created. For quoting purposes supply C<quote_table_names> and
1030 C<quote_field_names>.
1032 Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
1033 ref or an array ref, containing a list of source to deploy. If present, then
1034 only the sources listed will get deployed. Furthermore, you can use the
1035 C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1041 my ($self, $sqltargs, $dir) = @_;
1042 $self->throw_exception("Can't deploy without storage") unless $self->storage;
1043 $self->storage->deploy($self, undef, $sqltargs, $dir);
1046 =head2 deployment_statements
1050 =item Arguments: See L<DBIx::Class::Storage::DBI/deployment_statements>
1052 =item Return value: $listofstatements
1056 A convenient shortcut to
1057 C<< $self->storage->deployment_statements($self, @args) >>.
1058 Returns the SQL statements used by L</deploy> and
1059 L<DBIx::Class::Schema::Storage/deploy>.
1063 sub deployment_statements {
1066 $self->throw_exception("Can't generate deployment statements without a storage")
1067 if not $self->storage;
1069 $self->storage->deployment_statements($self, @_);
1072 =head2 create_ddl_dir (EXPERIMENTAL)
1076 =item Arguments: See L<DBIx::Class::Storage::DBI/create_ddl_dir>
1080 A convenient shortcut to
1081 C<< $self->storage->create_ddl_dir($self, @args) >>.
1083 Creates an SQL file based on the Schema, for each of the specified
1084 database types, in the given directory.
1088 sub create_ddl_dir {
1091 $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1092 $self->storage->create_ddl_dir($self, @_);
1099 =item Arguments: $database-type, $version, $directory, $preversion
1101 =item Return value: $normalised_filename
1105 my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
1107 This method is called by C<create_ddl_dir> to compose a file name out of
1108 the supplied directory, database type and version number. The default file
1109 name format is: C<$dir$schema-$version-$type.sql>.
1111 You may override this method in your schema if you wish to use a different
1117 my ($self, $type, $version, $dir, $preversion) = @_;
1119 my $filename = ref($self);
1120 $filename =~ s/::/-/g;
1121 $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
1122 $filename =~ s/$version/$preversion-$version/ if($preversion);
1129 Provided as the recommended way of thawing schema objects. You can call
1130 C<Storable::thaw> directly if you wish, but the thawed objects will not have a
1131 reference to any schema, so are rather useless
1136 my ($self, $obj) = @_;
1137 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1138 return Storable::thaw($obj);
1143 This doesn't actualy do anything more than call L<Storable/freeze>, it is just
1144 provided here for symetry.
1149 return Storable::freeze($_[1]);
1154 Recommeneded way of dcloning objects. This is needed to properly maintain
1155 references to the schema object (which itself is B<not> cloned.)
1160 my ($self, $obj) = @_;
1161 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1162 return Storable::dclone($obj);
1165 =head2 schema_version
1167 Returns the current schema class' $VERSION in a normalised way.
1171 sub schema_version {
1173 my $class = ref($self)||$self;
1175 # does -not- use $schema->VERSION
1176 # since that varies in results depending on if version.pm is installed, and if
1177 # so the perl or XS versions. If you want this to change, bug the version.pm
1178 # author to make vpp and vxs behave the same.
1183 $version = ${"${class}::VERSION"};
1189 =head2 register_class
1193 =item Arguments: $moniker, $component_class
1197 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.
1199 You will only need this method if you have your Result classes in
1200 files which are not named after the packages (or all in the same
1201 file). You may also need it to register classes at runtime.
1203 Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
1206 $schema->register_source($moniker, $component_class->result_source_instance);
1210 sub register_class {
1211 my ($self, $moniker, $to_register) = @_;
1212 $self->register_source($moniker => $to_register->result_source_instance);
1215 =head2 register_source
1219 =item Arguments: $moniker, $result_source
1223 This method is called by L</register_class>.
1225 Registers the L<DBIx::Class::ResultSource> in the schema with the given
1230 sub register_source {
1233 $self->_register_source(@_);
1236 =head2 register_extra_source
1240 =item Arguments: $moniker, $result_source
1244 As L</register_source> but should be used if the result class already
1245 has a source and you want to register an extra one.
1249 sub register_extra_source {
1252 $self->_register_source(@_, { extra => 1 });
1255 sub _register_source {
1256 my ($self, $moniker, $source, $params) = @_;
1258 my $orig_source = $source;
1260 $source = $source->new({ %$source, source_name => $moniker });
1261 $source->schema($self);
1262 weaken($source->{schema}) if ref($self);
1264 my $rs_class = $source->result_class;
1266 my %reg = %{$self->source_registrations};
1267 $reg{$moniker} = $source;
1268 $self->source_registrations(\%reg);
1270 return if ($params->{extra});
1271 return unless defined($rs_class) && $rs_class->can('result_source_instance');
1273 my %map = %{$self->class_mappings};
1275 exists $map{$rs_class}
1277 $map{$rs_class} ne $moniker
1279 $rs_class->result_source_instance ne $orig_source
1281 carp "$rs_class already has a source, use register_extra_source for additional sources";
1283 $map{$rs_class} = $moniker;
1284 $self->class_mappings(\%map);
1287 sub _unregister_source {
1288 my ($self, $moniker) = @_;
1289 my %reg = %{$self->source_registrations};
1291 my $source = delete $reg{$moniker};
1292 $self->source_registrations(\%reg);
1293 if ($source->result_class) {
1294 my %map = %{$self->class_mappings};
1295 delete $map{$source->result_class};
1296 $self->class_mappings(\%map);
1301 =head2 compose_connection (DEPRECATED)
1305 =item Arguments: $target_namespace, @db_info
1307 =item Return Value: $new_schema
1311 DEPRECATED. You probably wanted compose_namespace.
1313 Actually, you probably just wanted to call connect.
1317 (hidden due to deprecation)
1319 Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
1320 calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
1321 then injects the L<DBix::Class::ResultSetProxy> component and a
1322 resultset_instance classdata entry on all the new classes, in order to support
1323 $target_namespaces::$class->search(...) method calls.
1325 This is primarily useful when you have a specific need for class method access
1326 to a connection. In normal usage it is preferred to call
1327 L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
1328 on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
1338 sub compose_connection {
1339 my ($self, $target, @info) = @_;
1341 carp "compose_connection deprecated as of 0.08000"
1342 unless ($INC{"DBIx/Class/CDBICompat.pm"} || $warn++);
1344 my $base = 'DBIx::Class::ResultSetProxy';
1345 eval "require ${base};";
1346 $self->throw_exception
1347 ("No arguments to load_classes and couldn't load ${base} ($@)")
1350 if ($self eq $target) {
1351 # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
1352 foreach my $moniker ($self->sources) {
1353 my $source = $self->source($moniker);
1354 my $class = $source->result_class;
1355 $self->inject_base($class, $base);
1356 $class->mk_classdata(resultset_instance => $source->resultset);
1357 $class->mk_classdata(class_resolver => $self);
1359 $self->connection(@info);
1363 my $schema = $self->compose_namespace($target, $base);
1366 my $name = join '::', $target, 'schema';
1367 *$name = Sub::Name::subname $name, sub { $schema };
1370 $schema->connection(@info);
1371 foreach my $moniker ($schema->sources) {
1372 my $source = $schema->source($moniker);
1373 my $class = $source->result_class;
1374 #warn "$moniker $class $source ".$source->storage;
1375 $class->mk_classdata(result_source_instance => $source);
1376 $class->mk_classdata(resultset_instance => $source->resultset);
1377 $class->mk_classdata(class_resolver => $schema);
1387 Matt S. Trout <mst@shadowcatsystems.co.uk>
1391 You may distribute this code under the same terms as Perl itself.