Hi,

Attached is a patchset allowing an alternative way of specifying simple SQLT indexes in classes. Full documentation and a two tests are included (can't think of more). Castaway liked it, Ash didn't, so I accept suggestions for a better design. One thing is certain - using sqlt_deploy_hook for adding single column indexes is the most convoluted way possible.

Peter
Index: t/03podcoverage.t
===================================================================
--- t/03podcoverage.t	(revision 4250)
+++ t/03podcoverage.t	(working copy)
@@ -89,6 +89,7 @@
     'DBIx::Class::Storage::DBI::mysql'                  => { skip => 1 },
     'SQL::Translator::Parser::DBIx::Class'              => { skip => 1 },
     'SQL::Translator::Producer::DBIx::Class::File'      => { skip => 1 },
+    'DBIx::Class::Index::Simple'                        => { skip => 1 },
 
 # skipped because the synopsis covers it clearly
 
Index: t/lib/DBICTest/Schema/Event.pm
===================================================================
--- t/lib/DBICTest/Schema/Event.pm	(revision 4250)
+++ t/lib/DBICTest/Schema/Event.pm	(working copy)
@@ -4,14 +4,14 @@
 use warnings;
 use base qw/DBIx::Class::Core/;
 
-__PACKAGE__->load_components(qw/InflateColumn::DateTime/);
+__PACKAGE__->load_components(qw/InflateColumn::DateTime Index::Simple/);
 
 __PACKAGE__->table('event');
 
 __PACKAGE__->add_columns(
   id => { data_type => 'integer', is_auto_increment => 1 },
   starts_at => { data_type => 'datetime' },
-  created_on => { data_type => 'timestamp' }
+  created_on => { data_type => 'timestamp', index_as => 'created_test_simple_idx' }
 );
 
 __PACKAGE__->set_primary_key('id');
Index: t/86sqlt.t
===================================================================
--- t/86sqlt.t	(revision 4250)
+++ t/86sqlt.t	(working copy)
@@ -10,7 +10,7 @@
 
 my $schema = DBICTest->init_schema;
 
-plan tests => 160;
+plan tests => 162;
 
 my $translator = SQL::Translator->new( 
   parser_args => {
@@ -305,6 +305,14 @@
 );
 
 my $tschema = $translator->schema();
+
+# Test that the Index::Simple::sqlt_deploy_hook was called and that the correct
+# indexes were created:
+my ($s_idx) = grep { $_->name eq 'created_test_simple_idx'} ($tschema->get_table('event')->get_indices);
+my $s_cols = [ $s_idx ?  $s_idx->fields : '' ];
+ok( $s_idx, 'Index::Simple created an index with the correct name');
+is_deeply( $s_cols, [qw/created_on/], 'Index::Simple created an index on the correct column');
+
 # Test that the $schema->sqlt_deploy_hook was called okay and that it removed
 # the 'link' table
 ok( !defined($tschema->get_table('link')), "Link table was removed by hook");
Index: lib/DBIx/Class/Index/Simple.pm
===================================================================
--- lib/DBIx/Class/Index/Simple.pm	(revision 0)
+++ lib/DBIx/Class/Index/Simple.pm	(revision 0)
@@ -0,0 +1,93 @@
+package DBIx::Class::Index::Simple;
+
+use warnings;
+use strict;
+
+use base qw/DBIx::Class/;
+
+=head1 NAME
+
+DBIx::Class::Index::Simple - Easy definition of L<SQLT|SQL::Translator> non-unique indexes for single columns
+
+=head1 SYNOPSIS
+
+    __PACKAGE__->load_components(qw/Index::Simple Core/);
+    __PACKAGE__->add_columns(
+        ...
+        data => {
+            data_type 'VARCHAR',
+            size => '100',
+            index_as => 'data_idx',
+        },
+        ...
+    );
+
+=head1 DESCRIPTION
+
+This component allows easy definition of single column non-unique indexes for
+further use with L<SQLTranslator|SQL::Translator>. It provides a convenient alternative
+to the standard method of defining indexes as described in the
+L<Cookbook|DBIx::Class::Manual::Cookbook/"Adding Indexes And Functions To Your SQL">.
+Just add the attribute C<index_as> to every column you want to index, and supply the
+index name as the attribute value. The index name must be unique among all other index
+and/or unique constraint names defined for a specific resultsource, otherwise an
+exception is thrown. The example from the L<SYNOPSIS> above is identical to:
+
+    __PACKAGE__->add_columns(
+        ...
+        data => {
+            data_type 'VARCHAR',
+            size => '100',
+        },
+        ...
+    );
+
+    sub sqlt_deploy_hook {
+        my ($self, $sqlt_table) = @_;
+        $sqlt_table->add_index(name => 'data_idx', fields => ['data']);
+    }
+
+=head1 USAGE NOTES
+
+The module adds indexes by declaring a version of the C<sqlt_deploy_hook> method. If you
+want to use this component together with your own C<sqlt_deploy_hook>, you need add an
+explicit inherited method call to your version:
+
+    sub sqlt_deploy_hook {
+        my ($self, $sqlt_table) = @_;
+
+        <do your stuff>
+
+        $self->next::method ($sqlt_table);  #call sqlt_deploy_hook from Index::Simple
+    }
+
+=head1 AUTHORS
+
+Peter Rabbitson, <[EMAIL PROTECTED]>
+
+=head1 LICENSE
+
+You may distribute this code under the same terms as Perl itself.
+
+=cut
+
+sub sqlt_deploy_hook {
+    my $self = shift;
+    my ($sqlt_table) = @_;
+
+    foreach my $column ($self->columns) {
+        if (exists $self->column_info($column)->{index_as}) {
+
+            my $idx_name = $self->column_info($column)->{index_as};
+            if (not defined $idx_name or length ($idx_name) == 0) {
+                $self->throw_exception("You must supply an index name for $column");
+            }
+
+            $sqlt_table->add_index(name => $idx_name, fields => [$column]);
+        }
+    }
+
+    $self->next::method (@_) if $self->next::can;
+}
+
+1;
Index: lib/DBIx/Class/Manual/Cookbook.pod
===================================================================
--- lib/DBIx/Class/Manual/Cookbook.pod	(revision 4250)
+++ lib/DBIx/Class/Manual/Cookbook.pod	(working copy)
@@ -1056,6 +1056,18 @@
 L<SQL::Translator::Schema/add_view> or 
 L<SQL::Translator::Schema/add_procedure>.
 
+=head2 Adding Single Column Non-Unique Indexes
+
+If all you want to do is add a single column non-unique index to one or several
+columns you can use the L<Index::Simple|DBIx::Class::Index::Simple> component:
+
+ package My::Schema::Artist;
+
+ __PACKAGE__->load_components(qw/Index::Simple Core/);
+ __PACKAGE__->table('artist');
+ __PACKAGE__->add_columns(id => { ... }, name => { ... index_as => 'name', ... })
+
+
 =head2 Schema versioning
 
 The following example shows simplistically how you might use DBIx::Class to
_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/[EMAIL PROTECTED]

Reply via email to