basic structure in place
luke [Mon, 25 May 2009 22:13:05 +0000 (22:13 +0000)]
13 files changed:
Makefile.PL [new file with mode: 0644]
lib/DBIx/Class/ResultSet/WithMetaData.pm [new file with mode: 0644]
t/basic.t [new file with mode: 0644]
t/lib/DBICTest.pm [new file with mode: 0755]
t/lib/DBICTest/Schema.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/Artist.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/CD.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/CD_to_Producer.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/Producer.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/Tag.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/Track.pm [new file with mode: 0644]
t/lib/sqlite.sql [new file with mode: 0644]
t/var/DBIxClass.db [new file with mode: 0644]

diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644 (file)
index 0000000..3be7d9c
--- /dev/null
@@ -0,0 +1,18 @@
+use inc::Module::Install 0.87;
+
+name     'DBIx-Class-ResultSet-WithMetaData';
+perl_version '5.006001';
+all_from 'lib/DBIx/Class/ResultSet/WithMetaData.pm';
+
+requires 'DBIx::Class' => 0.08;
+requires 'MooseX::Method::Signatures' => 0.13;
+
+build_requires 'Test::More'       => 0.7;
+
+tests_recursive();
+
+auto_provides;
+
+auto_install;
+
+WriteAll;
diff --git a/lib/DBIx/Class/ResultSet/WithMetaData.pm b/lib/DBIx/Class/ResultSet/WithMetaData.pm
new file mode 100644 (file)
index 0000000..8179aaf
--- /dev/null
@@ -0,0 +1,98 @@
+package DBIx::Class::ResultSet::WithMetaData;
+
+use strict;
+use warnings;
+
+use Data::Alias;
+use Moose;
+use MooseX::Method::Signatures;
+extends 'DBIx::Class::ResultSet';
+
+has '_row_info' => (
+       is => 'rw',
+       isa => 'HashRef'
+);
+
+has 'was_row' => (
+       is => 'rw',
+       isa => 'Int'
+);
+
+sub new {
+       my $self = shift;
+  my $new = $self->next::method(@_);
+       foreach my $key (qw/_row_info/) {
+               alias $new->{$key} = $new->{attrs}{$key};
+               $new->{$key} = {} unless $new->{$key};
+       }
+
+       return $new;
+}
+
+method with_token {
+       foreach my $row ($self->all) {
+               my $token = $self->tokenify($row->get_column($self->token_col));
+               $self->add_row_info(id => $row->id, info => { join('_', 'token', $self->token_col) => $token });
+       }
+
+       return $self;
+}
+
+method display () {
+  my $rs = $self->search({});
+  $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
+  my @rows;
+       foreach my $row ($rs->all) {
+               if (my $info = $self->row_info_for(id => $row->{id})) {
+                       $row = { %{$row}, %{$info} };
+               }
+               push(@rows, $row);
+       }
+
+  return ($self->was_row) ? $rows[0] : \@rows;
+}
+
+method add_row_info (Int :$id, HashRef :$info) {
+       unless ($self->find($id)) {
+               warn $id;
+               die 'invalid id passed to add_row_info';
+       }
+
+       if (my $existing = $self->_row_info->{$id}) {
+               $info = { %{$existing}, %{$info} };
+       }
+
+       $self->_row_info->{$id} = $info;        
+}
+
+method row_info_for (Int :$id) {
+       return $self->_row_info->{$id};
+}
+
+method order_by (Str :$col) {
+       $col = "me.$col" unless ($col =~ m/\./);
+       return $self->search({}, { order_by => $col });
+}
+
+method limit (Int :$count) {
+       return $self->search({}, { rows => $count });
+}
+
+sub tokenify {
+  my ($self, $string) = @_;
+
+  $string =~ s/\s+$//;
+  $string =~ s/[,\.\-\+]//g;
+  $string =~ s/^\s+//;
+  $string =~ s/ /-/g;
+  $string = lc($string);
+  return $string;
+}
+
+sub clean_rs {
+  my $self = shift;
+
+  return $self->result_source->resultset;
+}
+
+1;
diff --git a/t/basic.t b/t/basic.t
new file mode 100644 (file)
index 0000000..8abbee4
--- /dev/null
+++ b/t/basic.t
@@ -0,0 +1,10 @@
+#!perl
+
+use Test::More tests => 9;
+use lib qw(t/lib);
+use DBICTest;
+use Data::Dumper;
+
+# set up and populate schema
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
diff --git a/t/lib/DBICTest.pm b/t/lib/DBICTest.pm
new file mode 100755 (executable)
index 0000000..9de9e27
--- /dev/null
@@ -0,0 +1,201 @@
+package # hide from PAUSE 
+    DBICTest;
+
+use strict;
+use warnings;
+use DBICTest::Schema;
+
+=head1 NAME
+
+DBICTest - Library to be used by DBIx::Class test scripts.
+
+=head1 SYNOPSIS
+
+  use lib qw(t/lib);
+  use DBICTest;
+  use Test::More;
+  
+  my $schema = DBICTest->init_schema();
+
+=head1 DESCRIPTION
+
+This module provides the basic utilities to write tests against 
+DBIx::Class.
+
+=head1 METHODS
+
+=head2 init_schema
+
+  my $schema = DBICTest->init_schema(
+    no_deploy=>1,
+    no_populate=>1,
+  );
+
+This method removes the test SQLite database in t/var/DBIxClass.db 
+and then creates a new, empty database.
+
+This method will call deploy_schema() by default, unless the 
+no_deploy flag is set.
+
+Also, by default, this method will call populate_schema() by 
+default, unless the no_deploy or no_populate flags are set.
+
+=cut
+
+sub init_schema {
+    my $self = shift;
+    my %args = @_;
+
+    my $db_file = "t/var/DBIxClass.db";
+
+    mkdir("t/var") unless -d "t/var";
+    if ( !$args{no_deploy} ) {
+      unlink($db_file) if -e $db_file;
+      unlink($db_file . "-journal") if -e $db_file . "-journal";
+    }
+
+    my $dsn = $args{"dsn"} || "dbi:SQLite:${db_file}";
+    my $dbuser = $args{"user"} || '';
+    my $dbpass = $args{"pass"} || '';
+
+    my $schema;
+
+    my @connect_info = ($dsn, $dbuser, $dbpass, { AutoCommit => 1 });
+
+    if ($args{compose_connection}) {
+      $schema = DBICTest::Schema->compose_connection(
+                  'DBICTest', @connect_info
+                );
+    } else {
+      $schema = DBICTest::Schema->compose_namespace('DBICTest')
+                                ->connect(@connect_info);
+    }
+
+    if ( !$args{no_deploy} ) {
+        __PACKAGE__->deploy_schema( $schema );
+        __PACKAGE__->populate_schema( $schema ) if( !$args{no_populate} );
+    }
+    return $schema;
+}
+
+
+sub get_ddl_file {
+  my $self = shift;
+  my $schema = shift;
+
+  return 't/lib/' . lc($schema->storage->dbh->{Driver}->{Name}) . '.sql';
+}
+
+=head2 deploy_schema
+
+  DBICTest->deploy_schema( $schema );
+
+=cut
+
+sub deploy_schema {
+    my $self = shift;
+    my $schema = shift;
+
+    my $file = shift || $self->get_ddl_file($schema);
+    open IN, $file;
+    my $sql;
+    { local $/ = undef; $sql = <IN>; }
+    close IN;
+    ($schema->storage->dbh->do($_) || print "Error on SQL: $_\n") for split(/;\n/, $sql);
+}
+
+=head2 clear_schema
+
+  DBICTest->clear_schema( $schema );
+
+=cut
+
+sub clear_schema {
+    my $self = shift;
+    my $schema = shift;
+
+    foreach my $class ($schema->sources) {
+      $schema->resultset($class)->delete;
+    }
+}
+
+
+=head2 populate_schema
+
+  DBICTest->populate_schema( $schema );
+
+After you deploy your schema you can use this method to populate 
+the tables with test data.
+
+=cut
+
+sub populate_schema {
+    my $self = shift;
+    my $schema = shift;
+
+    $schema->populate('Artist', [
+        [ qw/artistid name/ ],
+        [ 1, 'Caterwauler McCrae' ],
+        [ 2, 'Random Boy Band' ],
+        [ 3, 'We Are Goth' ],
+    ]);
+
+    $schema->populate('CD', [
+        [ qw/cdid artist title year/ ],
+        [ 1, 1, "Spoonful of bees", 1999 ],
+        [ 2, 1, "Forkful of bees", 2001 ],
+        [ 3, 1, "Caterwaulin' Blues", 1997 ],
+        [ 4, 2, "Generic Manufactured Singles", 2001 ],
+        [ 5, 2, "We like girls and stuff", 2003 ],
+        [ 6, 3, "Come Be Depressed With Us", 1998 ],
+    ]);
+
+    $schema->populate('Tag', [
+        [ qw/tagid cd tag/ ],
+        [ 1, 1, "Blue" ],
+        [ 2, 2, "Blue" ],
+        [ 3, 3, "Blue" ],
+        [ 4, 5, "Blue" ],
+        [ 5, 2, "Cheesy" ],
+        [ 6, 4, "Cheesy" ],
+        [ 7, 5, "Cheesy" ],
+        [ 8, 2, "Shiny" ],
+        [ 9, 4, "Shiny" ],
+    ]);
+
+    $schema->populate('Producer', [
+        [ qw/producerid name/ ],
+        [ 1, 'Matt S Trout' ],
+        [ 2, 'Bob The Builder' ],
+        [ 3, 'Fred The Phenotype' ],
+    ]);
+
+    $schema->populate('CD_to_Producer', [
+        [ qw/cd producer/ ],
+        [ 1, 1 ],
+        [ 1, 2 ],
+        [ 1, 3 ],
+    ]);
+
+    $schema->populate('Track', [
+        [ qw/trackid cd  position title last_updated_on/ ],
+        [ 4, 2, 1, "Stung with Success"],
+        [ 5, 2, 2, "Stripy"],
+        [ 6, 2, 3, "Sticky Honey"],
+        [ 7, 3, 1, "Yowlin"],
+        [ 8, 3, 2, "Howlin"],
+        [ 9, 3, 3, "Fowlin", '2007-10-20 00:00:00'],
+        [ 10, 4, 1, "Boring Name"],
+        [ 11, 4, 2, "Boring Song"],
+        [ 12, 4, 3, "No More Ideas"],
+        [ 13, 5, 1, "Sad"],
+        [ 14, 5, 2, "Under The Weather"],
+        [ 15, 5, 3, "Suicidal"],
+        [ 16, 1, 1, "The Bees Knees"],
+        [ 17, 1, 2, "Apiary"],
+        [ 18, 1, 3, "Beehind You"],
+    ]);
+}
+
+1;
diff --git a/t/lib/DBICTest/Schema.pm b/t/lib/DBICTest/Schema.pm
new file mode 100644 (file)
index 0000000..350eecc
--- /dev/null
@@ -0,0 +1,10 @@
+package # hide from PAUSE
+    DBICTest::Schema;
+
+use base qw/DBIx::Class::Schema/;
+
+no warnings qw/qw/;
+
+__PACKAGE__->load_classes(qw/Artist CD Track Tag Producer CD_to_Producer/);
+
+1;
diff --git a/t/lib/DBICTest/Schema/Artist.pm b/t/lib/DBICTest/Schema/Artist.pm
new file mode 100644 (file)
index 0000000..594a76d
--- /dev/null
@@ -0,0 +1,25 @@
+package # hide from PAUSE 
+    DBICTest::Schema::Artist;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('artist');
+__PACKAGE__->add_columns(
+  'artistid' => {
+    data_type => 'integer',
+    is_auto_increment => 1,
+  },
+  'name' => {
+    data_type => 'varchar',
+    size      => 100,
+    is_nullable => 1,
+  },
+);
+__PACKAGE__->set_primary_key('artistid');
+
+__PACKAGE__->has_many(
+    cds => 'DBICTest::Schema::CD', undef,
+    { order_by => 'year' },
+);
+
+1;
diff --git a/t/lib/DBICTest/Schema/CD.pm b/t/lib/DBICTest/Schema/CD.pm
new file mode 100644 (file)
index 0000000..a6f084f
--- /dev/null
@@ -0,0 +1,44 @@
+package # hide from PAUSE 
+    DBICTest::Schema::CD;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('cd');
+__PACKAGE__->add_columns(
+  'cdid' => {
+    data_type => 'integer',
+    is_auto_increment => 1,
+  },
+  'artist' => {
+    data_type => 'integer',
+  },
+  'title' => {
+    data_type => 'varchar',
+    size      => 100,
+  },
+  'year' => {
+    data_type => 'varchar',
+    size      => 100,
+  },
+);
+__PACKAGE__->set_primary_key('cdid');
+__PACKAGE__->add_unique_constraint([ qw/artist title/ ]);
+
+__PACKAGE__->belongs_to( artist => 'DBICTest::Schema::Artist' );
+
+__PACKAGE__->has_many( tracks => 'DBICTest::Schema::Track' );
+__PACKAGE__->has_many(
+    tags => 'DBICTest::Schema::Tag', undef,
+    { order_by => 'tag' },
+);
+__PACKAGE__->has_many(
+    cd_to_producer => 'DBICTest::Schema::CD_to_Producer' => 'cd'
+);
+
+__PACKAGE__->many_to_many( producers => cd_to_producer => 'producer' );
+__PACKAGE__->many_to_many(
+    producers_sorted => cd_to_producer => 'producer',
+    { order_by => 'producer.name' },
+);
+
+1;
diff --git a/t/lib/DBICTest/Schema/CD_to_Producer.pm b/t/lib/DBICTest/Schema/CD_to_Producer.pm
new file mode 100644 (file)
index 0000000..117a590
--- /dev/null
@@ -0,0 +1,23 @@
+package # hide from PAUSE 
+    DBICTest::Schema::CD_to_Producer;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('cd_to_producer');
+__PACKAGE__->add_columns(
+  cd => { data_type => 'integer' },
+  producer => { data_type => 'integer' },
+);
+__PACKAGE__->set_primary_key(qw/cd producer/);
+
+__PACKAGE__->belongs_to(
+  'cd', 'DBICTest::Schema::CD',
+  { 'foreign.cdid' => 'self.cd' }
+);
+
+__PACKAGE__->belongs_to(
+  'producer', 'DBICTest::Schema::Producer',
+  { 'foreign.producerid' => 'self.producer' }
+);
+
+1;
diff --git a/t/lib/DBICTest/Schema/Producer.pm b/t/lib/DBICTest/Schema/Producer.pm
new file mode 100644 (file)
index 0000000..036f9f2
--- /dev/null
@@ -0,0 +1,20 @@
+package # hide from PAUSE 
+    DBICTest::Schema::Producer;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('producer');
+__PACKAGE__->add_columns(
+  'producerid' => {
+    data_type => 'integer',
+    is_auto_increment => 1
+  },
+  'name' => {
+    data_type => 'varchar',
+    size      => 100,
+  },
+);
+__PACKAGE__->set_primary_key('producerid');
+__PACKAGE__->add_unique_constraint(prod_name => [ qw/name/ ]);
+
+1;
diff --git a/t/lib/DBICTest/Schema/Tag.pm b/t/lib/DBICTest/Schema/Tag.pm
new file mode 100644 (file)
index 0000000..b75c2ef
--- /dev/null
@@ -0,0 +1,24 @@
+package # hide from PAUSE 
+    DBICTest::Schema::Tag;
+
+use base qw/DBIx::Class::Core/;
+
+__PACKAGE__->table('tags');
+__PACKAGE__->add_columns(
+  'tagid' => {
+    data_type => 'integer',
+    is_auto_increment => 1,
+  },
+  'cd' => {
+    data_type => 'integer',
+  },
+  'tag' => {
+    data_type => 'varchar',
+    size      => 100,
+  },
+);
+__PACKAGE__->set_primary_key('tagid');
+
+__PACKAGE__->belongs_to( cd => 'DBICTest::Schema::CD' );
+
+1;
diff --git a/t/lib/DBICTest/Schema/Track.pm b/t/lib/DBICTest/Schema/Track.pm
new file mode 100644 (file)
index 0000000..3f224d5
--- /dev/null
@@ -0,0 +1,37 @@
+package # hide from PAUSE 
+    DBICTest::Schema::Track;
+
+use base 'DBIx::Class::Core';
+__PACKAGE__->load_components(qw/InflateColumn::DateTime/);
+
+__PACKAGE__->table('track');
+__PACKAGE__->add_columns(
+  'trackid' => {
+    data_type => 'integer',
+    is_auto_increment => 1,
+  },
+  'cd' => {
+    data_type => 'integer',
+  },
+  'position' => {
+    data_type => 'integer',
+    accessor => 'pos',
+  },
+  'title' => {
+    data_type => 'varchar',
+    size      => 100,
+  },
+  last_updated_on => {
+    data_type => 'datetime',
+    accessor => 'updated_date',
+    is_nullable => 1
+  },
+);
+__PACKAGE__->set_primary_key('trackid');
+
+__PACKAGE__->add_unique_constraint([ qw/cd position/ ]);
+__PACKAGE__->add_unique_constraint([ qw/cd title/ ]);
+
+__PACKAGE__->belongs_to( cd => 'DBICTest::Schema::CD' );
+
+1;
diff --git a/t/lib/sqlite.sql b/t/lib/sqlite.sql
new file mode 100644 (file)
index 0000000..1e21627
--- /dev/null
@@ -0,0 +1,63 @@
+-- 
+-- Created by SQL::Translator::Producer::SQLite
+-- Created on Tue Aug  8 01:53:20 2006
+-- 
+BEGIN TRANSACTION;
+
+--
+-- Table: cd_to_producer
+--
+CREATE TABLE cd_to_producer (
+  cd integer NOT NULL,
+  producer integer NOT NULL,
+  PRIMARY KEY (cd, producer)
+);
+
+--
+-- Table: artist
+--
+CREATE TABLE artist (
+  artistid INTEGER PRIMARY KEY NOT NULL,
+  name varchar(100)
+);
+
+
+--
+-- Table: cd
+--
+CREATE TABLE cd (
+  cdid INTEGER PRIMARY KEY NOT NULL,
+  artist integer NOT NULL,
+  title varchar(100) NOT NULL,
+  year varchar(100) NOT NULL
+);
+
+--
+-- Table: track
+--
+CREATE TABLE track (
+  trackid INTEGER PRIMARY KEY NOT NULL,
+  cd integer NOT NULL,
+  position integer NOT NULL,
+  title varchar(100) NOT NULL,
+  last_updated_on datetime NULL
+);
+
+--
+-- Table: tags
+--
+CREATE TABLE tags (
+  tagid INTEGER PRIMARY KEY NOT NULL,
+  cd integer NOT NULL,
+  tag varchar(100) NOT NULL
+);
+
+--
+-- Table: producer
+--
+CREATE TABLE producer (
+  producerid INTEGER PRIMARY KEY NOT NULL,
+  name varchar(100) NOT NULL
+);
+
+COMMIT;
diff --git a/t/var/DBIxClass.db b/t/var/DBIxClass.db
new file mode 100644 (file)
index 0000000..673dd37
Binary files /dev/null and b/t/var/DBIxClass.db differ