[Catalyst-commits] r7806 - in Catalyst-Controller-DBIC-API/1.000/trunk: . lib lib/Catalyst lib/Catalyst/Controller lib/Catalyst/Controller/CRUD lib/Catalyst/Controller/DBIC t t/lib t/lib/RestTest t/lib/RestTest/Controller t/lib/RestTest/Controller/API t/lib/RestTest/Controller/API/REST t/lib/RestTest/Controller/API/RPC t/lib/RestTest/Model t/lib/RestTest/Schema t/rest t/rpc t/var

lukes at dev.catalyst.perl.org lukes at dev.catalyst.perl.org
Mon May 26 19:10:17 BST 2008


Author: lukes
Date: 2008-05-26 19:10:17 +0100 (Mon, 26 May 2008)
New Revision: 7806

Added:
   Catalyst-Controller-DBIC-API/1.000/trunk/Makefile.PL
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/Base/
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/CRUD/
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/CRUD/DBIC/
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/Base.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/CRUD.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/REST.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/RPC.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/RPC/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/DBICTest.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Artist.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/CD.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Producer.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Track.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Artist.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/CD.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Producer.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Track.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/Root.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Model/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Model/RestTestDB.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Artist.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/CD.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/CD_to_Producer.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Producer.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Tag.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Track.pm
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/View/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/sqlite.sql
   Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/create.t
   Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/delete.t
   Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/update.t
   Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/create.t
   Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/delete.t
   Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/update.t
   Catalyst-Controller-DBIC-API/1.000/trunk/t/var/
   Catalyst-Controller-DBIC-API/1.000/trunk/t/var/DBIxClass.db
Log:
initial checkin - imported from http://code.google.com/p/catalyst-controller-rest-dbic

Added: Catalyst-Controller-DBIC-API/1.000/trunk/Makefile.PL
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/Makefile.PL	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/Makefile.PL	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,21 @@
+use inc::Module::Install 0.67;
+
+name     'Catalyst-Controller-DBIC-RPC';
+perl_version '5.006001';
+all_from 'lib/Catalyst/Controller/DBIC/RPC.pm';
+
+requires 'DBIx::Class' => 0.08;
+requires 'Catalyst' => 5.7000;
+requires 'JSON::Syck' => 0.26;
+requires 'Catalyst::Action::REST' => 0.60;
+
+build_requires 'Test::More'       => 0.7;
+build_requires 'Test::WWW::Mechanize::Catalyst'       => 0.37;
+
+tests_recursive();
+
+auto_provides;
+
+auto_install;
+
+WriteAll;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/Base.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/Base.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/Base.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,47 @@
+package Catalyst::Controller::DBIC::Base;
+
+use strict;
+use warnings;
+use base 'Catalyst::Controller::DBIC::CRUD';
+
+sub end :Private {
+	my ($self, $c) = @_;
+
+	# check for errors
+	my $default_status;
+	if ($self->get_errors($c)) {
+		$c->stash->{response}->{messages} = $self->get_errors($c);
+		$c->stash->{response}->{success} = 'false';
+		$default_status = 400;
+	} else {
+		$c->stash->{response}->{success} = 'true';
+		$default_status = 200;
+	}
+	
+	$c->res->status( $default_status || 200 );
+
+# 	my $json_response = JSON::Syck::Dump($c->stash->{response});
+# 	$c->res->body( $json_response );
+# 	$c->log->debug($c->res->body);
+}
+
+=head2 setup
+
+Just sets $c->stash->{class_rs} to the resultset specified by the 'class' config.
+This rs is then used by all other methods.
+
+=cut  
+
+sub setup :Chained('specify.in.subclass.config') :CaptureArgs(0) :PathPart('specify.in.subclass.config') {
+	my ($self, $c) = @_;
+
+	$c->stash->{class_rs} = $c->model($self->class);
+}
+
+=head1 AUTHOR
+
+luke saunders
+
+=cut
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/CRUD.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/CRUD.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/CRUD.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,240 @@
+package Catalyst::Controller::DBIC::CRUD;
+
+use strict;
+use warnings;
+use base 'Catalyst::Controller';
+
+__PACKAGE__->mk_accessors(qw(
+  class create_requires update_requires update_allows class_rs create_allows
+));
+
+__PACKAGE__->config(
+  class => undef,
+  create_requires => [],
+  create_allows => [],
+  update_requires => [],
+  update_allows => [],
+);
+
+=head2 create
+
+Matches cols specified in create_requires and create_allows to $c->req->params and $c->stash->{params} 
+to create a hash representing a new object which is then created.
+
+=cut
+
+sub create :Private {
+	my ($self, $c) = @_;
+
+	unless (ref($self->create_requires) eq 'ARRAY') {
+		die "create_requires must be an arrayref in config";
+	}
+	unless ($c->stash->{class_rs}) {
+		die "class resultset not set";
+	}
+
+	my $empty_object = $c->stash->{class_rs}->new_result({});
+	$self->validate_and_save_object($c, $empty_object);
+}
+
+=head2 update
+
+Matches cols specified in update_allows to $c->req->params and $c->stash->{params} 
+to create a hash which is used to update $c->stash->{object}
+
+=cut
+
+sub update :Private {
+	my ($self, $c) = @_;
+
+	return unless ($c->stash->{object});
+
+	unless (ref($self->update_allows) eq 'ARRAY') {
+		die "update_allows must be an arrayref in config";
+	}
+	unless ($c->stash->{class_rs}) {
+		die "class resultset not set";
+	}
+
+#	use Data::Dumper; $c->log->debug(Dumper(\%create_args));
+	my $object = $c->stash->{object};
+	$self->validate_and_save_object($c, $object);
+}
+
+=head2 delete
+
+	Deletes $c->stash->{object}
+
+=cut
+
+sub delete :Private {
+	my ($self, $c) = @_;
+
+	return unless ($c->stash->{object});
+
+	return $c->stash->{object}->delete;
+}
+
+=head2 validate_and_save_object
+
+=cut
+
+sub validate_and_save_object {
+	my ($self, $c, $object) = @_;
+
+	my $params;
+	unless ($params = $self->validate($c, $object)) {
+		return;
+	}
+
+	$self->save_object($c, $object, $params);
+}
+
+=head2 validate
+
+=cut
+
+sub validate {
+	my ($self, $c, $object) = @_;
+	my $params = $c->req->params;
+
+	# operation specific hooks. pointless?
+# 	if ($object->in_storage) {
+# 		$self->validate_update($object, $params);
+# 	} else {
+# 		$self->validate_create($object, $params);
+# 	}
+
+	my %values;
+	my %requires_map = map { $_ => 1 } @{($object->in_storage) ? [] : $self->create_requires};
+	my %allows_map = map { $_ => 1 } (keys %requires_map, @{($object->in_storage) ? $self->update_allows : $self->create_allows});
+
+#	use Data::Dumper; warn Dumper(\%requires_map, \%allows_map);
+	foreach my $key (keys %allows_map) {
+		# check value defined if key required
+		my $value = $params->{$key};
+		if ($requires_map{$key}) {
+			unless (defined($value)) {
+				# if not defined look for default
+				$value = $object->result_source
+					->column_info($key)
+					->{default_value};
+				unless (defined $value) {
+					$self->push_error($c, { message => "No value supplied for ${key} and no default" });
+				}
+			}		   			
+		}
+
+		# TODO: do col type checking here
+
+		# check for multiple values
+		if (ref($value)) {
+			$self->push_error($c, { message => "Multiple values for '${key}'" });
+		}
+
+		# check exists so we don't just end up with hash of undefs
+		# check defined to accound for default values being used
+		$values{$key} = $value if exists $params->{$key} || defined $value;
+	}
+
+#	use Data::Dumper; $c->log->debug(Dumper(\%values));
+	unless (keys %values || !$object->in_storage) {
+		$self->push_error($c, { message => "No valid keys passed" });
+	}
+
+#	$c->stash->{_save_values}->{$object} = \%values;
+	return ($self->get_errors($c)) ? 0 : \%values;  
+}
+
+sub validate_create { }
+sub validate_update { }
+
+=head2 save_object
+
+=cut
+
+sub save_object {
+	my ($self, $c, $object, $params) = @_;
+	
+	$object->set_columns($params);
+	if ($object->in_storage) {
+		$object->update;
+	} else {
+		$object->insert;
+	}
+}
+
+# =head2 add_to_rel
+
+# 	finds a related row and then creates the many_to_many linking row using ->add_to_$rel
+# 	This is a work in progress, it should really allow the related row to also be created
+# 	if it does not already exist.
+
+# =cut
+
+# sub add_to_rel : Chained('object') PathPart('add_to_rel') Args(1) {
+# 	my ($self, $c, $rel) = @_;
+
+# 	my $accessor = "add_to_$rel";
+# 	$self->__rel($c, $rel, $accessor);
+# }
+
+# =head2 remove_from_rel
+
+# 	finds a related row and then removes the many_to_many linking row using ->remove_from_$rel
+
+# =cut
+
+# sub remove_from_rel : Chained('object') PathPart('remove_from_rel') Args(1) {
+# 	my ($self, $c, $rel) = @_;
+
+# 	my $accessor = "remove_from_$rel";
+# 	$self->__rel($c, $rel, $accessor);
+# }
+
+# sub __rel {
+# 	my ($self, $c, $rel, $accessor) = @_;
+
+# 	my $related_rs;
+# 	# pretty grim but i want it to work for many_to_many as well (so not $source->has_relationship)
+# 	eval {
+# 		$related_rs = $c->stash->{object}->$rel;
+# 	};
+# 	if ($@) {
+# 		$c->detach( 'error', [{ message => "Invalid relationship $rel" }]);		
+# 	}
+# 	my $source = $related_rs->result_source;
+	
+# 	my %related_args = map { $_ => $c->req->params->{$_} } grep { $c->req->params->{$_} } $source->columns;
+
+# 	unless (keys %related_args) {
+# 		$c->detach( 'error', [{ message => "No valid keys passed" }]);
+# 	}
+																 
+# 	my $related_row = $related_rs->result_source->resultset->find(\%related_args);
+# 	unless ($related_row) {
+# 		$c->detach( 'error', [{ message => "Invalid related row" }]);
+# 	}
+	
+# 	$c->stash->{object}->$accessor($related_row);
+# }
+
+sub push_error {
+	my ( $self, $c, $params ) = @_;
+
+	push( @{$c->stash->{_dbic_crud_errors}}, $params->{message} || 'unknown error' );
+}
+
+sub get_errors {
+	my ( $self, $c, $params ) = @_;
+
+	return $c->stash->{_dbic_crud_errors};
+}
+
+=head1 AUTHOR
+
+luke saunders
+
+=cut
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/REST.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/REST.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/REST.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,122 @@
+package Catalyst::Controller::DBIC::REST;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::Base/;
+
+our $VERSION = '1.000000';
+
+__PACKAGE__->config(
+						'default'   => 'text/x-json',
+						'stash_key' => 'response',
+						'map'       => {
+							'text/x-json'        => 'JSON',
+						});
+=head1 NAME
+
+Catalyst::Controller::REST::DBIC
+
+=head1 SYNOPSIS
+
+  package MyApp::Controller::REST::CD;
+
+  use base qw/Catalyst::Controller::REST::DBIC/;
+
+  ...
+
+  __PACKAGE__->config
+    ( action => { setup => { PathPart => 'cd', Chained => '/api/rest/rest_base' } },
+      class => 'TestDB::CD',
+      create_requires => ['artist', 'title', 'year' ],
+      update_allows => ['title', 'year']
+      );
+
+=head1 METHODS
+
+=head2 end
+
+=cut 
+
+sub end :Private {
+	my ($self, $c) = @_;
+
+	$self->NEXT::end($c);	
+	$c->forward('serialize');
+}
+
+# from Catalyst::Action::Serialize
+sub serialize :ActionClass('Serialize') {
+	my ($self, $c) = @_;
+
+}
+
+sub begin :Private {
+	my ($self, $c) = @_;
+
+	$c->forward('deserialize');
+	use Data::Dumper; $c->log->debug(Dumper($c->req->data));
+	$c->req->params($c->req->data);
+	$self->NEXT::begin($c);	
+}
+
+# from Catalyst::Action::Serialize
+sub deserialize :ActionClass('Deserialize') {
+	my ($self, $c) = @_;
+
+}
+
+sub object :Chained('setup') :Args(1) :PathPart('id') :ActionClass('REST') {
+	my ($self, $c, $id) = @_;
+
+	my $object = $c->stash->{class_rs}->find( $id );
+	unless ($object) {
+		$self->push_error($c, { message => "Invalid id" });
+	}
+	$c->stash->{object} = $object;
+}
+
+sub object_POST {
+	my ($self, $c) = @_;
+
+	warn 'dsdsfdsf';
+	$c->forward('update');
+}
+
+sub object_PUT {
+	my ($self, $c) = @_;
+
+	warn 'dsdsfdsf';
+	$c->forward('update');
+}
+
+sub object_DELETE {
+	my ($self, $c) = @_;
+
+	$c->forward('delete');
+}
+
+
+sub base : Chained('setup') PathPart('') ActionClass('REST') Args(0) {
+	my ( $self, $c ) = @_;
+
+}
+
+sub base_PUT {
+	my ( $self, $c ) = @_;
+
+	$c->forward('create');
+}
+
+sub base_POST {
+	my ( $self, $c ) = @_;
+
+	$c->forward('create');
+}
+
+=head1 AUTHOR
+
+luke saunders
+
+=cut
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/RPC.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/RPC.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/lib/Catalyst/Controller/DBIC/RPC.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,177 @@
+package Catalyst::Controller::DBIC::RPC;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::Base/;
+use JSON::Syck;
+
+our $VERSION = '1.000000';
+
+__PACKAGE__->config(
+						'default'   => 'text/x-json',
+						'stash_key' => 'response',
+						'map'       => {
+							'application/x-www-form-urlencoded'        => 'JSON',
+						});
+=head1 NAME
+
+Catalyst::Controller::RPC::DBIC
+
+=head1 SYNOPSIS
+
+  package MyApp::Controller::RPC::CD;
+
+  use base qw/Catalyst::Controller::RPC::DBIC/;
+
+  ...
+
+  __PACKAGE__->config
+    ( action => { setup => { PathPart => 'cd', Chained => '/api/rpc/rest_base' } },
+      class => 'TestDB::CD',
+      create_requires => ['artist', 'title', 'year' ],
+      update_allows => ['title', 'year']
+      );
+
+=head1 METHODS
+
+=head2 end
+
+=cut 
+
+sub end :Private {
+	my ($self, $c) = @_;
+
+	$self->NEXT::end($c);	
+	$c->forward('serialize');
+}
+
+# from Catalyst::Action::Serialize
+sub serialize :ActionClass('Serialize') {
+	my ($self, $c) = @_;
+
+}
+
+=head2 object
+
+Sets the object that is used by update, delete etc which chain from this.
+
+=cut
+
+sub object :Chained('setup') :CaptureArgs(1) :PathPart('id') {
+	my ($self, $c, $id) = @_;
+
+	my $object = $c->stash->{class_rs}->find( $id );
+	unless ($object) {
+		$self->push_error($c, { message => "Invalid id" });
+	}
+	$c->stash->{object} = $object;
+}
+
+sub index : Chained('setup') PathPart('') Args(0) {
+	my ( $self, $c ) = @_;
+
+	$self->push_error($c, { message => 'Not implemented' });
+	$c->res->status( '404' );
+}
+
+=head2 create
+
+Matches cols specified in create_requires and create_allows to $c->req->params and $c->stash->{params} 
+to create a hash representing a new object which is then created.
+
+=cut
+
+sub create :Chained('setup') :PathPart('create') :Args(0) :Auth('read_write') {
+	my ($self, $c) = @_;
+
+	$self->NEXT::create($c);
+}
+
+=head2 update
+
+Matches cols specified in update_allows to $c->req->params and $c->stash->{params} 
+to create a hash which is used to update $c->stash->{object}
+
+=cut
+
+sub update :Chained('object') :PathPart('update') :Args(0) :Auth('read_write') {
+	my ($self, $c) = @_;
+
+	$self->NEXT::update($c);
+}
+
+=head2 delete
+
+	Deletes $c->stash->{object}
+
+=cut
+
+sub delete :Chained('object') :PathPart('delete') :Args(0) :Auth('read_write') {
+	my ($self, $c) = @_;
+
+	$self->NEXT::delete($c);
+}
+
+# =head2 add_to_rel
+
+# 	finds a related row and then creates the many_to_many linking row using ->add_to_$rel
+# 	This is a work in progress, it should really allow the related row to also be created
+# 	if it does not already exist.
+
+# =cut
+
+# sub add_to_rel : Chained('object') PathPart('add_to_rel') Args(1) {
+# 	my ($self, $c, $rel) = @_;
+
+# 	my $accessor = "add_to_$rel";
+# 	$self->__rel($c, $rel, $accessor);
+# }
+
+# =head2 remove_from_rel
+
+# 	finds a related row and then removes the many_to_many linking row using ->remove_from_$rel
+
+# =cut
+
+# sub remove_from_rel : Chained('object') PathPart('remove_from_rel') Args(1) {
+# 	my ($self, $c, $rel) = @_;
+
+# 	my $accessor = "remove_from_$rel";
+# 	$self->__rel($c, $rel, $accessor);
+# }
+
+# sub __rel {
+# 	my ($self, $c, $rel, $accessor) = @_;
+
+# 	my $related_rs;
+# 	# pretty grim but i want it to work for many_to_many as well (so not $source->has_relationship)
+# 	eval {
+# 		$related_rs = $c->stash->{object}->$rel;
+# 	};
+# 	if ($@) {
+# 		$c->detach( 'error', [{ message => "Invalid relationship $rel" }]);		
+# 	}
+# 	my $source = $related_rs->result_source;
+	
+# 	my %related_args = map { $_ => $c->req->params->{$_} } grep { $c->req->params->{$_} } $source->columns;
+
+# 	unless (keys %related_args) {
+# 		$c->detach( 'error', [{ message => "No valid keys passed" }]);
+# 	}
+																 
+# 	my $related_row = $related_rs->result_source->resultset->find(\%related_args);
+# 	unless ($related_row) {
+# 		$c->detach( 'error', [{ message => "Invalid related row" }]);
+# 	}
+	
+# 	$c->stash->{object}->$accessor($related_row);
+# }
+
+
+=head1 AUTHOR
+
+luke saunders
+
+=cut
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/DBICTest.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/DBICTest.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/DBICTest.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,199 @@
+package # hide from PAUSE 
+    DBICTest;
+
+use strict;
+use warnings;
+use RestTest::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";
+
+    unlink($db_file) if -e $db_file;
+    unlink($db_file . "-journal") if -e $db_file . "-journal";
+    mkdir("t/var") unless -d "t/var";
+
+    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 = RestTest::Schema->compose_connection(
+                  'DBICTest', @connect_info
+                );
+    } else {
+      $schema = RestTest::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 ],
+        [ 3, 2 ],
+        [ 2, 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;


Property changes on: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/DBICTest.pm
___________________________________________________________________
Name: svn:executable
   + *

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Artist.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Artist.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Artist.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,16 @@
+package RestTest::Controller::API::REST::Artist;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::REST/;
+use JSON::Syck;
+
+__PACKAGE__->config
+    ( action => { setup => { PathPart => 'artist', Chained => '/api/rest/rest_base' } },
+      class => 'RestTestDB::Artist',
+      create_requires => ['name'],
+      create_allows => ['name'],
+      update_allows => ['name']
+      );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/CD.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/CD.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/CD.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,15 @@
+package RestTest::Controller::API::REST::CD;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::REST/;
+use JSON::Syck;
+
+__PACKAGE__->config
+    ( action => { setup => { PathPart => 'cd', Chained => '/api/rest/rest_base' } },
+      class => 'RestTestDB::CD',
+      create_requires => ['artist', 'title', 'year' ],
+      update_allows => ['title', 'year']
+      );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Producer.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Producer.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Producer.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,15 @@
+package RestTest::Controller::API::REST::Producer;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::REST/;
+use JSON::Syck;
+
+__PACKAGE__->config
+    ( action => { setup => { PathPart => 'producer', Chained => '/api/rest/rest_base' } },
+      class => 'RestTestDB::Producer',
+      create_requires => ['name'],
+      update_allows => ['name']
+      );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Track.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Track.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST/Track.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,16 @@
+package RestTest::Controller::API::REST::Track;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::REST/;
+use JSON::Syck;
+
+__PACKAGE__->config
+    ( action => { setup => { PathPart => 'track', Chained => '/api/rest/rest_base' } },
+      class => 'RestTestDB::Track',
+      create_requires => ['cd', 'title' ],
+      create_allows => ['cd', 'title', 'position' ],
+      update_allows => ['title', 'position']
+      );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/REST.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,17 @@
+package RestTest::Controller::API::REST;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller/;
+
+sub rest_base : Chained('/api/api_base') PathPart('rest') CaptureArgs(0) {
+    my ( $self, $c ) = @_;
+
+}
+
+sub end :Private {
+	my ( $self, $c ) = @_;
+	
+}
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Artist.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Artist.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Artist.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,16 @@
+package RestTest::Controller::API::RPC::Artist;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::RPC/;
+use JSON::Syck;
+
+__PACKAGE__->config
+    ( action => { setup => { PathPart => 'artist', Chained => '/api/rpc/rpc_base' } },
+      class => 'RestTestDB::Artist',
+      create_requires => ['name'],
+      create_allows => ['name'],
+      update_allows => ['name']
+      );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/CD.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/CD.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/CD.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,15 @@
+package RestTest::Controller::API::RPC::CD;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::RPC/;
+use JSON::Syck;
+
+__PACKAGE__->config
+    ( action => { setup => { PathPart => 'cd', Chained => '/api/rpc/rpc_base' } },
+      class => 'RestTestDB::CD',
+      create_requires => ['artist', 'title', 'year' ],
+      update_allows => ['title', 'year']
+      );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Producer.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Producer.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Producer.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,15 @@
+package RestTest::Controller::API::RPC::Producer;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::RPC/;
+use JSON::Syck;
+
+__PACKAGE__->config
+    ( action => { setup => { PathPart => 'producer', Chained => '/api/rpc/rpc_base' } },
+      class => 'RestTestDB::Producer',
+      create_requires => ['name'],
+      update_allows => ['name']
+      );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Track.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Track.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC/Track.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,16 @@
+package RestTest::Controller::API::RPC::Track;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller::DBIC::RPC/;
+use JSON::Syck;
+
+__PACKAGE__->config
+    ( action => { setup => { PathPart => 'track', Chained => '/api/rpc/rpc_base' } },
+      class => 'RestTestDB::Track',
+      create_requires => ['cd', 'title' ],
+      create_allows => ['cd', 'title', 'position' ],
+      update_allows => ['title', 'position']
+      );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API/RPC.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,17 @@
+package RestTest::Controller::API::RPC;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller/;
+
+sub rpc_base : Chained('/api/api_base') PathPart('rpc') CaptureArgs(0) {
+    my ( $self, $c ) = @_;
+
+}
+
+sub end :Private {
+	my ( $self, $c ) = @_;
+	
+}
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/API.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,12 @@
+package RestTest::Controller::API;
+
+use strict;
+use warnings;
+use base qw/Catalyst::Controller/;
+
+sub api_base : Chained('/') PathPart('api') CaptureArgs(0) {
+    my ( $self, $c ) = @_;
+
+}
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/Root.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/Root.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Controller/Root.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,55 @@
+package RestTest::Controller::Root;
+
+use strict;
+use warnings;
+use base 'Catalyst::Controller';
+
+#
+# Sets the actions in this controller to be registered with no prefix
+# so they function identically to actions created in MyApp.pm
+#
+__PACKAGE__->config->{namespace} = '';
+
+=head1 NAME
+
+RestTest::Controller::Root - Root Controller for RestTest
+
+=head1 DESCRIPTION
+
+[enter your description here]
+
+=head1 METHODS
+
+=cut
+
+=head2 default
+
+=cut
+
+sub default : Private {
+    my ( $self, $c ) = @_;
+
+    # Hello World
+    $c->response->body( $c->welcome_message );
+}
+
+=head2 end
+
+Attempt to render a view, if needed.
+
+=cut 
+
+sub end : ActionClass('RenderView') {}
+
+=head1 AUTHOR
+
+luke saunders
+
+=head1 LICENSE
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Model/RestTestDB.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Model/RestTestDB.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Model/RestTestDB.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,19 @@
+package RestTest::Model::RestTestDB;
+
+use strict;
+use warnings;
+use base 'Catalyst::Model::DBIC::Schema';
+
+use Catalyst::Utils;
+
+__PACKAGE__->config(
+					schema_class => 'RestTest::Schema',
+					connect_info => [
+                        "DBI:SQLite:t/var/DBIxClass.db",
+                        "",
+                        "",
+					   {AutoCommit => 1}
+                      ]					  
+);
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Artist.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Artist.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Artist.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,25 @@
+package # hide from PAUSE 
+    RestTest::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 => 'RestTest::Schema::CD', undef,
+    { order_by => 'year' },
+);
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/CD.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/CD.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/CD.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,44 @@
+package # hide from PAUSE 
+    RestTest::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 => 'RestTest::Schema::Artist' );
+
+__PACKAGE__->has_many( tracks => 'RestTest::Schema::Track' );
+__PACKAGE__->has_many(
+    tags => 'RestTest::Schema::Tag', undef,
+    { order_by => 'tag' },
+);
+__PACKAGE__->has_many(
+    cd_to_producer => 'RestTest::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;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/CD_to_Producer.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/CD_to_Producer.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/CD_to_Producer.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,23 @@
+package # hide from PAUSE 
+    RestTest::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', 'RestTest::Schema::CD',
+  { 'foreign.cdid' => 'self.cd' }
+);
+
+__PACKAGE__->belongs_to(
+  'producer', 'RestTest::Schema::Producer',
+  { 'foreign.producerid' => 'self.producer' }
+);
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Producer.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Producer.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Producer.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,21 @@
+package # hide from PAUSE 
+    RestTest::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,
+	default_value => 'fred'
+  },
+);
+__PACKAGE__->set_primary_key('producerid');
+__PACKAGE__->add_unique_constraint(prod_name => [ qw/name/ ]);
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Tag.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Tag.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Tag.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,24 @@
+package # hide from PAUSE 
+    RestTest::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 => 'RestTest::Schema::CD' );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Track.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Track.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema/Track.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,38 @@
+package # hide from PAUSE 
+    RestTest::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',
+	default_value => 0
+  },
+  '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 => 'RestTest::Schema::CD' );
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest/Schema.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,10 @@
+package # hide from PAUSE
+    RestTest::Schema;
+
+use base qw/DBIx::Class::Schema/;
+
+no warnings qw/qw/;
+
+__PACKAGE__->load_classes(qw/Artist CD Track Tag Producer CD_to_Producer/);
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest.pm
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest.pm	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/RestTest.pm	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,62 @@
+package RestTest;
+
+use strict;
+use warnings;
+
+use Catalyst::Runtime '5.70';
+
+# Set flags and add plugins for the application
+#
+#         -Debug: activates the debug mode for very useful log messages
+#   ConfigLoader: will load the configuration from a YAML file in the
+#                 application's home directory
+# Static::Simple: will serve static files from the application's root 
+#                 directory
+
+use Catalyst qw/-Debug ConfigLoader Static::Simple/;
+
+our $VERSION = '0.01';
+
+# Configure the application. 
+#
+# Note that settings in RestTest.yml (or other external
+# configuration file that you set up manually) take precedence
+# over this when using ConfigLoader. Thus configuration
+# details given here can function as a default configuration,
+# with a external configuration file acting as an override for
+# local deployment.
+
+__PACKAGE__->config( name => 'RestTest' );
+
+# Start the application
+__PACKAGE__->setup;
+
+
+=head1 NAME
+
+RestTest - Catalyst based application
+
+=head1 SYNOPSIS
+
+    script/resttest_server.pl
+
+=head1 DESCRIPTION
+
+[enter your description here]
+
+=head1 SEE ALSO
+
+L<RestTest::Controller::Root>, L<Catalyst>
+
+=head1 AUTHOR
+
+luke saunders
+
+=head1 LICENSE
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+1;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/sqlite.sql
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/sqlite.sql	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/lib/sqlite.sql	2008-05-26 18:10:17 UTC (rev 7806)
@@ -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) 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;

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/create.t
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/create.t	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/create.t	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,67 @@
+use 5.6.0;
+
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+my $base = 'http://localhost';
+
+use RestTest;
+use DBICTest;
+use Test::More tests => 7;
+use Test::WWW::Mechanize::Catalyst 'RestTest';
+use HTTP::Request::Common;
+use JSON::Syck;
+
+my $mech = Test::WWW::Mechanize::Catalyst->new;
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $artist_create_url = "$base/api/rest/artist";
+my $producer_create_url = "$base/api/rest/producer";
+
+# test validation when no params sent
+{
+	my $test_data = JSON::Syck::Dump({ wrong_param => 'value' });
+	my $req = PUT( $artist_create_url );
+	$req->content_type('text/x-json');
+	$req->content_length(
+						 do { use bytes; length( $test_data ) }
+						 );
+	$req->content( $test_data );
+	$mech->request($req);
+
+	cmp_ok( $mech->status, '==', 400, 'attempt without required params caught' );
+	my $response = JSON::Syck::Load( $mech->content);
+	is_deeply( $response->{messages}, ['No value supplied for name and no default'], 'correct message returned' );
+}
+
+# test default value used if default value exists
+{
+	my $test_data = JSON::Syck::Dump({ });
+	my $req = PUT( $producer_create_url );
+	$req->content_type('text/x-json');
+	$req->content_length(
+						 do { use bytes; length( $test_data ) }
+						 );
+	$req->content( $test_data );
+	$mech->request($req);
+
+	cmp_ok( $mech->status, '==', 200, 'default value used when not supplied' );
+	ok($schema->resultset('Producer')->find({ name => 'fred' }), 'record created with default name');
+}
+
+# test create works as expected when passing required value
+{
+	my $test_data = JSON::Syck::Dump({ name => 'king luke' });
+	my $req = PUT( $producer_create_url );
+	$req->content_type('text/x-json');
+	$req->content_length(
+						 do { use bytes; length( $test_data ) }
+						 );
+	$req->content( $test_data );
+	$mech->request($req);
+
+	cmp_ok( $mech->status, '==', 200, 'request with valid content okay' );
+	ok($schema->resultset('Producer')->find({ name => 'king luke' }), 'record created with specified name');
+}

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/delete.t
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/delete.t	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/delete.t	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,41 @@
+use 5.6.0;
+
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+my $base = 'http://localhost';
+my $content_type = [ 'Content-Type', 'application/x-www-form-urlencoded' ];
+
+use RestTest;
+use DBICTest;
+use Test::More tests => 4;
+use Test::WWW::Mechanize::Catalyst 'RestTest';
+use HTTP::Request::Common;
+use JSON::Syck;
+
+my $mech = Test::WWW::Mechanize::Catalyst->new;
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $track = $schema->resultset('Track')->first;
+my %original_cols = $track->get_columns;
+
+my $track_delete_url = "$base/api/rest/track/id/" . $track->id;
+
+{
+  my $req = HTTP::Request->new( DELETE => $track_delete_url );
+  $req->content_type('text/x-json');
+  $mech->request($req);
+  cmp_ok( $mech->status, '==', 200, 'Attempt to delete track ok' );
+
+  my $deleted_track = $schema->resultset('Track')->find($track->id);
+  is($deleted_track, undef, 'track deleted');
+}
+
+{
+  my $req = HTTP::Request->new( DELETE => $track_delete_url );
+  $req->content_type('text/x-json');
+  $mech->request($req);
+  cmp_ok( $mech->status, '==', 400, 'Attempt to delete again caught' );
+}

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/update.t
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/update.t	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/rest/update.t	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,83 @@
+use 5.6.0;
+
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+my $base = 'http://localhost';
+my $content_type = [ 'Content-Type', 'application/x-www-form-urlencoded' ];
+
+use RestTest;
+use DBICTest;
+use Test::More tests => 15;
+use Test::WWW::Mechanize::Catalyst 'RestTest';
+use HTTP::Request::Common;
+use JSON::Syck;
+
+my $mech = Test::WWW::Mechanize::Catalyst->new;
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $track = $schema->resultset('Track')->first;
+my %original_cols = $track->get_columns;
+
+my $track_update_url = "$base/api/rest/track/id/" . $track->id;
+
+# test invalid track id caught
+{
+	foreach my $wrong_id ('sdsdsdsd', 3434234) {
+		my $incorrect_url = "$base/api/rest/track/id/" . $wrong_id;
+		my $test_data = JSON::Syck::Dump({ title => 'value' });
+		my $req = POST( $incorrect_url, Content => $test_data );
+		$req->content_type('text/x-json');
+		$mech->request($req);
+
+		cmp_ok( $mech->status, '==', 400, 'Attempt with invalid track id caught' );
+		
+		my $response = JSON::Syck::Load( $mech->content);
+		is_deeply( $response->{messages}, ['Invalid id'], 'correct message returned' );
+		
+		$track->discard_changes;
+		is_deeply({ $track->get_columns }, \%original_cols, 'no update occurred');
+	}
+}
+
+# validation when no params sent
+{
+	my $test_data = JSON::Syck::Dump({ wrong_param => 'value' });
+	my $req = POST( $track_update_url, Content => $test_data );
+	$req->content_type('text/x-json');
+	$mech->request($req);
+
+	cmp_ok( $mech->status, '==', 400, 'Update with no keys causes error' );
+
+	my $response = JSON::Syck::Load( $mech->content);
+	is_deeply( $response->{messages}, ['No valid keys passed'], 'correct message returned' );
+
+	$track->discard_changes;
+	is_deeply({ $track->get_columns }, \%original_cols, 'no update occurred');
+}
+
+{
+	my $test_data = JSON::Syck::Dump({ title => undef });
+	my $req = POST( $track_update_url, Content => $test_data );
+	$req->content_type('text/x-json');
+	$mech->request($req);
+	cmp_ok( $mech->status, '==', 200, 'Update with key with no value okay' );
+
+	$track->discard_changes;
+	isnt($track->title, $original_cols{title}, 'Title changed');
+	is($track->title, undef, 'Title changed to undef');
+}
+
+{
+	my $test_data = JSON::Syck::Dump({ title => 'monkey monkey' });
+	my $req = POST( $track_update_url, Content => $test_data );
+	$req->content_type('text/x-json');
+	$mech->request($req);
+
+	cmp_ok( $mech->status, '==', 200, 'Update with key with value okay' );
+
+	$track->discard_changes;
+	is($track->title, 'monkey monkey', 'Title changed to "monkey monkey"');
+}

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/create.t
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/create.t	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/create.t	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,55 @@
+use 5.6.0;
+
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+my $base = 'http://localhost';
+my $content_type = [ 'Content-Type', 'application/x-www-form-urlencoded' ];
+
+use RestTest;
+use DBICTest;
+use Test::More tests => 7;
+use Test::WWW::Mechanize::Catalyst 'RestTest';
+use HTTP::Request::Common;
+use JSON::Syck;
+
+my $mech = Test::WWW::Mechanize::Catalyst->new;
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $artist_create_url = "$base/api/rpc/artist/create";
+my $producer_create_url = "$base/api/rpc/producer/create";
+
+# test validation when no params sent
+{
+  my $req = POST( $artist_create_url, {
+	  wrong_param => 'value'
+  }, 'Accept' => 'text/json' );
+  $mech->request($req, $content_type);
+  cmp_ok( $mech->status, '==', 400, 'attempt without required params caught' );
+
+  my $response = JSON::Syck::Load( $mech->content);
+  is_deeply( $response->{messages}, ['No value supplied for name and no default'], 'correct message returned' );
+}
+
+# test default value used if default value exists
+{
+  my $req = POST( $producer_create_url, {
+
+  }, 'Accept' => 'text/json' );
+  $mech->request($req, $content_type);
+  cmp_ok( $mech->status, '==', 200, 'default value used when not supplied' );
+  ok($schema->resultset('Producer')->find({ name => 'fred' }), 'record created with default name');
+}
+
+# test create works as expected when passing required value
+{
+  my $req = POST( $producer_create_url, {
+	  name => 'king luke'
+  }, 'Accept' => 'text/json' );
+  $mech->request($req, $content_type);
+  cmp_ok( $mech->status, '==', 200, 'param value used when supplied' );
+
+  ok($schema->resultset('Producer')->find({ name => 'king luke' }), 'record created with specified name');
+}

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/delete.t
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/delete.t	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/delete.t	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,43 @@
+use 5.6.0;
+
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+my $base = 'http://localhost';
+my $content_type = [ 'Content-Type', 'application/x-www-form-urlencoded' ];
+
+use RestTest;
+use DBICTest;
+use Test::More tests => 4;
+use Test::WWW::Mechanize::Catalyst 'RestTest';
+use HTTP::Request::Common;
+use JSON::Syck;
+
+my $mech = Test::WWW::Mechanize::Catalyst->new;
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $track = $schema->resultset('Track')->first;
+my %original_cols = $track->get_columns;
+
+my $track_delete_url = "$base/api/rpc/track/id/" . $track->id . "/delete";
+
+{
+  my $req = POST( $track_delete_url, {
+
+  });
+  $mech->request($req, $content_type);
+  cmp_ok( $mech->status, '==', 200, 'Attempt to delete track ok' );
+
+  my $deleted_track = $schema->resultset('Track')->find($track->id);
+  is($deleted_track, undef, 'track deleted');
+}
+
+{
+  my $req = POST( $track_delete_url, {
+
+  });
+  $mech->request($req, $content_type);
+  cmp_ok( $mech->status, '==', 400, 'Attempt to delete again caught' );
+}

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/update.t
===================================================================
--- Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/update.t	                        (rev 0)
+++ Catalyst-Controller-DBIC-API/1.000/trunk/t/rpc/update.t	2008-05-26 18:10:17 UTC (rev 7806)
@@ -0,0 +1,95 @@
+use 5.6.0;
+
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+my $base = 'http://localhost';
+my $content_type = [ 'Content-Type', 'application/x-www-form-urlencoded' ];
+
+use RestTest;
+use DBICTest;
+use Test::More tests => 18;
+use Test::WWW::Mechanize::Catalyst 'RestTest';
+use HTTP::Request::Common;
+use JSON::Syck;
+
+my $mech = Test::WWW::Mechanize::Catalyst->new;
+ok(my $schema = DBICTest->init_schema(), 'got schema');
+
+my $track = $schema->resultset('Track')->first;
+my %original_cols = $track->get_columns;
+
+my $track_update_url = "$base/api/rpc/track/id/" . $track->id . "/update";
+
+# test invalid track id caught
+{
+	foreach my $wrong_id ('sdsdsdsd', 3434234) {
+		my $incorrect_url = "$base/api/rpc/track/id/" . $wrong_id . "/update";
+		my $req = POST( $incorrect_url, {
+			title => 'value'
+		});
+
+		$mech->request($req, $content_type);
+		cmp_ok( $mech->status, '==', 400, 'Attempt with invalid track id caught' );
+		
+		my $response = JSON::Syck::Load( $mech->content);
+		is_deeply( $response->{messages}, ['Invalid id'], 'correct message returned' );
+		
+		$track->discard_changes;
+		is_deeply({ $track->get_columns }, \%original_cols, 'no update occurred');
+	}
+}
+
+# validation when no params sent
+{
+  my $req = POST( $track_update_url, {
+	  wrong_param => 'value'
+  });
+  $mech->request($req, $content_type);
+  cmp_ok( $mech->status, '==', 400, 'Update with no keys causes error' );
+
+  my $response = JSON::Syck::Load( $mech->content);
+  is_deeply( $response->{messages}, ['No valid keys passed'], 'correct message returned' );
+
+  $track->discard_changes;
+  is_deeply({ $track->get_columns }, \%original_cols, 'no update occurred');
+}
+
+{
+  my $req = POST( $track_update_url, {
+	  wrong_param => 'value'
+  });
+  $mech->request($req, $content_type);
+  cmp_ok( $mech->status, '==', 400, 'Update with no keys causes error' );
+
+  my $response = JSON::Syck::Load( $mech->content);
+  is_deeply( $response->{messages}, ['No valid keys passed'], 'correct message returned' );
+
+  $track->discard_changes;
+  is_deeply({ $track->get_columns }, \%original_cols, 'no update occurred');
+}
+
+{
+  my $req = POST( $track_update_url, {
+	  title => undef
+  });
+  $mech->request($req, $content_type);
+  cmp_ok( $mech->status, '==', 200, 'Update with key with no value okay' );
+
+  $track->discard_changes;
+  isnt($track->title, $original_cols{title}, 'Title changed');
+  is($track->title, '', 'Title changed to undef');
+}
+
+{
+  my $req = POST( $track_update_url, {
+	  title => 'monkey monkey'
+  });
+  $mech->request($req, $content_type);
+  cmp_ok( $mech->status, '==', 200, 'Update with key with value okay' );
+
+  $track->discard_changes;
+  is($track->title, 'monkey monkey', 'Title changed to "monkey monkey"');
+}

Added: Catalyst-Controller-DBIC-API/1.000/trunk/t/var/DBIxClass.db
===================================================================
(Binary files differ)


Property changes on: Catalyst-Controller-DBIC-API/1.000/trunk/t/var/DBIxClass.db
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream




More information about the Catalyst-commits mailing list