- $schema->deploy now accepts a list of source (name)s to deploy
Ash Berlin [Mon, 27 Nov 2006 19:34:28 +0000 (19:34 +0000)]
- Also fixed creating of FK constraints to use is_foreign_key attr explicitly
  even if no back rel

lib/DBIx/Class/Schema.pm
lib/DBIx/Class/Storage/DBI.pm
lib/SQL/Translator/Parser/DBIx/Class.pm

index 1d6af1e..1bcd5b3 100644 (file)
@@ -898,12 +898,17 @@ sub throw_exception {
 Attempts to deploy the schema to the current storage using L<SQL::Translator>.
 
 Note that this feature is currently EXPERIMENTAL and may not work correctly
-across all databases, or fully handle complex relationships.
+across all databases, or fully handle complex relationships. Saying that, it
+has been used successfully by many people, including the core dev team.
 
 See L<SQL::Translator/METHODS> for a list of values for C<$sqlt_args>. The most
 common value for this would be C<< { add_drop_table => 1, } >> to have the SQL
 produced include a DROP TABLE statement for each table created.
 
+Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash 
+ref or an array ref, containing a list of source to deploy. If present, then 
+only the sources listed will get deployed.
+
 =cut
 
 sub deploy {
index 99896da..f95641a 100644 (file)
@@ -1266,6 +1266,12 @@ sub deployment_statements {
     $self->throw_exception($@) if $@;
     eval "use SQL::Translator::Producer::${type};";
     $self->throw_exception($@) if $@;
+
+    # sources needs to be a parser arg, but for simplicty allow at top level 
+    # coming in
+    $sqltargs->{parser_args}{sources} = delete $sqltargs->{sources}
+        if exists $sqltargs->{sources};
+
     my $tr = SQL::Translator->new(%$sqltargs);
     SQL::Translator::Parser::DBIx::Class::parse( $tr, $schema );
     return "SQL::Translator::Producer::${type}"->can('produce')->($tr);
index d8af4d6..ffe434a 100644 (file)
@@ -26,10 +26,11 @@ use base qw(Exporter);
 # We're working with DBIx::Class Schemas, not data streams.
 # -------------------------------------------------------------------
 sub parse {
-    my ($tr, $data) = @_;
-    my $args        = $tr->parser_args;
-    my $dbixschema  = $args->{'DBIx::Schema'} || $data;
-    $dbixschema   ||= $args->{'package'};
+    my ($tr, $data)   = @_;
+    my $args          = $tr->parser_args;
+    my $dbixschema    = $args->{'DBIx::Schema'} || $data;
+    $dbixschema     ||= $args->{'package'};
+    my $limit_sources = $args->{'sources'};
     
     die 'No DBIx::Schema' unless ($dbixschema);
     if (!ref $dbixschema) {
@@ -46,7 +47,23 @@ sub parse {
 
     my %seen_tables;
 
-    foreach my $moniker ($dbixschema->sources)
+    my @monikers = $dbixschema->sources;
+    if ($limit_sources) {
+        my $ref = ref $limit_sources || '';
+        die "'source' parameter must be an array or hash ref" unless $ref eq 'ARRAY' || ref eq 'HASH';
+
+        # limit monikers to those specified in 
+        my $sources;
+        if ($ref eq 'ARRAY') {
+            $sources->{$_} = 1 for (@$limit_sources);
+        } else {
+            $sources = $limit_sources;
+        }
+        @monikers = grep { $sources->{$_} } @monikers;
+    }
+
+
+    foreach my $moniker (@monikers)
     {
         #eval "use $tableclass";
         #print("Can't load $tableclass"), next if($@);
@@ -91,6 +108,9 @@ sub parse {
         }
 
         my @rels = $source->relationships();
+
+        my %created_FK_rels;
+
         foreach my $rel (@rels)
         {
             my $rel_info = $source->relationship_info($rel);
@@ -120,12 +140,22 @@ sub parse {
                     $on_update = $otherrelationship->{'attrs'}->{cascade_copy} ? 'CASCADE' : '';
                 }
 
+                # Make sure we dont create the same foreign key constraint twice
+                my $key_test = join("\x00", @keys);
+
                 #Decide if this is a foreign key based on whether the self
                 #items are our primary columns.
 
                 # If the sets are different, then we assume it's a foreign key from
                 # us to another table.
-                if (!$source->compare_relationship_keys(\@keys, \@primary)) {
+                # OR: If is_foreign_key attr is explicity set on one the local columns
+                if ( ! exists $created_FK_rels{$rel_table}->{$key_test} 
+                    && 
+                    ( !$source->compare_relationship_keys(\@keys, \@primary) ||
+                      grep { $source->column_info($_)->{is_foreign_key} } @keys 
+                    )
+                   ) {
+                    $created_FK_rels{$rel_table}->{$key_test} = 1;
                     $table->add_constraint(
                                 type             => 'foreign_key',
                                 name             => "fk_$keys[0]",