App-Context

 view release on metacpan or  search on metacpan

lib/App/quickstart.pod  view on Meta::CPAN

  perl -MCPAN -e shell
  cpan> install App::Options
  cpan> install App::Context
  cpan> install App::Repository
  cpan> install App::Widget
  cpan> exit

If it's not this easy, I need to work on making it easier.
Please let me know (spadkins@gmail.com) and I'll fix it.

=head1 QUICK START TO COMMAND LINE DATABASE PROGRAMS

One of the big advantages of using the App::Context Framework for
command-line programs is in developing a suite of database programs
(particularly for a MySQL database).

Choose a root directory for your system, assigning it to the PREFIX variable.

vi ~/.bash_profile

  export PREFIX=/usr/mycompany/prod

vi $PREFIX/etc/app.conf

  dbhost  = localhost
  dbname  = test
  dbuser  = scott
  dbpass  = tiger

vi $PREFIX/etc/app.pl

  $conf = {
    Repository => {
      default => { alias => "db", },
      db => {
        class => "App::Repository::MySQL",
      },
    },
  };

vi $PREFIX/bin/prog

  #!/usr/bin/perl -w
  use strict;
  use App::Options (
      options => [qw(dbhost dbname dbuser dbpass)],
      option => {
          dbhost => {
              description => "database host",
              required => 1,
          },
          dbname => {
              description => "database name",
              required => 1,
          },
          dbuser => {
              description => "database user",
              required => 1,
          },
          dbpass => {
              description => "database password",
              required => 1,
          },
      },
  );
  use App;
  use App::Repository;
  {
      my $context = $App->context();
      my $db = $context->repository();
      # perform database ops like ...
      # my $rows = $db->get_rows("customer", { last_name => "Smith" }, ["first_name", "last_name", "birth_dt"]);
      # my $hashes = $db->get_hashes("customer", { "birth_dt.le" => "2000-01-01" }, ["first_name", "last_name", "birth_dt"]);
      # my $age = $db->get("customer", { customer_id => 45 }, "age");
  }

The best parts about writing database programs with App::Repository in the App::Context framework
is that all of your programs get automatic SQL debugging, timing, and explaining.

  prog --debug_sql      # show all SQL statements and their timings
  prog --debug_sql=2    # show all SQL statements and their timings and all rows returned from selects
  prog --debug_sql --explain_sql   # show SQL statements and explain them

See L<App::Options>, L<App::Repository::quickstart>, and L<App::Repository::devguide> for more info on this.

=head1 QUICK START TO OBJECT-ORIENTED COMMAND LINE PROGRAMS

Another of the big advantages of using the App::Context Framework for
command line programs is in developing programs which use and operate on Business Objects
(the object-oriented analysis concept, not the commercial reporting software).

Many "object-oriented" programs are written without ever using a true Business Object.
The reason for this is that the issues of maintaining object state are so tricky that
people rarely get around to using Business Objects in their command line programs.

Business Objects come in two types: Business Entity Objects and Business Process Objects.
Business Entity Objects represent things in the business realm: Customer, Store, Employee,
Product, PurchaseOrder.  Business Process Objects are those objects that model business
processes.

The following abstractions exist in order to subclass for your business objects.
As you get into using them, you will learn when to use which one, and you will find that
there is of course more than one way to do it.

=over

=item * L<App::RepositoryObject> - An object whose state is shared across multiple sessions as a single row in a database (repository).  These are generally the Business Entity Objects.

=item * L<App::SessionObject> - A named object whose state is maintained throughout the session.  These are generally the Business Process Objects.

=item * L<App::SessionObject::RepositoryObjectSet> - A named object with session state and shared state consisting of a set of rows from a single table in a database (repository).

=item * L<App::SessionObject::RepositoryObjectDomain> - A named object with session state and shared state consisting of a set of related sets of rows from multiple tables in a database (repository).

=back

The big advantage of writing object-oriented programs is for code reuse.
Whenever someone whips up a perl script to do some processing on the system, that
programming logic is unavailable for use in any other program (such as an interactive
web application).

lib/App/quickstart.pod  view on Meta::CPAN

  $VERSION = "0.50";
  @ISA = ("App::SessionObject");
  use strict;

  sub check_customer_credit {
      my ($self, $options) = @_;
      my $customer_id = $options->{customer_id} || die "No customer ID provided";
      my $context = $self->{context};   # every Service has a reference to its Context
      my $db = $context->repository();  # get the default repository from the Context

      # There must be a table named customer with primary key of "customer_id" and
      # at least the columns "approval_ind char(1)", "denial_msg varchar(255)",
      # "first_name varchar(255)", and "last_name varchar(255)".
      my $customer = $db->get_object("customer", $customer_id);  # returns an App::RepositoryObject

      my ($approval_ind, $denial_msg);

      # ... do some processing ...
      if ($customer->{first_name} eq "Bill" && $customer->{last_name} eq "Gates") {
          $approval_ind = "N";
          $denial_msg = "Too rich";
      }
      else {
          $approval_ind = "N";
      }

      if ($approval_ind eq "Y") {
          $customer->set("approval_ind",$approval_ind);
          print "Customer $customer_id approved.\n";
      }
      else {
          $customer->set(["approval_ind","denial_msg"],[$approval_ind,$denial_msg]);
          print "Customer $customer_id denied: $denial_msg.\n";
      }
  }

  1;

vi $PREFIX/bin/check_customer_credit

  #!/usr/bin/perl -w
  # NOTE: All of this code is about the User Interface to the logic.
  #       The logic itself is hidden away in "App::SessionObject::CreditManager".
  use strict;
  use App::Options (
      options => [qw(dbhost dbname dbuser dbpass customer_id)],
      option => {
          dbhost => {
              description => "database host",
              required => 1,
          },
          dbname => {
              description => "database name",
              required => 1,
          },
          dbuser => {
              description => "database user",
              required => 1,
          },
          dbpass => {
              description => "database password",
              required => 1,
          },
          customer_id => {
              description => "the ID of the customer to check",
              required => 1,
              type => "integer",
          },
      },
  );
  use App;
  use App::Repository;
  {
      my $context = $App->context();
      my $db = $context->repository();
      my $credit_manager = $context->session_object("credit_manager");
      $credit_manager->check_customer_credit(\%App::options);
  }

=head1 QUICK START TO WEB PROGRAMS

A web program is simply choosing a widget to display on the browser.
Widgets may be arbitrarily complex, containing other widgets, and so taking
the form of an entire web application.  Since any widget can be viewed in a
browser, additional widgets may be developed and debugged before they are
integrated into a larger applications.

Widgets (L<App::Widget>) are simply SessionObject's with an html() method
which allows them to be viewed nicely by a web browser.  They maintain their
state throughout the duration of the session.



=cut



( run in 0.950 second using v1.01-cache-2.11-cpan-0d23b851a93 )