Set $result_source_class->table_class appropriately on views
Aaron Crane [Sun, 29 Sep 2013 13:19:19 +0000 (14:19 +0100)]
This constitutes partial support for the per-backend TODO items labelled
"introspect view SQL".  I've therefore left those items unchanged for the
backends that are now known to support this, and added a note for this part
of the work to the other backends.

Backends whose DBD implements enough of the DBI table_info method to indicate
whether a relation is in fact a view should also acquire support for setting
table_class, but there are no tests for other backends, so they haven't been
declared working.

Changes
TODO
lib/DBIx/Class/Schema/Loader/Base.pm
lib/DBIx/Class/Schema/Loader/DBI.pm
t/10_01sqlite_common.t
t/10_02mysql_common.t
t/10_03pg_common.t

diff --git a/Changes b/Changes
index 1a87135..880b687 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,8 @@
 Revision history for Perl extension DBIx::Class::Schema::Loader
 
+        - Set table_class to DBIx::Class::ResultSource::View for views, in
+          supported backends (SQLite, MySQL, and Pg) (arc@cpan.org)
+
 0.07036_03 2013-10-22
         - Restore support for PostgreSQL 8.3 (RT#87291)
         - Fix t/23dumpmore on perl 5.8.8 and earlier
diff --git a/TODO b/TODO
index 6895711..51efebf 100644 (file)
--- a/TODO
+++ b/TODO
     - domains
   - DB2
     - table/column comments
-    - introspect view SQL
+    - introspect view SQL and set table_class
     - domains
   - Oracle
-    - introspect view SQL
+    - introspect view SQL and set table_class
     - domains
   - Sybase ASE
     - table/column comments
     - introspect on_update/on_delete/is_deferrable
-    - introspect view SQL
+    - introspect view SQL and set table_class
     - domains
   - MSSQL
     - table/column comments
-    - introspect view SQL
+    - introspect view SQL and set table_class
     - computed column support
     - domains
     - Optimization
       - use placeholders when available
   - SQLAnywhere
     - table/column comments
-    - introspect view SQL
+    - introspect view SQL and set table_class
     - domains
   - Firebird
     - table/column comments
     - introspect on_update/on_delete/is_deferrable
-    - introspect view SQL
+    - introspect view SQL and set table_class
     - domains
   - Informix
     - support opaque types
     - datetime/interval precision detection
     - table/column comments
     - introspect on_update/on_delete/is_deferrable
-    - introspect view SQL
+    - introspect view SQL and set table_class
     - domains
index 6fb22e9..cf97c01 100644 (file)
@@ -2468,6 +2468,11 @@ sub _make_column_accessor_name {
     return $accessor;
 }
 
+sub _table_is_view {
+    #my ($self, $table) = @_;
+    return 0;
+}
+
 # Set up metadata (cols, pks, etc)
 sub _setup_src_meta {
     my ($self, $table) = @_;
@@ -2478,6 +2483,9 @@ sub _setup_src_meta {
     my $table_class   = $self->classes->{$table->sql_name};
     my $table_moniker = $self->monikers->{$table->sql_name};
 
+    $self->_dbic_stmt($table_class, 'table_class', 'DBIx::Class::ResultSource::View')
+        if $self->_table_is_view($table);
+
     $self->_dbic_stmt($table_class, 'table', $table->dbic_name);
 
     my $cols     = $self->_table_columns($table);
index 71fd3d6..34c5a92 100644 (file)
@@ -680,6 +680,14 @@ sub dbh {
     return $self->schema->storage->dbh;
 }
 
+sub _table_is_view {
+    my ($self, $table) = @_;
+
+    my $info = $self->_dbh_table_info($self->dbh, $table)
+        or return 0;
+    return $info->{TABLE_TYPE} eq 'VIEW';
+}
+
 =head1 SEE ALSO
 
 L<DBIx::Class::Schema::Loader>
index c0b7434..233c079 100644 (file)
@@ -139,7 +139,7 @@ my $tester = dbixcsl_common_tests->new(
         drop  => [ qw/extra_loader_test1 extra_loader_test2 extra_loader_test3
                       extra_loader_test4 extra_loader_test6 extra_loader_test7
                       extra_loader_test8 extra_loader_test9 extra_loader_test10 / ],
-        count => 19,
+        count => 20,
         run   => sub {
             my ($schema, $monikers, $classes) = @_;
 
@@ -170,6 +170,10 @@ my $tester = dbixcsl_common_tests->new(
             is $schema->resultset($monikers->{extra_loader_test5})->result_source->column_info('person_id')->{data_type}, 'integer',
                 'columns for views are introspected';
 
+            # test that views are marked as such
+            isa_ok $schema->resultset($monikers->{extra_loader_test5})->result_source, 'DBIx::Class::ResultSource::View',
+                'views have table_class set correctly';
+
             isnt $schema->resultset($monikers->{extra_loader_test6})->result_source->column_info('id1')->{is_auto_increment}, 1,
                 q{two integer PKs don't get marked autoinc};
 
index 27840db..26f086a 100644 (file)
@@ -201,7 +201,7 @@ my $tester = dbixcsl_common_tests->new(
         ],
         pre_drop_ddl => [ 'DROP VIEW mysql_loader_test2', ],
         drop => [ 'mysql_loader-test1', 'mysql_loader_test3', 'mysql_loader_test11', 'mysql_loader_test12' ],
-        count => 8 + 30 * 2,
+        count => 9 + 30 * 2,
         run => sub {
             my ($monikers, $classes);
             ($schema, $monikers, $classes) = @_;
@@ -214,6 +214,10 @@ my $tester = dbixcsl_common_tests->new(
             is $rsrc->column_info('value')->{data_type}, 'varchar',
                 'view introspected successfully';
 
+            # test that views are marked as such
+            isa_ok $schema->resultset($monikers->{mysql_loader_test2})->result_source, 'DBIx::Class::ResultSource::View',
+                'views have table_class set correctly';
+
             $rsrc = $schema->source('MysqlLoaderTest3');
 
             is_deeply $rsrc->column_info('del_group')->{extra}{list}, ['19,90 (<500)/0 EUR','4,90 (<120)/0 EUR','7,90 (<200)/0 CHF','300 (<6000)/0 CZK','4,90 (<100)/0 EUR','39 (<900)/0 DKK','299 (<5000)/0 EEK','9,90 (<250)/0 EUR','3,90 (<100)/0 GBP','3000 (<70000)/0 HUF','4000 (<70000)/0 JPY','13,90 (<200)/0 LVL','99 (<2500)/0 NOK','39 (<1000)/0 PLN','1000 (<20000)/0 RUB','49 (<2500)/0 SEK','29 (<600)/0 USD','19,90 (<600)/0 EUR','0 EUR','0 CHF'],
index e3a8b03..477ff0a 100644 (file)
@@ -242,15 +242,20 @@ my $tester = dbixcsl_common_tests->new(
                         on delete restrict on update set null deferrable
                 )
             },
+            q{
+                create view pg_loader_test11 as
+                    select * from pg_loader_test1
+            },
         ],
         pre_drop_ddl => [
             'DROP SCHEMA dbicsl_test CASCADE',
             'DROP SCHEMA "dbicsl-test" CASCADE',
             'DROP SCHEMA "dbicsl.test" CASCADE',
             'DROP TYPE pg_loader_test_enum',
+            'DROP VIEW pg_loader_test11',
         ],
         drop  => [ qw/pg_loader_test1 pg_loader_test2 pg_loader_test9 pg_loader_test10/ ],
-        count => 8 + 30 * 2,
+        count => 9 + 30 * 2,
         run   => sub {
             my ($schema, $monikers, $classes) = @_;
 
@@ -440,6 +445,10 @@ my $tester = dbixcsl_common_tests->new(
                         ->has_relationship('pg_loader_test8s');
                 } 'cross-schema relationship in multi-db_schema';
             }
+
+            # test that views are marked as such
+            isa_ok $schema->resultset($monikers->{pg_loader_test11})->result_source, 'DBIx::Class::ResultSource::View',
+                'views have table_class set correctly';
         },
     },
 );