pod cleanup, release
[catagits/Catalyst-Model-DBIC-Schema.git] / lib / Catalyst / Model / DBIC / Schema.pm
CommitLineData
ad91060a 1package Catalyst::Model::DBIC::Schema;
2
0fbbc8d5 3use Moose;
0f3de2c4 4use mro 'c3';
0fbbc8d5 5extends 'Catalyst::Model';
fb691af9 6with 'CatalystX::Component::Traits';
0fbbc8d5 7
ce9e19dc 8our $VERSION = '0.32';
7dfd616a 9$VERSION = eval $VERSION;
f090a149 10
73f72d28 11use namespace::autoclean;
bd309c0c 12use Carp::Clan '^Catalyst::Model::DBIC::Schema';
bfcd6e3d 13use Data::Dumper;
2201c2e4 14use DBIx::Class ();
ad91060a 15
61ed82a5 16use Catalyst::Model::DBIC::Schema::Types
2fa0a1f1 17 qw/ConnectInfo LoadedClass SchemaClass/;
61ed82a5 18
41bcf32f 19use MooseX::Types::Moose qw/ArrayRef Str ClassName Undef/;
0fbbc8d5 20
ad91060a 21=head1 NAME
22
23Catalyst::Model::DBIC::Schema - DBIx::Class::Schema Model Class
24
25=head1 SYNOPSIS
26
cbe03ea7 27First, prepare your database schema using L<DBIx::Class>, see
28L<Catalyst::Helper::Model::DBIC::Schema> for how to generate a
29L<DBIx::Class::Schema> from your database using the Helper script, and
30L<DBIx::Class::Schema::Loader::Base>.
07edc53e 31
cbe03ea7 32A typical usage of the helper script would be:
aabc1d75 33
cbe03ea7 34 script/myapp_create.pl model FilmDB DBIC::Schema MyApp::Schema::FilmDB \
35 create=static dbi:mysql:filmdb dbusername dbpass \
36 quote_char='`' name_sep='.'
aabc1d75 37
cbe03ea7 38If you are unfamiliar with L<DBIx::Class>, see L<DBIx::Class::Manual::Intro>
39first.
aabc1d75 40
cbe03ea7 41These examples assume that you already have a schema called
42C<MyApp::Schema::FilmDB>, which defines some Result classes for tables in
43C<MyApp::Schema::FilmDB::Result::Actor> and
44C<MyApp::Schema::FilmDB::Result::Film>. Either created by the helper script (as
45shown above) or manually.
aabc1d75 46
cbe03ea7 47The helper also creates a Model in C<lib/MyApp/Model/FilmDB.pm>, if you already
48have a schema you can create just the Model using:
07edc53e 49
cbe03ea7 50 script/myapp_create.pl model FilmDB DBIC::Schema MyApp::Schema::FilmDB
51 dbi:mysql:filmdb dbusername dbpass
aabc1d75 52
cbe03ea7 53The connect_info is optional and will be hardcoded into the Model if provided.
54It's better to configure it in your L<Catalyst> config file, which will also
55override any hardcoded config, see L</connect_info> for examples.
aabc1d75 56
95b41ca8 57Now you have a working Model which accesses your separate DBIC Schema. This can
58be used/accessed in the normal Catalyst manner, via C<< $c->model() >>:
aabc1d75 59
95b41ca8 60 my $db_model = $c->model('FilmDB'); # a Catalyst::Model
61 my $dbic = $c->model('FilmDB')->schema; # the actual DBIC object
aabc1d75 62
cbe03ea7 63The Model proxies to the C<Schema> instance so you can do:
07edc53e 64
95b41ca8 65 my $rs = $db_model->resultset('Actor'); # ... or ...
66 my $rs = $dbic ->resultset('Actor'); # same!
07edc53e 67
95b41ca8 68There is also a shortcut, which returns a L<DBIx::Class::ResultSet> directly,
69instead of a L<Catalyst::Model>:
07edc53e 70
95b41ca8 71 my $rs = $c->model('FilmDB::Actor');
aabc1d75 72
cbe03ea7 73See L<DBIx::Class::ResultSet> to find out more about which methods can be
74called on ResultSets.
75
76You can also define your own ResultSet methods to encapsulate the
77database/business logic of your applications. These go into, for example,
78C<lib/MyApp/Schema/FilmDB/ResultSet/Actor.pm>. The class must inherit from
79L<DBIx::Class::ResultSet> and is automatically loaded.
80
81Then call your methods like any other L<DBIx::Class::ResultSet> method:
82
83 $c->model('FilmDB::Actor')->SAG_members
aabc1d75 84
95b41ca8 85=head2 Some examples:
aabc1d75 86
f1613faa 87 # to access schema methods directly:
88 $c->model('FilmDB')->schema->source(...);
89
90 # to access the source object, resultset, and class:
07edc53e 91 $c->model('FilmDB')->source(...);
92 $c->model('FilmDB')->resultset(...);
93 $c->model('FilmDB')->class(...);
c12b7310 94
07edc53e 95 # For resultsets, there's an even quicker shortcut:
96 $c->model('FilmDB::Actor')
97 # is the same as $c->model('FilmDB')->resultset('Actor')
ad91060a 98
f1613faa 99 # To get the composed schema for making new connections:
100 my $newconn = $c->model('FilmDB')->composed_schema->connect(...);
101
102 # Or the same thing via a convenience shortcut:
103 my $newconn = $c->model('FilmDB')->connect(...);
104
105 # or, if your schema works on different storage drivers:
106 my $newconn = $c->model('FilmDB')->composed_schema->clone();
107 $newconn->storage_type('::LDAP');
108 $newconn->connection(...);
109
110 # and again, a convenience shortcut
111 my $newconn = $c->model('FilmDB')->clone();
112 $newconn->storage_type('::LDAP');
113 $newconn->connection(...);
114
95b41ca8 115To set up authentication, see L</"Setting up DBIC authentication"> below.
116
ad91060a 117=head1 DESCRIPTION
118
7b39f3f0 119This is a Catalyst Model for L<DBIx::Class::Schema>-based Models. See
ef91bcf9 120the documentation for L<Catalyst::Helper::Model::DBIC::Schema> for
121information on generating these Models via Helper scripts.
ad91060a 122
cbe03ea7 123When your Catalyst app starts up, a thin Model layer is created as an interface
124to your DBIC Schema. It should be clearly noted that the model object returned
125by C<< $c->model('FilmDB') >> is NOT itself a DBIC schema or resultset object,
126but merely a wrapper proving L<methods|/METHODS> to access the underlying
127schema (but also proxies other methods to the underlying schema.)
d52bc376 128
129In addition to this model class, a shortcut class is generated for each
130source in the schema, allowing easy and direct access to a resultset of the
131corresponding type. These generated classes are even thinner than the model
132class, providing no public methods but simply hooking into Catalyst's
133model() accessor via the
134L<ACCEPT_CONTEXT|Catalyst::Component/ACCEPT_CONTEXT> mechanism. The complete
135contents of each generated class is roughly equivalent to the following:
136
137 package MyApp::Model::FilmDB::Actor
138 sub ACCEPT_CONTEXT {
139 my ($self, $c) = @_;
140 $c->model('FilmDB')->resultset('Actor');
141 }
142
143In short, there are three techniques available for obtaining a DBIC
144resultset object:
145
146 # the long way
147 my $rs = $c->model('FilmDB')->schema->resultset('Actor');
148
149 # using the shortcut method on the model object
150 my $rs = $c->model('FilmDB')->resultset('Actor');
151
152 # using the generated class directly
153 my $rs = $c->model('FilmDB::Actor');
154
c082639a 155In order to add methods to a DBIC resultset, you cannot simply add them to
156the source (row, table) definition class; you must define a separate custom
cbe03ea7 157resultset class. This is just a matter of making a
158C<lib/MyApp/Schema/ResultSet/Actor.pm> class that inherits from
159L<DBIx::Class::ResultSet>, if you are using
160L<DBIx::Class::Schema/load_namespaces>, the default for helper script generated
161schemas.
162
163See L<DBIx::Class::Manual::Cookbook/"Predefined searches">
164for information on definining your own L<DBIx::Class::ResultSet> classes for
165use with L<DBIx::Class::Schema/load_classes>, the old default.
c082639a 166
ad91060a 167=head1 CONFIG PARAMETERS
168
b9cc2f76 169Any options in your config not listed here are passed to your schema.
170
c4fee9b8 171=head2 schema_class
ad91060a 172
173This is the classname of your L<DBIx::Class::Schema> Schema. It needs
aabc1d75 174to be findable in C<@INC>, but it does not need to be inside the
175C<Catalyst::Model::> namespace. This parameter is required.
ad91060a 176
c4fee9b8 177=head2 connect_info
ad91060a 178
179This is an arrayref of connection parameters, which are specific to your
b9a72351 180C<storage_type> (see your storage type documentation for more details).
181If you only need one parameter (e.g. the DSN), you can just pass a string
182instead of an arrayref.
ad91060a 183
0f2fd2c0 184This is not required if C<schema_class> already has connection information
d89e6c8a 185defined inside itself (which isn't highly recommended, but can be done)
0f2fd2c0 186
7db6da78 187For L<DBIx::Class::Storage::DBI>, which is the only supported
188C<storage_type> in L<DBIx::Class> at the time of this writing, the
189parameters are your dsn, username, password, and connect options hashref.
190
018eb0e2 191See L<DBIx::Class::Storage::DBI/connect_info> for a detailed explanation
192of the arguments supported.
7db6da78 193
194Examples:
195
2201c2e4 196 connect_info => {
197 dsn => 'dbi:Pg:dbname=mypgdb',
198 user => 'postgres',
199 password => ''
200 }
07edc53e 201
2201c2e4 202 connect_info => {
203 dsn => 'dbi:SQLite:dbname=foo.db',
204 on_connect_do => [
205 'PRAGMA synchronous = OFF',
206 ]
207 }
07edc53e 208
2201c2e4 209 connect_info => {
210 dsn => 'dbi:Pg:dbname=mypgdb',
211 user => 'postgres',
212 password => '',
213 pg_enable_utf8 => 1,
214 on_connect_do => [
215 'some SQL statement',
216 'another SQL statement',
217 ],
218 }
7db6da78 219
8281c933 220Or using L<Config::General>:
221
222 <Model::FilmDB>
223 schema_class MyApp::Schema::FilmDB
c34bcab6 224 traits Caching
8281c933 225 <connect_info>
2201c2e4 226 dsn dbi:Pg:dbname=mypgdb
227 user postgres
42e14c31 228 password ""
2201c2e4 229 auto_savepoint 1
a75b6e58 230 quote_char """
8281c933 231 on_connect_do some SQL statement
232 on_connect_do another SQL statement
233 </connect_info>
b9cc2f76 234 user_defined_schema_accessor foo
8281c933 235 </Model::FilmDB>
236
237or
238
239 <Model::FilmDB>
240 schema_class MyApp::Schema::FilmDB
241 connect_info dbi:SQLite:dbname=foo.db
242 </Model::FilmDB>
243
2201c2e4 244Or using L<YAML>:
245
246 Model::MyDB:
247 schema_class: MyDB
b9cc2f76 248 traits: Caching
2201c2e4 249 connect_info:
250 dsn: dbi:Oracle:mydb
251 user: mtfnpy
252 password: mypass
253 LongReadLen: 1000000
254 LongTruncOk: 1
b9cc2f76 255 on_connect_call: 'datetime_setup'
a75b6e58 256 quote_char: '"'
2201c2e4 257
258The old arrayref style with hashrefs for L<DBI> then L<DBIx::Class> options is also
259supported:
260
261 connect_info => [
262 'dbi:Pg:dbname=mypgdb',
263 'postgres',
264 '',
265 {
266 pg_enable_utf8 => 1,
267 },
268 {
0fbbc8d5 269 auto_savepoint => 1,
2201c2e4 270 on_connect_do => [
271 'some SQL statement',
272 'another SQL statement',
273 ],
274 }
275 ]
276
c34bcab6 277=head2 traits
0fbbc8d5 278
41bcf32f 279Array of Traits to apply to the instance. Traits are L<Moose::Role>s.
280
fb691af9 281They are relative to the C<< MyApp::TraitFor::Model::DBIC::Schema:: >>, then the C<<
282Catalyst::TraitFor::Model::DBIC::Schema:: >> namespaces, unless prefixed with C<+>
41bcf32f 283in which case they are taken to be a fully qualified name. E.g.:
2201c2e4 284
c34bcab6 285 traits Caching
fb691af9 286 traits +MyApp::TraitFor::Model::Foo
2201c2e4 287
0fbbc8d5 288A new instance is created at application time, so any consumed required
289attributes, coercions and modifiers will work.
2201c2e4 290
fb691af9 291Traits are applied at L<Catalyst::Component/COMPONENT> time using
292L<CatalystX::Component::Traits>.
0fbbc8d5 293
41bcf32f 294C<ref $self> will be an anon class if any traits are applied, C<<
295$self->_original_class_name >> will be the original class.
f090a149 296
c7d7b849 297When writing a Trait, interesting points to modify are C<BUILD>, L</setup> and
298L</ACCEPT_CONTEXT>.
0fbbc8d5 299
c34bcab6 300Traits that come with the distribution:
0fbbc8d5 301
302=over 4
2201c2e4 303
fb691af9 304=item L<Catalyst::TraitFor::Model::DBIC::Schema::Caching>
0fbbc8d5 305
fb691af9 306=item L<Catalyst::TraitFor::Model::DBIC::Schema::Replicated>
c4fee9b8 307
0fbbc8d5 308=back
8281c933 309
c4fee9b8 310=head2 storage_type
ad91060a 311
312Allows the use of a different C<storage_type> than what is set in your
313C<schema_class> (which in turn defaults to C<::DBI> if not set in current
f1613faa 314L<DBIx::Class>). Completely optional, and probably unnecessary for most
315people until other storage backends become available for L<DBIx::Class>.
ad91060a 316
c7d7b849 317=head1 ATTRIBUTES
318
319The keys you pass in the model configuration are available as attributes.
320
321Other attributes available:
322
323=head2 connect_info
324
325Your connect_info args normalized to hashref form (with dsn/user/password.) See
326L<DBIx::Class::Storage::DBI/connect_info> for more info on the hashref form of
327L</connect_info>.
328
329=head2 model_name
330
331The model name L<Catalyst> uses to resolve this model, the part after
332C<::Model::> or C<::M::> in your class name. E.g. if your class name is
333C<MyApp::Model::DB> the L</model_name> will be C<DB>.
334
c7d7b849 335=head2 _default_cursor_class
336
6f6b9c2d 337What to reset your L<DBIx::Class::Storage::DBI/cursor_class> to if a custom one
c7d7b849 338doesn't work out. Defaults to L<DBIx::Class::Storage::DBI::Cursor>.
339
fb691af9 340=head1 ATTRIBUTES FROM L<MooseX::Traits::Pluggable>
341
342=head2 _original_class_name
343
344The class name of your model before any L</traits> are applied. E.g.
345C<MyApp::Model::DB>.
346
c7d7b849 347=head2 _traits
348
6f6b9c2d 349Unresolved arrayref of traits passed in the config.
c7d7b849 350
351=head2 _resolved_traits
352
353Traits you used resolved to full class names.
354
ad91060a 355=head1 METHODS
356
46a2eb0c 357Methods not listed here are delegated to the connected schema used by the model
358instance, so the following are equivalent:
359
360 $c->model('DB')->schema->my_accessor('foo');
361 # or
362 $c->model('DB')->my_accessor('foo');
363
364Methods on the model take precedence over schema methods.
365
c4fee9b8 366=head2 new
ad91060a 367
368Instantiates the Model based on the above-documented ->config parameters.
0f2fd2c0 369The only required parameter is C<schema_class>. C<connect_info> is
370required in the case that C<schema_class> does not already have connection
371information defined for it.
ad91060a 372
c4fee9b8 373=head2 schema
f1613faa 374
375Accessor which returns the connected schema being used by the this model.
376There are direct shortcuts on the model class itself for
377schema->resultset, schema->source, and schema->class.
378
c4fee9b8 379=head2 composed_schema
f1613faa 380
381Accessor which returns the composed schema, which has no connection info,
382which was used in constructing the C<schema> above. Useful for creating
383new connections based on the same schema/model. There are direct shortcuts
384from the model object for composed_schema->clone and composed_schema->connect
385
c4fee9b8 386=head2 clone
f1613faa 387
388Shortcut for ->composed_schema->clone
389
c4fee9b8 390=head2 connect
f1613faa 391
392Shortcut for ->composed_schema->connect
393
c4fee9b8 394=head2 source
c12b7310 395
f1613faa 396Shortcut for ->schema->source
397
c4fee9b8 398=head2 class
f1613faa 399
400Shortcut for ->schema->class
401
c4fee9b8 402=head2 resultset
f1613faa 403
404Shortcut for ->schema->resultset
405
c4fee9b8 406=head2 storage
f1613faa 407
408Provides an accessor for the connected schema's storage object.
409Used often for debugging and controlling transactions.
b8427e0b 410
ad91060a 411=cut
412
c34bcab6 413has schema_class => (
0fbbc8d5 414 is => 'ro',
2fa0a1f1 415 isa => SchemaClass,
0fbbc8d5 416 coerce => 1,
417 required => 1
418);
419
c34bcab6 420has storage_type => (is => 'rw', isa => Str);
0fbbc8d5 421
18b829f0 422has connect_info => (is => 'rw', isa => ConnectInfo, coerce => 1);
0fbbc8d5 423
c7d7b849 424has model_name => (
425 is => 'ro',
426 isa => Str,
427 required => 1,
428 lazy_build => 1,
429);
ad91060a 430
c34bcab6 431has _default_cursor_class => (
61ed82a5 432 is => 'ro',
7314403a 433 isa => LoadedClass,
61ed82a5 434 default => 'DBIx::Class::Storage::DBI::Cursor',
435 coerce => 1
436);
437
0fbbc8d5 438sub BUILD {
f27a05ea 439 my ($self, $args) = @_;
f2488839 440 my $class = $self->_original_class_name;
2201c2e4 441 my $schema_class = $self->schema_class;
ad91060a 442
2201c2e4 443 if( !$self->connect_info ) {
f1613faa 444 if($schema_class->storage && $schema_class->storage->connect_info) {
2201c2e4 445 $self->connect_info($schema_class->storage->connect_info);
f1613faa 446 }
447 else {
39f5f008 448 die "Either ->config->{connect_info} must be defined for $class"
460e3ac8 449 . " or $schema_class must have connect info defined on it."
450 . " Here's what we got:\n"
f1613faa 451 . Dumper($self);
452 }
7db6da78 453 }
454
0fbbc8d5 455 if (exists $self->connect_info->{cursor_class}) {
456 eval { Class::MOP::load_class($self->connect_info->{cursor_class}) }
457 or croak "invalid connect_info: Cannot load your cursor_class"
458 . " ".$self->connect_info->{cursor_class}.": $@";
459 }
460
0fbbc8d5 461 $self->setup;
462
f1613faa 463 $self->composed_schema($schema_class->compose_namespace($class));
2201c2e4 464
cbe03ea7 465 my $was_mutable = $self->meta->is_mutable;
466
7bd33abf 467 $self->meta->make_mutable;
46a2eb0c 468 $self->meta->add_attribute('schema',
469 is => 'rw',
180c1a1a 470 isa => 'DBIx::Class::Schema',
46a2eb0c 471 handles => $self->_delegates
472 );
cbe03ea7 473 $self->meta->make_immutable unless $was_mutable;
46a2eb0c 474
f1613faa 475 $self->schema($self->composed_schema->clone);
476
f27a05ea 477 $self->_pass_options_to_schema($args);
7bd33abf 478
2201c2e4 479 $self->schema->storage_type($self->storage_type)
480 if $self->storage_type;
7db6da78 481
2201c2e4 482 $self->schema->connection($self->connect_info);
483
484 $self->_install_rs_models;
2201c2e4 485}
486
487sub clone { shift->composed_schema->clone(@_); }
488
489sub connect { shift->composed_schema->connect(@_); }
490
c4fee9b8 491=head2 setup
2201c2e4 492
e203cd42 493Called at C<BUILD> time before configuration, but after L</connect_info> is
c7d7b849 494set. To do something after configuuration use C<< after BUILD => >>.
2201c2e4 495
496=cut
497
0fbbc8d5 498sub setup { 1 }
2201c2e4 499
c4fee9b8 500=head2 ACCEPT_CONTEXT
2201c2e4 501
73f72d28 502Point of extension for doing things at C<< $c->model >> time with context,
503returns the model instance, see L<Catalyst::Manual::Intro/ACCEPT_CONTEXT> for
504more information.
2201c2e4 505
0fbbc8d5 506=cut
2201c2e4 507
0fbbc8d5 508sub ACCEPT_CONTEXT { shift }
2201c2e4 509
510sub _install_rs_models {
511 my $self = shift;
7b1fe8c2 512 my $class = $self->_original_class_name;
2201c2e4 513
ad91060a 514 no strict 'refs';
39f5f008 515
516 my @sources = $self->schema->sources;
517
ca7cf6f0 518 unless (@sources) {
519 warn <<'EOF' unless $ENV{CMDS_NO_SOURCES};
520******************************* WARNING ***************************************
521* No sources found (did you forget to define your tables?) *
522* *
523* To turn off this warning, set the CMDS_NO_SOURCES environment variable. *
524*******************************************************************************
525EOF
526 }
39f5f008 527
528 foreach my $moniker (@sources) {
0b2a7108 529 my $classname = "${class}::$moniker";
7db6da78 530 *{"${classname}::ACCEPT_CONTEXT"} = sub {
ad91060a 531 shift;
2201c2e4 532 shift->model($self->model_name)->resultset($moniker);
ad91060a 533 }
534 }
2201c2e4 535}
ad91060a 536
61ed82a5 537sub _reset_cursor_class {
538 my $self = shift;
539
540 if ($self->storage->can('cursor_class')) {
541 $self->storage->cursor_class($self->_default_cursor_class)
542 if $self->storage->cursor_class ne $self->_default_cursor_class;
543 }
544}
545
50f488ec 546{
547 my %COMPOSED_CACHE;
548
549 sub composed_schema {
550 my $self = shift;
551 my $class = $self->_original_class_name;
552 my $store = \$COMPOSED_CACHE{$class}{$self->schema_class};
553
554 $$store = shift if @_;
555
556 return $$store
557 }
558}
559
c7d7b849 560sub _build_model_name {
561 my $self = shift;
562 my $class = $self->_original_class_name;
563 (my $model_name = $class) =~ s/^[\w:]+::(?:Model|M):://;
564
565 return $model_name;
41bcf32f 566}
567
180c1a1a 568sub _delegates {
46a2eb0c 569 my $self = shift;
570
b9cc2f76 571 my $schema_meta = Class::MOP::Class->initialize($self->schema_class);
572 my @schema_methods = $schema_meta->get_all_method_names;
46a2eb0c 573
180c1a1a 574# combine with any already added by other schemas
575 my @handles = eval {
576 @{ $self->meta->find_attribute_by_name('schema')->handles }
577 };
578
579# now kill the attribute, otherwise add_attribute in BUILD will not do the right
b9cc2f76 580# thing (it clears the handles for some reason.) May be a Moose bug.
180c1a1a 581 eval { $self->meta->remove_attribute('schema') };
582
583 my %schema_methods;
584 @schema_methods{ @schema_methods, @handles } = ();
585 @schema_methods = keys %schema_methods;
586
587 my @my_methods = $self->meta->get_all_method_names;
46a2eb0c 588 my %my_methods;
589 @my_methods{@my_methods} = ();
590
591 my @delegates;
592 for my $method (@schema_methods) {
593 push @delegates, $method unless exists $my_methods{$method};
594 }
595
596 return \@delegates;
597}
598
7bd33abf 599sub _pass_options_to_schema {
f27a05ea 600 my ($self, $args) = @_;
601
602 my @attributes = map {
603 $_->init_arg || ()
604 } $self->meta->get_all_attributes;
7bd33abf 605
7bd33abf 606 my %attributes;
607 @attributes{@attributes} = ();
608
f27a05ea 609 for my $opt (keys %$args) {
7bd33abf 610 if (not exists $attributes{$opt}) {
294245b0 611 next unless $self->schema->can($opt);
7bd33abf 612 $self->schema->$opt($self->{$opt});
613 }
614 }
615}
616
0fbbc8d5 617__PACKAGE__->meta->make_immutable;
2201c2e4 618
ca7cf6f0 619=head1 ENVIRONMENT
620
621=over 4
622
623=item CMDS_NO_SOURCES
624
cbe03ea7 625Set this variable if you will be using schemas with no sources (Result classes)
626to disable the warning. The warning is there because having no Result classes
627is usually a mistake.
ca7cf6f0 628
629=back
630
95b41ca8 631=head1 Setting up DBIC authentication
632
633You can set this up with
634L<Catalyst::Authentication::Store::DBIx::Class> in MyApp.pm:
635
636 package MyApp;
637
638 use Catalyst qw/... Authentication .../;
639
640 ...
641
10c73a30 642 __PACKAGE__->config('Plugin::Authentication' =>
643 {
95b41ca8 644 default_realm => 'members',
10c73a30 645 members => {
646 credential => {
647 class => 'Password',
648 password_field => 'password',
649 password_type => 'hashed'
650 password_hash_type => 'SHA-256'
651 },
652 store => {
653 class => 'DBIx::Class',
654 user_model => 'DB::User',
655 role_relation => 'roles',
656 role_field => 'rolename',
95b41ca8 657 }
658 }
10c73a30 659 });
95b41ca8 660
ad91060a 661=head1 SEE ALSO
662
7b39f3f0 663General Catalyst Stuff:
664
665L<Catalyst::Manual>, L<Catalyst::Test>, L<Catalyst::Request>,
666L<Catalyst::Response>, L<Catalyst::Helper>, L<Catalyst>,
667
668Stuff related to DBIC and this Model style:
669
670L<DBIx::Class>, L<DBIx::Class::Schema>,
f090a149 671L<DBIx::Class::Schema::Loader>, L<Catalyst::Helper::Model::DBIC::Schema>,
e203cd42 672L<CatalystX::Component::Traits>, L<MooseX::Traits::Pluggable>
ad91060a 673
c34bcab6 674Traits:
c4fee9b8 675
fb691af9 676L<Catalyst::TraitFor::Model::DBIC::Schema::Caching>,
cbe03ea7 677L<Catalyst::TraitFor::Model::DBIC::Schema::Replicated>,
678L<Catalyst::TraitFor::Model::DBIC::Schema::QueryLog>
c4fee9b8 679
ad91060a 680=head1 AUTHOR
681
e203cd42 682Brandon L Black C<blblack at gmail.com>
ad91060a 683
e203cd42 684=head1 CONTRIBUTORS
2ff00e2b 685
e203cd42 686caelum: Rafael Kitover C<rkitover at cpan.org>
2ff00e2b 687
4e251d1a 688dandv: Dan Dascalescu C<dandv at cpan.org>
6d9e2623 689
4e251d1a 690bluefeet: Aran Deltac C<bluefeet@cpan.org>
691
692t0m: Tomas Doran C<bobtfish@bobtfish.net>
693
694osfameron: C<osfameron@cpan.org>
49c75c04 695
cbe03ea7 696ozum: Ozum Eldogan C<ozum@ozum.net>
ce9e19dc 697
ad91060a 698=head1 COPYRIGHT
699
4e251d1a 700Copyright (c) 2006 - 2009
701the Catalyst::Model::DBIC::Schema L</AUTHOR> and L</CONTRIBUTORS>
702as listed above.
703
704=head1 LICENSE
705
6d9e2623 706This program is free software. You can redistribute it and/or modify it
ad91060a 707under the same terms as Perl itself.
708
709=cut
710
7111;
c7d7b849 712# vim:sts=4 sw=4 et: