Author: spadkins
Date: Tue Sep 11 11:04:00 2007
New Revision: 9934
Modified:
p5ee/trunk/App-Repository/lib/App/Repository.pm
p5ee/trunk/App-Repository/lib/App/SessionObject/RepositoryObjectDomain.pm
p5ee/trunk/App-Repository/lib/App/SessionObject/RepositoryObjectSet.pm
p5ee/trunk/App-Repository/t/DBI-repobjectdom.t
p5ee/trunk/App-Repository/t/DBI-repobjectset.t
Log:
added support for temporary objects sets and object domains
Modified: p5ee/trunk/App-Repository/lib/App/Repository.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository.pm (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository.pm Tue Sep 11 11:04:00 2007
@@ -1375,6 +1375,125 @@
return($hash_of_hashes);
}
+###########################################################################
+# Indexes
+###########################################################################
+
+# $self->get_index([EMAIL PROTECTED], [EMAIL PROTECTED], \%options);
+sub get_index {
+ &App::sub_entry if ($App::trace);
+ my ($self, $rows, $key_columns, $options) = @_;
+
+ my ($key);
+ my $index = {};
+ my $is_array_of_arrays = ($#$rows > -1 && ref($rows->[0]) eq "ARRAY") ? 1
: 0;
+ if ($is_array_of_arrays) {
+ # TBD
+ }
+ else {
+ foreach my $row (@$rows) {
+ $key = join(",", @[EMAIL PROTECTED]);
+ if ($index->{$key}) {
+ push(@{$index->{$key}}, $row);
+ }
+ else {
+ $index->{$key} = [ $row ];
+ }
+ }
+ }
+ &App::sub_exit($index) if ($App::trace);
+ return($index);
+}
+
+# $self->get_unique_index([EMAIL PROTECTED], [EMAIL PROTECTED], \%options);
+sub get_unique_index {
+ &App::sub_entry if ($App::trace);
+ my ($self, $rows, $key_columns, $options) = @_;
+
+ my ($key);
+ my $unique_index = {};
+ my $is_array_of_arrays = ($#$rows > -1 && ref($rows->[0]) eq "ARRAY") ? 1
: 0;
+ if ($is_array_of_arrays) {
+ # TBD
+ }
+ else {
+ foreach my $row (@$rows) {
+ $key = join(",", @[EMAIL PROTECTED]);
+ $unique_index->{$key} = $row;
+ }
+ }
+ &App::sub_exit($unique_index) if ($App::trace);
+ return($unique_index);
+}
+
+# $self->get_column_values([EMAIL PROTECTED], $key_column, \%options);
+sub get_column_values {
+ &App::sub_entry if ($App::trace);
+ my ($self, $rows, $key_column, $options) = @_;
+
+ my $values = [];
+ my (%value_seen, $value);
+ my $is_array_of_arrays = ($#$rows > -1 && ref($rows->[0]) eq "ARRAY") ? 1
: 0;
+ if ($is_array_of_arrays) {
+ # TBD
+ }
+ else {
+ foreach my $row (@$rows) {
+ $value = $row->{$key_column};
+ if (!defined $value_seen{$value}) {
+ $value_seen{$value} = 1;
+ push(@$values, $value);
+ }
+ }
+ }
+ &App::sub_exit($values) if ($App::trace);
+ return($values);
+}
+
+sub create_temporary_object_domain {
+ &App::sub_entry if ($App::trace);
+ my ($self, $params, $objects_by_table, $class) = @_;
+ $params ||= {};
+ $objects_by_table ||= {};
+ $class ||= "App::SessionObject::RepositoryObjectDomain";
+ my @args = (
+ class => $class,
+ params => $params,
+ temporary => 1,
+ );
+ my $context = $self->{context};
+ my $object_domain = $context->session_object("temporary", @args);
+ my ($object_set, $objects);
+ foreach my $table (keys %$objects_by_table) {
+ $object_set = $object_domain->get_object_set($table);
+ $objects = $objects_by_table->{$table};
+ $object_set->set_objects($objects_by_table->{$table});
+ }
+ &App::sub_exit($object_domain) if ($App::trace);
+ return($object_domain);
+}
+
+sub create_temporary_object_set {
+ &App::sub_entry if ($App::trace);
+ my ($self, $table, $params, $columns, $objects, $class) = @_;
+ if (!$columns && $#$objects > -1) {
+ $columns = [ sort keys %{$objects->[0]} ];
+ }
+ $class ||= "App::SessionObject::RepositoryObjectSet";
+ my @args = (
+ class => $class,
+ table => $table,
+ columns => $columns,
+ temporary => 1,
+ );
+ my $context = $self->{context};
+ my $object_set = $context->session_object("temporary", @args);
+ $object_set->set_params($params);
+ $object_set->{objects} = $objects;
+ &App::sub_exit($object_set) if ($App::trace);
+ return($object_set);
+}
+
#############################################################################
# set_hash()
#############################################################################
Modified:
p5ee/trunk/App-Repository/lib/App/SessionObject/RepositoryObjectDomain.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/SessionObject/RepositoryObjectDomain.pm
(original)
+++ p5ee/trunk/App-Repository/lib/App/SessionObject/RepositoryObjectDomain.pm
Tue Sep 11 11:04:00 2007
@@ -43,27 +43,29 @@
sub _clear_cache {
&App::sub_entry if ($App::trace);
my ($self, $table) = @_;
- my (@tables);
- if ($table) {
- @tables = ($table);
- }
- else {
- my $object_set_def = $self->{table};
- if (ref($object_set_def) eq "HASH") {
- foreach my $table (keys %$object_set_def) {
- if ($object_set_def->{$table}{gotten}) {
- delete $object_set_def->{$table}{gotten};
- push(@tables, $table);
+ if (!$self->{temporary}) {
+ my (@tables);
+ if ($table) {
+ @tables = ($table);
+ }
+ else {
+ my $object_set_def = $self->{table};
+ if (ref($object_set_def) eq "HASH") {
+ foreach my $table (keys %$object_set_def) {
+ if ($object_set_def->{$table}{gotten}) {
+ delete $object_set_def->{$table}{gotten};
+ push(@tables, $table);
+ }
}
}
}
- }
- my $context = $self->{context};
- my ($object_set_name, $object_set);
- foreach my $table (@tables) {
- $object_set_name = $self->{table}{$table}{name} ||
"$self->{name}-$table";
- $object_set = $context->session_object($object_set_name);
- $object_set->_clear_cache();
+ my $context = $self->{context};
+ my ($object_set_name, $object_set);
+ foreach my $table (@tables) {
+ $object_set_name = $self->{table}{$table}{name} ||
"$self->{name}-$table";
+ $object_set = $context->session_object($object_set_name);
+ $object_set->_clear_cache();
+ }
}
&App::sub_exit() if ($App::trace);
}
@@ -90,25 +92,36 @@
$self->{table}{$table} = $tabledef;
}
- # object-sets can be named something other than the default name.
- my $object_set_name = $tabledef->{name} || "$self->{name}-$table";
+ my $object_set = $tabledef->{object_set};
+ if (!$object_set) {
+ my $new_args = $tabledef->{new_args} || {};
+ my ($object_set_name);
+ if ($self->{temporary}) {
+ $object_set_name = $tabledef->{name} || "temporary";
+ $new_args->{temporary} = 1;
+ }
+ else {
+ # object-sets can be named something other than the default name.
+ $object_set_name = $tabledef->{name} || "$self->{name}-$table";
+ }
- # object-sets can have special arguments passed to them on initial
construction
- my $new_args = $tabledef->{new_args} || {};
- if (!$new_args->{class}) {
- $new_args->{class} = "App::SessionObject::RepositoryObjectSet";
- }
- # object-sets can refer to physical tables which are different from the
object-set name.
- if (!$new_args->{table}) {
- $new_args->{table} = $tabledef->{table} || $table;
- }
- # object-sets can have a select set of parameters (i.e. a subset of all
known to the object-domain)
- if (!$new_args->{params}) {
- my $new_params = $tabledef->{params} || $domain_params || {};
- $new_args->{params} = { %$new_params };
+ # object-sets can have special arguments passed to them on initial
construction
+ if (!$new_args->{class}) {
+ $new_args->{class} = "App::SessionObject::RepositoryObjectSet";
+ }
+ # object-sets can refer to physical tables which are different from
the object-set name.
+ if (!$new_args->{table}) {
+ $new_args->{table} = $tabledef->{table} || $table;
+ }
+ # object-sets can have a select set of parameters (i.e. a subset of
all known to the object-domain)
+ if (!$new_args->{params}) {
+ my $new_params = $tabledef->{params} || $domain_params || {};
+ $new_args->{params} = { %$new_params };
+ }
+ $object_set = $context->session_object($object_set_name, %$new_args);
+ $tabledef->{object_set} = $object_set;
+ $tabledef->{gotten} = 1;
}
- my $object_set = $context->session_object($object_set_name, %$new_args);
- $tabledef->{gotten} = 1;
if ($tabledef->{params}) {
my (%object_set_param_values, $domain_param);
@@ -123,6 +136,7 @@
else {
$object_set->set_params($domain_params);
}
+
&App::sub_exit($object_set) if ($App::trace);
return($object_set);
}
Modified: p5ee/trunk/App-Repository/lib/App/SessionObject/RepositoryObjectSet.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/SessionObject/RepositoryObjectSet.pm
(original)
+++ p5ee/trunk/App-Repository/lib/App/SessionObject/RepositoryObjectSet.pm
Tue Sep 11 11:04:00 2007
@@ -54,7 +54,7 @@
my $table = $self->{table} || die "table not defined";
$self->_clear_cache_if_auto_params_changed() if ($self->{auto_params});
# sets params from auto_params
$self->_clear_cache_if_auto_columns_changed() if ($self->{auto_columns});
# sets columns from auto_columns
- if (!$self->{columns}) {
+ if (!$self->{columns} && !$self->{temporary}) {
my $context = $self->{context};
my $repname = $self->{repository};
my $rep = $context->repository($repname);
@@ -63,16 +63,44 @@
&App::sub_exit() if ($App::trace);
}
+# This should only be relevant for temporary
+sub set_objects {
+ &App::sub_entry if ($App::trace);
+ my ($self, $objects, $columns) = @_;
+ if ($self->{temporary}) {
+ $self->{objects} = $objects;
+ delete $self->{index};
+ delete $self->{unique_index};
+ delete $self->{column_values};
+ delete $self->{max_age_time};
+ delete $self->{ext_summary};
+ delete $self->{summary};
+ if ($columns) {
+ $self->{columns} = $columns;
+ }
+ elsif (!$self->{columns} && $#$objects > -1) {
+ $columns = [ sort keys %{$objects->[0]} ];
+ $self->{columns} = $columns;
+ }
+ }
+ else {
+ die "set_objects() is not allowed on a non-temporary object set";
+ }
+ &App::sub_exit() if ($App::trace);
+}
+
sub _clear_cache {
&App::sub_entry if ($App::trace);
my ($self) = @_;
- delete $self->{objects};
- delete $self->{index};
- delete $self->{unique_index};
- delete $self->{column_values};
- delete $self->{max_age_time};
- delete $self->{ext_summary};
- delete $self->{summary};
+ if (!$self->{temporary}) {
+ delete $self->{objects};
+ delete $self->{index};
+ delete $self->{unique_index};
+ delete $self->{column_values};
+ delete $self->{max_age_time};
+ delete $self->{ext_summary};
+ delete $self->{summary};
+ }
&App::sub_exit() if ($App::trace);
}
@@ -137,17 +165,6 @@
&App::sub_exit() if ($App::trace);
}
-# The RepositoryObjectSet should know its table at construction time.
-# It should never allow the table to be set afterwards.
-#sub set_table {
-# &App::sub_entry if ($App::trace);
-# my ($self, $table, $repository) = @_;
-# $self->{repository} = $repository || "default";
-# $self->{table} = $table;
-# $self->_clear_cache();
-# &App::sub_exit() if ($App::trace);
-#}
-
sub set_params {
&App::sub_entry if ($App::trace);
my ($self, $params) = @_;
@@ -207,16 +224,23 @@
my ($self) = @_;
my $objects = $self->{objects};
if (!$objects) {
- my $context = $self->{context};
- my $repname = $self->{repository};
- my $rep = $context->repository($repname);
- my $table = $self->{table} || die "table not defined";
- my $params = $self->{params} || {};
- my $columns = $self->{columns};
- $params = {%$params};
- $objects = $rep->get_objects($table, $params, $columns,
{extend_columns => 1});
- $self->{objects} = $objects;
- $self->{max_age_time} = time();
+ if ($self->{temporary}) {
+ $objects = [];
+ }
+ else {
+ my $context = $self->{context};
+ my $repname = $self->{repository};
+ my $rep = $context->repository($repname);
+ my $table = $self->{table} || die "table not defined";
+ my $params = $self->{params} || {};
+ my $columns = $self->{columns};
+ # Make a copy of $params so that if $db->get_objects() changes
them,
+ # it does not affect the cacheing aspects of the object set.
+ $params = {%$params};
+ $objects = $rep->get_objects($table, $params, $columns,
{extend_columns => 1});
+ $self->{objects} = $objects;
+ $self->{max_age_time} = time();
+ }
}
&App::sub_exit($objects) if ($App::trace);
return($objects);
Modified: p5ee/trunk/App-Repository/t/DBI-repobjectdom.t
==============================================================================
--- p5ee/trunk/App-Repository/t/DBI-repobjectdom.t (original)
+++ p5ee/trunk/App-Repository/t/DBI-repobjectdom.t Tue Sep 11 11:04:00 2007
@@ -158,9 +158,101 @@
$objset->get_unique_index(["first_name"]);
my $object = $objset->get_object("stephen",["first_name"]);
ok($object->{age} == 39, "got stephen object (age 39)");
+
+ $rep->_disconnect();
+ my $hashes = [
+ { person_id => 1, age => 39, name => "stephen", gender => "M", state
=> "GA", num_kids => 3, },
+ { person_id => 2, age => 37, name => "susan", gender => "F", state
=> "GA", num_kids => 3, },
+ { person_id => 3, age => 6, name => "maryalice", gender => "F", state
=> "GA", num_kids => 0, },
+ { person_id => 4, age => 3, name => "paul", gender => "M", state
=> "GA", num_kids => 0, },
+ { person_id => 5, age => 1, name => "christine", gender => "F", state
=> "GA", num_kids => undef, },
+ { person_id => 6, age => 45, name => "tim", gender => "M", state
=> "GA", num_kids => 2, },
+ { person_id => 7, age => 39, name => "keith", gender => "M", state
=> "GA", num_kids => 4, },
+ ];
+
+ #$App::trace = 1;
+
+ my $new_object_domain = $rep->create_temporary_object_domain({fee =>
1,fie => 2,foe => "fum"},{test_person => $hashes,test_person2 => $hashes});
+ my $new_object_domain2 = $rep->create_temporary_object_domain({fee =>
1,fie => 2,foe => "fum"},{test_person => $hashes,test_person2 => $hashes});
+ is(ref($new_object_domain), "App::SessionObject::RepositoryObjectDomain",
"Correct class (RepositoryObjectDomain)");
+ $new_object_domain2->{foo} = "bar";
+ ok(! defined $new_object_domain->{foo}, "new_object_domain()s (temporary)
don't share storage");
+ ok($new_object_domain->{temporary}, "new_object_domain (temporary) has
{temporary} attribute set");
+
+ my $new_object_set = $new_object_domain->get_object_set("test_person2");
+ my $new_object_set2 = $new_object_domain->get_object_set("test_person");
+ #my $new_object_set3 = $new_object_domain->get_object_set("test_person3");
+ is(ref($new_object_set), "App::SessionObject::RepositoryObjectSet",
"Correct class (RepositoryObjectSet)");
+
+ $new_object_set->{foo} = "bar";
+ ok(! defined $new_object_set2->{foo}, "new_object_set()s (temporary) don't
share storage");
+ my $hashes2 = $new_object_set->get_objects();
+ is($hashes2, $hashes, "Got same exact reference to set of objects");
+ is($#$hashes2, $#$hashes, "Got same exact number of objects");
+ is($rep, $new_object_set->get_repository(), "Got same exact reference to a
repository");
+ is("test_person2", $new_object_set->get_table(), "Got same exact table");
+ my $columns = $new_object_set->get_columns();
+ is($#$columns, 5, "Got 6 columns");
+ is($columns->[0], "age", "Got 1st column as age");
+
+ $index = $new_object_set->get_index(["gender"]);
+ my $females = $index->{F};
+ is($#$females, 2, "Got 3 females");
+ is($females->[0]{name}, "susan", "Got susan as 1st female");
+
+ $index = $new_object_set->get_index(["state"]);
+ my $georgians = $index->{GA};
+ is($#$georgians, 6, "Got 7 georgians");
+ is($georgians->[3]{name}, "paul", "Got paul as 4th georgian");
+
+ $index = $new_object_set->get_index(["gender","age"]);
+ my $m39s = $index->{"M,39"};
+ is($#$m39s, 1, "Got 2 m39s");
+ is($m39s->[1]{name}, "keith", "Got keith as 2nd m39");
+
+ $index = $new_object_set->get_unique_index(["gender","age"]);
+ my $m39 = $index->{"M,39"};
+ ok($m39, "Got an m39");
+ is($m39->{name}, "keith", "Got keith as the last (assumed unique) m39");
+
+ my $summaries = $new_object_set->get_summary([]);
+ is(ref($summaries), "HASH", "Got summary hash");
+ is($summaries->{""}{num_kids}, 12, "Got 12 total kids");
+
+ my $ext_summary = $new_object_set->get_ext_summary([]);
+ is(ref($ext_summary), "HASH", "Got summary hash");
+ is($ext_summary->{""}{num_kids}{sum}, 12, "Got sum 12 kids");
+ is($ext_summary->{""}{num_kids}{average}, 2, "Got average 2 kids");
+ is($ext_summary->{""}{num_kids}{count}, 6, "Got count 6 kids");
+ is(ref($ext_summary->{""}{num_kids}{distinct}), "HASH", "Got distinct
hashref");
+ my $distinct_values = [ keys %{$ext_summary->{""}{num_kids}{distinct}} ];
+ is($#$distinct_values, 3, "Got distinct 4 kids");
+ is($ext_summary->{""}{num_kids}{min}, 0, "Got min 2 kids");
+ is($ext_summary->{""}{num_kids}{max}, 4, "Got max 2 kids");
+ is($ext_summary->{""}{num_kids}{sum_sq}, 38, "Got sum_sq 2 kids");
+ is($ext_summary->{""}{num_kids}{median}, 2.5, "Got median 2 kids");
+ ok($ext_summary->{""}{num_kids}{stddev} >= 1.6733200 &&
$ext_summary->{""}{num_kids}{stddev} <= 1.6733201, "Got stddev 1.673320 kids");
+ is($ext_summary->{""}{num_kids}{mode}, 2, "Got mode 2 kids");
+
+ my $column_values = $new_object_set->get_column_values("gender");
+ is($#$column_values, 1, "Got 2 column_values for gender");
+ is($column_values->[0], "M", "Got M as first gender value");
+ is($column_values->[1], "F", "Got F as second gender value");
+
+ $object = $new_object_set->get_object(1, ["person_id"]);
+ is($object->{name}, "stephen", "Got stephen as person_id 1");
+ $object = $new_object_set->get_object("39,keith", ["age","name"]);
+ is($object->{name}, "keith", "Got keith as person_id named keith age 39");
+
+ $females = $new_object_set->get_objects("F",["gender"]);
+ is($#$females, 2, "Got 3 females (without explicit use of an index)");
+ is($females->[0]{name}, "susan", "Got susan as 1st female (without
explicit use of an index)");
+
+ ok(! defined $rep->{dbh}, "Never reconnected to the database");
}
{
+ $rep->_connect();
my $dbh = $rep->{dbh};
$dbh->do("drop table test_person");
}
Modified: p5ee/trunk/App-Repository/t/DBI-repobjectset.t
==============================================================================
--- p5ee/trunk/App-Repository/t/DBI-repobjectset.t (original)
+++ p5ee/trunk/App-Repository/t/DBI-repobjectset.t Tue Sep 11 11:04:00 2007
@@ -167,9 +167,93 @@
is($objects->[0]{age}, 40, "max_age: no refresh by overriding small
max_age on objset with large max_age");
$objects = $objset->get_objects(); # NOTE: we get the
update.
is($objects->[0]{age}, 41, "max_age: refresh with max_age on objset");
+
+ $rep->_disconnect();
+ my $hashes = [
+ { person_id => 1, age => 39, name => "stephen", gender => "M", state
=> "GA", num_kids => 3, },
+ { person_id => 2, age => 37, name => "susan", gender => "F", state
=> "GA", num_kids => 3, },
+ { person_id => 3, age => 6, name => "maryalice", gender => "F", state
=> "GA", num_kids => 0, },
+ { person_id => 4, age => 3, name => "paul", gender => "M", state
=> "GA", num_kids => 0, },
+ { person_id => 5, age => 1, name => "christine", gender => "F", state
=> "GA", num_kids => undef, },
+ { person_id => 6, age => 45, name => "tim", gender => "M", state
=> "GA", num_kids => 2, },
+ { person_id => 7, age => 39, name => "keith", gender => "M", state
=> "GA", num_kids => 4, },
+ ];
+ my $new_object_set = $rep->create_temporary_object_set("test_person",
{fee => 1, fie => 2, foe => "fum"}, undef, $hashes);
+ my $new_object_set2 = $rep->create_temporary_object_set("test_person",
{fee => 1, fie => 2, foe => "fum"}, undef, $hashes);
+ is(ref($new_object_set), "App::SessionObject::RepositoryObjectSet",
"Correct class (RepositoryObjectSet)");
+ ok($new_object_set->{temporary}, "new_object_set (temporary) has
{temporary} attribute set");
+
+ #$App::trace = 1;
+
+ $new_object_set->{foo} = "bar";
+ ok(! defined $new_object_set2->{foo}, "new_object_set()s (temporary) don't
share storage");
+ my $hashes2 = $new_object_set->get_objects();
+ is($hashes2, $hashes, "Got same exact reference to set of objects");
+ is($#$hashes2, $#$hashes, "Got same exact number of objects");
+ is($rep, $new_object_set->get_repository(), "Got same exact reference to a
repository");
+ is("test_person", $new_object_set->get_table(), "Got same exact table");
+ my $columns = $new_object_set->get_columns();
+ is($#$columns, 5, "Got 6 columns");
+ is($columns->[0], "age", "Got 1st column as age");
+
+ $index = $new_object_set->get_index(["gender"]);
+ my $females = $index->{F};
+ is($#$females, 2, "Got 3 females");
+ is($females->[0]{name}, "susan", "Got susan as 1st female");
+
+ $index = $new_object_set->get_index(["state"]);
+ my $georgians = $index->{GA};
+ is($#$georgians, 6, "Got 7 georgians");
+ is($georgians->[3]{name}, "paul", "Got paul as 4th georgian");
+
+ $index = $new_object_set->get_index(["gender","age"]);
+ my $m39s = $index->{"M,39"};
+ is($#$m39s, 1, "Got 2 m39s");
+ is($m39s->[1]{name}, "keith", "Got keith as 2nd m39");
+
+ $index = $new_object_set->get_unique_index(["gender","age"]);
+ my $m39 = $index->{"M,39"};
+ ok($m39, "Got an m39");
+ is($m39->{name}, "keith", "Got keith as the last (assumed unique) m39");
+
+ my $summaries = $new_object_set->get_summary([]);
+ is(ref($summaries), "HASH", "Got summary hash");
+ is($summaries->{""}{num_kids}, 12, "Got 12 total kids");
+
+ my $ext_summary = $new_object_set->get_ext_summary([]);
+ is(ref($ext_summary), "HASH", "Got summary hash");
+ is($ext_summary->{""}{num_kids}{sum}, 12, "Got sum 12 kids");
+ is($ext_summary->{""}{num_kids}{average}, 2, "Got average 2 kids");
+ is($ext_summary->{""}{num_kids}{count}, 6, "Got count 6 kids");
+ is(ref($ext_summary->{""}{num_kids}{distinct}), "HASH", "Got distinct
hashref");
+ my $distinct_values = [ keys %{$ext_summary->{""}{num_kids}{distinct}} ];
+ is($#$distinct_values, 3, "Got distinct 4 kids");
+ is($ext_summary->{""}{num_kids}{min}, 0, "Got min 2 kids");
+ is($ext_summary->{""}{num_kids}{max}, 4, "Got max 2 kids");
+ is($ext_summary->{""}{num_kids}{sum_sq}, 38, "Got sum_sq 2 kids");
+ is($ext_summary->{""}{num_kids}{median}, 2.5, "Got median 2 kids");
+ ok($ext_summary->{""}{num_kids}{stddev} >= 1.6733200 &&
$ext_summary->{""}{num_kids}{stddev} <= 1.6733201, "Got stddev 1.673320 kids");
+ is($ext_summary->{""}{num_kids}{mode}, 2, "Got mode 2 kids");
+
+ my $column_values = $new_object_set->get_column_values("gender");
+ is($#$column_values, 1, "Got 2 column_values for gender");
+ is($column_values->[0], "M", "Got M as first gender value");
+ is($column_values->[1], "F", "Got F as second gender value");
+
+ $object = $new_object_set->get_object(1, ["person_id"]);
+ is($object->{name}, "stephen", "Got stephen as person_id 1");
+ $object = $new_object_set->get_object("39,keith", ["age","name"]);
+ is($object->{name}, "keith", "Got keith as person_id named keith age 39");
+
+ $females = $new_object_set->get_objects("F",["gender"]);
+ is($#$females, 2, "Got 3 females (without explicit use of an index)");
+ is($females->[0]{name}, "susan", "Got susan as 1st female (without
explicit use of an index)");
+
+ ok(! defined $rep->{dbh}, "Never reconnected to the database");
}
{
+ $rep->_connect();
my $dbh = $rep->{dbh};
$dbh->do("drop table test_person");
}