Author: spadkins
Date: Tue Jun 22 20:50:54 2010
New Revision: 14184
Added:
p5ee/trunk/App-Moose/
p5ee/trunk/App-Moose/CHANGES
p5ee/trunk/App-Moose/INSTALL.SKIP
p5ee/trunk/App-Moose/MANIFEST.SKIP
p5ee/trunk/App-Moose/Makefile.PL
p5ee/trunk/App-Moose/README
p5ee/trunk/App-Moose/TODO
p5ee/trunk/App-Moose/lib/
p5ee/trunk/App-Moose/lib/App/
p5ee/trunk/App-Moose/lib/App/Moose/
p5ee/trunk/App-Moose/lib/App/Moose/RepositoryObject.pm
p5ee/trunk/App-Moose/lib/App/Moose/SessionObject.pm
p5ee/trunk/App-Moose/t/
p5ee/trunk/App-Moose/t/RepositoryObject.t (contents, props changed)
p5ee/trunk/App-Moose/t/RepositoryTestUtils.pm (contents, props changed)
p5ee/trunk/App-Moose/t/SessionObject.t (contents, props changed)
p5ee/trunk/App-Moose/t/app.conf.sample
Log:
add Moose support
Added: p5ee/trunk/App-Moose/CHANGES
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/CHANGES Tue Jun 22 20:50:54 2010
@@ -0,0 +1,7 @@
+#############################################################################
+# CHANGE LOG
+#############################################################################
+
+VERSION 0.50
+ o First version
+
Added: p5ee/trunk/App-Moose/INSTALL.SKIP
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/INSTALL.SKIP Tue Jun 22 20:50:54 2010
@@ -0,0 +1,19 @@
+# NOTE: the master INSTALL.SKIP is in the mv/common project
+~$
+^MANIFEST\.
+^Makefile$
+^pm_to_blib$
+^tmp
+\.trash$
+\.old$
+\.bak$
+\.swp$
+\.cvsignore$
+\.tar\.gz$
+\.zip$
+htdocs/.exists
+htdocs/lib
+.svn/
+CVS/
+\.#
+^pm_to
Added: p5ee/trunk/App-Moose/MANIFEST.SKIP
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/MANIFEST.SKIP Tue Jun 22 20:50:54 2010
@@ -0,0 +1,14 @@
+~$
+^_build
+^Build$
+^MANIFEST\.
+^Makefile$
+^blib/
+^pm_to_blib$
+\.old$
+\.bak$
+\.cvsignore$
+\.tar\.gz$
+\.svn
+htdocs/.exists
+CVS/
Added: p5ee/trunk/App-Moose/Makefile.PL
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/Makefile.PL Tue Jun 22 20:50:54 2010
@@ -0,0 +1,27 @@
+
+######################################################################
+## File: $Id: Makefile.PL 13875 2010-03-26 17:22:46Z spadkins $
+######################################################################
+
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+
+my @programs = (
+);
+
+%opts = (
+ NAME => "App-Moose",
+ DISTNAME => "App-Moose",
+ VERSION => "0.969", # the first release is 0.969 just to
make it even with App-Context and App-Repository
+ EXE_FILES => [ @programs ],
+ PREREQ_PM => {
+ "App-Context" => "0.969", # This is the first version
that supports App-Moose
+ "App-Repository" => "0.969", # This is the first version
that supports App-Moose
+ "Moose" => "0.93", # There's no particular
reason I chose this version. It is simply what I tested the code for.
+ "namespace::autoclean" => "0.11", # There's no particular
reason I chose this version. It is simply what I tested the code for.
+ },
+);
+
+WriteMakefile(%opts);
+
Added: p5ee/trunk/App-Moose/README
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/README Tue Jun 22 20:50:54 2010
@@ -0,0 +1,30 @@
+######################################################################
+## File: $Id: README 3442 2005-05-14 14:14:01Z spadkins $
+######################################################################
+
+1. What is the App-Moose distribution?
+
+The App-Moose distribution implements three of the primary abstractions
+of the App-Context Framework as Moose-friendly classes.
+
+ App::Moose::SessionObject - a stateless or stateful object with methods
+ which implement business or application logic. If it has state,
+ that state is maintained in the current application session.
+
+ App::Moose::RepositoryObject - an object which represents a business
+ entity (i.e. a row from a database table). This object's state
+ is maintained in an App::Repository table (usually a database).
+
+ App::Moose::SessionObject::RepositoryObjectSet - an object which
+ represents a collection of RepositoryObjects.
+
+2. How do I install it?
+
+To install this module, cd to the directory that contains this README
+file and type the following (as usual).
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+
Added: p5ee/trunk/App-Moose/TODO
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/TODO Tue Jun 22 20:50:54 2010
@@ -0,0 +1,7 @@
+x######################################################################
+## File: $Id: TODO 10141 2007-10-30 19:11:51Z spadkins $
+######################################################################
+
+These items are what will be required to go to the next release to CPAN
+ o do it
+
Added: p5ee/trunk/App-Moose/lib/App/Moose/RepositoryObject.pm
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/lib/App/Moose/RepositoryObject.pm Tue Jun 22
20:50:54 2010
@@ -0,0 +1,96 @@
+
+#############################################################################
+## $Id: RepositoryObject.pm 7868 2006-10-03 14:43:34Z spadkins $
+#############################################################################
+
+package App::Moose::RepositoryObject;
+$VERSION = (q$Revision: 7868 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers
generated by svn
+use Moose;
+use namespace::autoclean;
+
+extends "Moose::Object", "App::RepositoryObject"; # We need the
Moose::Object::new constructor and the other methods from App::RepositoryObject
+
+has "_repository" => (is => "ro", isa => "App::Repository");
+has "_table" => (is => "ro", isa => "Str", required => 1);
+has "_key" => (is => "ro", isa => "Str");
+
+#TODO: I ought to make a RepositoryObject automatically define the attributes
based on the table (along with getters and setters)
+# But that will have to wait.
+
+=head1 NAME
+
+App::Moose::RepositoryObject - Persistent, global business entity objects
(i.e. rows in a database)
+
+=head1 SYNOPSIS
+
+ [in app.conf]
+ repositoryobject_class = App::Moose::RepositoryObject # the default
without this setting is App::RepositoryObject
+
+ [in perl code]
+
+ # For these examples, there is presumed to be a table in the database
named "person" with an auto-incrementing
+ # primary key called "person_id" and columns "first_name", "last_name",
and "age".
+
+ use App;
+ my $context = App->context();
+ my $db = $context->repository():
+
+ my ($person, $person2, $persons);
+ my ($first_name, $last_name, $age, $success);
+
+ # retrieve an existing person or set of persons
+ $person = $db->get_object("person", 1); # a scalar for
$params implies a primary key value
+ $person = $db->get_object("person", { person_id => 1 }); # use arbitrary
$params. get the first object.
+ $persons = $db->get_objects("person", { last_name => "Smith" }); # use
arbitrary $params, all objects.
+
+ # create a new person (
+ $person2 = $db->new_object("person", { first_name => "John", last_name =
"Doe", age => 18 });
+
+ # delete a person (
+ $success = $db->delete("person", 1); # on the App::Repository (preferred)
+ $success = $person2->delete(); # on the App::RepositoryObject
itself
+
+ # getters and setters (consistent with App::RepositoryObject)
+ $age = $person->get("age");
# get a single attribute
+ ($first_name, $last_name) = $person->get(["first_name", "last_name"]);
# get multiple attributes
+ $success = $person->set("age",19);
# set a single attribute
+ $success = $person->set(["first_name", "last_name"], ["Jane","Smith"]);
# set multiple attributes
+
+ # FUTURE: NOT YET IMPLEMENTED
+
+ # getters and setters (new with App::Moose::RepositoryObject) (only
available for physical or default columns)
+ $age = $person->age;
# get a single attribute
+ $success = $person->age(19);
# set a single attribute
+
+=cut
+
+=head1 DESCRIPTION
+
+The App::Moose::RepositoryObject class is a reimplementation of the
+App::RepositoryObject class as a base class written with Moose.
+
+Moose is the next generation of Object-Oriented capabilities implemented
+in Perl 5. Many of these features are from Perl 6.
+
+See the documentation for App::RepositoryObject for a discussion of
+what a RepositoryObject is.
+
+=cut
+
+=head1 ACKNOWLEDGEMENTS
+
+ * Author: Stephen Adkins <[email protected]>
+ * License: This is free software. It is licensed under the same terms as Perl
itself.
+
+=head1 SEE ALSO
+
+L<C<App::Context>|App::Context>,
+L<C<App::Repository>|App::Repository>,
+L<C<App::RepositoryObject>|App::RepositoryObject>
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
Added: p5ee/trunk/App-Moose/lib/App/Moose/SessionObject.pm
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/lib/App/Moose/SessionObject.pm Tue Jun 22 20:50:54 2010
@@ -0,0 +1,82 @@
+
+#############################################################################
+## $Id: SessionObject.pm 7868 2006-10-03 14:43:34Z spadkins $
+#############################################################################
+
+package App::Moose::SessionObject;
+$VERSION = (q$Revision: 7868 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers
generated by svn
+use Moose;
+use namespace::autoclean;
+
+extends "Moose::Object", "App::SessionObject"; # We need the
Moose::Object::new constructor and the other methods from App::SessionObject
+
+has 'context' => (is => 'ro', isa => 'App::Context');
+has 'name' => (is => 'ro', isa => 'Str');
+has 'stateless' => (is => 'ro', isa => 'Bool', default => 0);
+has 'anonymous' => (is => 'ro', isa => 'Bool', default => 0);
+has 'lang' => (is => 'ro', isa => 'Str', default => "en");
+has 'dict' => (is => 'ro', isa => 'HashRef');
+
+=head1 NAME
+
+App::Moose::SessionObject - Named, Configurable, Cached, Stateless or Stateful
(in the Session) business or application objects (i.e. screens, business
processes, application logic, etc.)
+
+=head1 SYNOPSIS
+
+ [in app.conf]
+ sessionobject_class = App::Moose::SessionObject # the default without
this setting is App::SessionObject
+
+ [in perl code]
+
+ # For these examples, there is presumed to be a table in the database
named "person" with an auto-incrementing
+ # primary key called "person_id" and columns "first_name", "last_name",
and "age".
+
+ use App;
+ my $context = App->context();
+ my $cart = $context->session_object("shopping_cart"):
+ my $tax_calc = $context->session_object("tax_calculator", { stateless =>
1, country_cd => "US" }):
+
+ # # getters and setters (consistent with App::SessionObject)
+ # $age = $person->get("age");
# get a single attribute
+ # ($first_name, $last_name) = $person->get(["first_name", "last_name"]);
# get multiple attributes
+ # $success = $person->set("age",19);
# set a single attribute
+ # $success = $person->set(["first_name", "last_name"],
["Jane","Smith"]); # set multiple attributes
+
+ # # FUTURE: NOT YET IMPLEMENTED
+
+ # # getters and setters (new with App::Moose::SessionObject) (only
available for physical or default columns)
+ # $age = $person->age;
# get a single attribute
+ # $success = $person->age(19);
# set a single attribute
+
+=cut
+
+=head1 DESCRIPTION
+
+The App::Moose::SessionObject class is a reimplementation of the
+App::SessionObject class as a base class written with Moose.
+
+Moose is the next generation of Object-Oriented capabilities implemented
+in Perl 5. Many of these features are from Perl 6.
+
+See the documentation for App::SessionObject for a discussion of
+what a SessionObject is.
+
+=cut
+
+=head1 ACKNOWLEDGEMENTS
+
+ * Author: Stephen Adkins <[email protected]>
+ * License: This is free software. It is licensed under the same terms as Perl
itself.
+
+=head1 SEE ALSO
+
+L<C<App::Context>|App::Context>,
+L<C<App::Repository>|App::Repository>,
+L<C<App::SessionObject>|App::SessionObject>
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
Added: p5ee/trunk/App-Moose/t/RepositoryObject.t
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/t/RepositoryObject.t Tue Jun 22 20:50:54 2010
@@ -0,0 +1,251 @@
+#!/usr/bin/perl -w
+
+use App::Options (
+ options => [qw(dbdriver dbclass dbhost dbname dbuser dbpass)],
+ option => {
+ dbclass => { default => "App::Repository::MySQL", },
+ dbdriver => { default => "mysql", },
+ dbhost => { default => "localhost", },
+ dbname => { default => "test", },
+ dbuser => { default => "", },
+ dbpass => { default => "", },
+ },
+);
+
+use Test::More qw(no_plan);
+use lib "../App-Context/lib";
+use lib "../../App-Context/lib";
+use lib "lib";
+use lib "../lib";
+use lib ".";
+use lib "t";
+
+use App;
+use App::Repository;
+use App::RepositoryObject;
+use RepositoryTestUtils qw(create_table drop_table populate_table);
+
+package App::Moose::RepositoryObject::Man;
+use vars qw($VERSION);
+$VERSION = 0.01;
+use Moose;
+extends "App::Moose::RepositoryObject";
+
+package App::Moose::RepositoryObject::Woman;
+use vars qw($VERSION);
+$VERSION = 0.01;
+use Moose;
+extends "App::Moose::RepositoryObject";
+
+package main;
+
+use strict;
+
+if (!$App::options{dbuser}) {
+ ok(1, "No dbuser given. Tests assumed OK. (add dbuser=xxx and dbpass=yyy
to app.conf in 't' directory)");
+ exit(0);
+}
+
+my $context = App->context(
+ conf_file => "",
+ conf => {
+ Repository => {
+ default => {
+ class => $App::options{dbclass},
+ dbdriver => $App::options{dbdriver},
+ dbhost => $App::options{dbhost},
+ dbname => $App::options{dbname},
+ dbuser => $App::options{dbuser},
+ dbpass => $App::options{dbpass},
+ table => {
+ test_person => {
+ class => [
+ [ "gender", "F",
"App::Moose::RepositoryObject::Woman" ],
+ # [ undef, undef,
"App::Moose::RepositoryObject::Man" ], # otherwise Man
+ ],
+ primary_key => ["person_id"],
+ },
+ },
+ },
+ },
+ },
+ debug_sql => $App::options{debug_sql},
+ trace => $App::options{trace},
+ repositoryobject_class => $App::options{repositoryobject_class},
+);
+
+my $rep = $context->repository();
+
+&drop_table($rep, "test_person");
+&create_table($rep, "test_person");
+&populate_table($rep, "test_person");
+
+&drop_table($rep, "test_visit");
+&create_table($rep, "test_visit");
+&populate_table($rep, "test_visit");
+
+&drop_table($rep, "test_city");
+&create_table($rep, "test_city");
+&populate_table($rep, "test_city");
+
+my $dbtype = $App::options{dbtype} || "mysql";
+
+###########################################################################
+# DATA ACCESS TESTS
+###########################################################################
+my ($person_id, $first_name, $last_name, $address, $city, $state, $zip,
$country);
+my ($home_phone, $work_phone, $email_address, $gender, $birth_dt, $age);
+
+my $columns = [ "person_id", "age", "first_name", "gender", "state" ];
+my $rows = [
+ [ 1, 39, "stephen", "M", "GA", ],
+ [ 2, 37, "susan", "F", "GA", ],
+ [ 3, 6, "maryalice", "F", "GA", ],
+ [ 4, 3, "paul", "M", "GA", ],
+ [ 5, 1, "christine", "F", "GA", ],
+ [ 6, 45, "tim", "M", "GA", ],
+ [ 7, 39, "keith", "M", "GA", ],
+];
+
+my ($row, $nrows);
+
+#####################################################################
+# $value = $rep->get ($table, $key, $col, \%options);
+# $rep->set($table, $key, $col, $value, \%options);
+#####################################################################
+{
+ my $obj = $rep->get_object("test_person", 1);
+ isa_ok($obj, "App::Moose::RepositoryObject", "stephen");
+ $first_name = $obj->get("first_name");
+ is($first_name, "stephen", "get() first_name [$first_name]");
+ is($obj->set("first_name", "steve"),1,"set() first name [steve]");
+}
+{
+ my $obj = $rep->get_object("test_person", 1);
+ $first_name = $obj->get("first_name");
+ is($first_name, "steve", "get() modified first_name [$first_name]");
+ $age = $obj->get("age");
+ is($age, 39, "get() age");
+}
+{
+ my $obj = $rep->get_object("test_person", 1, []);
+ $first_name = $obj->get("first_name");
+ is($first_name, "steve", "get() modified first_name [$first_name] from
uninit object");
+ $age = $obj->get("age");
+ is($age, 39, "get() age from uninit object");
+}
+
+{
+ my $obj = $rep->get_object("test_person", 2, []);
+ isa_ok($obj, "App::Moose::RepositoryObject", "susan");
+ ok($obj->set(["first_name","age"], ["sue",38]), "set() 2 values");
+ ($first_name, $age) = $obj->get(["first_name","age"]);
+ is($first_name, "sue", "get() 2 values (checking 1 of 2)");
+ is($age, 38, "get() 2 values (checking 2 of 2)");
+}
+
+{
+ my $obj = $rep->get_object("test_person", 2);
+ isa_ok($obj, "App::Moose::RepositoryObject::Woman", "susan");
+}
+
+{
+ my $objs = $rep->get_objects("test_person", {}, undef, {order_by =>
"person_id"});
+ is($objs->[0]{_key}, 1, "get_objects() automatically set the _key");
+ isa_ok($objs->[0], "App::Moose::RepositoryObject", "by get_objects(),
stephen");
+ isa_ok($objs->[1], "App::Moose::RepositoryObject::Woman", "by
get_objects(), susan");
+}
+
+{
+ my $obj = $rep->get_object("test_person", {}, undef, {order_by =>
"person_id"});
+ is($obj->{_key}, 1, "get_object() automatically set the _key");
+}
+
+{
+ ok($rep->set_row("test_person", {first_name=>'paul'}, ["age", "state"],
[5, "CA"]),"set_row() 2 values w/ %crit");
+ my $obj = $rep->get_object("test_person", {first_name=>'paul'}, ["age",
"state","person_id"]);
+ is($obj->{age}, 5, "get_object() 3 values w/ %crit (checking 1 of
3)");
+ is($obj->{state}, "CA", "get_object() 3 values w/ %crit (checking 2 of
3)");
+ is($obj->{person_id}, 4, "get_object() 3 values w/ %crit (checking 3 of
3)");
+}
+
+{
+ my $obj = $rep->get_object("test_person", 1);
+ is($obj->{_key}, 1, "get_object() by key");
+
+ my $retval = $obj->delete();
+ ok($retval, "delete() seems to have worked");
+
+ my $obj2 = $rep->get_object("test_person", 1);
+ ok(! defined $obj2, "delete() yep, it's really gone");
+
+ $obj2 = $rep->new_object("test_person", $obj);
+ is($obj2->{first_name},$obj->{first_name}, "new.first_name seems ok");
+ is($obj2->{age},$obj->{age}, "new.age seems ok");
+ is($obj2->{_key},$obj->{_key}, "new._key seems ok");
+
+ my $obj3 = $rep->get_object("test_person", 1);
+ ok(defined $obj2, "new() it's back");
+ is($obj3->{first_name},$obj->{first_name}, "new.first_name seems ok");
+ is($obj3->{age},$obj->{age}, "new.age seems ok");
+ is($obj3->{_key},$obj->{_key}, "new._key seems ok");
+
+ my $obj4 = $rep->new_object("test_person",{first_name => "christine",
gender => "F"});
+ is($obj4->{first_name},"christine", "new.first_name (2) seems ok");
+ is($obj4->{_key},8, "new._key is ok");
+ is($obj4->{person_id},8, "new.person_id is ok");
+ isa_ok($obj4, "App::Moose::RepositoryObject::Woman", "by new_object(),
christine");
+
+ $obj = { city_cd => "BOS", city_nm => "Boston" };
+ $obj2 = $rep->new_object("test_city", $obj);
+ isa_ok($obj2, "App::Moose::RepositoryObject", "new_object(city,{BOS})");
+ is($obj2->{city_cd},$obj->{city_cd}, "new_object(city,{BOS}).city_cd
= [$obj->{city_cd}]");
+ is($obj2->{_repository}{name}, "default",
"new_object(city,{BOS})._repository = [default]");
+ is($obj2->{_table}, "test_city", "new_object(city,{BOS})._table =
[$obj2->{_table}]");
+ is($obj2->{_key}, $obj->{city_cd}, "new_object(city,{BOS})._key =
[$obj2->{_key}]");
+ my $json = "{'_key' : 'BOS', '_repository' : 'default', '_table' :
'test_city', 'arp_nm' : null, 'city_cd' : 'BOS', 'city_nm' : 'Boston',
'country' : null, 'state' : null}";
+ is($obj2->TO_JSON(), $json, "new_object(city,{BOS}).TO_JSON = [{...}]");
+ $nrows = $obj2->set("arp_nm", "Logan Airport");
+ is($nrows, 1, "obj(city)->set(col, value): works");
+ $obj3 = $rep->get_object("test_city", "BOS");
+ is($obj3->{arp_nm},"Logan Airport", "obj(city).arp_nm = [Logan Airport]");
+
+ $obj = { city_cd => "BOS", person_id => undef };
+ eval {
+ $obj2 = $rep->new_object("test_visit", $obj);
+ };
+ ok(($@ ? 1 : 0), "new_object(visit) correctly failed when insufficient
initial values given");
+ $obj = { city_cd => "BOS", person_id => 1, visit_dt => "1980-08-30" };
+ eval {
+ $obj2 = $rep->new_object("test_visit", $obj);
+ };
+ ok(($@ ? 1 : 0), "new_object(visit) correctly failed when primary key
violated");
+ $obj = { city_cd => "BOS", person_id => 1, visit_dt => "1980-08-31",
occasion => "back again" };
+ $obj2 = $rep->new_object("test_visit", $obj);
+ isa_ok($obj2, "App::Moose::RepositoryObject", "new_object(visit)");
+ is($obj2->{city_cd}, $obj->{city_cd}, "new_object(visit).city_cd =
[$obj->{city_cd}]");
+ is($obj2->{person_id}, $obj->{person_id}, "new_object(visit).person_id =
[$obj->{person_id}]");
+ is($obj2->{visit_dt}, $obj->{visit_dt}, "new_object(visit).visit_dt =
[$obj->{visit_dt}]");
+ is($obj2->{occasion}, $obj->{occasion}, "new_object(visit).occasion =
[$obj->{occasion}]");
+ $nrows = $obj2->set(["occasion"], ["woke up in the morning"]);
+ is($nrows, 1, "obj(visit)->set(col, value): works");
+ $obj3 = $rep->get_object("test_visit", "BOS,1,1980-08-31");
+ is($obj3->{occasion},"woke up in the morning", "obj(visit).occasion
successfully changed");
+}
+
+{
+ # This is experimental. It should not be accepted as part of the official
API yet.
+ # In other words... Use the constructors on App::Repository, not the new()
constructor on the class.
+ my $obj = App::Moose::RepositoryObject->new(_table => "test_person", _key
=> 1);
+ isa_ok($obj, "App::Moose::RepositoryObject", "non-factory constructor
works");
+ is($obj->{_key}, 1, "new() sets the _key");
+}
+
+{
+ &drop_table($rep, "test_person");
+ &drop_table($rep, "test_visit");
+ &drop_table($rep, "test_city");
+}
+
+exit 0;
+
Added: p5ee/trunk/App-Moose/t/RepositoryTestUtils.pm
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/t/RepositoryTestUtils.pm Tue Jun 22 20:50:54 2010
@@ -0,0 +1,477 @@
+
+#############################################################################
+# $Id: HotelUtils.pm 25141 2008-08-19 15:38:16Z asawczyn $
+#############################################################################
+
+package RepositoryTestUtils;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+
+require Exporter;
+
+...@isa = qw(Exporter);
+
+...@export = qw(
+);
+
+...@export_ok = qw(
+ create_table_test_person
+ drop_table_test_person
+ populate_table_test_person
+ create_table_test_app_cache
+ drop_table_test_app_cache
+ create_table
+ drop_table
+ populate_table
+);
+
+use App;
+use App::Repository;
+
+sub create_table_test_person {
+ &App::sub_entry if ($App::trace);
+ my ($rep) = @_;
+ my $dbh = $rep->{dbh};
+
+ my ($ddl, $rc);
+ my $dbtype = $App::options{dbtype} || "mysql";
+
+ my $autoincrement = "";
+ my $suffix = "";
+ if ($dbtype eq "mysql") {
+ $autoincrement = " auto_increment";
+ $suffix = " ENGINE=InnoDB DEFAULT CHARSET=latin1";
+ }
+
+ my $double_type = ($dbtype eq "mysql") ? 'double' : 'float';
+ my $datetime_type = ($dbtype eq "mysql") ? 'datetime' : 'date';
+
+ $ddl = <<EOF;
+create table test_person (
+ person_id integer not null$autoincrement,
+ first_name varchar(99) null,
+ last_name varchar(99) null,
+ address varchar(99) null,
+ city varchar(99) null,
+ state varchar(99) null,
+ zip varchar(10) null,
+ country char(2) null,
+ city_cd varchar(5) null,
+ home_phone varchar(99) null,
+ work_phone varchar(99) null,
+ email_address varchar(99) null,
+ gender char(1) null,
+ birth_dt date null,
+ age integer null,
+ data blob null,
+ chess_rating float null,
+ modify_dttm timestamp null,
+ change_dttm $datetime_type null,
+ deci_col decimal null,
+ double_col $double_type null,
+ long_col long varchar null,
+ primary key (person_id)
+)$suffix
+EOF
+ print "DEBUG:\n$ddl\n" if ($App::options{debug_sql});
+ $rc = $dbh->do($ddl);
+ print "DEBUG: rc=[$rc] errstr=[$DBI::errstr]\n" if
($App::options{debug_sql});
+
+ $ddl = "create unique index test_person_ak1 on test_person (first_name,
state, gender)";
+ print "DEBUG:\n$ddl\n" if ($App::options{debug_sql});
+ $rc = $dbh->do($ddl);
+ print "DEBUG: rc=[$rc] errstr=[$DBI::errstr]\n" if
($App::options{debug_sql});
+
+ $ddl = "create index test_person_ie1 on test_person (last_name,
first_name)";
+ $dbh->do($ddl);
+ if ($dbtype eq "oracle") {
+ $ddl = <<EOF;
+create sequence test_person_seq start with 1 increment by 1 nomaxvalue nocycle
cache 200
+EOF
+ $dbh->do($ddl);
+ $ddl = <<EOF;
+CREATE OR REPLACE TRIGGER tib_test_person
+BEFORE INSERT ON test_person
+FOR EACH ROW
+WHEN (new.person_id IS NULL or new.person_id = 0)
+BEGIN
+ SELECT test_person_seq.NEXTVAL
+ INTO :new.person_id
+ FROM DUAL;
+END tib_test_person;
+EOF
+ $dbh->do($ddl);
+ }
+
+ &App::sub_exit() if ($App::trace);
+}
+
+sub drop_table_test_person {
+ &App::sub_entry if ($App::trace);
+ my ($rep) = @_;
+ my $dbh = $rep->{dbh};
+
+ my $dbtype = $App::options{dbtype} || "mysql";
+
+ print "DEBUG:\ndrop table test_person\n" if ($App::options{debug_sql});
+ my ($rc);
+ eval { $dbh->do("drop table test_person"); };
+ print "DEBUG: rc=[$rc] errstr=[$DBI::errstr]\n" if
($App::options{debug_sql});
+ #warn $@ if ($@);
+ if ($dbtype eq "oracle") {
+ eval { $dbh->do("drop sequence test_person_seq"); };
+ }
+
+ &App::sub_exit() if ($App::trace);
+}
+
+sub populate_table_test_person {
+ &App::sub_entry if ($App::trace);
+ my ($rep) = @_;
+ my $dbh = $rep->{dbh};
+ $dbh->do("insert into test_person (age,first_name,gender,state) values
(39,'stephen', 'M','GA')");
+ $dbh->do("insert into test_person (age,first_name,gender,state) values
(37,'susan', 'F','GA')");
+ $dbh->do("insert into test_person (age,first_name,gender,state) values (
6,'maryalice','F','GA')");
+ $dbh->do("insert into test_person (age,first_name,gender,state) values (
3,'paul', 'M','GA')");
+ $dbh->do("insert into test_person (age,first_name,gender,state) values (
1,'christine','F','GA')");
+ $dbh->do("insert into test_person (age,first_name,gender,state) values
(45,'tim', 'M','GA')");
+ $dbh->do("insert into test_person (age,first_name,gender,state) values
(39,'keith', 'M','GA')");
+ &App::sub_exit() if ($App::trace);
+}
+
+sub create_table_test_app_cache {
+ my ($rep) = @_;
+ my $dbh = $rep->{dbh};
+ my $dbtype = $App::options{dbtype} || "mysql";
+
+ my $suffix = "";
+ my $CURRENT_TIMESTAMP = "";
+ my $datetime = "date";
+ my $longblob = "blob";
+ if ($dbtype eq "mysql") {
+ $suffix = "ENGINE=InnoDB DEFAULT CHARSET=latin1";
+ $CURRENT_TIMESTAMP = "default CURRENT_TIMESTAMP on update
CURRENT_TIMESTAMP";
+ $datetime = "datetime";
+ $longblob = "longblob";
+ }
+
+ eval { $dbh->do("drop table test_app_cache"); };
+ my $ddl = <<EOF;
+create table test_app_cache (
+ cache_type varchar(16) not null,
+ cache_key varchar(40) not null,
+ generate_dttm $datetime default null,
+ serializer varchar(12) default null,
+ serialization_args varchar(64) default null,
+ data $longblob,
+ modify_dttm timestamp not null $CURRENT_TIMESTAMP,
+ primary key (cache_type,cache_key)
+) $suffix
+EOF
+ $dbh->do($ddl);
+ $ddl = "create index test_app_cache_ie1 on test_app_cache (modify_dttm)";
+ $dbh->do($ddl);
+
+ if ($dbtype eq 'oracle') {
+ $ddl = <<EOF;
+CREATE OR REPLACE TRIGGER tib_test_app_cache
+BEFORE INSERT ON test_app_cache
+FOR EACH ROW
+WHEN (new.modify_dttm IS NULL)
+BEGIN
+ SELECT sysdate
+ INTO :new.modify_dttm
+ FROM DUAL;
+END tib_test_app_cache;
+EOF
+ $dbh->do($ddl);
+ }
+}
+
+sub drop_table_test_app_cache {
+ &App::sub_entry if ($App::trace);
+ my ($rep) = @_;
+ my $dbh = $rep->{dbh};
+ my $dbtype = $App::options{dbtype} || "mysql";
+ eval { $dbh->do("drop table test_app_cache"); };
+ &App::sub_exit() if ($App::trace);
+}
+
+######################################################################################################
+# GENERIC DATABASE TABLE GENERATION
+######################################################################################################
+
+my (%table_schema, %table_index, %table_autoid_column, %table_data);
+
+$table_schema{test_person} = <<EOF;
+create table test_person (
+ person_id integer not null AUTOINCREMENT,
+ first_name varchar(99) null,
+ last_name varchar(99) null,
+ address varchar(99) null,
+ city varchar(99) null,
+ state varchar(99) null,
+ zip varchar(10) null,
+ country char(2) null,
+ city_cd varchar(5) null,
+ home_phone varchar(99) null,
+ work_phone varchar(99) null,
+ email_address varchar(99) null,
+ gender char(1) null,
+ birth_dt date null,
+ age integer null,
+ data blob null,
+ chess_rating float null,
+ modify_dttm timestamp null,
+ change_dttm DATETIME null,
+ deci_col decimal null,
+ double_col DOUBLE null,
+ long_col long varchar null,
+ primary key (person_id)
+)SUFFIX
+EOF
+$table_index{test_person} = [
+ "create unique index test_person_ak1 on test_person (first_name, state,
gender)",
+ "create index test_person_ie1 on test_person (last_name, first_name)",
+];
+$table_autoid_column{test_person} = "person_id";
+$table_data{test_person} = [
+ "insert into test_person (age,first_name,gender,state,country) values
(39,'stephen', 'M','GA','US')",
+ "insert into test_person (age,first_name,gender,state,country) values
(37,'susan', 'F','GA','US')",
+ "insert into test_person (age,first_name,gender,state,country) values (
6,'maryalice','F','GA','US')",
+ "insert into test_person (age,first_name,gender,state,country) values (
3,'paul', 'M','GA','US')",
+ "insert into test_person (age,first_name,gender,state,country) values (
1,'christine','F','GA','US')",
+ "insert into test_person (age,first_name,gender,state,country) values
(45,'tim', 'M','GA','US')",
+ "insert into test_person (age,first_name,gender,state,country) values
(39,'keith', 'M','GA','US')",
+];
+
+$table_schema{test_country} = <<EOF;
+create table test_country (
+ country_id integer not null AUTOINCREMENT,
+ country char(2) not null,
+ country_nm varchar(64) not null,
+ primary key (country_id)
+)SUFFIX
+EOF
+$table_index{test_country} = [
+ "create index test_country_ie1 on test_country (country)",
+ "create index test_country_ie2 on test_country (country_nm)",
+];
+$table_autoid_column{test_country} = "country_id";
+$table_data{test_country} = [
+ "insert into test_country (country, country_nm) values ('AU','AUSTRALIA')",
+ "insert into test_country (country, country_nm) values ('BR','BRAZIL')",
+ "insert into test_country (country, country_nm) values ('CN','CHINA')",
+ "insert into test_country (country, country_nm) values ('DE','GERMANY')",
+ "insert into test_country (country, country_nm) values ('ES','SPAIN')",
+ "insert into test_country (country, country_nm) values ('FR','FRANCE')",
+ "insert into test_country (country, country_nm) values ('GB','UNITED
KINGDOM')",
+ "insert into test_country (country, country_nm) values ('IT','ITALY')",
+ "insert into test_country (country, country_nm) values ('JP','JAPAN')",
+ "insert into test_country (country, country_nm) values ('MX','MEXICO')",
+ "insert into test_country (country, country_nm) values ('RU','RUSSIAN
FEDERATION')",
+ "insert into test_country (country, country_nm) values ('US','UNITED
STATES')",
+ "insert into test_country (country, country_nm) values ('ZA','SOUTH
AFRICA')",
+];
+
+$table_schema{test_city} = <<EOF;
+create table test_city (
+ city_cd char(3) not null,
+ state char(2) null,
+ country char(2) null,
+ city_nm varchar(99) not null,
+ arp_nm varchar(99) null,
+ primary key (city_cd)
+)SUFFIX
+EOF
+$table_index{test_city} = [
+ "create index test_city_ie1 on test_city (city_nm)",
+ "create index test_city_ie2 on test_city (state)",
+ "create index test_city_ie3 on test_city (country)",
+];
+$table_data{test_city} = [
+ "insert into test_city values ('ATL', 'GA', 'US', 'Atlanta',
'William B. Hartsfield International Airport')",
+ "insert into test_city values ('CDG', '', 'FR', 'Paris',
'Roissy Ch. de Gaulle')",
+ "insert into test_city values ('DFW', 'TX', 'US', 'Dallas/Fort Worth',
'Dallas/Fort Worth Int''l')",
+ "insert into test_city values ('EWR', 'NJ', 'US', 'Newark',
'Newark International Airport')",
+ "insert into test_city values ('FCO', '', 'IT', 'Roma',
'Leonardo da Vinci/Fiumicino')",
+ "insert into test_city values ('HKG', '', 'CN', 'Hong Kong',
'Chek Lap Kok International Airport')",
+ "insert into test_city values ('HND', '', 'JP', 'Tokyo',
'Haneda')",
+ "insert into test_city values ('IAD', 'DC', 'US', 'Washington',
'Washington Dulles Int''l Airport')",
+ "insert into test_city values ('JFK', 'NY', 'US', 'New York',
'John F. Kennedy International Airport')",
+ "insert into test_city values ('JNB', '', 'ZA', 'Johannesburg',
'Johannesburg International Airport')",
+ "insert into test_city values ('LAX', 'CA', 'US', 'Los Angeles',
'Los Angeles International Airport')",
+ "insert into test_city values ('LGA', 'NY', 'US', 'New York', 'La
Guardia Airport')",
+ "insert into test_city values ('LGW', '', 'GB', 'London',
'Gatwick Airport')",
+ "insert into test_city values ('MAD', '', 'ES', 'Madrid',
'Barajas')",
+ "insert into test_city values ('MDW', 'IL', 'US', 'Chicago',
'Chicago Midway Airport')",
+ "insert into test_city values ('MEX', '', 'MX', 'Mexico City',
'Benito Juarez International')",
+ "insert into test_city values ('NRT', '', 'JP', 'Tokyo',
'Narita')",
+ "insert into test_city values ('ORD', 'IL', 'US', 'Chicago',
'Chicago-O''Hare International Airport')",
+ "insert into test_city values ('SDU', 'RJ', 'BR', 'Rio de Janeiro',
'Aeroporto Santos Dumont')",
+ "insert into test_city values ('SVO', '', 'RU', 'Moscow',
'Sheremetyevo')",
+ "insert into test_city values ('SXF', '', 'DE', 'Berlin',
'Schoenefeld')",
+ "insert into test_city values ('SYD', '', 'AU', 'Sydney',
'Kingsford Smith')",
+ "insert into test_city values ('THF', '', 'DE', 'Berlin',
'Tempelhof')",
+ "insert into test_city values ('TXL', '', 'DE', 'Berlin',
'Tegel')",
+];
+
+$table_schema{test_visit} = <<EOF;
+create table test_visit (
+ city_cd char(3) not null,
+ person_id integer not null,
+ visit_dt date not null,
+ occasion varchar(99) null,
+ primary key (city_cd, person_id, visit_dt)
+)SUFFIX
+EOF
+$table_data{test_visit} = [
+ "insert into test_visit values ('LAX', 1, '1962-11-09', 'Born')",
+ "insert into test_visit values ('BOS', 1, '1980-08-30', 'College')",
+ "insert into test_visit values ('JNB', 1, '1986-10-20', 'Mission Trip')",
+ "insert into test_visit values ('WAS', 1, '1991-08-20', 'Back to
college')",
+ "insert into test_visit values ('ATL', 1, '1993-06-01', 'Move after
graduation')",
+];
+
+$table_schema{test_hotel_prop} = <<EOF;
+create table test_hotel_prop (
+ prop_id integer not null AUTOINCREMENT,
+ prop_cd char(12) not null,
+ prop_nm varchar(99) not null,
+ address varchar(255) null,
+ chain_cd char(2) null,
+ state char(2) null,
+ country char(2) null,
+ primary key (prop_id)
+)SUFFIX
+EOF
+$table_index{test_hotel_prop} = [
+ "create unique index test_hotel_prop_ak1 on test_hotel_prop (prop_cd)",
+];
+$table_autoid_column{test_hotel_prop} = "prop_id";
+$table_data{test_hotel_prop} = [
+ "insert into test_hotel_prop
(prop_cd,prop_nm,address,chain_cd,state,country) values ('9128' ,'Hilton New
York' ,'1335 Avenue Of The Americas, New York, NY
10019','HH','NY','US')",
+ "insert into test_hotel_prop
(prop_cd,prop_nm,address,chain_cd,state,country) values ('13111','Marriott
Marquis NYC' ,'1535 BROADWAY, New York, NY 10036'
,'MC','NY','US')",
+ "insert into test_hotel_prop
(prop_cd,prop_nm,address,chain_cd,state,country) values ('668' ,'Sheraton New
York Hotel&Towers','811 7th Ave, New York, NY 10019'
,'SI','NY','US')",
+ "insert into test_hotel_prop
(prop_cd,prop_nm,address,chain_cd,state,country) values ('3391' ,'Crowne Plaza
Time Sq Manhattan','1605 Broadway, Manhattan, NY 10019'
,'CP','NY','US')",
+ "insert into test_hotel_prop
(prop_cd,prop_nm,address,chain_cd,state,country) values ('962' ,'Grand Hyatt
New York' ,'Park Ave At Grand Central, New York, NY 10017'
,'HY','NY','US')",
+];
+
+$table_schema{test_hotel_bkg} = <<EOF;
+create table test_hotel_bkg (
+ bkg_id integer not null AUTOINCREMENT,
+ conf_num varchar(24) not null,
+ bkg_dt date not null,
+ person_id integer not null,
+ prop_id integer not null,
+ arv_dt date not null,
+ dpt_dt date not null,
+ cancel_dt date null,
+ rooms integer not null,
+ rev_amt_usd float not null,
+ primary key (bkg_id)
+)SUFFIX
+EOF
+$table_index{test_hotel_bkg} = [
+ "create unique index test_hotel_bkg_ak1 on test_hotel_bkg (conf_num,
bkg_dt)",
+];
+$table_autoid_column{test_hotel_bkg} = "bkg_id";
+$table_data{test_hotel_bkg} = [
+ "insert into test_hotel_bkg values
(null,'AAA001','2008-11-01',1,1,'2008-12-01','2008-12-04',null,1,300)",
+];
+
+sub create_table {
+ &App::sub_entry if ($App::trace);
+ my ($rep, $table) = @_;
+ my $dbh = $rep->{dbh};
+
+ my $ddl = $table_schema{$table} || die "Schema not defined for table
[$table]\n";
+ my $dbtype = $App::options{dbtype} || "mysql";
+
+ my $autoincrement = "";
+ my $suffix = "";
+ if ($dbtype eq "mysql") {
+ $autoincrement = " auto_increment";
+ $suffix = " ENGINE=InnoDB DEFAULT CHARSET=latin1";
+ }
+
+ my $double_type = ($dbtype eq "mysql") ? 'double' : 'float';
+ my $datetime_type = ($dbtype eq "mysql") ? 'datetime' : 'date';
+
+ $ddl =~ s/AUTOINCREMENT/$autoincrement/g;
+ $ddl =~ s/SUFFIX/$suffix/g;
+ $ddl =~ s/DOUBLE/$double_type/g;
+ $ddl =~ s/DATETIME/$datetime_type/g;
+ if ($dbtype eq "oracle") {
+ $ddl =~ s/varchar\(/varchar2\(/ig;
+ }
+ print "DEBUG:\n$ddl\n" if ($App::options{debug_sql});
+ my $rc = $dbh->do($ddl);
+ print "DEBUG: rc=[$rc] errstr=[$DBI::errstr]\n" if
($App::options{debug_sql});
+
+ my $ddls = $table_index{$table};
+ if ($ddls) {
+ foreach $ddl (@$ddls) {
+ $dbh->do($ddl);
+ }
+ }
+
+ my ($autoid_column);
+ if ($dbtype eq "oracle") {
+ $autoid_column = $table_autoid_column{$table};
+ if ($autoid_column) {
+ $ddl = <<EOF;
+create sequence ${table}_seq start with 1 increment by 1 nomaxvalue nocycle
cache 200
+EOF
+ $dbh->do($ddl);
+ $ddl = <<EOF;
+CREATE OR REPLACE TRIGGER tib_$table
+BEFORE INSERT ON $table
+FOR EACH ROW
+WHEN (new.$autoid_column IS NULL or new.$autoid_column = 0)
+BEGIN
+ SELECT ${table}_seq.NEXTVAL
+ INTO :new.$autoid_column
+ FROM DUAL;
+END tib_${table};
+EOF
+ $dbh->do($ddl);
+ }
+ }
+
+ &App::sub_exit() if ($App::trace);
+}
+
+sub drop_table {
+ &App::sub_entry if ($App::trace);
+ my ($rep, $table) = @_;
+ my $dbh = $rep->{dbh};
+
+ my $dbtype = $App::options{dbtype} || "mysql";
+
+ print "DEBUG:\ndrop table $table\n" if ($App::options{debug_sql});
+ my ($rc);
+ eval { $rc = $dbh->do("drop table $table"); };
+ print "DEBUG: rc=[$rc] errstr=[$DBI::errstr]\n" if
($App::options{debug_sql});
+ if ($dbtype eq "oracle") {
+ eval { $dbh->do("drop sequence ${table}_seq"); };
+ }
+
+ &App::sub_exit() if ($App::trace);
+}
+
+sub populate_table {
+ &App::sub_entry if ($App::trace);
+ my ($rep, $table) = @_;
+ my $dbh = $rep->{dbh};
+ my $data = $table_data{$table};
+ if ($data) {
+ foreach my $sql (@$data) {
+ $dbh->do($sql);
+ }
+ }
+ &App::sub_exit() if ($App::trace);
+}
+
+1;
Added: p5ee/trunk/App-Moose/t/SessionObject.t
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/t/SessionObject.t Tue Jun 22 20:50:54 2010
@@ -0,0 +1,136 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+use App::Options (
+ options => [qw(dbdriver dbclass dbhost dbname dbuser dbpass)],
+ option => {
+ dbclass => { default => "App::Repository::MySQL", },
+ dbdriver => { default => "mysql", },
+ dbhost => { default => "localhost", },
+ dbname => { default => "test", },
+ dbuser => { default => "", },
+ dbpass => { default => "", },
+ },
+);
+
+use Test::More qw(no_plan);
+use lib "../App-Context/lib";
+use lib "../../App-Context/lib";
+use lib "lib";
+use lib "../lib";
+use lib ".";
+use lib "t";
+
+use App;
+
+my ($context);
+
+$context = App->context(
+ conf_file => "",
+ sessionobject_class => $App::options{sessionobject_class},
+);
+
+sub verify_session_object {
+ my ($obj, $name, $stateless, $anonymous, $lang) = @_;
+ my $obj_name = $obj->{name};
+ if (!$obj_name) {
+ ok($obj_name, "object has a name [$obj_name]");
+ }
+ else {
+ is($obj->get("context"), $context, "[$name]->{context}
[$context] is set (accessible with get())");
+ is($obj->context, $context, "[$name]->{context}
[$context] is set (accessible with accessor)");
+ is($obj->{context}, $context, "[$name]->{context}
[$context] is set (accessible directly)");
+ is($obj->get("name"), $name, "[$name]->{name} [$name]
is set (accessible with get())");
+ is($obj->name, $name, "[$name]->{name} [$name]
is set (accessible with accessor)");
+ is($obj->{name}, $name, "[$name]->{name} [$name]
is set (accessible directly)");
+ is($obj->get("stateless"), $stateless, "[$name]->{stateless}
[$stateless] is set (accessible with get())");
+ is($obj->stateless, $stateless, "[$name]->{stateless}
[$stateless] is set (accessible with accessor)");
+ is($obj->{stateless}, $stateless, "[$name]->{stateless}
[$stateless] is set (accessible directly)");
+ is($obj->get("anonymous"), $anonymous, "[$name]->{anonymous}
[$anonymous] is set (accessible with get())");
+ is($obj->anonymous, $anonymous, "[$name]->{anonymous}
[$anonymous] is set (accessible with accessor)");
+ is($obj->{anonymous}, $anonymous, "[$name]->{anonymous}
[$anonymous] is set (accessible directly)");
+ is($obj->get("lang"), $lang, "[$name]->{lang} [$lang]
is set (accessible with get())");
+ is($obj->lang, $lang, "[$name]->{lang} [$lang]
is set (accessible with accessor)");
+ is($obj->{lang}, $lang, "[$name]->{lang} [$lang]
is set (accessible directly)");
+ }
+}
+
+{
+ my $session_object = $context->service("SessionObject");
+
+ my $options = $context->{options};
+ my $session_store = $context->{session}{store};
+ my $session_cache = $context->{session}{cache};
+
+ ok(defined $session_object, "[default] constructor ok");
+ isa_ok($session_object, "App::Moose::SessionObject", "[default] right
class");
+ is($session_object->service_type(), "SessionObject", "[default] right
service type");
+ my $dump = $session_object->dump(1);
+ ok($dump =~ /^\$VAR1 = bless.*App::Moose::SessionObject/s, "dump formatted
ok"); # NOTE: a Moose dump() is a slightly different format from an
App::Service dump()
+ #print STDERR $dump;
+ &verify_session_object($session_object, "default", 0, 0, "en");
+
+ is($session_cache->{SessionObject}{default}, $session_object, "Object is
stored in the session cache [$session_cache->{SessionObject}{default} =
$session_object]");
+ my $so2 = $context->session_object();
+ is($so2, $session_object, "Second attempt gets the same object [$so2 =
$session_object]");
+
+ $so2->set("foo","bar");
+ is($session_object->get("foo"), "bar", "Got value on one object which was
set on another");
+ is($context->so_get("foo"), "bar", "Got same value from the Context");
+ # NOTE: The following two cases are INTERNAL (not part of the published
API)
+ is($session_cache->{SessionObject}{default}{foo}, "bar", "Got same value
from the internal cache of the Context");
+ is($session_store->{SessionObject}{default}{foo}, "bar", "Got same value
from the internal store of the Context");
+
+ my ($foo2);
+ $so2->set("{foo2}{subfoo}","bar");
+ is($session_object->get("{foo2}{subfoo}"), "bar", "Got deep value on one
object which was set on another");
+ $foo2 = $session_object->get("foo2");
+ is($foo2->{subfoo}, "bar", "Got same deep value from the object in two
steps");
+ is($context->so_get("{foo2}{subfoo}"), "bar", "Got same deep value from
the Context");
+ is($context->so_get("default", "{foo2}{subfoo}"), "bar", "Got same deep
value from the Context (using name and attribute)");
+ $foo2 = $context->so_get("foo2");
+ is($foo2->{subfoo}, "bar", "Got same deep value from the Context in two
steps");
+ # NOTE: The following two cases are INTERNAL (not part of the published
API)
+ is($session_cache->{SessionObject}{default}{foo2}{subfoo}, "bar", "Got
same deep value from the internal cache of the Context");
+ is($session_store->{SessionObject}{default}{foo2}{subfoo}, "bar", "Got
same deep value from the internal store of the Context");
+
+ # An anonymous SessionObject for a name that already exists
+ my $so_anon = $context->session_object("default", anonymous => 1, lang =>
"fr");
+ ok($so_anon ne $so2, "Anonymous default SessionObject [$so_anon] differs
from Stateful default SessionObject [$so2]");
+ &verify_session_object($so_anon, "default", 1, 1, "fr");
+ &verify_session_object($session_object, "default", 0, 0, "en");
+
+ # An anonymous SessionObject for a name that does not already exist
+ $so_anon = $context->session_object("anon", anonymous => 1);
+ &verify_session_object($so_anon, "anon", 1, 1, "en");
+ # NOTE: The following two cases are INTERNAL (not part of the published
API)
+ is($session_cache->{SessionObject}{anon}, undef, "Anonymous SessionObject
does not affect the internal cache of the Context");
+ is($session_store->{SessionObject}{anon}, undef, "Anonymous SessionObject
does not affect the internal store of the Context");
+ $so_anon->set("foo", "baz");
+ is($so_anon->{foo}, "baz", "Anonymous SessionObject set() works");
+ is($so_anon->get("foo"), "baz", "Anonymous SessionObject get() works");
+ is($session_cache->{SessionObject}{anon}, undef, "Anonymous SessionObject
still does not affect the internal cache of the Context");
+ is($session_store->{SessionObject}{anon}, undef, "Anonymous SessionObject
still does not affect the internal store of the Context");
+
+ # Another anonymous SessionObject for a name that does not already exist
+ my $so_anon2 = $context->session_object("anon", anonymous => 1);
+ &verify_session_object($so_anon2, "anon", 1, 1, "en");
+ ok($so_anon2 ne $so_anon, "Anonymous SessionObject [$so_anon2] differs
from earlier Anonymous SessionObject [$so_anon]");
+
+ # A stateless SessionObject
+ my $so_stateless = $context->session_object("state_less", stateless => 1,
foo => "bar");
+ &verify_session_object($so_stateless, "state_less", 1, 0, "en");
+ # NOTE: The following two cases are INTERNAL (not part of the published
API)
+ is($session_cache->{SessionObject}{state_less}, $so_stateless, "Stateless
SessionObject does affect the internal cache of the Context");
+ is($session_store->{SessionObject}{state_less}, undef, "Stateless
SessionObject does not affect the internal store of the Context");
+ is($so_stateless->{foo}, "bar", "Stateless SessionObject retains
unexpected initializers");
+ $so_stateless->set("foo", "baz");
+ is($so_stateless->{foo}, "baz", "Stateless SessionObject set() works");
+ is($so_stateless->get("foo"), "baz", "Stateless SessionObject get()
works");
+ is($session_cache->{SessionObject}{state_less}{foo}, "baz", "Stateless
SessionObject still does affect the internal cache of the Context");
+ is($session_store->{SessionObject}{state_less}, undef, "Stateless
SessionObject still does not affect the internal store of the Context");
+}
+
+exit 0;
+
Added: p5ee/trunk/App-Moose/t/app.conf.sample
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Moose/t/app.conf.sample Tue Jun 22 20:50:54 2010
@@ -0,0 +1,29 @@
+
+dbtype = mysql
+#dbtype = oracle
+
+sessionobject_class = App::Moose::SessionObject
+repositoryobject_class = App::Moose::RepositoryObject
+
+[dbtype=oracle]
+dbclass = App::Repository::Oracle
+dbhost = sampleoraclehost
+dbname = sampledb
+dbuser = scott
+dbpass = tiger
+dbschema = scott
+oracle_home = /usr/app/oracle/product/11.1.0/client
+ENV{ORACLE_HOME} = /usr/app/oracle/product/11.1.0/client
+
+[dbtype=mysql]
+dbclass = App::Repository::MySQL
+dbdriver = mysql
+dbhost = samplemysqlhost
+dbname = test
+dbuser = ralph
+dbpass = ocelot
+
+[ALL]
+flush_imports = 1
+prefix = $ENV{PREFIX}
+