Author: spadkins
Date: Tue Jun 22 20:48:49 2010
New Revision: 14183

Modified:
   p5ee/trunk/App-Context/CHANGES
   p5ee/trunk/App-Context/MANIFEST
   p5ee/trunk/App-Context/Makefile.PL
   p5ee/trunk/App-Context/lib/App/Context.pm
   p5ee/trunk/App-Context/lib/App/Serializer/Json.pm
   p5ee/trunk/App-Context/lib/App/SessionObject.pm
   p5ee/trunk/App-Repository/Makefile.PL
   p5ee/trunk/App-Repository/lib/App/Repository.pm
   p5ee/trunk/App-Repository/lib/App/RepositoryShell.pm
   p5ee/trunk/App-Repository/t/DBI-getset-cache.t
   p5ee/trunk/App-Repository/t/DBI-getset.t
   p5ee/trunk/App-Repository/t/DBI-repobjects.t
   p5ee/trunk/App-Repository/t/RepositoryTestUtils.pm

Log:
add Moose support

Modified: p5ee/trunk/App-Context/CHANGES
==============================================================================
--- p5ee/trunk/App-Context/CHANGES      (original)
+++ p5ee/trunk/App-Context/CHANGES      Tue Jun 22 20:48:49 2010
@@ -2,6 +2,11 @@
 # CHANGE LOG
 #########################################
 
+VERSION 0.968
+ x Did initial work to make App::Context::ModPerl work (full tested version 
should come soon)
+ x introduced deprecated flag for services in the service() method
+ x keep the app.Request.keep_url_params on the form tag url
+
 VERSION 0.967
  x App::Request::CGI     - added the url() method to support putting the URL 
into the form tag in App::Widget
  x App::Service          - added get_sym_label() method for various uses in 
turning a symbol into a label

Modified: p5ee/trunk/App-Context/MANIFEST
==============================================================================
--- p5ee/trunk/App-Context/MANIFEST     (original)
+++ p5ee/trunk/App-Context/MANIFEST     Tue Jun 22 20:48:49 2010
@@ -17,19 +17,25 @@
 lib/App/Conf/File.pm
 lib/App/Conf/File.pod
 lib/App/Context.pm
+lib/App/Context/ClusterController.pm
+lib/App/Context/ClusterNode.pm
 lib/App/Context/Cmd.pm
 lib/App/Context/HTTP.pm
+lib/App/Context/ModPerl.pm
+lib/App/Context/NetServer.pm
 lib/App/Context/POE.pm
-lib/App/Context/POE/Server.pm
 lib/App/Context/POE/ClusterController.pm
 lib/App/Context/POE/ClusterNode.pm
+lib/App/Context/POE/Server.pm
 lib/App/Context/Server.pm
 lib/App/datetime.pod
 lib/App/devguide.pod
+lib/App/Documentation.pm
 lib/App/Exceptions.pm
 lib/App/exceptions.pod
 lib/App/faq.pod
 lib/App/installguide.pod
+lib/App/installguide.pod.ota
 lib/App/installguide/hosted.pod
 lib/App/installguide/win32.pod
 lib/App/MessageDispatcher.pm
@@ -38,12 +44,18 @@
 lib/App/Reference.pm
 lib/App/Request.pm
 lib/App/Request/CGI.pm
+lib/App/ResourceLocker.pm
+lib/App/ResourceLocker/IPCLocker.pm
+lib/App/ResourceLocker/IPCSemaphore.pm
 lib/App/Response.pm
 lib/App/Serializer.pm
+lib/App/Serializer/Html.pm
 lib/App/Serializer/Ini.pm
+lib/App/Serializer/Json.pm
 lib/App/Serializer/OneLine.pm
 lib/App/Serializer/Perl.pm
 lib/App/Serializer/Properties.pm
+lib/App/Serializer/Scalar.pm
 lib/App/Serializer/Storable.pm
 lib/App/Serializer/TextArray.pm
 lib/App/Serializer/Xml.pm
@@ -58,7 +70,6 @@
 lib/App/ValueDomain.pm
 Makefile.PL
 MANIFEST
-META.yml                       Module meta-data (added by MakeMaker)
 README
 t/app.ini
 t/app.pl

Modified: p5ee/trunk/App-Context/Makefile.PL
==============================================================================
--- p5ee/trunk/App-Context/Makefile.PL  (original)
+++ p5ee/trunk/App-Context/Makefile.PL  Tue Jun 22 20:48:49 2010
@@ -16,7 +16,7 @@
 %opts = (
     "NAME"        => "App-Context",
     "DISTNAME"    => "App-Context",
-    "VERSION"     => "0.967",
+    "VERSION"     => "0.969",
     "EXE_FILES"   => [ @programs ],
     "PREREQ_PM"   => {
         # "Apache"                             => "0.01",  # used for mod_perl 
integration

Modified: p5ee/trunk/App-Context/lib/App/Context.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App/Context.pm   (original)
+++ p5ee/trunk/App-Context/lib/App/Context.pm   Tue Jun 22 20:48:49 2010
@@ -558,11 +558,28 @@
         $name = "default";
     }
 
+    # A SessionObject can have three types:
+    # stateful  - The object is named and its state is stored in the session. 
This is the default.
+    # stateless - The object state is *NOT* stored in the session. The object 
is named, so it is cached for the duration of the current process.
+    # anonymous - The object is not cached, so unless a reference to it is 
maintained, its internal state is lost.
+    #             Any SessionObject which is anonymous is effectively 
stateless.
+    #             Note: "anonymous" is a synonym for the older, deprecated 
"temporary".
+
+    my $anonymous = 0;
+    my $stateless = 0;
+    if ($name eq "anonymous" || $args->{anonymous} || $name eq "temporary" || 
$args->{temporary}) {
+        $anonymous = 1;
+        $args->{anonymous} = 1;
+        $args->{stateless} = 1 if (!$args->{stateless});
+    }
+    elsif ($args->{stateless}) {
+        $stateless = 1;
+    }
+
     $session = $self->{session};
-    $service = $session->{cache}{$type}{$name};  # check the cache
+    $service = $session->{cache}{$type}{$name} if (!$anonymous);  # check the 
cache
     $conf = $self->{conf};
     $service_conf = $conf->{$type}{$name};
-    my $temporary = ($name eq "temporary") || $args->{temporary};
     my $service_initialized = ($service && ref($service) ne "HASH");
     #print "$type($name): SERVICE=$service INIT=$service_initialized\n";
 
@@ -649,16 +666,16 @@
 
     $new_service = 0;
 
-    #   NEVER DEFINED     OR   NON-BLESSED HASH (fully defined services are 
blessed into classes)
-    if ($temporary || !defined $service || ref($service) eq "HASH") {
+    #   NEVER DEFINED OR NON-BLESSED HASH (fully defined services are blessed 
into classes)
+    if ($anonymous || !defined $service || ref($service) eq "HASH") {
         $service = {} if (!defined $service);  # start with new hash ref
         $service->{name} = $name;
         $service->{context} = $self;
 
         $service_store = $session->{store}{$type}{$name};
-        if ($temporary) {
+        if ($anonymous) {
             $service_store = undef;
-            $service->{temporary} = 1;
+            $service->{anonymous} = 1;
         }
 
         if ($App::DEBUG && $self->dbg(6)) {
@@ -725,7 +742,7 @@
     # This is really handy when you have something like a huge spreadsheet
     # of text entry cells (usually an indexed variable).
 
-    if ($temporary) {                            # may be specified implicitly
+    if ($stateless || $anonymous) {                            # may be 
specified implicitly
         $lightweight = 1;
     }
     elsif (defined $args->{lightweight}) {       # may be specified explicitly
@@ -759,7 +776,7 @@
         $self->dbgprint("Context->service() new service [$name]")
             if ($App::DEBUG && $self->dbg(3));
 
-        if (!$temporary && defined $service->{default}) {
+        if (!$stateless && !$anonymous && defined $service->{default}) {
             $default = $service->{default};
             if ($default =~ /^\{today\}\+?(-?[0-9]+)?$/) {
                 $default = time2str("%Y-%m-%d",time + 2*3600 + ($1 ? 
($1*3600*24) : 0));
@@ -771,11 +788,12 @@
         }
 
         $class = $service->{class};      # find class of service
-
         if (!defined $class || $class eq "") {
-            $class = "App::$type";   # assume the "generic" class
+            my $default_class_option_var = lc($type) . "_class";
+            $class = $options->{$default_class_option_var} || "App::$type";   
# assume the "generic" class
             $service->{class} = $class;
         }
+        my $constructor = ($class =~ /Moose/) ? "new" : undef; # TODO: I might 
want to make this more general/configurable
 
         if (! $self->{used}{$class}) {                        # load the code
             App->use($class);
@@ -784,8 +802,19 @@
         $self->dbgprint("Context->service() service class [$class]")
             if ($App::DEBUG && $self->dbg(3));
 
-        bless $service, $class;            # bless the service into the class
-        if (!$temporary) {
+        if ($constructor) {
+            my $constructed_service = $class->$constructor($service);
+            foreach my $attrib (keys %$service) {
+                if (! exists $constructed_service->{$attrib}) {
+                    $constructed_service->{$attrib} = $service->{$attrib};
+                }
+            }
+            $service = $constructed_service;
+        }
+        else {
+            bless $service, $class;        # bless the service into the class
+        }
+        if (!$anonymous) {
             $session->{cache}{$type}{$name} = $service;   # save in the cache
         }
         $service->_init();               # perform additional initializations

Modified: p5ee/trunk/App-Context/lib/App/Serializer/Json.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App/Serializer/Json.pm   (original)
+++ p5ee/trunk/App-Context/lib/App/Serializer/Json.pm   Tue Jun 22 20:48:49 2010
@@ -48,9 +48,9 @@
 
 use JSON;
 
-use constant true => JSON::true;
+use constant true  => JSON::true;
 use constant false => JSON::false;
-use constant null => JSON::null;
+use constant null  => JSON::null;
 
 sub serialize {
     &App::sub_entry if ($App::trace);

Modified: p5ee/trunk/App-Context/lib/App/SessionObject.pm
==============================================================================
--- p5ee/trunk/App-Context/lib/App/SessionObject.pm     (original)
+++ p5ee/trunk/App-Context/lib/App/SessionObject.pm     Tue Jun 22 20:48:49 2010
@@ -358,11 +358,16 @@
     &App::sub_entry if ($App::trace);
     my ($self, $value) = @_;
     my $name = $self->{name};
-    if ($name =~ /^(.+)\.([a-zA-Z][a-zA-Z0-9_]*)$/) {
-        $self->{context}->so_set($1, $2, $value);
+    if ($self->{stateless}) {
+        $self->{_value} = $value;
     }
     else {
-        $self->{context}->so_set("default", $name, $value);
+        if ($name =~ /^(.+)\.([a-zA-Z][a-zA-Z0-9_]*)$/) {
+            $self->{context}->so_set($1, $2, $value);
+        }
+        else {
+            $self->{context}->so_set("default", $name, $value);
+        }
     }
     &App::sub_exit() if ($App::trace);
 }
@@ -386,7 +391,13 @@
 sub get_value {
     &App::sub_entry if ($App::trace);
     my ($self, $default, $setdefault) = @_;
-    my $value = $self->{context}->so_get($self->{name}, "", $default, 
$setdefault);
+    my ($value);
+    if ($self->{stateless}) {
+        $value = $self->{_value};
+    }
+    else {
+        $value = $self->{context}->so_get($self->{name}, "", $default, 
$setdefault);
+    }
     &App::sub_exit($value) if ($App::trace);
     return $value;
 }
@@ -485,7 +496,12 @@
 sub set {
     &App::sub_entry if ($App::trace);
     my ($self, $var, $value) = @_;
-    $self->{context}->so_set($self->{name}, $var, $value);
+    if ($self->{stateless}) {
+        $self->{$var} = $value;
+    }
+    else {
+        $self->{context}->so_set($self->{name}, $var, $value);
+    }
     &App::sub_exit() if ($App::trace);
 }
 
@@ -514,7 +530,13 @@
 sub get {
     &App::sub_entry if ($App::trace);
     my ($self, $var, $default, $setdefault) = @_;
-    my $value = $self->{context}->so_get($self->{name}, $var, $default, 
$setdefault);
+    my ($value);
+    if ($self->{stateless}) {
+        $value = $self->{$var};
+    }
+    else {
+        $value = $self->{context}->so_get($self->{name}, $var, $default, 
$setdefault);
+    }
     &App::sub_exit($value) if ($App::trace);
     $value;
 }
@@ -538,7 +560,14 @@
 sub delete {
     &App::sub_entry if ($App::trace);
     my ($self, $var) = @_;
-    my $result = $self->{context}->so_delete($self->{name}, $var);
+    my ($result);
+    if ($self->{stateless}) {
+        delete $self->{$var};
+        $result = 1;
+    }
+    else {
+        $result = $self->{context}->so_delete($self->{name}, $var);
+    }
     &App::sub_exit($result) if ($App::trace);
     $result;
 }
@@ -563,7 +592,19 @@
 sub set_default {
     &App::sub_entry if ($App::trace);
     my ($self, $var, $default) = @_;
-    my $value = $self->{context}->so_get($self->{name}, $var, $default, 1);
+    my ($value);
+    if ($self->{stateless}) {
+        if (defined $self->{$var}) {
+            $value = $self->{$var};
+        }
+        else {
+            $self->{$var} = $default;
+            $value = $default;
+        }
+    }
+    else {
+        $value = $self->{context}->so_get($self->{name}, $var, $default, 1);
+    }
     &App::sub_exit($value) if ($App::trace);
     $value;
 }

Modified: p5ee/trunk/App-Repository/Makefile.PL
==============================================================================
--- p5ee/trunk/App-Repository/Makefile.PL       (original)
+++ p5ee/trunk/App-Repository/Makefile.PL       Tue Jun 22 20:48:49 2010
@@ -16,13 +16,12 @@
 %opts = (
     'NAME'        => 'App-Repository',
     'DISTNAME'    => 'App-Repository',
-    'VERSION'     => '0.966',
+    'VERSION'     => '0.969',
     'EXE_FILES'   => [ @programs ],
     'PREREQ_PM'   => {
-                       'App::Options' => 0,  # core services
-                       'App::Context' => 0,  # core services
+                       'App::Options' => "0.01",  # core services
+                       'App::Context' => "0.01",  # core services
                        'DBI'          => "0.01",  # database access
-                       'DBIx::Compat' => 0,       # database compatibility
                      },
 );
 

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 Jun 22 20:48:49 2010
@@ -662,7 +662,7 @@
                 $hash_options = undef if (! %$hash_options);
             }
             $hashkey = $sds->hashkey([$table, $params, $cols, $hash_options, 
"row"]);
-            $context->log("Cache Check: $table $hashkey (get_row)\n") if 
($log_cache);
+            $context->log("Cache Check: $table $hashkey (get_row) : 
cache_exception_on_miss=[$cache_exception_on_miss]\n") if ($log_cache);
             if (!$cache_refresh) {
                 my $ref = $sds->get_ref($hashkey);
                 if (defined $ref) {
@@ -678,6 +678,7 @@
                 }
                 else {  # missed the cache (no cache entry exists)
                     if ($cache_exception_on_miss) {
+                        $context->log("Cache Miss:  $table $hashkey (get_row) 
: THROWING EXCEPTION\n") if ($log_cache);
                         die "CACHE-MISS:get_row($table)";
                     }
                     else {
@@ -981,7 +982,7 @@
                 $hash_options = undef if (! %$hash_options);
             }
             $hashkey = $sds->hashkey([$table, $params, $cols, $hash_options, 
"rows"]);
-            $context->log("Cache Check: $table $hashkey (get_rows)\n") if 
($log_cache);
+            $context->log("Cache Check: $table $hashkey (get_rows) : 
cache_exception_on_miss=[$cache_exception_on_miss]\n") if ($log_cache);
             if (!$cache_refresh) {
                 my $ref = $sds->get_ref($hashkey);
                 if (defined $ref) {
@@ -997,6 +998,7 @@
                 }
                 else {  # missed the cache (no cache entry exists)
                     if ($cache_exception_on_miss) {
+                        $context->log("Cache Miss:  $table $hashkey (get_rows) 
: THROWING EXCEPTION\n") if ($log_cache);
                         die "CACHE-MISS:get_rows($table)";
                     }
                     else {
@@ -1036,8 +1038,35 @@
                 }
                 $cols = $new_cols;        # then point to the new columns 
regardless
             }
+
+            my ($summary_table, $summary_column_defs, 
$summary_repository_name);
+            #my $summary_tables = $table_def->{summary_tables};
+            #if ($summary_tables) {
+            #    foreach my $summary_table_spec (@$summary_tables) {
+            #        ($summary_table, $summary_column_defs, 
$summary_repository_name) = @$summary_table_spec;   # assume this summary will 
work
+            #        foreach $col (@$cols) {
+            #            if (!$column_defs->{$col}{expr} && 
!$summary_columns_defs->{$col}) {   # the column doesn't exist on the summary 
table
+            #                $summary_table = undef;                           
                 # so the summary won't work
+            #                last;
+            #            }
+            #        }
+            #        last if ($summary_table);
+            #    }
+            #}
     
-            $rows = $self->_get_rows($table, $params, $cols, $options);
+            if ($summary_table) {
+                if ($summary_repository_name) {
+                    my $rep = $context->repository($summary_repository_name);
+                    $rows = $rep->get_rows($summary_table, $params, $cols, 
$options);
+                }
+                else {
+                    $rows = $self->get_rows($summary_table, $params, $cols, 
$options);
+                }
+                $summary_table = undef if ($#$rows == -1);  # got no rows
+            }
+            if (!$summary_table) {
+                $rows = $self->_get_rows($table, $params, $cols, $options);
+            }
     
             if ($contains_expr) {
                 $self->evaluate_expressions($table, $params, $cols, $rows, 
$options);
@@ -1048,6 +1077,7 @@
                 $context->log("Cache Save:  $table $hashkey (get_rows)\n") if 
($log_cache);
             }
         }
+
         if ($sds && $tabledef->{cache_minimum_columns}) {
             my $requested_rows = [];
             foreach my $row (@$rows) {
@@ -1374,14 +1404,18 @@
     $object = $self->get_hash($table, $params, $cols, $options);
 
     if ($object) {
-        my $class = $table_def->{class} || "App::RepositoryObject";
+        my $context = $self->{context};
+        my $context_options = $context->{options};
+
+        my $class = $table_def->{class} || 
$context_options->{repositoryobject_class} || "App::RepositoryObject";
         # if $class is an ARRAY ref, we need to examine the qualifier(s) to 
determine the class
         $class = $self->_get_qualified_class($class, $object) if (ref($class));
+        my $constructor = ($class =~ /Moose/) ? "new" : undef; # TODO: I might 
want to make this more general/configurable
+
         App->use($class);
 
         $object->{_repository} = $self;
         $object->{_table} = $table;
-        bless $object, $class;
         if (!ref($params)) {
             $object->{_key} = $params;
         }
@@ -1408,6 +1442,19 @@
                 $object->{_key} = $key if (defined $key);
             }
         }
+        if ($constructor) {
+            # Use what was going to be the object as a set of initializers to 
the true constructor
+            my $constructed_object = $class->$constructor($object);
+            foreach my $attrib (keys %$object) {
+                if (! exists $constructed_object->{$attrib}) {
+                    $constructed_object->{$attrib} = $object->{$attrib};
+                }
+            }
+            $object = $constructed_object;
+        }
+        else {
+            bless $object, $class;
+        }
     }
     &App::sub_exit($object) if ($App::trace);
     return($object);
@@ -1449,17 +1496,22 @@
     my $primary_key = $table_def->{primary_key};
     $primary_key = [$primary_key] if (ref($primary_key) eq "");
     my ($key, $class, %used);
-    foreach my $object (@$objects) {
+    my ($object, $constructor, $constructed_object);
+    my $context_options = $self->{context}{options};
+    for (my $i = 0; $i <= $#$objects; $i++) {
+        $object = $objects->[$i];
         $object->{_repository} = $self;
         $object->{_table} = $table;
-        $class = $table_def->{class} || "App::RepositoryObject";
+        $class = $table_def->{class} || 
$context_options->{repositoryobject_class} || "App::RepositoryObject";
         # if $class is an ARRAY ref, we need to examine the qualifier(s) to 
determine the class
         $class = $self->_get_qualified_class($class, $object) if (ref($class));
+        $constructor = ($class =~ /Moose/) ? "new" : undef; # TODO: I might 
want to make this more general/configurable
+
         if (!$used{$class}) {
             App->use($class);
             $used{$class} = 1;
         }
-        bless $object, $class;
+
         if ($primary_key) {
             $key = undef;
             foreach my $column (@$primary_key) {
@@ -1478,6 +1530,21 @@
             }
             $object->{_key} = $key if (defined $key);
         }
+
+        if ($constructor) {
+            # Use what was going to be the object as a set of initializers to 
the true constructor
+            $constructed_object = $class->$constructor($object);
+            # Then make sure that every attribute that was not set by the 
constructor gets set
+            foreach my $attrib (keys %$object) {
+                if (! exists $constructed_object->{$attrib}) {
+                    $constructed_object->{$attrib} = $object->{$attrib};
+                }
+            }
+            $objects->[$i] = $constructed_object;
+        }
+        else {
+            bless $object, $class;
+        }
     }
     &App::sub_exit($objects) if ($App::trace);
     return($objects);
@@ -1500,7 +1567,10 @@
             }
         }
     }
-    $class ||= "App::RepositoryObject";
+    if (!$class) {
+        my $context_options = $self->{context}{options};
+        $class = $context_options->{repositoryobject_class} || 
"App::RepositoryObject";
+    }
     &App::sub_exit($class) if ($App::trace);
     return($class);
 }
@@ -2164,17 +2234,33 @@
         $object = {};
     }
 
-    my $class = $table_def->{class} || "App::RepositoryObject";
+    my $context_options = $self->{context}{options};
+    my $class = $table_def->{class} || 
$context_options->{repositoryobject_class} || "App::RepositoryObject";
     # if $class is an ARRAY ref, we need to examine the qualifier(s) to 
determine the class
     $class = $self->_get_qualified_class($class, $object) if (ref($class));
+
     App->use($class);
+
     bless $object, $class;
     $object->_init();
     $self->_check_default_and_required_fields($object);
 
     $options = $options ? { %$options } : {};
     $options->{last_inserted_id} = 1;
-    if (!$options->{temp}) {
+    if ($options->{temp}) {
+        my $constructor = ($class =~ /Moose/) ? "new" : undef; # TODO: I might 
want to make this more general/configurable
+        if ($constructor) {
+            # Use what was going to be the object as a set of initializers to 
the true constructor
+            my $constructed_object = $class->$constructor($object);
+            foreach my $attrib (keys %$object) {
+                if (! exists $constructed_object->{$attrib}) {
+                    $constructed_object->{$attrib} = $object->{$attrib};
+                }
+            }
+            $object = $constructed_object;
+        }
+    }
+    else {
         my $retval = $self->insert_row($table, $object, undef, $options);
         die "new($table) unable to create a new row" if (!$retval);
         my $params = $self->last_inserted_id($table);

Modified: p5ee/trunk/App-Repository/lib/App/RepositoryShell.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/RepositoryShell.pm        (original)
+++ p5ee/trunk/App-Repository/lib/App/RepositoryShell.pm        Tue Jun 22 
20:48:49 2010
@@ -232,9 +232,18 @@
     &App::sub_entry if ($App::trace);
     my ($self, $command_entry) = @_;
     my ($command);
+    my %command_alias = (
+        desc => "describe",
+        descr => "describe",
+        descri => "describe",
+        describ => "describe",
+    );
     if ($command_entry =~ /^([a-zA-Z_\?]+)/) {
         $command = lc($1);
     }
+    if ($command_alias{$command}) {
+        $command = $command_alias{$command};
+    }
     &App::sub_exit($command) if ($App::trace);
     return($command);
 }
@@ -294,14 +303,16 @@
     elsif ($command eq "repository") {
         $self->execute_repository_command($command_entry, $options);
     }
+    elsif ($command eq "show") {
+        $self->execute_show_command($command_entry, $options);
+    }
+    elsif ($command eq "describe") {
+        $self->execute_describe_command($command_entry, $options);
+    }
     elsif ($command eq "select") {
         $self->execute_select_command($command_entry, $options);
         $self->save_sql($command_entry);
     }
-    elsif ($direct_command{$command}) {
-        $self->execute_direct_command($command_entry, $options);
-        $self->save_sql($command_entry);
-    }
     elsif ($command eq "edit") {
         $self->execute_edit_command($command_entry, $options);
         $self->execute_run_command("run", $options);
@@ -321,6 +332,10 @@
     elsif ($command eq "exit" || $command eq "quit" || $command eq "bye") {
         $done = 1;
     }
+    elsif ($command) {
+        $self->execute_direct_command($command_entry, $options);
+        $self->save_sql($command_entry);
+    }
     else {
         print "I don't know the '$command' command.\n";
         print "Please try 'help' for help on the available commands and their 
use\n";
@@ -506,15 +521,10 @@
     if ($@) {
         # [23480] 2009-03-10 23:48:55 DBI Exception (fail) in _do(): 
DBD::Oracle::db prepare failed: ORA-00942: table or view does not exist (DBD 
ERROR: error possibly near <*> indicator at char 16 in 'select foo from 
<*>boo') [for Statement "select foo from boo"] at 
/usr/rubicon/spadkins/src/p5ee/App-Repository/lib/App/Repository/DBI.pm line 
2556. select foo from booDBD::Oracle::db prepare failed: ORA-00942: table or 
view does not exist (DBD ERROR: error possibly near <*> indicator at char 16 in 
'select foo from <*>boo') [for Statement "select foo from boo"] at 
/usr/rubicon/spadkins/src/p5ee/App-Repository/lib/App/Repository/DBI.pm line 
2556.
         my $e = $@;
-        #print "EXCEPTION: [$e]\n";
         $e =~ s/ at (\S+) line .*//;
-        #print "EXCEPTION: (remove at*) [$e]\n";
         $e =~ s/.* _do\(\): //;
-        #print "EXCEPTION: (remove _do()*) [$e]\n";
         $e =~ s/(\(DBD ERROR:)/\n$1/;
-        #print "EXCEPTION: (newline before DBD ERROR) [$e]\n";
         $e =~ s/(\[for Statement)/\n$1/;
-        #print "EXCEPTION: (newline before for Statement) [$e]\n";
         print $e;
     }
     else {
@@ -534,6 +544,64 @@
     &App::sub_exit() if ($App::trace);
 }
 
+sub execute_direct_command {
+    &App::sub_entry if ($App::trace);
+    my ($self, $command_entry, $options) = @_;
+    my $sql = $self->get_multiline_command_entry("sql", $command_entry, ";", 
$options);
+    my $context  = $self->{context};
+    my $db       = $context->repository($self->{repository});
+    my $columns  = [];
+    my $command  = $self->get_command_from_command_entry($command_entry);
+    my $retval_str = ($command =~ /^(insert|update|delete)$/) ? "Rows 
affected" : "Return Value";
+    my ($retval);
+    eval {
+        $retval = $db->_do($sql);
+    };
+    if ($@) {
+        # [23480] 2009-03-10 23:48:55 DBI Exception (fail) in _do(): 
DBD::Oracle::db prepare failed: ORA-00942: table or view does not exist (DBD 
ERROR: error possibly near <*> indicator at char 16 in 'select foo from 
<*>boo') [for Statement "select foo from boo"] at 
/usr/rubicon/spadkins/src/p5ee/App-Repository/lib/App/Repository/DBI.pm line 
2556. select foo from booDBD::Oracle::db prepare failed: ORA-00942: table or 
view does not exist (DBD ERROR: error possibly near <*> indicator at char 16 in 
'select foo from <*>boo') [for Statement "select foo from boo"] at 
/usr/rubicon/spadkins/src/p5ee/App-Repository/lib/App/Repository/DBI.pm line 
2556.
+        my $e = $@;
+        $e =~ s/ at (\S+) line .*//;
+        $e =~ s/.* _do\(\): //;
+        $e =~ s/(\(DBD ERROR:)/\n$1/;
+        $e =~ s/(\[for Statement)/\n$1/;
+        print $e;
+    }
+    else {
+        print "$retval_str: [$retval]\n";
+    }
+    $self->{last_command_entry} = $command_entry;
+    &App::sub_exit() if ($App::trace);
+}
+
+sub execute_show_command {
+    &App::sub_entry if ($App::trace);
+    my ($self, $command_entry, $options) = @_;
+    &App::sub_exit() if ($App::trace);
+}
+
+sub execute_describe_command {
+    &App::sub_entry if ($App::trace);
+    my ($self, $command_entry, $options) = @_;
+    if ($command_entry =~ /^\s*\S+\s+([a-zA-Z_][a-zA-Z_0-9\.]*)/s) {
+        my $table     = lc($1);
+        my $context   = $self->{context};
+        my $db        = $context->repository($self->{repository});
+print "REPOSITORY: name=[$db->{name}] dbh=[$db->{dbh}] rep=[$db]\n";
+        my $table_def = $db->get_table_def($table);
+print "TABLEDEF[$table]: ", join("|", %$table_def), "\n";
+        my $column_defs = $table_def->{column};
+        my ($column_def);
+        foreach my $column (keys %$column_defs) {
+            $column_def = $column_defs->{$column};
+            print "$column: ", join("|", %$column_def), "\n";
+        }
+    }
+    else {
+        print "ERROR: I could not find the table name in that command 
[$command_entry]\n";
+    }
+    &App::sub_exit() if ($App::trace);
+}
+
 sub edit {
     &App::sub_entry if ($App::trace);
     my ($self, $command_entry) = @_;

Modified: p5ee/trunk/App-Repository/t/DBI-getset-cache.t
==============================================================================
--- p5ee/trunk/App-Repository/t/DBI-getset-cache.t      (original)
+++ p5ee/trunk/App-Repository/t/DBI-getset-cache.t      Tue Jun 22 20:48:49 2010
@@ -97,7 +97,7 @@
     [ 7, 39, "keith",     "M", "GA", ],
 ];
 
-my ($row, $data_rows, $data_rows2, $nrows);
+my ($row, $data_rows, $data_rows2, $nrows, $e);
 
 #####################################################################
 #  $value  = $rep->get ($table, $key,     $col,   \%options);
@@ -159,8 +159,47 @@
 $first_name = $rep->get("test_person", 1, "first_name", { cache_skip => 1 });
 is($first_name, "steve", "get() modified first_name [$first_name] by skipping 
the cache");
 
-$data_rows = $rep->get_rows("test_person", {}, [ "person_id", "age", 
"first_name", "gender", "state" ], {order_by=>["person_id"], cache_refresh => 
1});
+#####################################################################################################
+# Test cache_exception_on_miss logic
+#####################################################################################################
+$data_rows  = undef;
+eval {
+    $data_rows  = $rep->get_rows("test_person", {}, ["state"], 
{order_by=>["person_id"], cache_exception_on_miss => 1, foo => 1});
+};
+$e = $@;
+chomp($e);
+ok($e && $e =~ /^CACHE-MISS:/, "get_rows() with cache_exception_on_miss (on 
MISS): exception=[$e]" . ($data_rows ? " rows=[$data_rows] 
maxidx=[$#$data_rows]" : ""));
+
+$data_rows  = undef;
+eval {
+    $data_rows  = $rep->get_rows("test_person", {}, ["state"], 
{order_by=>["person_id"], cache_exception_on_miss => 1});
+};
+$e = $@;
+chomp($e);
+ok(!$e && $#$data_rows == 6, "get_rows() with cache_exception_on_miss (on HIT) 
: exception=[$e]" . ($data_rows ? " rows=[$data_rows] maxidx=[$#$data_rows]" : 
""));
+
+$first_name = undef;
+eval {
+    $first_name = $rep->get("test_person", {person_id => 1}, "first_name", 
{cache_exception_on_miss => 1, foo => 1});
+};
+$e = $@;
+chomp($e);
+ok($e && $e =~ /^CACHE-MISS:/, "get_row()  with cache_exception_on_miss (on 
MISS): exception=[$e] first_name=[$first_name]");
+
+$first_name = undef;
+eval {
+    $first_name = $rep->get("test_person", {person_id => 1}, "first_name", 
{cache_exception_on_miss => 1});
+};
+$e = $@;
+chomp($e);
+ok(!$e && $first_name eq "steve", "get_row()  with cache_exception_on_miss (on 
HIT) : exception=[$e] first_name=[$first_name]");
+
+#####################################################################################################
+# END OF TESTS
+#####################################################################################################
 exit;
+
+$data_rows = $rep->get_rows("test_person", {}, [ "person_id", "age", 
"first_name", "gender", "state" ], {order_by=>["person_id"], cache_refresh => 
1});
 is_deeply($data_rows, $data_rows2, "get_rows() refreshed cached data thanks to 
cache_refresh");
 
 $first_name = $rep->get("test_person", 1, "first_name", { cache_refresh => 1 
});

Modified: p5ee/trunk/App-Repository/t/DBI-getset.t
==============================================================================
--- p5ee/trunk/App-Repository/t/DBI-getset.t    (original)
+++ p5ee/trunk/App-Repository/t/DBI-getset.t    Tue Jun 22 20:48:49 2010
@@ -217,6 +217,16 @@
 is($years_older, 21, "get() years_older [$years_older] base_age = 20");
 
 #####################################################################
+# params with weird characters that need quoting
+#####################################################################
+$last_name = $rep->get("test_person", {first_name => "step'hen"}, "last_name");
+is($last_name, undef, "get() step'hen is undef");
+$last_name = $rep->get("test_person", {"first_name.contains" => "step'hen"}, 
"last_name");
+is($last_name, undef, "get() %step'hen% is undef");
+$last_name = $rep->get("test_person", {"first_name.matches" => "step'hen*"}, 
"last_name");
+is($last_name, undef, "get() step'hen* is undef");
+
+#####################################################################
 #  $rep->set_rows($table, undef,    \...@cols, $rows, \%options);
 #####################################################################
 # eval {

Modified: p5ee/trunk/App-Repository/t/DBI-repobjects.t
==============================================================================
--- p5ee/trunk/App-Repository/t/DBI-repobjects.t        (original)
+++ p5ee/trunk/App-Repository/t/DBI-repobjects.t        Tue Jun 22 20:48:49 2010
@@ -23,7 +23,7 @@
 use App;
 use App::Repository;
 use App::RepositoryObject;
-use RepositoryTestUtils qw(create_table_test_person drop_table_test_person 
populate_table_test_person);
+use RepositoryTestUtils qw(create_table drop_table populate_table);
 
 package App::RepositoryObject::Man;
 @ISA = ("App::RepositoryObject");
@@ -70,9 +70,18 @@
 );
 
 my $rep = $context->repository();
-&drop_table_test_person($rep);
-&create_table_test_person($rep);
-&populate_table_test_person($rep);
+
+&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";
 
@@ -181,11 +190,52 @@
     is($obj4->{_key},8, "new._key is ok");
     is($obj4->{person_id},8, "new.person_id is ok");
     isa_ok($obj4, "App::RepositoryObject::Woman", "by new_object(), 
christine");
-}
 
-{
-    my $dbh = $rep->{dbh};
-    $dbh->do("drop table test_person");
+    $obj = { city_cd => "BOS", city_nm => "Boston" };
+    $obj2 = $rep->new_object("test_city", $obj);
+    isa_ok($obj2, "App::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::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");
+
+    # 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)
+
+    # &drop_table($rep, "test_person");
+    # &drop_table($rep, "test_visit");
+    # &drop_table($rep, "test_city");
 }
 
 exit 0;

Modified: p5ee/trunk/App-Repository/t/RepositoryTestUtils.pm
==============================================================================
--- p5ee/trunk/App-Repository/t/RepositoryTestUtils.pm  (original)
+++ p5ee/trunk/App-Repository/t/RepositoryTestUtils.pm  Tue Jun 22 20:48:49 2010
@@ -29,13 +29,14 @@
 use App;
 use App::Repository;
 
+my $dbtype = $App::options{dbtype} || "mysql";
+
 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 = "";
@@ -112,8 +113,6 @@
     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"); };
@@ -143,7 +142,6 @@
 sub create_table_test_app_cache {
     my ($rep) = @_;
     my $dbh = $rep->{dbh};
-    my $dbtype = $App::options{dbtype} || "mysql";
 
     my $suffix = "";
     my $CURRENT_TIMESTAMP = "";
@@ -193,7 +191,6 @@
     &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);
 }
@@ -317,6 +314,35 @@
     "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
+
+if ($dbtype eq "oracle") {
+    $table_data{test_visit} = [
+        "insert into test_visit values ('LAX', 1, 
to_date('1962-11-09','YYYY-MM-DD'), 'Born')",
+        "insert into test_visit values ('BOS', 1, 
to_date('1980-08-30','YYYY-MM-DD'), 'College')",
+        "insert into test_visit values ('JNB', 1, 
to_date('1986-10-20','YYYY-MM-DD'), 'Mission Trip')",
+        "insert into test_visit values ('WAS', 1, 
to_date('1991-08-20','YYYY-MM-DD'), 'Back to college')",
+        "insert into test_visit values ('ATL', 1, 
to_date('1993-06-01','YYYY-MM-DD'), 'Move after graduation')",
+    ];
+}
+else {
+    $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,
@@ -370,7 +396,6 @@
     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 = "";
@@ -431,8 +456,6 @@
     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"); };

Reply via email to