1 package Catalyst::Model::DBIC::Schema;
4 use base qw/Catalyst::Model Class::Accessor::Fast Class::Data::Accessor/;
6 use UNIVERSAL::require;
10 our $VERSION = '0.11';
12 __PACKAGE__->mk_classaccessor('composed_schema');
13 __PACKAGE__->mk_accessors('schema');
17 Catalyst::Model::DBIC::Schema - DBIx::Class::Schema Model Class
21 package MyApp::Model::Foo;
23 use base 'Catalyst::Model::DBIC::Schema';
26 schema_class => 'Foo::SchemaClass',
27 connect_info => [ 'dbi:Pg:dbname=foodb',
31 { limit_dialect => 'xxx',
46 # ->schema To access schema methods:
47 $c->model('Foo')->schema->source(...);
49 # certain ->schema methods (source, resultset, class) have shortcuts
50 $c->model('Foo')->source(...);
51 $c->model('Foo')->resultset(...);
52 $c->model('Foo')->class(...);
54 # For resultsets, there's an even quicker shortcut:
56 # is the same as $c->model('Foo')->resultset('Bar')
58 # To get the composed schema for making new connections:
59 my $newconn = $c->model('Foo')->composed_schema->connect(...);
61 # Or the same thing via a convenience shortcut:
62 my $newconn = $c->model('Foo')->connect(...);
64 # or, if your schema works on different storage drivers:
65 my $newconn = $c->model('Foo')->composed_schema->clone();
66 $newconn->storage_type('::LDAP');
67 $newconn->connection(...);
69 # and again, a convenience shortcut
70 my $newconn = $c->model('Foo')->clone();
71 $newconn->storage_type('::LDAP');
72 $newconn->connection(...);
76 This is a Catalyst Model for L<DBIx::Class::Schema>-based Models. See
77 the documentation for L<Catalyst::Helper::Model::DBIC::Schema> and
78 L<Catalyst::Helper::Model::DBIC::SchemaLoader> for information
79 on generating these Models via Helper scripts. The latter of the two
80 will also generated a L<DBIx::Class::Schema::Loader>-based Schema class
83 =head1 CONFIG PARAMETERS
89 This is the classname of your L<DBIx::Class::Schema> Schema. It needs
90 to be findable in C<@INC>, but it does not need to be underneath
91 C<Catalyst::Model::>. This parameter is required.
95 This is an arrayref of connection parameters, which are specific to your
96 C<storage_type> (see your storage type documentation for more details).
98 This is not required if C<schema_class> already has connection information
99 defined in itself (which would be the case for a Schema defined by
100 L<DBIx::Class::Schema::Loader>, for instance).
102 For L<DBIx::Class::Storage::DBI>, which is the only supported
103 C<storage_type> in L<DBIx::Class> at the time of this writing, the
104 parameters are your dsn, username, password, and connect options hashref.
106 If you need to specify the L<DBIx::Class::Storage::DBI> specific parameter
107 C<on_connect_do>, or the related C<sql_maker> options C<limit_dialect>,
108 C<quote_char>, or C<name_sep>, you can place these options into a hashref
109 as the final element of the C<connect_info> arrayref. If in doubt, don't
110 specify these options. You would know it if you needed them.
114 connect_info => [ 'dbi:Pg:dbname=mypgdb', 'postgres', '' ],
116 'dbi:SQLite:dbname=foo.db',
119 'some SQL statement',
120 'another SQL statement',
125 'dbi:Pg:dbname=mypgdb',
131 'some SQL statement',
132 'another SQL statement',
139 Allows the use of a different C<storage_type> than what is set in your
140 C<schema_class> (which in turn defaults to C<::DBI> if not set in current
141 L<DBIx::Class>). Completely optional, and probably unnecessary for most
142 people until other storage backends become available for L<DBIx::Class>.
152 Instantiates the Model based on the above-documented ->config parameters.
153 The only required parameter is C<schema_class>. C<connect_info> is
154 required in the case that C<schema_class> does not already have connection
155 information defined for it.
159 Accessor which returns the connected schema being used by the this model.
160 There are already direct shortcuts on the model class itself for
161 schema->resultset, schema->source, and schema->class.
163 =item composed_schema
165 Accessor which returns the composed schema, which has no connection info,
166 which was used in constructing the C<schema> above. Useful for creating
167 new connections based on the same schema/model. There are direct shortcuts
168 from the model object for composed_schema->clone and composed_schema->connect
172 Shortcut for ->composed_schema->clone
176 Shortcut for ->composed_schema->connect
180 Shortcut for ->schema->source
184 Shortcut for ->schema->class
188 Shortcut for ->schema->resultset
192 Provides an accessor for the connected schema's storage object.
193 Used often for debugging and controlling transactions.
200 my $self = shift->NEXT::new(@_);
202 my $class = ref($self);
203 my $model_name = $class;
204 $model_name =~ s/^[\w:]+::(?:Model|M):://;
206 croak "->config->{schema_class} must be defined for this model"
207 unless $self->{schema_class};
209 my $schema_class = $self->{schema_class};
211 $schema_class->require
212 or croak "Cannot load schema class '$schema_class': $@";
214 if( !$self->{connect_info} ) {
215 if($schema_class->storage && $schema_class->storage->connect_info) {
216 $self->{connect_info} = $schema_class->storage->connect_info;
219 croak "Either ->config->{connect_info} must be defined for $class"
220 . " or $schema_class must have connect info defined on it";
224 $self->composed_schema($schema_class->compose_namespace($class));
225 $self->schema($self->composed_schema->clone);
227 $self->schema->storage_type($self->{storage_type})
228 if $self->{storage_type};
230 # XXX This is temporary, until DBIx::Class::Storage::DBI supports the
231 # same syntax and we switch our requisite to that version somewhere
232 # down the line. This syntax is already committed into DBIx::Class
233 # dev branch post-0.06.
234 # At that time, this whole block can revert back to just being:
235 # $self->schema->connection(@{$self->{connect_info}});
237 my $connect_info = [ @{$self->{connect_info}} ];
238 my ($on_connect_do, %sql_maker_opts);
239 if($DBIx::Class::VERSION < 0.069) {
241 my $last_info = $self->{connect_info}->[-1];
242 if(ref $last_info eq 'HASH') {
243 if($on_connect_do = $last_info->{on_connect_do}) {
246 for my $sql_maker_opt (qw/limit_dialect quote_char name_sep/) {
247 if(my $opt_val = $last_info->{$sql_maker_opt}) {
249 $sql_maker_opts{$sql_maker_opt} = $opt_val;
252 pop(@$connect_info) if $used;
256 $self->schema->connection(@$connect_info);
258 if($DBIx::Class::VERSION < 0.069) {
259 $self->schema->storage->on_connect_do($on_connect_do)
261 foreach my $sql_maker_opt (keys %sql_maker_opts) {
262 $self->schema->storage->sql_maker->$sql_maker_opt(
263 $sql_maker_opts{$sql_maker_opt}
268 # XXX end of compatibility block referenced above
271 foreach my $moniker ($self->schema->sources) {
272 my $classname = "${class}::$moniker";
273 *{"${classname}::ACCEPT_CONTEXT"} = sub {
275 shift->model($model_name)->resultset($moniker);
282 sub clone { shift->composed_schema->clone(@_); }
284 sub connect { shift->composed_schema->connect(@_); }
286 sub storage { shift->schema->storage(@_); }
290 General Catalyst Stuff:
292 L<Catalyst::Manual>, L<Catalyst::Test>, L<Catalyst::Request>,
293 L<Catalyst::Response>, L<Catalyst::Helper>, L<Catalyst>,
295 Stuff related to DBIC and this Model style:
297 L<DBIx::Class>, L<DBIx::Class::Schema>,
298 L<DBIx::Class::Schema::Loader>, L<Catalyst::Helper::Model::DBIC::Schema>,
299 L<Catalyst::Helper::Model::DBIC::SchemaLoader>
303 Brandon L Black, C<blblack@gmail.com>
307 This program is free software, you can redistribute it and/or modify it
308 under the same terms as Perl itself.