__PACKAGE__->load_components(qw/AccessorGroup/);
__PACKAGE__->mk_group_accessors('simple' =>
- qw/connect_info _dbh _sql_maker _connection_pid debug debugfh cursor
- on_connect_do transaction_depth/);
+ qw/connect_info _dbh _sql_maker _conn_pid _conn_tid debug debugfh
+ cursor on_connect_do transaction_depth/);
sub new {
my $new = bless({}, ref $_[0] || $_[0]);
sub connected {
my ($self) = @_;
- my $dbh;
- (($dbh = $self->_dbh) && $dbh->FETCH('Active') && $dbh->ping)
+ if(my $dbh = $self->_dbh) {
+ if(defined $self->_conn_tid && $self->_conn_tid != threads->tid) {
+ $self->_sql_maker(undef);
+ return $self->_dbh(undef);
+ }
+ elsif($self->_conn_pid != $$) {
+ $self->_dbh->{InactiveDestroy} = 1;
+ $self->_sql_maker(undef);
+ return $self->_dbh(undef)
+ }
+ return ($dbh->FETCH('Active') && $dbh->ping);
+ }
+
+ return 0;
}
sub ensure_connected {
sub dbh {
my ($self) = @_;
- if($self->_connection_pid && $self->_connection_pid != $$) {
- $self->_dbh->{InactiveDestroy} = 1;
- $self->_dbh(undef)
- }
$self->ensure_connected;
return $self->_dbh;
}
$self->_dbh->do($sql_statement);
}
- $self->_connection_pid($$);
+ $self->_conn_pid($$);
+ $self->_conn_tid(threads->tid) if $INC{'threads.pm'};
}
sub _connect {
else {
--$self->{transaction_depth} == 0 ?
$self->dbh->rollback :
- die DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->new;
+ die DBIx::Class::Storage::NESTED_ROLLBACK_EXCEPTION->new;
}
};
=cut
+# override this in a subclass if your DBD ->can('column_info'),
+# but the call itself is horribly broken.
+sub _column_info_broken { 0 }
+
sub columns_info_for {
my ($self, $table) = @_;
+
my %result;
- if ( $self->dbh->can( 'column_info' ) ){
+ if ( $self->dbh->can( 'column_info' ) && !$self->_column_info_broken){
my $sth = $self->dbh->column_info( undef, undef, $table, '%' );
$sth->execute();
while ( my $info = $sth->fetchrow_hashref() ){
my %column_info;
$column_info{data_type} = $info->{TYPE_NAME};
$column_info{size} = $info->{COLUMN_SIZE};
- $column_info{is_nullable} = $info->{NULLABLE};
+ $column_info{is_nullable} = $info->{NULLABLE} ? 1 : 0;
+ $column_info{default_value} = $info->{COLUMN_DEF};
$result{$info->{COLUMN_NAME}} = \%column_info;
}
} else {
my $sth = $self->dbh->prepare("SELECT * FROM $table WHERE 1=0");
$sth->execute;
- my @columns = @{$sth->{NAME}};
+ my @columns = @{$sth->{NAME_lc}};
for my $i ( 0 .. $#columns ){
- $result{$columns[$i]}{data_type} = $sth->{TYPE}->[$i];
+ my %column_info;
+ my $type_num = $sth->{TYPE}->[$i];
+ my $type_name;
+ if(defined $type_num && $self->dbh->can('type_info')) {
+ my $type_info = $self->dbh->type_info($type_num);
+ $type_name = $type_info->{TYPE_NAME} if $type_info;
+ }
+ $column_info{data_type} = $type_name ? $type_name : $type_num;
+ $column_info{size} = $sth->{PRECISION}->[$i];
+ $column_info{is_nullable} = $sth->{NULLABLE}->[$i] ? 1 : 0;
+ $result{$columns[$i]} = \%column_info;
}
}
return \%result;
sub sqlt_type { shift->dbh->{Driver}->{Name} }
sub deployment_statements {
- my ($self, $schema, $type) = @_;
+ my ($self, $schema, $type, $sqltargs) = @_;
$type ||= $self->sqlt_type;
eval "use SQL::Translator";
$self->throw_exception("Can't deploy without SQL::Translator: $@") if $@;
$self->throw_exception($@) if $@;
eval "use SQL::Translator::Producer::${type};";
$self->throw_exception($@) if $@;
- my $tr = SQL::Translator->new(
- # Print debug info
- debug => 1,
- # Print Parse::RecDescent trace
- trace => 0,
- # Don't include comments in output
- no_comments => 1,
- # Print name mutations, conflicts
- show_warnings => 0,
- # Add "drop table" statements
- add_drop_table => 1,
- # Validate schema object
- validate => 1,
- # Make all table names CAPS in producers which support this option
- format_table_name => sub {my $tablename = shift; return uc($tablename)},
- );
-
+ my $tr = SQL::Translator->new(%$sqltargs);
SQL::Translator::Parser::DBIx::Class::parse( $tr, $schema );
return "SQL::Translator::Producer::${type}"->can('produce')->($tr);
}
sub deploy {
- my ($self, $schema, $type) = @_;
- foreach(split(";\n", $self->deployment_statements($schema, $type))) {
+ my ($self, $schema, $type, $sqltargs) = @_;
+ foreach(split(";\n", $self->deployment_statements($schema, $type, $sqltargs))) {
$self->debugfh->print("$_\n") if $self->debug;
- $self->dbh->do($_) or warn "SQL was:\n $_";
+ $self->dbh->do($_) or warn "SQL was:\n $_";
}
}