1 package DBIx::Class::Admin;
8 require DBIx::Class::Optional::Dependencies;
9 if (my $missing = DBIx::Class::Optional::Dependencies->req_missing_for ('admin') ) {
10 die "The following extra modules are required for DBIx::Class::Admin: $missing\n";
14 use JSON::Any qw(DWIW PP JSON CPANEL XS);
16 use MooseX::Types::Moose qw/Int Str Any Bool/;
17 use DBIx::Class::Admin::Types qw/DBICConnectInfo DBICHashRef/;
18 use MooseX::Types::JSON qw(JSON);
19 use MooseX::Types::Path::Class qw(Dir File);
20 use MooseX::Types::LoadableClass qw(LoadableClass);
26 DBIx::Class::Admin - Administration object for schemas
32 $ dbicadmin --schema=MyApp::Schema \
33 --connect='["dbi:SQLite:my.db", "", ""]' \
36 $ dbicadmin --schema=MyApp::Schema --class=Employee \
37 --connect='["dbi:SQLite:my.db", "", ""]' \
38 --op=update --set='{ "name": "New_Employee" }'
40 use DBIx::Class::Admin;
43 my $admin = DBIx::Class::Admin->new(
44 schema_class=> 'MY::Schema',
46 connect_info => { dsn => $dsn, user => $user, password => $pass },
50 $admin->create('SQLite');
52 # create SQL diff for an upgrade
53 $admin->create('SQLite', {} , "1.0");
58 # install a version for an unversioned schema
59 $admin->install("3.0");
63 The Admin interface has additional requirements not currently part of
64 L<DBIx::Class>. See L<DBIx::Class::Optional::Dependencies> for more details.
70 the class of the schema to load
74 has 'schema_class' => (
82 A pre-connected schema object can be provided for manipulation
88 isa => 'DBIx::Class::Schema',
95 $self->connect_info->[3]{ignore_version} = 1;
96 return $self->schema_class->connect(@{$self->connect_info});
101 a resultset from the schema to operate on
113 a hash ref or json string to be used for identifying data to manipulate
126 a hash ref or json string to be used for inserting or updating data
139 a hash ref or json string to be used for passing additional info to the ->search call
152 connect_info the arguments to provide to the connect call of the schema_class
156 has 'connect_info' => (
158 isa => DBICConnectInfo,
163 sub _build_connect_info {
165 return $self->_find_stanza($self->config, $self->config_stanza);
171 config_file provide a config_file to read connect_info from, if this is provided
172 config_stanze should also be provided to locate where the connect_info is in the config
173 The config file should be in a format readable by Config::Any.
186 config_stanza for use with config_file should be a '::' delimited 'path' to the connection information
187 designed for use with catalyst config files
191 has 'config_stanza' => (
199 Instead of loading from a file the configuration can be provided directly as a hash ref. Please note
200 config_stanza will still be required.
213 try { require Config::Any }
214 catch { die ("Config::Any is required to parse the config file.\n") };
216 my $cfg = Config::Any->load_files ( {files => [$self->config_file], use_ext =>1, flatten_to_hash=>1});
218 # just grab the config from the config file
219 $cfg = $cfg->{$self->config_file};
226 The location where sql ddl files should be created or found for an upgrade.
239 The type of sql dialect to use for creating sql files from schema
250 Used for install, the version which will be 'installed' in the schema
262 Previous version of the schema to create an upgrade diff for, the full sql for that version of the sql must be in the sql_dir
274 Try and force certain operations.
286 Be less verbose about actions
303 Toggle DBIx::Class debug output
310 trigger => \&_trigger_trace,
314 my ($self, $new, $old) = @_;
315 $self->schema->storage->debug($new);
325 =item Arguments: $sqlt_type, \%sqlt_args, $preversion
329 C<create> will generate sql for the supplied schema_class in sql_dir. The
330 flavour of sql to generate can be controlled by supplying a sqlt_type which
331 should be a L<SQL::Translator> name.
333 Arguments for L<SQL::Translator> can be supplied in the sqlt_args hashref.
335 Optional preversion can be supplied to generate a diff to be used by upgrade.
340 my ($self, $sqlt_type, $sqlt_args, $preversion) = @_;
342 $preversion ||= $self->preversion();
343 $sqlt_type ||= $self->sql_type();
345 my $schema = $self->schema();
347 $schema->create_ddl_dir( $sqlt_type, (defined $schema->schema_version ? $schema->schema_version : ""), $self->sql_dir->stringify, $preversion, $sqlt_args );
355 =item Arguments: <none>
359 upgrade will attempt to upgrade the connected database to the same version as the schema_class.
360 B<MAKE SURE YOU BACKUP YOUR DB FIRST>
366 my $schema = $self->schema();
368 if (!$schema->get_db_version()) {
369 # schema is unversioned
370 $schema->throw_exception ("Could not determin current schema version, please either install() or deploy().\n");
372 $schema->upgrade_directory ($self->sql_dir) if $self->sql_dir; # this will override whatever default the schema has
373 my $ret = $schema->upgrade();
383 =item Arguments: $version
387 install is here to help when you want to move to L<DBIx::Class::Schema::Versioned> and have an existing
388 database. install will take a version and add the version tracking tables and 'install' the version. No
389 further ddl modification takes place. Setting the force attribute to a true value will allow overriding of
390 already versioned databases.
395 my ($self, $version) = @_;
397 my $schema = $self->schema();
398 $version ||= $self->version();
399 if (!$schema->get_db_version() ) {
400 # schema is unversioned
401 print "Going to install schema version\n" if (!$self->quiet);
402 my $ret = $schema->install($version);
403 print "return is $ret\n" if (!$self->quiet);
405 elsif ($schema->get_db_version() and $self->force ) {
406 warn "Forcing install may not be a good idea\n";
407 if($self->_confirm() ) {
408 $self->schema->_set_db_version({ version => $version});
412 $schema->throw_exception ("Schema already has a version. Try upgrade instead.\n");
422 =item Arguments: $args
426 deploy will create the schema at the connected database. C<$args> are passed straight to
427 L<DBIx::Class::Schema/deploy>.
432 my ($self, $args) = @_;
433 my $schema = $self->schema();
434 $schema->deploy( $args, $self->sql_dir );
441 =item Arguments: $rs, $set
445 insert takes the name of a resultset from the schema_class and a hashref of data to insert
451 my ($self, $rs, $set) = @_;
453 $rs ||= $self->resultset();
454 $set ||= $self->set();
455 my $resultset = $self->schema->resultset($rs);
456 my $obj = $resultset->new_result($set)->insert;
457 print ''.ref($resultset).' ID: '.join(',',$obj->id())."\n" if (!$self->quiet);
465 =item Arguments: $rs, $set, $where
469 update takes the name of a resultset from the schema_class, a hashref of data to update and
470 a where hash used to form the search for the rows to update.
475 my ($self, $rs, $set, $where) = @_;
477 $rs ||= $self->resultset();
478 $where ||= $self->where();
479 $set ||= $self->set();
480 my $resultset = $self->schema->resultset($rs);
481 $resultset = $resultset->search( ($where||{}) );
483 my $count = $resultset->count();
484 print "This action will modify $count ".ref($resultset)." records.\n" if (!$self->quiet);
486 if ( $self->force || $self->_confirm() ) {
487 $resultset->update_all( $set );
496 =item Arguments: $rs, $where, $attrs
500 delete takes the name of a resultset from the schema_class, a where hashref and a attrs to pass to ->search.
501 The found data is deleted and cannot be recovered.
506 my ($self, $rs, $where, $attrs) = @_;
508 $rs ||= $self->resultset();
509 $where ||= $self->where();
510 $attrs ||= $self->attrs();
511 my $resultset = $self->schema->resultset($rs);
512 $resultset = $resultset->search( ($where||{}), ($attrs||()) );
514 my $count = $resultset->count();
515 print "This action will delete $count ".ref($resultset)." records.\n" if (!$self->quiet);
517 if ( $self->force || $self->_confirm() ) {
518 $resultset->delete_all();
527 =item Arguments: $rs, $where, $attrs
531 select takes the name of a resultset from the schema_class, a where hashref and a attrs to pass to ->search.
532 The found data is returned in a array ref where the first row will be the columns list.
537 my ($self, $rs, $where, $attrs) = @_;
539 $rs ||= $self->resultset();
540 $where ||= $self->where();
541 $attrs ||= $self->attrs();
542 my $resultset = $self->schema->resultset($rs);
543 $resultset = $resultset->search( ($where||{}), ($attrs||()) );
546 my @columns = $resultset->result_source->columns();
547 push @data, [@columns];#
549 while (my $row = $resultset->next()) {
551 foreach my $column (@columns) {
552 push( @fields, $row->get_column($column) );
554 push @data, [@fields];
563 # mainly here for testing
564 return 1 if ($self->meta->get_attribute('_confirm')->get_value($self));
566 print "Are you sure you want to do this? (type YES to confirm) \n";
567 my $response = <STDIN>;
569 return ($response=~/^YES/);
573 my ($self, $cfg, $stanza) = @_;
574 my @path = split /::/, $stanza;
575 while (my $path = shift @path) {
576 if (exists $cfg->{$path}) {
577 $cfg = $cfg->{$path};
580 die ("Could not find $stanza in config, $path does not seem to exist.\n");
583 $cfg = $cfg->{connect_info} if exists $cfg->{connect_info};
587 =head1 FURTHER QUESTIONS?
589 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
591 =head1 COPYRIGHT AND LICENSE
593 This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
594 by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
595 redistribute it and/or modify it under the same terms as the
596 L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.