use String::TT qw(strip tt);
use Scalar::Util qw(blessed);
use namespace::autoclean;
+use Devel::Dwarn;
our $VERSION = 0.01;
# have to use source name lookups rather than result class here
# because we don't actually have a result class on the raw sources
$table->add_relationship('parent', $parent->raw_source_name, \%pk_join);
- $self->deploy_depends_on->{$parent->source_name} = 1;
+ $self->deploy_depends_on->{$parent->result_class} = 1;
}
foreach my $add (@{$self->additional_parents||[]}) {
$table->add_relationship(
'parent_'.$add->name, $add->source_name, \%pk_join
);
- $self->deploy_depends_on->{$add->source_name} = 1;
+ $self->deploy_depends_on->{$add->result_class} = 1;
}
# add every column that's actually a concrete part of us
*names_of = sub (@cols) { map $_->{name}, @cols };
- *functionbody = sub ($name, $args, $body_parts) {
+ *function_body = sub {
+ my ($name,$args,$body_parts) = @_;
my $arglist = join(
', ',
map "_${\$_->{name}} ${\uc($_->{data_type})}",
$function$ LANGUAGE plpgsql;
};
};
+ #*function_body = sub ($name,$args,$body_parts) {
+ #my $arglist = join(
+ #', ',
+ #map "_${\$_->{name}} ${\uc($_->{data_type})}",
+ #@$args
+ #);
+ #my $body = join("\n", '', map " $_;", @$body_parts);
+ #return strip tt q{
+ #CREATE OR REPLACE FUNCTION [% name %]
+ #([% arglist %])
+ #RETURNS VOID AS $function$
+ #BEGIN
+ #[%- body %]
+ #END;
+ #$function$ LANGUAGE plpgsql;
+ #};
+ #};
}
BEGIN {
# NOTE: this assumes a single PK col called id with a sequence somewhere
# but nothing else -should- so fixing this should make everything work
my $insert_func =
- functionbody
+ function_body
$self->name.'_insert',
\@body_cols,
[
# UPDATE function
my $update_func =
- functionbody
+ function_body
$self->name.'_update',
[ @pk_cols, @body_cols ],
[ map $sqla->update(
# DELETE function
my $delete_func =
- functionbody
+ function_body
$self->name.'_delete',
[ @pk_cols ],
[ map $sqla->delete($_->name, $pk_where), @sources ];
use warnings;
use lib 't/lib';
use Test::More qw(no_plan);
-use Carp::Always;
+#use Carp::Always;
BEGIN { use_ok 'MTITest'; }
dies_ok { MTITest->source('Foo')->view_definition }
"Can't generate view def without connected schema";
-my $schema = MTITest->connect('dbi:SQLite::memory:');
+#my $schema = MTITest->connect('dbi:SQLite::memory:');
+my $schema = MTITest->connect('dbi:Pg:dbname=mti','postgres','');
+
#diag("MTITest view definition: ", $schema->resultset('Bar')->result_source->view_definition);
my $dir = "t/sql"; # tempdir(CLEANUP => 0);
$schema->create_ddl_dir([ 'PostgreSQL' ], 0.1, $dir);
-
+$schema->deploy({add_drop_table => 1, add_drop_view => 1});
#diag DwarnS $schema->source($_)->view_definition for qw(Foo Bar);
#diag DwarnS $schema->source($_) for qw(Foo Bar);
--- /dev/null
+use strict;
+use warnings;
+use lib 't/lib';
+use Test::More;
+use Test::Exception;
+use Devel::Dwarn;
+use Carp::Always;
+
+BEGIN {
+ use_ok 'Cafe';
+ $ENV{DBIC_TRACE} = 1;
+}
+
+my $schema = Cafe->connect('dbi:Pg:dbname=cafe','postgres','');
+
+my $dir = "t/sql"; # tempdir(CLEANUP => 0);
+$schema->create_ddl_dir([ 'PostgreSQL' ], 0.1, $dir);
+$schema->deploy({add_drop_table => 1, add_drop_view => 1});
+
+my $drink = $schema->resultset('Sumatra')->create({sweetness => 4, aroma => 'earthy', flavor => 'great'});
+#my $cup = $schema->resultset('Coffee');
+
+#diag(Dwarn $cup->result_source->columns);
+#diag(Dwarn $schema->resultset('Sumatra')->result_source->columns);
+#my $drink = $schema->resultset('Sumatra')->new_result({sweetness => 6, aroma => 'chocolate'});
+#ok($drink, "made new drink OK");
+#$drink->insert;
+#diag(Dwarn $drink->result_source->columns);
+
+#diag(Dwarn mro::get_linear_isa $drink);
+
+#$drink->insert_or_update;
+
+done_testing;
--- /dev/null
+package Cafe;
+
+use strict;
+use warnings;
+use parent 'DBIx::Class::Schema';
+use aliased 'DBIx::Class::ResultSource::MultipleTableInheritance' => 'MTIView';
+
+for my $p (__PACKAGE__) {
+ $p->load_namespaces;
+ $_->attach_additional_sources
+ for grep $_->isa(MTIView), map $p->source($_), $p->sources;
+}
+
+1;
--- /dev/null
+package Cafe::Result::Coffee;
+
+use strict;
+use warnings;
+use parent 'DBIx::Class::Core';
+use aliased 'DBIx::Class::ResultSource::MultipleTableInheritance' => 'MTI';
+
+__PACKAGE__->table_class(MTI);
+__PACKAGE__->table('coffee');
+__PACKAGE__->add_columns(
+ "id", { data_type => "integer", is_auto_increment => 1, },
+ "flavor", { data_type => "text", default_value => "good" },
+);
+
+__PACKAGE__->set_primary_key("id");
+
+1;
--- /dev/null
+package Cafe::Result::Sugar;
+
+use strict;
+use warnings;
+use parent 'DBIx::Class::Core';
+
+__PACKAGE__->table('sugar');
+
+__PACKAGE__->add_columns(
+ id => {
+ data_type => 'integer',
+ is_auto_increment => 1,
+ },
+ sweetness => { data_type => 'integer', default => '2' }
+);
+
+__PACKAGE__->set_primary_key('id');
+
+1;
--- /dev/null
+package Cafe::Result::Sumatra;
+
+use strict;
+use warnings;
+use parent 'Cafe::Result::Coffee';
+
+require Cafe::Result::Sugar;
+
+__PACKAGE__->table('sumatra');
+__PACKAGE__->result_source_instance->add_additional_parent(
+ Cafe::Result::Sugar->result_source_instance );
+
+__PACKAGE__->add_columns(
+ "aroma", { data_type => "text" }
+);
+
+#__PACKAGE__->has_many( 'coffees', 'Cafe::Result::Coffee',
+ #{ 'foreign.id' => 'self.id' } );
+
+1;
__PACKAGE__->table('bar');
__PACKAGE__->result_source_instance->add_additional_parent(
- MTITest::Result::Mixin->result_source_instance
-);
+ MTITest::Result::Mixin->result_source_instance );
-__PACKAGE__->add_columns(
- b => { data_type => 'integer' }
-);
+__PACKAGE__->add_columns( b => { data_type => 'integer' } );
-__PACKAGE__->belongs_to(
- 'b_thang',
- 'MTITest::Result::JustATable',
- { 'foreign.id' => 'self.b' },
+__PACKAGE__->belongs_to( 'b_thang', 'MTITest::Result::JustATable',
+ { 'foreign.id' => 'self.b' },
);
-__PACKAGE__->has_many(
- 'foos',
- 'MTITest::Result::Foo',
- { 'foreign.a' => 'self.id' }
-);
+__PACKAGE__->has_many( 'foos', 'MTITest::Result::Foo',
+ { 'foreign.a' => 'self.id' } );
1;
__PACKAGE__->table('foo');
__PACKAGE__->add_columns(
- id => { data_type => 'integer', is_auto_increment => 1 },
- a => { data_type => 'integer', is_nullable => 1 }
+ id => { data_type => 'integer', is_auto_increment => 1 },
+ a => { data_type => 'integer', is_nullable => 1 }
);
__PACKAGE__->set_primary_key('id');
-__PACKAGE__->belongs_to(
- 'bar',
- 'MTITest::Result::Bar',
- { 'foreign.id' => 'self.a' }
-);
+__PACKAGE__->belongs_to( 'bar', 'MTITest::Result::Bar',
+ { 'foreign.id' => 'self.a' } );
1;
--- /dev/null
+--
+-- Created by SQL::Translator::Producer::PostgreSQL
+-- Created on Tue Jun 15 07:49:49 2010
+--
+--
+-- Table: _coffee
+--
+DROP TABLE "_coffee" CASCADE;
+CREATE TABLE "_coffee" (
+ "id" serial NOT NULL,
+ "flavor" text DEFAULT 'good' NOT NULL,
+ PRIMARY KEY ("id")
+);
+
+--
+-- Table: _sumatra
+--
+DROP TABLE "_sumatra" CASCADE;
+CREATE TABLE "_sumatra" (
+ "id" integer NOT NULL,
+ "aroma" text NOT NULL,
+ PRIMARY KEY ("id")
+);
+
+--
+-- Table: sugar
+--
+DROP TABLE "sugar" CASCADE;
+CREATE TABLE "sugar" (
+ "id" serial NOT NULL,
+ "sweetness" integer NOT NULL,
+ PRIMARY KEY ("id")
+);
+
+--
+-- View: "coffee"
+--
+DROP VIEW IF EXISTS "coffee";
+CREATE VIEW "coffee" ( "id", "flavor" ) AS
+ SELECT _coffee.id, flavor FROM _coffee;
+
+CREATE OR REPLACE FUNCTION coffee_insert
+ (_flavor TEXT)
+ RETURNS VOID AS $function$
+ BEGIN
+ INSERT INTO _coffee ( flavor) VALUES ( _flavor );
+ END;
+$function$ LANGUAGE plpgsql;
+
+
+CREATE OR REPLACE FUNCTION coffee_update
+ (_id INTEGER, _flavor TEXT)
+ RETURNS VOID AS $function$
+ BEGIN
+ UPDATE _coffee SET flavor = _flavor WHERE ( id = _id );
+ END;
+$function$ LANGUAGE plpgsql;
+
+
+CREATE OR REPLACE FUNCTION coffee_delete
+ (_id INTEGER)
+ RETURNS VOID AS $function$
+ BEGIN
+ DELETE FROM _coffee WHERE ( id = _id );
+ END;
+$function$ LANGUAGE plpgsql;
+
+
+CREATE RULE _coffee_insert_rule AS
+ ON INSERT TO coffee
+ DO INSTEAD (
+ SELECT coffee_insert(NEW.flavor)
+ );
+
+
+CREATE RULE _coffee_update_rule AS
+ ON UPDATE TO coffee
+ DO INSTEAD (
+ SELECT coffee_update(OLD.id, NEW.flavor)
+ );
+
+
+CREATE RULE _coffee_delete_rule AS
+ ON DELETE TO coffee
+ DO INSTEAD (
+ SELECT coffee_delete(OLD.id)
+ );
+
+;
+
+--
+-- View: "sumatra"
+--
+DROP VIEW IF EXISTS "sumatra";
+CREATE VIEW "sumatra" ( "id", "flavor", "sweetness", "aroma" ) AS
+ SELECT _sumatra.id, aroma, sweetness, flavor FROM _sumatra _sumatra JOIN sugar sugar ON sugar.id = _sumatra.id JOIN coffee coffee ON coffee.id = _sumatra.id;
+
+CREATE OR REPLACE FUNCTION sumatra_insert
+ (_aroma TEXT, _sweetness INTEGER, _flavor TEXT)
+ RETURNS VOID AS $function$
+ BEGIN
+ INSERT INTO coffee ( flavor) VALUES ( _flavor );
+ INSERT INTO _sumatra ( aroma, id) VALUES ( _aroma, currval('_coffee_id_seq') );
+ INSERT INTO sugar ( id, sweetness) VALUES ( currval('_coffee_id_seq'), _sweetness );
+ END;
+$function$ LANGUAGE plpgsql;
+
+
+CREATE OR REPLACE FUNCTION sumatra_update
+ (_id INTEGER, _aroma TEXT, _sweetness INTEGER, _flavor TEXT)
+ RETURNS VOID AS $function$
+ BEGIN
+ UPDATE _sumatra SET aroma = _aroma WHERE ( id = _id );
+ UPDATE sugar SET sweetness = _sweetness WHERE ( id = _id );
+ UPDATE coffee SET flavor = _flavor WHERE ( id = _id );
+ END;
+$function$ LANGUAGE plpgsql;
+
+
+CREATE OR REPLACE FUNCTION sumatra_delete
+ (_id INTEGER)
+ RETURNS VOID AS $function$
+ BEGIN
+ DELETE FROM _sumatra WHERE ( id = _id );
+ DELETE FROM sugar WHERE ( id = _id );
+ DELETE FROM coffee WHERE ( id = _id );
+ END;
+$function$ LANGUAGE plpgsql;
+
+
+CREATE RULE _sumatra_insert_rule AS
+ ON INSERT TO sumatra
+ DO INSTEAD (
+ SELECT sumatra_insert(NEW.aroma, NEW.sweetness, NEW.flavor)
+ );
+
+
+CREATE RULE _sumatra_update_rule AS
+ ON UPDATE TO sumatra
+ DO INSTEAD (
+ SELECT sumatra_update(OLD.id, NEW.aroma, NEW.sweetness, NEW.flavor)
+ );
+
+
+CREATE RULE _sumatra_delete_rule AS
+ ON DELETE TO sumatra
+ DO INSTEAD (
+ SELECT sumatra_delete(OLD.id)
+ );
+
+;
+
--
-- Created by SQL::Translator::Producer::PostgreSQL
--- Created on Tue Jun 1 20:00:58 2010
+-- Created on Mon Jun 14 20:16:23 2010
--
--
-- Table: just_a_table
--
-- View: "bar"
--
-DROP VIEW "bar";
+DROP VIEW IF EXISTS "bar";
CREATE VIEW "bar" ( "id", "a", "words", "b" ) AS
SELECT _bar.id, b, words, a FROM _bar _bar JOIN mixin mixin ON mixin.id = _bar.id JOIN foo foo ON foo.id = _bar.id;
--
-- View: "foo"
--
-DROP VIEW "foo";
+DROP VIEW IF EXISTS "foo";
CREATE VIEW "foo" ( "id", "a" ) AS
SELECT _foo.id, a FROM _foo;