fix master debug output for ::Replicated
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Schema.pm
CommitLineData
a02675cd 1package DBIx::Class::Schema;
2
3use strict;
4use warnings;
aa562407 5
4981dc70 6use DBIx::Class::Exception;
701da8c4 7use Carp::Clan qw/^DBIx::Class/;
a917fb06 8use Scalar::Util qw/weaken/;
c9d2e0a2 9use File::Spec;
ddc0a6c8 10use Sub::Name ();
7cb86b38 11require Module::Find;
a02675cd 12
41a6f8c0 13use base qw/DBIx::Class/;
a02675cd 14
0dc79249 15__PACKAGE__->mk_classdata('class_mappings' => {});
16__PACKAGE__->mk_classdata('source_registrations' => {});
1e10a11d 17__PACKAGE__->mk_classdata('storage_type' => '::DBI');
d7156e50 18__PACKAGE__->mk_classdata('storage');
82cc0386 19__PACKAGE__->mk_classdata('exception_action');
4b946902 20__PACKAGE__->mk_classdata('stacktrace' => $ENV{DBIC_TRACE} || 0);
e6c747fd 21__PACKAGE__->mk_classdata('default_resultset_attributes' => {});
a02675cd 22
c2da098a 23=head1 NAME
24
25DBIx::Class::Schema - composable schemas
26
27=head1 SYNOPSIS
28
24d67825 29 package Library::Schema;
c2da098a 30 use base qw/DBIx::Class::Schema/;
bab77431 31
829517d4 32 # load all Result classes in Library/Schema/Result/
33 __PACKAGE__->load_namespaces();
c2da098a 34
829517d4 35 package Library::Schema::Result::CD;
03312470 36 use base qw/DBIx::Class/;
829517d4 37 __PACKAGE__->load_components(qw/Core/); # for example
24d67825 38 __PACKAGE__->table('cd');
c2da098a 39
5d9076f2 40 # Elsewhere in your code:
24d67825 41 my $schema1 = Library::Schema->connect(
a3d93194 42 $dsn,
43 $user,
44 $password,
24d67825 45 { AutoCommit => 0 },
a3d93194 46 );
bab77431 47
24d67825 48 my $schema2 = Library::Schema->connect($coderef_returning_dbh);
c2da098a 49
829517d4 50 # fetch objects using Library::Schema::Result::DVD
24d67825 51 my $resultset = $schema1->resultset('DVD')->search( ... );
52 my @dvd_objects = $schema2->resultset('DVD')->search( ... );
c2da098a 53
54=head1 DESCRIPTION
55
a3d93194 56Creates database classes based on a schema. This is the recommended way to
57use L<DBIx::Class> and allows you to use more than one concurrent connection
58with your classes.
429bd4f1 59
03312470 60NB: If you're used to L<Class::DBI> it's worth reading the L</SYNOPSIS>
2053ab2a 61carefully, as DBIx::Class does things a little differently. Note in
03312470 62particular which module inherits off which.
63
829517d4 64=head1 SETUP METHODS
c2da098a 65
829517d4 66=head2 load_namespaces
87c4e602 67
27f01d1f 68=over 4
69
829517d4 70=item Arguments: %options?
27f01d1f 71
72=back
076652e8 73
829517d4 74 __PACKAGE__->load_namespaces();
66d9ef6b 75
829517d4 76 __PACKAGE__->load_namespaces(
77 result_namespace => 'Res',
78 resultset_namespace => 'RSet',
79 default_resultset_class => '+MyDB::Othernamespace::RSet',
80 );
076652e8 81
829517d4 82With no arguments, this method uses L<Module::Find> to load all your
83Result classes from a sub-namespace F<Result> under your Schema class'
84namespace. Eg. With a Schema of I<MyDB::Schema> all files in
85I<MyDB::Schema::Result> are assumed to be Result classes.
c2da098a 86
829517d4 87It also finds all ResultSet classes in the namespace F<ResultSet> and
88loads them into the appropriate Result classes using for you. The
89matching is done by assuming the package name of the ResultSet class
90is the same as that of the Result class.
74b92d9a 91
672687db 92You will be warned if ResultSet classes are discovered for which there
829517d4 93are no matching Result classes like this:
87c4e602 94
829517d4 95 load_namespaces found ResultSet class $classname with no corresponding Result class
27f01d1f 96
829517d4 97If a Result class is found to already have a ResultSet class set using
98L</resultset_class> to some other class, you will be warned like this:
27f01d1f 99
829517d4 100 We found ResultSet class '$rs_class' for '$result', but it seems
101 that you had already set '$result' to use '$rs_set' instead
076652e8 102
829517d4 103Both of the sub-namespaces are configurable if you don't like the defaults,
104via the options C<result_namespace> and C<resultset_namespace>.
076652e8 105
829517d4 106If (and only if) you specify the option C<default_resultset_class>, any found
107Result classes for which we do not find a corresponding
108ResultSet class will have their C<resultset_class> set to
109C<default_resultset_class>.
076652e8 110
829517d4 111All of the namespace and classname options to this method are relative to
112the schema classname by default. To specify a fully-qualified name, prefix
113it with a literal C<+>.
2a4d9487 114
829517d4 115Examples:
2a4d9487 116
829517d4 117 # load My::Schema::Result::CD, My::Schema::Result::Artist,
118 # My::Schema::ResultSet::CD, etc...
119 My::Schema->load_namespaces;
2a4d9487 120
829517d4 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',
129 );
2a4d9487 130
829517d4 131 # Put things in other namespaces
132 My::Schema->load_namespaces(
133 result_namespace => '+Some::Place::Results',
134 resultset_namespace => '+Another::Place::RSets',
135 );
2a4d9487 136
829517d4 137If you'd like to use multiple namespaces of each type, simply use an arrayref
138of namespaces for that option. In the case that the same result
139(or resultset) class exists in multiple namespaces, the latter entries in
140your list of namespaces will override earlier ones.
2a4d9487 141
829517d4 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' ],
146 );
2a4d9487 147
148=cut
149
829517d4 150# Pre-pends our classname to the given relative classname or
151# class namespace, unless there is a '+' prefix, which will
152# be stripped.
153sub _expand_relative_name {
154 my ($class, $name) = @_;
155 return if !$name;
156 $name = $class . '::' . $name if ! ($name =~ s/^\+//);
157 return $name;
2a4d9487 158}
159
f3405058 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
162# to be safe
163sub _findallmod {
164 my $proto = shift;
165 my $ns = shift || ref $proto || $proto;
166
167 my @mods = Module::Find::findallmod($ns);
168
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;
173}
174
829517d4 175# returns a hash of $shortname => $fullname for every package
b488020e 176# found in the given namespaces ($shortname is with the $fullname's
177# namespace stripped off)
829517d4 178sub _map_namespaces {
179 my ($class, @namespaces) = @_;
6eec9003 180
829517d4 181 my @results_hash;
182 foreach my $namespace (@namespaces) {
183 push(
184 @results_hash,
185 map { (substr($_, length "${namespace}::"), $_) }
f3405058 186 $class->_findallmod($namespace)
829517d4 187 );
0dc79249 188 }
27f01d1f 189
829517d4 190 @results_hash;
ea20d0fd 191}
192
b488020e 193# returns the result_source_instance for the passed class/object,
194# or dies with an informative message (used by load_namespaces)
195sub _ns_get_rsrc_instance {
196 my $class = shift;
197 my $rs = ref ($_[0]) || $_[0];
198
199 if ($rs->can ('result_source_instance') ) {
200 return $rs->result_source_instance;
201 }
202 else {
203 $class->throw_exception (
204 "Attempt to load_namespaces() class $rs failed - are you sure this is a real Result Class?"
205 );
206 }
207}
208
829517d4 209sub load_namespaces {
210 my ($class, %args) = @_;
0dc79249 211
829517d4 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};
0dc79249 215
829517d4 216 $class->throw_exception('load_namespaces: unknown option(s): '
217 . join(q{,}, map { qq{'$_'} } keys %args))
218 if scalar keys %args;
0dc79249 219
829517d4 220 $default_resultset_class
221 = $class->_expand_relative_name($default_resultset_class);
9b1ba0f2 222
829517d4 223 for my $arg ($result_namespace, $resultset_namespace) {
224 $arg = [ $arg ] if !ref($arg) && $arg;
9b1ba0f2 225
829517d4 226 $class->throw_exception('load_namespaces: namespace arguments must be '
227 . 'a simple string or an arrayref')
228 if ref($arg) ne 'ARRAY';
9b1ba0f2 229
829517d4 230 $_ = $class->_expand_relative_name($_) for (@$arg);
231 }
ea20d0fd 232
829517d4 233 my %results = $class->_map_namespaces(@$result_namespace);
234 my %resultsets = $class->_map_namespaces(@$resultset_namespace);
27f01d1f 235
829517d4 236 my @to_register;
237 {
238 no warnings 'redefine';
239 local *Class::C3::reinitialize = sub { };
240 use warnings 'redefine';
27f01d1f 241
3d27f771 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);
245
246 foreach my $result (@subclass_last) {
829517d4 247 my $result_class = $results{$result};
82b01c38 248
829517d4 249 my $rs_class = delete $resultsets{$result};
b488020e 250 my $rs_set = $class->_ns_get_rsrc_instance ($result_class)->resultset_class;
3d27f771 251
829517d4 252 if($rs_set && $rs_set ne 'DBIx::Class::ResultSet') {
3d27f771 253 if($rs_class && $rs_class ne $rs_set) {
341d5ede 254 carp "We found ResultSet class '$rs_class' for '$result', but it seems "
829517d4 255 . "that you had already set '$result' to use '$rs_set' instead";
256 }
257 }
258 elsif($rs_class ||= $default_resultset_class) {
259 $class->ensure_class_loaded($rs_class);
b488020e 260 $class->_ns_get_rsrc_instance ($result_class)->resultset_class($rs_class);
829517d4 261 }
82b01c38 262
b488020e 263 my $source_name = $class->_ns_get_rsrc_instance ($result_class)->source_name || $result;
0e6c5d58 264
265 push(@to_register, [ $source_name, $result_class ]);
829517d4 266 }
267 }
ea20d0fd 268
829517d4 269 foreach (sort keys %resultsets) {
341d5ede 270 carp "load_namespaces found ResultSet class $_ with no "
829517d4 271 . 'corresponding Result class';
272 }
ea20d0fd 273
829517d4 274 Class::C3->reinitialize;
275 $class->register_class(@$_) for (@to_register);
ea20d0fd 276
829517d4 277 return;
ea20d0fd 278}
279
87c4e602 280=head2 load_classes
281
27f01d1f 282=over 4
283
284=item Arguments: @classes?, { $namespace => [ @classes ] }+
285
286=back
076652e8 287
829517d4 288Alternative method to L</load_namespaces> which you should look at
289using if you can.
290
82b01c38 291With no arguments, this method uses L<Module::Find> to find all classes under
292the schema's namespace. Otherwise, this method loads the classes you specify
293(using L<use>), and registers them (using L</"register_class">).
076652e8 294
2053ab2a 295It is possible to comment out classes with a leading C<#>, but note that perl
296will think it's a mistake (trying to use a comment in a qw list), so you'll
297need to add C<no warnings 'qw';> before your load_classes call.
5ce32fc1 298
829517d4 299If any classes found do not appear to be Result class files, you will
300get the following warning:
301
302 Failed to load $comp_class. Can't find source_name method. Is
303 $comp_class really a full DBIC result class? Fix it, move it elsewhere,
304 or make your load_classes call more specific.
305
2053ab2a 306Example:
82b01c38 307
308 My::Schema->load_classes(); # loads My::Schema::CD, My::Schema::Artist,
75d07914 309 # etc. (anything under the My::Schema namespace)
82b01c38 310
311 # loads My::Schema::CD, My::Schema::Artist, Other::Namespace::Producer but
312 # not Other::Namespace::LinerNotes nor My::Schema::Track
313 My::Schema->load_classes(qw/ CD Artist #Track /, {
314 Other::Namespace => [qw/ Producer #LinerNotes /],
315 });
316
076652e8 317=cut
318
a02675cd 319sub load_classes {
5ce32fc1 320 my ($class, @params) = @_;
bab77431 321
5ce32fc1 322 my %comps_for;
bab77431 323
5ce32fc1 324 if (@params) {
325 foreach my $param (@params) {
326 if (ref $param eq 'ARRAY') {
327 # filter out commented entries
328 my @modules = grep { $_ !~ /^#/ } @$param;
bab77431 329
5ce32fc1 330 push (@{$comps_for{$class}}, @modules);
331 }
332 elsif (ref $param eq 'HASH') {
333 # more than one namespace possible
334 for my $comp ( keys %$param ) {
335 # filter out commented entries
336 my @modules = grep { $_ !~ /^#/ } @{$param->{$comp}};
337
338 push (@{$comps_for{$comp}}, @modules);
339 }
340 }
341 else {
342 # filter out commented entries
343 push (@{$comps_for{$class}}, $param) if $param !~ /^#/;
344 }
345 }
346 } else {
bc0c9800 347 my @comp = map { substr $_, length "${class}::" }
f3405058 348 $class->_findallmod;
5ce32fc1 349 $comps_for{$class} = \@comp;
41a6f8c0 350 }
5ce32fc1 351
e6efde04 352 my @to_register;
353 {
354 no warnings qw/redefine/;
355 local *Class::C3::reinitialize = sub { };
356 foreach my $prefix (keys %comps_for) {
357 foreach my $comp (@{$comps_for{$prefix}||[]}) {
358 my $comp_class = "${prefix}::${comp}";
c037c03a 359 $class->ensure_class_loaded($comp_class);
bab77431 360
89271e56 361 my $snsub = $comp_class->can('source_name');
362 if(! $snsub ) {
341d5ede 363 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.";
89271e56 364 next;
365 }
366 $comp = $snsub->($comp_class) || $comp;
367
93405cf0 368 push(@to_register, [ $comp, $comp_class ]);
bfb2bd4f 369 }
5ce32fc1 370 }
a02675cd 371 }
e6efde04 372 Class::C3->reinitialize;
373
374 foreach my $to (@to_register) {
375 $class->register_class(@$to);
376 # if $class->can('result_source_instance');
377 }
a02675cd 378}
379
829517d4 380=head2 storage_type
2374c5ff 381
382=over 4
383
829517d4 384=item Arguments: $storage_type|{$storage_type, \%args}
385
386=item Return value: $storage_type|{$storage_type, \%args}
387
388=item Default value: DBIx::Class::Storage::DBI
2374c5ff 389
390=back
391
829517d4 392Set the storage class that will be instantiated when L</connect> is called.
393If the classname starts with C<::>, the prefix C<DBIx::Class::Storage> is
394assumed by L</connect>.
2374c5ff 395
829517d4 396You want to use this to set subclasses of L<DBIx::Class::Storage::DBI>
397in cases where the appropriate subclass is not autodetected, such as
398when dealing with MSSQL via L<DBD::Sybase>, in which case you'd set it
399to C<::DBI::Sybase::MSSQL>.
85bd0538 400
829517d4 401If your storage type requires instantiation arguments, those are
402defined as a second argument in the form of a hashref and the entire
403value needs to be wrapped into an arrayref or a hashref. We support
404both types of refs here in order to play nice with your
405Config::[class] or your choice. See
406L<DBIx::Class::Storage::DBI::Replicated> for an example of this.
0f4ec1d2 407
829517d4 408=head2 exception_action
f017c022 409
829517d4 410=over 4
0f4ec1d2 411
829517d4 412=item Arguments: $code_reference
f017c022 413
829517d4 414=item Return value: $code_reference
85bd0538 415
829517d4 416=item Default value: None
2374c5ff 417
829517d4 418=back
f017c022 419
829517d4 420If C<exception_action> is set for this class/object, L</throw_exception>
421will prefer to call this code reference with the exception as an argument,
422rather than L<DBIx::Class::Exception/throw>.
f017c022 423
829517d4 424Your subroutine should probably just wrap the error in the exception
425object/class of your choosing and rethrow. If, against all sage advice,
426you'd like your C<exception_action> to suppress a particular exception
427completely, simply have it return true.
f017c022 428
829517d4 429Example:
f017c022 430
829517d4 431 package My::Schema;
432 use base qw/DBIx::Class::Schema/;
433 use My::ExceptionClass;
434 __PACKAGE__->exception_action(sub { My::ExceptionClass->throw(@_) });
435 __PACKAGE__->load_classes;
2374c5ff 436
829517d4 437 # or:
438 my $schema_obj = My::Schema->connect( .... );
439 $schema_obj->exception_action(sub { My::ExceptionClass->throw(@_) });
0f4ec1d2 440
829517d4 441 # suppress all exceptions, like a moron:
442 $schema_obj->exception_action(sub { 1 });
25fb14bd 443
829517d4 444=head2 stacktrace
f017c022 445
829517d4 446=over 4
2374c5ff 447
829517d4 448=item Arguments: boolean
2374c5ff 449
829517d4 450=back
2374c5ff 451
829517d4 452Whether L</throw_exception> should include stack trace information.
453Defaults to false normally, but defaults to true if C<$ENV{DBIC_TRACE}>
454is true.
0f4ec1d2 455
829517d4 456=head2 sqlt_deploy_hook
0f4ec1d2 457
829517d4 458=over
0f4ec1d2 459
829517d4 460=item Arguments: $sqlt_schema
2374c5ff 461
829517d4 462=back
2374c5ff 463
829517d4 464An optional sub which you can declare in your own Schema class that will get
465passed the L<SQL::Translator::Schema> object when you deploy the schema via
466L</create_ddl_dir> or L</deploy>.
0f4ec1d2 467
829517d4 468For an example of what you can do with this, see
469L<DBIx::Class::Manual::Cookbook/Adding Indexes And Functions To Your SQL>.
fdcd8145 470
2d7d8459 471Note that sqlt_deploy_hook is called by L</deployment_statements>, which in turn
472is called before L</deploy>. Therefore the hook can be used only to manipulate
473the L<SQL::Translator::Schema> object before it is turned into SQL fed to the
474database. If you want to execute post-deploy statements which can not be generated
475by L<SQL::Translator>, the currently suggested method is to overload L</deploy>
476and use L<dbh_do|DBIx::Class::Storage::DBI/dbh_do>.
477
829517d4 478=head1 METHODS
2374c5ff 479
829517d4 480=head2 connect
87c4e602 481
27f01d1f 482=over 4
483
829517d4 484=item Arguments: @connectinfo
429bd4f1 485
d601dc88 486=item Return Value: $new_schema
27f01d1f 487
488=back
076652e8 489
829517d4 490Creates and returns a new Schema object. The connection info set on it
491is used to create a new instance of the storage backend and set it on
492the Schema object.
1c133e22 493
829517d4 494See L<DBIx::Class::Storage::DBI/"connect_info"> for DBI-specific
5d52945a 495syntax on the C<@connectinfo> argument, or L<DBIx::Class::Storage> in
829517d4 496general.
1c133e22 497
5d52945a 498Note that C<connect_info> expects an arrayref of arguments, but
499C<connect> does not. C<connect> wraps it's arguments in an arrayref
500before passing them to C<connect_info>.
501
4c7d99ca 502=head3 Overloading
503
504C<connect> is a convenience method. It is equivalent to calling
505$schema->clone->connection(@connectinfo). To write your own overloaded
506version, overload L</connection> instead.
507
076652e8 508=cut
509
829517d4 510sub connect { shift->clone->connection(@_) }
e678398e 511
829517d4 512=head2 resultset
77254782 513
27f01d1f 514=over 4
515
829517d4 516=item Arguments: $source_name
82b01c38 517
829517d4 518=item Return Value: $resultset
27f01d1f 519
520=back
13765dad 521
829517d4 522 my $rs = $schema->resultset('DVD');
82b01c38 523
829517d4 524Returns the L<DBIx::Class::ResultSet> object for the registered source
525name.
77254782 526
527=cut
528
829517d4 529sub resultset {
530 my ($self, $moniker) = @_;
531 return $self->source($moniker)->resultset;
b7951443 532}
533
829517d4 534=head2 sources
6b43ba5f 535
536=over 4
537
829517d4 538=item Return Value: @source_names
6b43ba5f 539
540=back
541
829517d4 542 my @source_names = $schema->sources;
6b43ba5f 543
829517d4 544Lists names of all the sources registered on this Schema object.
6b43ba5f 545
829517d4 546=cut
161fb223 547
829517d4 548sub sources { return keys %{shift->source_registrations}; }
106d5f3b 549
829517d4 550=head2 source
87c4e602 551
27f01d1f 552=over 4
553
829517d4 554=item Arguments: $source_name
66d9ef6b 555
829517d4 556=item Return Value: $result_source
27f01d1f 557
558=back
82b01c38 559
829517d4 560 my $source = $schema->source('Book');
85f78622 561
829517d4 562Returns the L<DBIx::Class::ResultSource> object for the registered
563source name.
66d9ef6b 564
565=cut
566
829517d4 567sub source {
568 my ($self, $moniker) = @_;
569 my $sreg = $self->source_registrations;
570 return $sreg->{$moniker} if exists $sreg->{$moniker};
571
572 # if we got here, they probably passed a full class name
573 my $mapped = $self->class_mappings->{$moniker};
574 $self->throw_exception("Can't find source for ${moniker}")
575 unless $mapped && exists $sreg->{$mapped};
576 return $sreg->{$mapped};
161fb223 577}
578
829517d4 579=head2 class
87c4e602 580
27f01d1f 581=over 4
582
829517d4 583=item Arguments: $source_name
66d9ef6b 584
829517d4 585=item Return Value: $classname
27f01d1f 586
587=back
82b01c38 588
829517d4 589 my $class = $schema->class('CD');
590
591Retrieves the Result class name for the given source name.
66d9ef6b 592
593=cut
594
829517d4 595sub class {
596 my ($self, $moniker) = @_;
597 return $self->source($moniker)->result_class;
598}
08b515f1 599
4012acd8 600=head2 txn_do
08b515f1 601
4012acd8 602=over 4
08b515f1 603
4012acd8 604=item Arguments: C<$coderef>, @coderef_args?
08b515f1 605
4012acd8 606=item Return Value: The return value of $coderef
08b515f1 607
4012acd8 608=back
08b515f1 609
4012acd8 610Executes C<$coderef> with (optional) arguments C<@coderef_args> atomically,
611returning its result (if any). Equivalent to calling $schema->storage->txn_do.
612See L<DBIx::Class::Storage/"txn_do"> for more information.
08b515f1 613
4012acd8 614This interface is preferred over using the individual methods L</txn_begin>,
615L</txn_commit>, and L</txn_rollback> below.
08b515f1 616
281719d2 617WARNING: If you are connected with C<AutoCommit => 0> the transaction is
618considered nested, and you will still need to call L</txn_commit> to write your
619changes when appropriate. You will also want to connect with C<auto_savepoint =>
6201> to get partial rollback to work, if the storage driver for your database
621supports it.
622
623Connecting with C<AutoCommit => 1> is recommended.
624
4012acd8 625=cut
08b515f1 626
4012acd8 627sub txn_do {
628 my $self = shift;
08b515f1 629
4012acd8 630 $self->storage or $self->throw_exception
631 ('txn_do called on $schema without storage');
08b515f1 632
4012acd8 633 $self->storage->txn_do(@_);
634}
66d9ef6b 635
6936e902 636=head2 txn_scope_guard
75c8a7ab 637
89028f42 638Runs C<txn_scope_guard> on the schema's storage. See
639L<DBIx::Class::Storage/txn_scope_guard>.
75c8a7ab 640
b85be4c1 641=cut
642
1bc193ac 643sub txn_scope_guard {
644 my $self = shift;
645
646 $self->storage or $self->throw_exception
647 ('txn_scope_guard called on $schema without storage');
648
649 $self->storage->txn_scope_guard(@_);
650}
651
4012acd8 652=head2 txn_begin
a62cf8d4 653
4012acd8 654Begins a transaction (does nothing if AutoCommit is off). Equivalent to
655calling $schema->storage->txn_begin. See
656L<DBIx::Class::Storage::DBI/"txn_begin"> for more information.
27f01d1f 657
4012acd8 658=cut
82b01c38 659
4012acd8 660sub txn_begin {
661 my $self = shift;
27f01d1f 662
4012acd8 663 $self->storage or $self->throw_exception
664 ('txn_begin called on $schema without storage');
a62cf8d4 665
4012acd8 666 $self->storage->txn_begin;
667}
a62cf8d4 668
4012acd8 669=head2 txn_commit
a62cf8d4 670
4012acd8 671Commits the current transaction. Equivalent to calling
672$schema->storage->txn_commit. See L<DBIx::Class::Storage::DBI/"txn_commit">
673for more information.
a62cf8d4 674
4012acd8 675=cut
a62cf8d4 676
4012acd8 677sub txn_commit {
678 my $self = shift;
a62cf8d4 679
4012acd8 680 $self->storage or $self->throw_exception
681 ('txn_commit called on $schema without storage');
a62cf8d4 682
4012acd8 683 $self->storage->txn_commit;
684}
70634260 685
4012acd8 686=head2 txn_rollback
a62cf8d4 687
4012acd8 688Rolls back the current transaction. Equivalent to calling
689$schema->storage->txn_rollback. See
690L<DBIx::Class::Storage::DBI/"txn_rollback"> for more information.
a62cf8d4 691
692=cut
693
4012acd8 694sub txn_rollback {
695 my $self = shift;
a62cf8d4 696
19630353 697 $self->storage or $self->throw_exception
4012acd8 698 ('txn_rollback called on $schema without storage');
a62cf8d4 699
4012acd8 700 $self->storage->txn_rollback;
a62cf8d4 701}
702
829517d4 703=head2 storage
66d9ef6b 704
829517d4 705 my $storage = $schema->storage;
04786a4c 706
829517d4 707Returns the L<DBIx::Class::Storage> object for this Schema. Grab this
708if you want to turn on SQL statement debugging at runtime, or set the
709quote character. For the default storage, the documentation can be
710found in L<DBIx::Class::Storage::DBI>.
66d9ef6b 711
87c4e602 712=head2 populate
713
27f01d1f 714=over 4
715
16c5f7d3 716=item Arguments: $source_name, \@data;
27f01d1f 717
829517d4 718=item Return value: \@$objects | nothing
719
27f01d1f 720=back
a37a4697 721
16c5f7d3 722Pass this method a resultsource name, and an arrayref of
723arrayrefs. The arrayrefs should contain a list of column names,
724followed by one or many sets of matching data for the given columns.
725
744076d8 726In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
727to insert the data, as this is a fast method. However, insert_bulk currently
728assumes that your datasets all contain the same type of values, using scalar
729references in a column in one row, and not in another will probably not work.
730
731Otherwise, each set of data is inserted into the database using
16c5f7d3 732L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
733objects is returned.
82b01c38 734
735i.e.,
a37a4697 736
24d67825 737 $schema->populate('Artist', [
738 [ qw/artistid name/ ],
739 [ 1, 'Popular Band' ],
740 [ 2, 'Indie Band' ],
a62cf8d4 741 ...
742 ]);
5a93e138 743
744Since wantarray context is basically the same as looping over $rs->create(...)
745you won't see any performance benefits and in this case the method is more for
746convenience. Void context sends the column information directly to storage
747using <DBI>s bulk insert method. So the performance will be much better for
748storages that support this method.
749
750Because of this difference in the way void context inserts rows into your
751database you need to note how this will effect any loaded components that
752override or augment insert. For example if you are using a component such
753as L<DBIx::Class::UUIDColumns> to populate your primary keys you MUST use
754wantarray context if you want the PKs automatically created.
a37a4697 755
756=cut
757
758sub populate {
759 my ($self, $name, $data) = @_;
c4e67d31 760 if(my $rs = $self->resultset($name)) {
761 if(defined wantarray) {
762 return $rs->populate($data);
763 } else {
764 $rs->populate($data);
54e0bd06 765 }
c4e67d31 766 } else {
767 $self->throw_exception("$name is not a resultset");
8b93a938 768 }
a37a4697 769}
770
829517d4 771=head2 connection
772
773=over 4
774
775=item Arguments: @args
776
777=item Return Value: $new_schema
778
779=back
780
781Similar to L</connect> except sets the storage object and connection
782data in-place on the Schema class. You should probably be calling
783L</connect> to get a proper Schema object instead.
784
4c7d99ca 785=head3 Overloading
786
787Overload C<connection> to change the behaviour of C<connect>.
829517d4 788
789=cut
790
791sub connection {
792 my ($self, @info) = @_;
793 return $self if !@info && $self->storage;
794
795 my ($storage_class, $args) = ref $self->storage_type ?
796 ($self->_normalize_storage_type($self->storage_type),{}) : ($self->storage_type, {});
797
798 $storage_class = 'DBIx::Class::Storage'.$storage_class
799 if $storage_class =~ m/^::/;
800 eval "require ${storage_class};";
801 $self->throw_exception(
802 "No arguments to load_classes and couldn't load ${storage_class} ($@)"
803 ) if $@;
804 my $storage = $storage_class->new($self=>$args);
805 $storage->connect_info(\@info);
806 $self->storage($storage);
807 return $self;
808}
809
810sub _normalize_storage_type {
811 my ($self, $storage_type) = @_;
812 if(ref $storage_type eq 'ARRAY') {
813 return @$storage_type;
814 } elsif(ref $storage_type eq 'HASH') {
815 return %$storage_type;
816 } else {
817 $self->throw_exception('Unsupported REFTYPE given: '. ref $storage_type);
818 }
819}
820
821=head2 compose_namespace
82cc0386 822
823=over 4
824
829517d4 825=item Arguments: $target_namespace, $additional_base_class?
826
827=item Retur Value: $new_schema
828
829=back
830
831For each L<DBIx::Class::ResultSource> in the schema, this method creates a
832class in the target namespace (e.g. $target_namespace::CD,
833$target_namespace::Artist) that inherits from the corresponding classes
834attached to the current schema.
835
836It also attaches a corresponding L<DBIx::Class::ResultSource> object to the
837new $schema object. If C<$additional_base_class> is given, the new composed
838classes will inherit from first the corresponding classe from the current
839schema then the base class.
840
841For example, for a schema with My::Schema::CD and My::Schema::Artist classes,
842
843 $schema->compose_namespace('My::DB', 'Base::Class');
844 print join (', ', @My::DB::CD::ISA) . "\n";
845 print join (', ', @My::DB::Artist::ISA) ."\n";
846
847will produce the output
848
849 My::Schema::CD, Base::Class
850 My::Schema::Artist, Base::Class
851
852=cut
853
854# this might be oversimplified
855# sub compose_namespace {
856# my ($self, $target, $base) = @_;
857
858# my $schema = $self->clone;
859# foreach my $moniker ($schema->sources) {
860# my $source = $schema->source($moniker);
861# my $target_class = "${target}::${moniker}";
862# $self->inject_base(
863# $target_class => $source->result_class, ($base ? $base : ())
864# );
865# $source->result_class($target_class);
866# $target_class->result_source_instance($source)
867# if $target_class->can('result_source_instance');
868# $schema->register_source($moniker, $source);
869# }
870# return $schema;
871# }
872
873sub compose_namespace {
874 my ($self, $target, $base) = @_;
875 my $schema = $self->clone;
876 {
877 no warnings qw/redefine/;
878# local *Class::C3::reinitialize = sub { };
879 foreach my $moniker ($schema->sources) {
880 my $source = $schema->source($moniker);
881 my $target_class = "${target}::${moniker}";
882 $self->inject_base(
883 $target_class => $source->result_class, ($base ? $base : ())
884 );
885 $source->result_class($target_class);
886 $target_class->result_source_instance($source)
887 if $target_class->can('result_source_instance');
888 $schema->register_source($moniker, $source);
889 }
890 }
891# Class::C3->reinitialize();
892 {
893 no strict 'refs';
894 no warnings 'redefine';
895 foreach my $meth (qw/class source resultset/) {
896 *{"${target}::${meth}"} =
897 sub { shift->schema->$meth(@_) };
898 }
899 }
900 return $schema;
901}
902
903sub setup_connection_class {
904 my ($class, $target, @info) = @_;
905 $class->inject_base($target => 'DBIx::Class::DB');
906 #$target->load_components('DB');
907 $target->connection(@info);
908}
909
910=head2 svp_begin
911
912Creates a new savepoint (does nothing outside a transaction).
913Equivalent to calling $schema->storage->svp_begin. See
914L<DBIx::Class::Storage::DBI/"svp_begin"> for more information.
915
916=cut
917
918sub svp_begin {
919 my ($self, $name) = @_;
920
921 $self->storage or $self->throw_exception
922 ('svp_begin called on $schema without storage');
923
924 $self->storage->svp_begin($name);
925}
926
927=head2 svp_release
928
929Releases a savepoint (does nothing outside a transaction).
930Equivalent to calling $schema->storage->svp_release. See
931L<DBIx::Class::Storage::DBI/"svp_release"> for more information.
932
933=cut
934
935sub svp_release {
936 my ($self, $name) = @_;
937
938 $self->storage or $self->throw_exception
939 ('svp_release called on $schema without storage');
82cc0386 940
829517d4 941 $self->storage->svp_release($name);
942}
82cc0386 943
829517d4 944=head2 svp_rollback
db5dc233 945
829517d4 946Rollback to a savepoint (does nothing outside a transaction).
947Equivalent to calling $schema->storage->svp_rollback. See
948L<DBIx::Class::Storage::DBI/"svp_rollback"> for more information.
82cc0386 949
829517d4 950=cut
82cc0386 951
829517d4 952sub svp_rollback {
953 my ($self, $name) = @_;
82cc0386 954
829517d4 955 $self->storage or $self->throw_exception
956 ('svp_rollback called on $schema without storage');
82cc0386 957
829517d4 958 $self->storage->svp_rollback($name);
959}
db5dc233 960
829517d4 961=head2 clone
613397e7 962
84c5863b 963=over 4
613397e7 964
829517d4 965=item Return Value: $new_schema
613397e7 966
967=back
968
829517d4 969Clones the schema and its associated result_source objects and returns the
970copy.
971
972=cut
973
974sub clone {
975 my ($self) = @_;
976 my $clone = { (ref $self ? %$self : ()) };
977 bless $clone, (ref $self || $self);
978
979 $clone->class_mappings({ %{$clone->class_mappings} });
980 $clone->source_registrations({ %{$clone->source_registrations} });
981 foreach my $moniker ($self->sources) {
982 my $source = $self->source($moniker);
983 my $new = $source->new($source);
984 # we use extra here as we want to leave the class_mappings as they are
985 # but overwrite the source_registrations entry with the new source
986 $clone->register_extra_source($moniker => $new);
987 }
988 $clone->storage->set_schema($clone) if $clone->storage;
989 return $clone;
990}
613397e7 991
5160b401 992=head2 throw_exception
701da8c4 993
75d07914 994=over 4
82b01c38 995
ebc77b53 996=item Arguments: $message
82b01c38 997
998=back
999
1000Throws an exception. Defaults to using L<Carp::Clan> to report errors from
db5dc233 1001user's perspective. See L</exception_action> for details on overriding
4b946902 1002this method's behavior. If L</stacktrace> is turned on, C<throw_exception>'s
1003default behavior will provide a detailed stack trace.
701da8c4 1004
1005=cut
1006
1007sub throw_exception {
82cc0386 1008 my $self = shift;
4981dc70 1009
1010 DBIx::Class::Exception->throw($_[0], $self->stacktrace)
1011 if !$self->exception_action || !$self->exception_action->(@_);
701da8c4 1012}
1013
dfccde48 1014=head2 deploy
1c339d71 1015
82b01c38 1016=over 4
1017
10976519 1018=item Arguments: \%sqlt_args, $dir
82b01c38 1019
1020=back
1021
1022Attempts to deploy the schema to the current storage using L<SQL::Translator>.
ec6704d4 1023
10976519 1024See L<SQL::Translator/METHODS> for a list of values for C<\%sqlt_args>.
1025The most common value for this would be C<< { add_drop_table => 1 } >>
1026to have the SQL produced include a C<DROP TABLE> statement for each table
1027created. For quoting purposes supply C<quote_table_names> and
3e82fc27 1028C<quote_field_names>.
51bace1c 1029
499adf63 1030Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash
1031ref or an array ref, containing a list of source to deploy. If present, then
0e2c6809 1032only the sources listed will get deployed. Furthermore, you can use the
1033C<add_fk_index> parser parameter to prevent the parser from creating an index for each
1034FK.
499adf63 1035
1c339d71 1036=cut
1037
1038sub deploy {
6e73ac25 1039 my ($self, $sqltargs, $dir) = @_;
1c339d71 1040 $self->throw_exception("Can't deploy without storage") unless $self->storage;
6e73ac25 1041 $self->storage->deploy($self, undef, $sqltargs, $dir);
1c339d71 1042}
1043
0e0ce6c1 1044=head2 deployment_statements
1045
1046=over 4
1047
10976519 1048=item Arguments: See L<DBIx::Class::Storage::DBI/deployment_statements>
0e0ce6c1 1049
829517d4 1050=item Return value: $listofstatements
1051
0e0ce6c1 1052=back
1053
10976519 1054A convenient shortcut to
1055C<< $self->storage->deployment_statements($self, @args) >>.
1056Returns the SQL statements used by L</deploy> and
1057L<DBIx::Class::Schema::Storage/deploy>.
0e0ce6c1 1058
1059=cut
1060
1061sub deployment_statements {
7ad93f5a 1062 my $self = shift;
0e0ce6c1 1063
1064 $self->throw_exception("Can't generate deployment statements without a storage")
1065 if not $self->storage;
1066
7ad93f5a 1067 $self->storage->deployment_statements($self, @_);
0e0ce6c1 1068}
1069
c0f61310 1070=head2 create_ddl_dir (EXPERIMENTAL)
1071
1072=over 4
1073
10976519 1074=item Arguments: See L<DBIx::Class::Storage::DBI/create_ddl_dir>
c0f61310 1075
1076=back
1077
10976519 1078A convenient shortcut to
1079C<< $self->storage->create_ddl_dir($self, @args) >>.
c9d2e0a2 1080
10976519 1081Creates an SQL file based on the Schema, for each of the specified
1082database types, in the given directory.
c9d2e0a2 1083
c0f61310 1084=cut
1085
6e73ac25 1086sub create_ddl_dir {
e673f011 1087 my $self = shift;
1088
1089 $self->throw_exception("Can't create_ddl_dir without storage") unless $self->storage;
1090 $self->storage->create_ddl_dir($self, @_);
1091}
1092
e63a82f7 1093=head2 ddl_filename
9b83fccd 1094
c9d2e0a2 1095=over 4
1096
99a74c4a 1097=item Arguments: $database-type, $version, $directory, $preversion
c9d2e0a2 1098
829517d4 1099=item Return value: $normalised_filename
1100
c9d2e0a2 1101=back
1102
99a74c4a 1103 my $filename = $table->ddl_filename($type, $version, $dir, $preversion)
c9d2e0a2 1104
1105This method is called by C<create_ddl_dir> to compose a file name out of
1106the supplied directory, database type and version number. The default file
1107name format is: C<$dir$schema-$version-$type.sql>.
9b83fccd 1108
c9d2e0a2 1109You may override this method in your schema if you wish to use a different
1110format.
9b83fccd 1111
1112=cut
1113
6e73ac25 1114sub ddl_filename {
99a74c4a 1115 my ($self, $type, $version, $dir, $preversion) = @_;
e673f011 1116
99a74c4a 1117 my $filename = ref($self);
1118 $filename =~ s/::/-/g;
1119 $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
1120 $filename =~ s/$version/$preversion-$version/ if($preversion);
1121
1122 return $filename;
e673f011 1123}
1124
4146e3da 1125=head2 thaw
1126
829517d4 1127Provided as the recommended way of thawing schema objects. You can call
4146e3da 1128C<Storable::thaw> directly if you wish, but the thawed objects will not have a
1129reference to any schema, so are rather useless
1130
1131=cut
1132
1133sub thaw {
1134 my ($self, $obj) = @_;
1135 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1136 return Storable::thaw($obj);
1137}
1138
1139=head2 freeze
1140
1141This doesn't actualy do anything more than call L<Storable/freeze>, it is just
1142provided here for symetry.
1143
d2f3e87b 1144=cut
1145
4146e3da 1146sub freeze {
1147 return Storable::freeze($_[1]);
1148}
1149
1150=head2 dclone
1151
1152Recommeneded way of dcloning objects. This is needed to properly maintain
1153references to the schema object (which itself is B<not> cloned.)
1154
1155=cut
1156
1157sub dclone {
1158 my ($self, $obj) = @_;
1159 local $DBIx::Class::ResultSourceHandle::thaw_schema = $self;
1160 return Storable::dclone($obj);
1161}
1162
93e4d41a 1163=head2 schema_version
1164
829517d4 1165Returns the current schema class' $VERSION in a normalised way.
93e4d41a 1166
1167=cut
1168
1169sub schema_version {
1170 my ($self) = @_;
1171 my $class = ref($self)||$self;
1172
1173 # does -not- use $schema->VERSION
1174 # since that varies in results depending on if version.pm is installed, and if
1175 # so the perl or XS versions. If you want this to change, bug the version.pm
1176 # author to make vpp and vxs behave the same.
1177
1178 my $version;
1179 {
1180 no strict 'refs';
1181 $version = ${"${class}::VERSION"};
1182 }
1183 return $version;
1184}
1185
829517d4 1186
1187=head2 register_class
1188
1189=over 4
1190
1191=item Arguments: $moniker, $component_class
1192
1193=back
1194
1195This 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.
1196
1197You will only need this method if you have your Result classes in
1198files which are not named after the packages (or all in the same
1199file). You may also need it to register classes at runtime.
1200
1201Registers a class which isa DBIx::Class::ResultSourceProxy. Equivalent to
1202calling:
1203
1204 $schema->register_source($moniker, $component_class->result_source_instance);
1205
1206=cut
1207
1208sub register_class {
1209 my ($self, $moniker, $to_register) = @_;
1e36ef62 1210 $self->register_source($moniker => $to_register->result_source_instance);
829517d4 1211}
1212
1213=head2 register_source
1214
1215=over 4
1216
1217=item Arguments: $moniker, $result_source
1218
1219=back
1220
1221This method is called by L</register_class>.
1222
1223Registers the L<DBIx::Class::ResultSource> in the schema with the given
1224moniker.
1225
1226=cut
1227
1228sub register_source {
1229 my $self = shift;
1230
1231 $self->_register_source(@_);
1232}
1233
1234=head2 register_extra_source
1235
1236=over 4
1237
1238=item Arguments: $moniker, $result_source
1239
1240=back
1241
1242As L</register_source> but should be used if the result class already
1243has a source and you want to register an extra one.
1244
1245=cut
1246
1247sub register_extra_source {
1248 my $self = shift;
1249
1250 $self->_register_source(@_, { extra => 1 });
1251}
1252
1253sub _register_source {
1254 my ($self, $moniker, $source, $params) = @_;
1255
6d4f9d94 1256 my $orig_source = $source;
2461ae19 1257
0e6c5d58 1258 $source = $source->new({ %$source, source_name => $moniker });
2461ae19 1259 $source->schema($self);
1260 weaken($source->{schema}) if ref($self);
1261
1262 my $rs_class = $source->result_class;
829517d4 1263
1264 my %reg = %{$self->source_registrations};
1265 $reg{$moniker} = $source;
1266 $self->source_registrations(\%reg);
1267
829517d4 1268 return if ($params->{extra});
5dfe40b8 1269 return unless defined($rs_class) && $rs_class->can('result_source_instance');
829517d4 1270
2461ae19 1271 my %map = %{$self->class_mappings};
f18d2d04 1272 if (
1273 exists $map{$rs_class}
1274 and
1275 $map{$rs_class} ne $moniker
1276 and
1277 $rs_class->result_source_instance ne $orig_source
1278 ) {
2461ae19 1279 carp "$rs_class already has a source, use register_extra_source for additional sources";
829517d4 1280 }
2461ae19 1281 $map{$rs_class} = $moniker;
1282 $self->class_mappings(\%map);
829517d4 1283}
1284
1285sub _unregister_source {
1286 my ($self, $moniker) = @_;
1287 my %reg = %{$self->source_registrations};
1288
1289 my $source = delete $reg{$moniker};
1290 $self->source_registrations(\%reg);
1291 if ($source->result_class) {
1292 my %map = %{$self->class_mappings};
1293 delete $map{$source->result_class};
1294 $self->class_mappings(\%map);
1295 }
1296}
1297
1298
1299=head2 compose_connection (DEPRECATED)
1300
1301=over 4
1302
1303=item Arguments: $target_namespace, @db_info
1304
1305=item Return Value: $new_schema
1306
1307=back
1308
1309DEPRECATED. You probably wanted compose_namespace.
1310
1311Actually, you probably just wanted to call connect.
1312
1313=begin hidden
1314
1315(hidden due to deprecation)
1316
1317Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
1318calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
1319then injects the L<DBix::Class::ResultSetProxy> component and a
1320resultset_instance classdata entry on all the new classes, in order to support
1321$target_namespaces::$class->search(...) method calls.
1322
1323This is primarily useful when you have a specific need for class method access
1324to a connection. In normal usage it is preferred to call
1325L<DBIx::Class::Schema/connect> and use the resulting schema object to operate
1326on L<DBIx::Class::ResultSet> objects with L<DBIx::Class::Schema/resultset> for
1327more information.
1328
1329=end hidden
1330
1331=cut
1332
1333{
1334 my $warn;
1335
1336 sub compose_connection {
1337 my ($self, $target, @info) = @_;
1338
341d5ede 1339 carp "compose_connection deprecated as of 0.08000"
829517d4 1340 unless ($INC{"DBIx/Class/CDBICompat.pm"} || $warn++);
1341
1342 my $base = 'DBIx::Class::ResultSetProxy';
1343 eval "require ${base};";
1344 $self->throw_exception
1345 ("No arguments to load_classes and couldn't load ${base} ($@)")
1346 if $@;
1347
1348 if ($self eq $target) {
1349 # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
1350 foreach my $moniker ($self->sources) {
1351 my $source = $self->source($moniker);
1352 my $class = $source->result_class;
1353 $self->inject_base($class, $base);
1354 $class->mk_classdata(resultset_instance => $source->resultset);
1355 $class->mk_classdata(class_resolver => $self);
1356 }
1357 $self->connection(@info);
1358 return $self;
1359 }
1360
1361 my $schema = $self->compose_namespace($target, $base);
1362 {
1363 no strict 'refs';
1364 my $name = join '::', $target, 'schema';
1365 *$name = Sub::Name::subname $name, sub { $schema };
1366 }
1367
1368 $schema->connection(@info);
1369 foreach my $moniker ($schema->sources) {
1370 my $source = $schema->source($moniker);
1371 my $class = $source->result_class;
1372 #warn "$moniker $class $source ".$source->storage;
1373 $class->mk_classdata(result_source_instance => $source);
1374 $class->mk_classdata(resultset_instance => $source->resultset);
1375 $class->mk_classdata(class_resolver => $schema);
1376 }
1377 return $schema;
1378 }
1379}
1380
a02675cd 13811;
c2da098a 1382
c2da098a 1383=head1 AUTHORS
1384
daec44b8 1385Matt S. Trout <mst@shadowcatsystems.co.uk>
c2da098a 1386
1387=head1 LICENSE
1388
1389You may distribute this code under the same terms as Perl itself.
1390
1391=cut