make self-service session cache module configurable, start framework for in-database...
authorivan <ivan>
Tue, 8 Feb 2005 20:22:46 +0000 (20:22 +0000)
committerivan <ivan>
Tue, 8 Feb 2005 20:22:46 +0000 (20:22 +0000)
17 files changed:
FS/FS.pm
FS/FS/ClientAPI/Agent.pm
FS/FS/ClientAPI/MyAccount.pm
FS/FS/ClientAPI/Signup.pm
FS/FS/ClientAPI_SessionCache.pm [new file with mode: 0644]
FS/FS/Conf.pm
FS/FS/clientapi_session.pm [new file with mode: 0644]
FS/FS/clientapi_session_field.pm [new file with mode: 0644]
FS/MANIFEST
FS/bin/freeside-setup
FS/t/ClientAPI_SessionCache.t [new file with mode: 0644]
FS/t/clientapi_session.t [new file with mode: 0644]
FS/t/clientapi_session_field.t [new file with mode: 0644]
README.1.5.0pre7
httemplate/docs/install.html
httemplate/docs/schema.html
httemplate/docs/upgrade10.html

index 57a1f6c..f5b2b96 100644 (file)
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -160,6 +160,24 @@ L<FS::queue_depend> - Job dependencies
 
 L<FS::msgcat> - Message catalogs
 
+L<FS::clientapi_session>
+
+L<FS::clientapi_session_field>
+
+=head1 Client API
+
+L<FS::ClientAPI>
+
+L<FS::ClientAPI_SessionCache>
+
+L<FS::ClientAPI::Signup>
+
+L<FS::ClientAPI::passwd>
+
+L<FS::ClientAPI::MyAccount>
+
+L<FS::ClientAPI::Agent>
+
 =head1 Remote API modules
 
 L<FS::SelfService>
@@ -194,15 +212,9 @@ L<freeside-bill>
 
 L<freeside-overdue>
 
-=head2 User Interface classes (under (stalled) development; not yet usable)
-
-L<FS::UI::Base> - User-interface base class
-
-L<FS::UI::Gtk> - Gtk user-interface class
-
-L<FS::UI::CGI> - CGI (HTML) user-interface class
+=head2 User Interface classes
 
-L<FS::UI::agent> - agent table user-interface class
+L<FS::UI::Web> - Web user-interface class
 
 =head2 Notes
 
index e4a58c0..daede59 100644 (file)
@@ -4,16 +4,18 @@ package FS::ClientAPI::Agent;
 
 use strict;
 use vars qw($cache);
+use subs qw(_cache);
 use Digest::MD5 qw(md5_hex);
-use Cache::SharedMemoryCache; #store in db?
 use FS::Record qw(qsearchs); # qsearch dbdef dbh);
+use FS::ClientAPI_SessionCache;
 use FS::agent;
 use FS::cust_main qw(smart_search);
 
-#store in db?
-my $cache = new Cache::SharedMemoryCache( {
-   'namespace' => 'FS::ClientAPI::Agent',
-} );
+sub _cache {
+  $cache ||= new FS::ClientAPI_SessionCache( {
+               'namespace' => 'FS::ClientAPI::Agent',
+             } );
+}
 
 sub agent_login {
   my $p = shift;
@@ -37,9 +39,9 @@ sub agent_login {
   my $session_id;
   do {
     $session_id = md5_hex(md5_hex(time(). {}. rand(). $$))
-  } until ( ! defined $cache->get($session_id) ); #just in case
+  } until ( ! defined _cache->get($session_id) ); #just in case
 
-  $cache->set( $session_id, $session, '1 hour' );
+  _cache->set( $session_id, $session, '1 hour' );
 
   { 'error'      => '',
     'session_id' => $session_id,
@@ -49,7 +51,7 @@ sub agent_login {
 sub agent_logout {
   my $p = shift;
   if ( $p->{'session_id'} ) {
-    $cache->remove($p->{'session_id'});
+    _cache->remove($p->{'session_id'});
     return { 'error' => '' };
   } else {
     return { 'error' => "Can't resume session" }; #better error message
@@ -59,7 +61,7 @@ sub agent_logout {
 sub agent_info {
   my $p = shift;
 
-  my $session = $cache->get($p->{'session_id'})
+  my $session = _cache->get($p->{'session_id'})
     or return { 'error' => "Can't resume session" }; #better error message
 
   #my %return;
@@ -84,7 +86,7 @@ sub agent_info {
 sub agent_list_customers {
   my $p = shift;
 
-  my $session = $cache->get($p->{'session_id'})
+  my $session = _cache->get($p->{'session_id'})
     or return { 'error' => "Can't resume session" }; #better error message
 
   #my %return;
@@ -120,3 +122,4 @@ sub agent_list_customers {
 
 }
 
+1;
index 58966b3..d18a6e4 100644 (file)
@@ -2,14 +2,15 @@ package FS::ClientAPI::MyAccount;
 
 use strict;
 use vars qw($cache);
+use subs qw(_cache);
 use Digest::MD5 qw(md5_hex);
 use Date::Format;
 use Business::CreditCard;
-use Cache::SharedMemoryCache; #store in db?
 use FS::CGI qw(small_custview); #doh
 use FS::Conf;
 use FS::Record qw(qsearch qsearchs);
 use FS::Msgcat qw(gettext);
+use FS::ClientAPI_SessionCache;
 use FS::svc_acct;
 use FS::svc_domain;
 use FS::svc_external;
@@ -30,10 +31,11 @@ use vars qw( @cust_main_editable_fields );
 
 use subs qw(_provision);
 
-#store in db?
-my $cache = new Cache::SharedMemoryCache( {
-   'namespace' => 'FS::ClientAPI::MyAccount',
-} );
+sub _cache {
+  $cache ||= new FS::ClientAPI_SessionCache( {
+               'namespace' => 'FS::ClientAPI::MyAccount',
+             } );
+}
 
 #false laziness w/FS::ClientAPI::passwd::passwd
 sub login {
@@ -69,9 +71,9 @@ sub login {
   my $session_id;
   do {
     $session_id = md5_hex(md5_hex(time(). {}. rand(). $$))
-  } until ( ! defined $cache->get($session_id) ); #just in case
+  } until ( ! defined _cache->get($session_id) ); #just in case
 
-  $cache->set( $session_id, $session, '1 hour' );
+  _cache->set( $session_id, $session, '1 hour' );
 
   return { 'error'      => '',
            'session_id' => $session_id,
@@ -81,7 +83,7 @@ sub login {
 sub logout {
   my $p = shift;
   if ( $p->{'session_id'} ) {
-    $cache->remove($p->{'session_id'});
+    _cache->remove($p->{'session_id'});
     return { 'error' => '' };
   } else {
     return { 'error' => "Can't resume session" }; #better error message
@@ -150,7 +152,7 @@ sub customer_info {
 
 sub edit_info {
   my $p = shift;
-  my $session = $cache->get($p->{'session_id'})
+  my $session = _cache->get($p->{'session_id'})
     or return { 'error' => "Can't resume session" }; #better error message
 
   my $custnum = $session->{'custnum'}
@@ -190,7 +192,7 @@ sub edit_info {
 
 sub payment_info {
   my $p = shift;
-  my $session = $cache->get($p->{'session_id'})
+  my $session = _cache->get($p->{'session_id'})
     or return { 'error' => "Can't resume session" }; #better error message
 
   ##
@@ -267,7 +269,7 @@ sub process_payment {
 
   my $p = shift;
 
-  my $session = $cache->get($p->{'session_id'})
+  my $session = _cache->get($p->{'session_id'})
     or return { 'error' => "Can't resume session" }; #better error message
 
   my %return;
@@ -357,7 +359,7 @@ sub process_payment {
 
 sub invoice {
   my $p = shift;
-  my $session = $cache->get($p->{'session_id'})
+  my $session = _cache->get($p->{'session_id'})
     or return { 'error' => "Can't resume session" }; #better error message
 
   my $custnum = $session->{'custnum'};
@@ -379,7 +381,7 @@ sub invoice {
 
 sub list_invoices {
   my $p = shift;
-  my $session = $cache->get($p->{'session_id'})
+  my $session = _cache->get($p->{'session_id'})
     or return { 'error' => "Can't resume session" }; #better error message
 
   my $custnum = $session->{'custnum'};
@@ -400,7 +402,7 @@ sub list_invoices {
 
 sub cancel {
   my $p = shift;
-  my $session = $cache->get($p->{'session_id'})
+  my $session = _cache->get($p->{'session_id'})
     or return { 'error' => "Can't resume session" }; #better error message
 
   my $custnum = $session->{'custnum'};
@@ -571,7 +573,7 @@ sub order_pkg {
 
 sub cancel_pkg {
   my $p = shift;
-  my $session = $cache->get($p->{'session_id'})
+  my $session = _cache->get($p->{'session_id'})
     or return { 'error' => "Can't resume session" }; #better error message
 
   my $custnum = $session->{'custnum'};
@@ -740,14 +742,14 @@ sub _custoragent_session_custnum {
   if ( $p->{'session_id'} ) {
 
     $context = 'customer';
-    $session = $cache->get($p->{'session_id'})
+    $session = _cache->get($p->{'session_id'})
       or return { 'error' => "Can't resume session" }; #better error message
     $custnum = $session->{'custnum'};
 
   } elsif ( $p->{'agent_session_id'} ) {
 
     $context = 'agent';
-    my $agent_cache = new Cache::SharedMemoryCache( {
+    my $agent_cache = new FS::ClientAPI_SessionCache( {
       'namespace' => 'FS::ClientAPI::Agent',
     } );
     $session = $agent_cache->get($p->{'agent_session_id'})
@@ -762,6 +764,5 @@ sub _custoragent_session_custnum {
 
 }
 
-
 1;
 
index 4947a64..ede7ba9 100644 (file)
@@ -5,6 +5,7 @@ use Tie::RefHash;
 use FS::Conf;
 use FS::Record qw(qsearch qsearchs dbdef);
 use FS::Msgcat qw(gettext);
+use FS::ClientAPI_SessionCache;
 use FS::agent;
 use FS::cust_main_county;
 use FS::part_pkg;
@@ -88,7 +89,7 @@ sub signup_info {
 
   my $session = '';
   if ( exists $packet->{'session_id'} ) {
-    my $cache = new Cache::SharedMemoryCache( {
+    my $cache = new FS::ClientAPI_SessionCache( {
       'namespace' => 'FS::ClientAPI::Agent',
     } );
     $session = $cache->get($packet->{'session_id'});
@@ -164,7 +165,7 @@ sub new_customer {
 
   my $agentnum;
   if ( exists $packet->{'session_id'} ) {
-    my $cache = new Cache::SharedMemoryCache( {
+    my $cache = new FS::ClientAPI_SessionCache( {
       'namespace' => 'FS::ClientAPI::Agent',
     } );
     my $session = $cache->get($packet->{'session_id'});
diff --git a/FS/FS/ClientAPI_SessionCache.pm b/FS/FS/ClientAPI_SessionCache.pm
new file mode 100644 (file)
index 0000000..b722484
--- /dev/null
@@ -0,0 +1,78 @@
+package FS::ClientAPI_SessionCache;
+
+use strict;
+use vars qw($module);
+use FS::UID qw(datasrc);
+
+#ask FS::UID to run this stuff for us later
+install_callback FS::UID sub { 
+  my $conf = new FS::Conf;
+  $module = $conf->config('selfservice_server-cache_module')
+            || 'Cache::SharedMemoryCache';
+};
+
+=head1 NAME
+
+FS::ClientAPI_SessionCache;
+
+=head1 SYNOPSIS
+
+=head1 DESCRIPTION
+
+Minimal Cache::Cache-alike interface for storing session cache information.
+Backends to Cache::SharedMemoryCache, Cache::FileCache, or an internal
+implementation which stores information in the clientapi_session and
+clientapi_session_field database tables.
+
+=head1 METHODS
+
+=over 4
+
+=item new
+
+=cut
+
+sub new {
+  my $proto = shift;
+  my $class = ref($proto) || $proto;
+  unless ( $module =~ /^_Database$/ ) {
+    eval "use $module;";
+    die $@ if $@;
+    my $self = $module->new(@_);
+    $self->set_cache_root('/usr/local/etc/freeside/clientapi_session.'.datasrc)
+      if $module =~ /^Cache::FileCache$/;
+    $self;
+  } else {
+    my $self = shift;
+    bless ($self, $class);
+  }
+}
+
+sub get {
+  my($self, $session_id) = @_;
+  die '_Database self-service session cache not yet implemented';
+}
+
+sub set {
+  my($self, $session_id, $session, $expiration) = @_;
+  die '_Database self-service session cache not yet implemented';
+}
+
+sub remove {
+  my($self, $session_id) = @_;
+  die '_Database self-service session cache not yet implemented';
+}
+
+=back
+
+=head1 BUGS
+
+Minimal documentation.
+
+=head1 SEE ALSO
+
+L<Cache::Cache>, L<FS::clientapi_session>, L<FS::clientapi_session_field>
+
+=cut
+
+1;
index 187a6f9..8ce5138 100644 (file)
@@ -1383,6 +1383,13 @@ httemplate/docs/config.html
     'type'        => 'checkbox',
   },
 
+  { 'key'         => 'selfservice_server-cache_module',
+    'section'     => '',
+    'description' => 'Module used to store self-service session information.  All modules handle any number of self-service servers.  Cache::SharedMemoryCache is appropriate for a single database / single Freeside server.  Cache::FileCache is useful for multiple databases on a single server, or when IPC::ShareLite is not available (i.e. FreeBSD).', #  _Database stores session information in the database and is appropriate for multiple Freeside servers, but may be slower.',
+    'type'        => 'select',
+    'select_enum' => [ 'Cache::SharedMemoryCache', 'Cache::FileCache', ], # '_Database' ],
+  },
+
 );
 
 1;
diff --git a/FS/FS/clientapi_session.pm b/FS/FS/clientapi_session.pm
new file mode 100644 (file)
index 0000000..f71a126
--- /dev/null
@@ -0,0 +1,121 @@
+package FS::clientapi_session;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw( qsearch qsearchs );
+
+@ISA = qw(FS::Record);
+
+=head1 NAME
+
+FS::clientapi_session - Object methods for clientapi_session records
+
+=head1 SYNOPSIS
+
+  use FS::clientapi_session;
+
+  $record = new FS::clientapi_session \%hash;
+  $record = new FS::clientapi_session { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::clientapi_session object represents an FS::ClientAPI session.
+FS::clientapi_session inherits from FS::Record.  The following fields are
+currently supported:
+
+=over 4
+
+=item sessionnum - primary key
+
+=item sessionid - session ID
+
+=item namespace - session namespace
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new record.  To add the record to the database, see L<"insert">.
+
+Note that this stores the hash reference, not a distinct copy of the hash it
+points to.  You can ask the object for a copy with the I<hash> method.
+
+=cut
+
+# the new method can be inherited from FS::Record, if a table method is defined
+
+sub table { 'clientapi_session'; }
+
+=item insert
+
+Adds this record to the database.  If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+# the insert method can be inherited from FS::Record
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+# the delete method can be inherited from FS::Record
+
+=item replace OLD_RECORD
+
+Replaces the OLD_RECORD with this one in the database.  If there is an error,
+returns the error, otherwise returns false.
+
+=cut
+
+# the replace method can be inherited from FS::Record
+
+=item check
+
+Checks all fields to make sure this is a valid record.  If there is
+an error, returns the error, otherwise returns false.  Called by the insert
+and replace methods.
+
+=cut
+
+# the check method should currently be supplied - FS::Record contains some
+# data checking routines
+
+sub check {
+  my $self = shift;
+
+  my $error = 
+    $self->ut_numbern('primary_key')
+    || $self->ut_number('validate_other_fields')
+  ;
+  return $error if $error;
+
+  $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::ClientAPI>, <FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
diff --git a/FS/FS/clientapi_session_field.pm b/FS/FS/clientapi_session_field.pm
new file mode 100644 (file)
index 0000000..f790da8
--- /dev/null
@@ -0,0 +1,126 @@
+package FS::clientapi_session_field;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw( qsearch qsearchs );
+
+@ISA = qw(FS::Record);
+
+=head1 NAME
+
+FS::clientapi_session_field - Object methods for clientapi_session_field records
+
+=head1 SYNOPSIS
+
+  use FS::clientapi_session_field;
+
+  $record = new FS::clientapi_session_field \%hash;
+  $record = new FS::clientapi_session_field { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::clientapi_session_field object represents a FS::ClientAPI session data
+field.  FS::clientapi_session_field inherits from FS::Record.  The following
+fields are currently supported:
+
+=over 4
+
+=item fieldnum - primary key
+
+=item sessionnum - Base ClientAPI sesison (see L<FS::clientapi_session>)
+
+=item fieldname
+
+=item fieldvalie
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new record.  To add the record to the database, see L<"insert">.
+
+Note that this stores the hash reference, not a distinct copy of the hash it
+points to.  You can ask the object for a copy with the I<hash> method.
+
+=cut
+
+# the new method can be inherited from FS::Record, if a table method is defined
+
+sub table { 'clientapi_session_field'; }
+
+=item insert
+
+Adds this record to the database.  If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+# the insert method can be inherited from FS::Record
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+# the delete method can be inherited from FS::Record
+
+=item replace OLD_RECORD
+
+Replaces the OLD_RECORD with this one in the database.  If there is an error,
+returns the error, otherwise returns false.
+
+=cut
+
+# the replace method can be inherited from FS::Record
+
+=item check
+
+Checks all fields to make sure this is a valid record.  If there is
+an error, returns the error, otherwise returns false.  Called by the insert
+and replace methods.
+
+=cut
+
+# the check method should currently be supplied - FS::Record contains some
+# data checking routines
+
+sub check {
+  my $self = shift;
+
+  my $error = 
+    $self->ut_numbern('primary_key')
+    || $self->ut_number('validate_other_fields')
+  ;
+  return $error if $error;
+
+  $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+The author forgot to customize this manpage.
+
+=head1 SEE ALSO
+
+L<FS::clientapi_session>, L<FS::ClientAPI, L<FS::Record>, schema.html from the
+base documentation.
+
+=cut
+
+1;
+
index 4e33efe..921bbc9 100644 (file)
@@ -28,6 +28,7 @@ FS.pm
 FS/CGI.pm
 FS/InitHandler.pm
 FS/ClientAPI.pm
+FS/ClientAPI_SessionCache.pm
 FS/ClientAPI/passwd.pm
 FS/ClientAPI/MyAccount.pm
 FS/Conf.pm
@@ -38,10 +39,7 @@ FS/Report.pm
 FS/Report/Table.pm
 FS/Report/Table/Monthly.pm
 FS/SearchCache.pm
-FS/UI/Base.pm
-FS/UI/CGI.pm
-FS/UI/Gtk.pm
-FS/UI/agent.pm
+FS/UI/Web.pm
 FS/UID.pm
 FS/Msgcat.pm
 FS/acct_snarf.pm
@@ -149,11 +147,14 @@ FS/queue_arg.pm
 FS/queue_depend.pm
 FS/msgcat.pm
 FS/cust_tax_exempt.pm
+FS/clientapi_session.pm
+FS/clientapi_session_field.pm
 t/agent.t
 t/agent_type.t
 t/CGI.t
 t/InitHandler.t
 t/ClientAPI.t
+t/ClientAPI_SessionCache.t
 t/Conf.t
 t/ConfItem.t
 t/Misc.t
@@ -267,3 +268,5 @@ t/queue_arg.t
 t/queue_depend.t
 t/msgcat.t
 t/raddb.t
+t/clientapi_session.t
+t/clientapi_session_field.t
index 24b0685..5ab6eb9 100755 (executable)
@@ -142,7 +142,11 @@ foreach $attribute (@check_attributes) {
 }
 
 #create history tables (false laziness w/create-history-tables)
-foreach my $table ( grep { ! /^h_/ } $dbdef->tables ) {
+foreach my $table (
+  grep { ! /^clientapi_session/ }
+  grep { ! /^h_/ }
+  $dbdef->tables
+) {
   my $tableobj = $dbdef->table($table)
     or die "unknown table $table";
 
@@ -1230,6 +1234,29 @@ sub tables_hash_hack {
       'index'       => [ [ 'codenum' ] ],
     },
 
+    'clientapi_session' => {
+      'columns' => [
+        'sessionnum',  'serial',  '', '',
+        'sessionid',  'varchar',  '', $char_d,
+        'namespace',  'varchar',  '', $char_d,
+      ],
+      'primary_key' => 'sessionnum',
+      'unique'      => [ [ 'sessionid', 'namespace' ] ],
+      'index'       => [],
+    },
+
+    'clientapi_session_field' => {
+      'columns' => [
+        'fieldnum',    'serial',     '', '',
+        'sessionnum',     'int',     '', '',
+        'fieldname',  'varchar',     '', $char_d,
+        'fieldvalue',    'text', 'NULL', '',
+      ],
+      'primary_key' => 'fieldnum',
+      'unique'      => [ [ 'sessionnum', 'fieldname' ] ],
+      'index'       => [],
+    },
+
   );
 
   %tables;
diff --git a/FS/t/ClientAPI_SessionCache.t b/FS/t/ClientAPI_SessionCache.t
new file mode 100644 (file)
index 0000000..4ba88e2
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::ClientAPI::SessionCache;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/clientapi_session.t b/FS/t/clientapi_session.t
new file mode 100644 (file)
index 0000000..a6414c3
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::clientapi_session;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/clientapi_session_field.t b/FS/t/clientapi_session_field.t
new file mode 100644 (file)
index 0000000..a9d4fa9
--- /dev/null
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::clientapi_session_field;
+$loaded=1;
+print "ok 1\n";
index 5c136ab..67554c8 100644 (file)
@@ -47,6 +47,23 @@ CREATE TABLE reg_code_pkg (
 CREATE UNIQUE INDEX reg_code_pkg1 ON reg_code_pkg ( codenum, pkgpart );
 CREATE INDEX reg_code_pkg2 ON reg_code_pkg ( codenum );
 
+CREATE TABLE clientapi_session (
+    sessionnum serial NOT NULL,
+    sessionid varchar(80) NOT NULL,
+    namespace varchar(80) NOT NULL,
+    PRIMARY KEY (sessionnum)
+);
+CREATE UNIQUE INDEX clientapi_session1 ON clientapi_session ( sessionid, namespace );
+
+CREATE TABLE clientapi_session_field (
+    fieldnum serial NOT NULL,
+    sessionnum int NOT NULL,
+    fieldname varchar(80) NOT NULL,
+    fieldvalue text NULL,
+    PRIMARY KEY (fieldnum)
+);
+CREATE UNIQUE INDEX clientapi_session_field1 ON clientapi_session_field ( sessionnum, fieldname );
+
 ALTER TABLE part_pkg ADD promo_code varchar(80) NULL;
 ALTER TABLE h_part_pkg ADD promo_code varchar(80) NULL;
 CREATE INDEX part_pkg2 ON part_pkg ( promo_code );
index a880d91..51c700b 100644 (file)
@@ -54,7 +54,7 @@ Before installing, you need:
       <li><a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a>
       <li><a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a>
       <li><a href="http://search.cpan.org/search?dist=Storable">Storable</a>
-<!-- MyAccounts, maybe only for dev     <li><a href="http://search.cpan.org/search?dist=Cache-Cache">Cache::Cache</a> -->
+      <li><a href="http://search.cpan.org/search?dist=Cache-Cache">Cache::Cache</a>
       <li><a href="http://search.cpan.org/search?dist=NetAddr-IP">NetAddr-IP</a>
       <li><a href="http://search.cpan.org/search?dist=Chart">Chart</a>
       <li><a href="http://search.cpan.org/search?dist=Crypt-PasswdMD5">Crypt::PasswdMD5</a>
index 8af8aa9..63c7953 100644 (file)
     <li><a name="rate_prefix" href="man/FS/rate_prefix.html">rate_prefix</a> - Call rate prefix
       <ul>
         <li>prefixnum - primary key
-        <li>regionnum <a href="#rate_region">rate region</a>
+        <li>regionnum <a href="#rate_region">rate region</a>
         <li>countrycode
         <li>npa
         <li>nxx
         <li>locale - locale
         <li>msg - Message text
       </ul>
+    <li><a name="clientapi_session" href="man/FS/clientapi_session.html">clientapi_session</a> - ClientAPI session store
+      <ul>
+        <li>sessionnum - primary key
+        <li>sessionid - session ID
+        <li>namespace - session namespace
+      </ul>
+    <li><a name="clientapi_session_field" href="man/FS/clientapi_session_field.html">clientapi_session_field</a> - Client API session store data
+      <ul>
+        <li>fieldnum - primary key
+        <li>sessionnum - <a href="#session">session</a>
+        <li>fieldname
+        <li>fieldvalue
+      </ul>
   </ul>
 </body>
index 7441cf1..977755b 100644 (file)
@@ -8,7 +8,7 @@ install Net::SSH 0.08
 - In httpd.conf, change &lt;Files ~ \.cgi&gt; to  &lt;Files ~ (\.cgi|\.html)&gt;
 - In httpd.conf, change <b>AddHandler perl-script .cgi</b> or <b>SetHandler perl-script</b> to <b>AddHandler perl-script .cgi .html</b>
 
-install NetAddr::IP, Chart::Base, IPC::ShareLite, Locale::SubCountry, 
+install NetAddr::IP, Chart::Base, Locale::SubCountry, 
 JavaScript::RPC (JavaScript::RPC::Server::CGI) <!-- and Crypt::YAPassGen-->
 
 INSERT INTO msgcat ( msgnum, msgcode, locale, msg ) VALUES ( 20, 'svc_external-id', 'en_US', 'External ID' );
@@ -240,6 +240,23 @@ CREATE TABLE reg_code_pkg (
 CREATE UNIQUE INDEX reg_code_pkg1 ON reg_code_pkg ( codenum, pkgpart );
 CREATE INDEX reg_code_pkg2 ON reg_code_pkg ( codenum );
 
+CREATE TABLE clientapi_session (
+    sessionnum serial NOT NULL,
+    sessionid varchar(80) NOT NULL,
+    namespace varchar(80) NOT NULL,
+    PRIMARY KEY (sessionnum)
+);
+CREATE UNIQUE INDEX clientapi_session1 ON clientapi_session ( sessionid, namespace );
+
+CREATE TABLE clientapi_session_field (
+    fieldnum serial NOT NULL,
+    sessionnum int NOT NULL,
+    fieldname varchar(80) NOT NULL,
+    fieldvalue text NULL,
+    PRIMARY KEY (fieldnum)
+);
+CREATE UNIQUE INDEX clientapi_session_field1 ON clientapi_session_field ( sessionnum, fieldname );
+
 DROP INDEX cust_bill_pkg1;
 
 ALTER TABLE cust_bill_pkg ADD itemdesc varchar(80) NULL;