##### LISTING ONE ##### #!/usr/bin/perl use strict; use warnings; BEGIN { package My::RDBO; $INC{"My/RDBO.pm"} = __FILE__; use base qw(Rose::DB::Object); sub init_db { shift; My::RDB->new } } BEGIN { package My::RDB; $INC{"My/RDB.pm"} = __FILE__; use base qw(Rose::DB); our $FILENAME = __FILE__ . ".sqlite"; __PACKAGE__->register_db (driver => 'sqlite', database => $FILENAME, ); unless (0 and -f $FILENAME) { __PACKAGE__->initialize_database; } sub initialize_database { my $class = shift; my $db = $class->new; die unless $db->driver eq "sqlite"; unlink $db->database; my $dbh = $db->dbh; $dbh->{RaiseError} = 0; $dbh->{PrintError} = 0; $dbh->do($_) or die "$DBI::errstr for $_" for split /\n{2,}/, <<'END_OF_SQL'; CREATE TABLE persons ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, birthdate DATE ) CREATE TABLE films ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, release_date DATE ) CREATE TABLE roles ( id INTEGER PRIMARY KEY AUTOINCREMENT, person_id INTEGER REFERENCES persons(id), film_id INTEGER REFERENCES films(id), category TEXT, detail TEXT ) CREATE TABLE studios ( name TEXT PRIMARY KEY ) CREATE TABLE film_studio_map ( film_id INTEGER REFERENCES films(id), studio_name TEXT REFERENCES studios(name), PRIMARY KEY (film_id, studio_name) ) END_OF_SQL } if ("use loader") { require Rose::DB::Object::Loader; my $loader = Rose::DB::Object::Loader->new (db_class => __PACKAGE__, base_class => 'My::RDBO', class_prefix => 'My::RDBO', ); my @classes = $loader->make_classes; if ("show resulting classes") { foreach my $class (@classes) { print "#" x 70, "\n"; if ($class->isa('Rose::DB::Object')) { print $class->meta->perl_class_definition; } else { # Rose::DB::Object::Manager subclasses print $class->perl_class_definition, "\n"; } } } } } ##### LISTING TWO ##### ###################################################################### package My::RDBO::Person; use strict; use base qw(My::RDBO); __PACKAGE__->meta->setup( table => 'persons', columns => [ id => { type => 'integer' }, name => { type => 'text' }, birthdate => { type => 'date' }, ], primary_key_columns => [ 'id' ], relationships => [ roles => { class => 'My::RDBO::Role', column_map => { id => 'person_id' }, type => 'one to many', }, ], ); 1; ###################################################################### package My::RDBO::Person::Manager; use base qw(Rose::DB::Object::Manager); use My::RDBO::Person; sub object_class { 'My::RDBO::Person' } __PACKAGE__->make_manager_methods('persons'); 1; ###################################################################### package My::RDBO::Film; use strict; use base qw(My::RDBO); __PACKAGE__->meta->setup( table => 'films', columns => [ id => { type => 'integer' }, title => { type => 'text' }, release_date => { type => 'date' }, ], primary_key_columns => [ 'id' ], relationships => [ roles => { class => 'My::RDBO::Role', column_map => { id => 'film_id' }, type => 'one to many', }, studios => { column_map => { film_id => 'id' }, foreign_class => 'My::RDBO::Studio', map_class => 'My::RDBO::FilmStudioMap', map_from => 'film', map_to => 'studio', type => 'many to many', }, ], ); 1; ###################################################################### package My::RDBO::Film::Manager; use base qw(Rose::DB::Object::Manager); use My::RDBO::Film; sub object_class { 'My::RDBO::Film' } __PACKAGE__->make_manager_methods('films'); 1; ###################################################################### package My::RDBO::Role; use strict; use base qw(My::RDBO); __PACKAGE__->meta->setup( table => 'roles', columns => [ id => { type => 'integer' }, person_id => { type => 'integer' }, film_id => { type => 'integer' }, category => { type => 'text' }, detail => { type => 'text' }, ], primary_key_columns => [ 'id' ], foreign_keys => [ film => { class => 'My::RDBO::Film', key_columns => { film_id => 'id' }, }, person => { class => 'My::RDBO::Person', key_columns => { person_id => 'id' }, }, ], ); 1; ###################################################################### package My::RDBO::Role::Manager; use base qw(Rose::DB::Object::Manager); use My::RDBO::Role; sub object_class { 'My::RDBO::Role' } __PACKAGE__->make_manager_methods('roles'); 1; ###################################################################### package My::RDBO::Studio; use strict; use base qw(My::RDBO); __PACKAGE__->meta->setup( table => 'studios', columns => [ name => { type => 'text' }, ], primary_key_columns => [ 'name' ], relationships => [ films => { column_map => { studio_name => 'name' }, foreign_class => 'My::RDBO::Film', map_class => 'My::RDBO::FilmStudioMap', map_from => 'studio', map_to => 'film', type => 'many to many', }, ], ); 1; ###################################################################### package My::RDBO::Studio::Manager; use base qw(Rose::DB::Object::Manager); use My::RDBO::Studio; sub object_class { 'My::RDBO::Studio' } __PACKAGE__->make_manager_methods('studios'); 1; ###################################################################### package My::RDBO::FilmStudioMap; use strict; use base qw(My::RDBO); __PACKAGE__->meta->setup( table => 'film_studio_map', columns => [ film_id => { type => 'integer' }, studio_name => { type => 'text' }, ], primary_key_columns => [ 'film_id', 'studio_name' ], foreign_keys => [ film => { class => 'My::RDBO::Film', key_columns => { film_id => 'id' }, }, studio => { class => 'My::RDBO::Studio', key_columns => { studio_name => 'name' }, }, ], ); 1; ###################################################################### package My::RDBO::FilmStudioMap::Manager; use base qw(Rose::DB::Object::Manager); use My::RDBO::FilmStudioMap; sub object_class { 'My::RDBO::FilmStudioMap' } __PACKAGE__->make_manager_methods('film_studio_map'); 1;