[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SF.net SVN: ledger-smb:[6558] trunk



Revision: 6558
          http://sourceforge.net/p/ledger-smb/code/6558
Author:   einhverfr
Date:     2014-01-20 10:49:13 +0000 (Mon, 20 Jan 2014)
Log Message:
-----------
Centralized a fair bit of database connection code.
Also provided a functional interface to App_State so we can depricate direct value access.

Modified Paths:
--------------
    trunk/LedgerSMB/App_State.pm
    trunk/LedgerSMB/Form.pm
    trunk/LedgerSMB.pm
    trunk/lsmb-request.pl
    trunk/old-handler.pl
    trunk/sql/modules/LOADORDER

Added Paths:
-----------
    trunk/LedgerSMB/DBH.pm

Modified: trunk/LedgerSMB/App_State.pm
===================================================================
--- trunk/LedgerSMB/App_State.pm	2014-01-20 07:55:57 UTC (rev 6557)
+++ trunk/LedgerSMB/App_State.pm	2014-01-20 10:49:13 UTC (rev 6558)
@@ -81,26 +81,86 @@
 
 =back
 
-=head1 METHODS 
+Each of the above has an accessor function fo the same name which reads the 
+data, and a set_... function which writes it.  The set_ function should be 
+used sparingly.
 
+The direct access approach is deprecated and is likely to go away in 1.5 with 
+the variables above given a "my" scope instead of an "our" one.
 
-=head2 zero()
+=cut
 
-zeroes out all majro parts.
+sub _set_n {
+    no strict 'refs';
+    my ($att) = shift @_;
+    for (@_){
+        if ($_ ne __PACKAGE__){
+            $$att = $_;
+            return $_;
+        }
+    }
+}
 
-=cut
+sub DBName {
+    return $DBName;
+}
 
-sub zero() {
-    $User = undef;
-    #tshvr4 leave it initialised, otherwise 'Can't call method "text" on an undefined value' if
-    # still errors between calling this method and and end of script
-    #$Locale = undef;
-    $DBH = undef;
-    @Roles = ();
-    $DBName = undef;
-    $Role_Prefix = undef;
+sub set_DBName {
+    return _set_n('DBName', @_);
 }
 
+sub User {
+    return $User;
+}
+
+sub set_User {
+    return _set_n('User', @_);
+}
+
+sub Locale {
+    return $Locale;
+}
+
+sub set_Locale {
+    return _set_n('Locale', @_);
+}
+
+sub Roles {
+    return @Roles;
+}
+
+sub set_Roles {
+    shift @_ if $_[0] eq __PACKAGE__;
+    @Roles = @_;
+    return @Roles;
+}
+
+sub Company_Settings {
+    return $Company_Settings;
+}
+
+sub set_Company_Settings {
+    return _set_n('Company_Settings', @_);
+}
+
+sub DBH {
+    return $DBH;
+}
+
+sub set_DBH {
+    return _set_n('DBH', @_);
+}
+
+sub Role_Prefix {
+    return $Role_Prefix;
+}
+
+sub set_Role_Prefix {
+    return _set_n('Role_Prefix', @_);
+}
+
+=head1 METHODS 
+
 =head2 cleanup
 
 Deletes all objects attached here.

Added: trunk/LedgerSMB/DBH.pm
===================================================================
--- trunk/LedgerSMB/DBH.pm	                        (rev 0)
+++ trunk/LedgerSMB/DBH.pm	2014-01-20 10:49:13 UTC (rev 6558)
@@ -0,0 +1,111 @@
+=head1 NAME
+
+LedgerSMB::DBH - Database Connection Routines for LedgerSMB
+
+=head1 SYNPOSIS
+
+  my $dbh = LedgerSMB::DBH->connect($company, $username, $password);
+
+or
+
+  my $dbh = LedgerSMB::DBH->connect($company)
+
+to use credentials returned by LedgerSMB::Auth::get_credentials
+
+=cut
+
+package LedgerSMB::DBH;
+use strict;
+use LedgerSMB::Auth;
+use LedgerSMB::Sysconfig;
+use LedgerSMB::App_State;
+use LedgerSMB::Setting;
+use DBI;
+
+=head1 DESCRIPTION
+
+Sets up and manages the db connection.  This returns a DBI database handle.
+
+=head1 FUNCTIONS
+
+=head2 connect ($username, $password)
+
+Returns a connection authenticated with $username and $password.  If $username 
+is not sent, then these are taken from LedgerSMB::Auth::get_credentials.
+
+Note:  if get_credentials returns a username of 'logoud', then this will return
+control there to prompt for credentials again.
+
+=cut
+
+sub connect {
+    my ($package, $company, $username, $password) = @_;
+    if (!$username){
+        my $creds = LedgerSMB::Auth::get_credentials;
+        LedgerSMB::Auth::credential_prompt() if $creds->{login} eq 'logout';
+        $username = $creds->{login};    
+        $password = $creds->{password};    
+    }
+    return undef unless $username;
+    my $dbh = DBI->connect(qq|dbi:Pg:dbname="$company"|, $username, $password,
+           { AutoCommit => 0, pg_enable_utf8 => 1, pg_server_prepare => 0 });
+    my $dbi_trace=$LedgerSMB::Sysconfig::DBI_TRACE;
+    if($dbi_trace)
+    {
+     $dbh->trace(split /=/,$dbi_trace,2);#http://search.cpan.org/~timb/DBI-1.616/DBI.pm#TRACING
+    }
+
+    return $dbh;
+}
+
+=head2 set_datestyle
+
+This is used for old code, to set the datetyle for input.  It is not needed 
+for new code because of PGDate support to/from the db.  For this reason, once
+order entry is removed, we should probably remove support for it.
+
+=cut
+
+sub set_datestyle {
+    my $dbh = LedgerSMB::App_State::DBH;
+    my $datequery = 'select dateformat from user_preference join users using(id)
+                      where username = CURRENT_USER';
+    my $date_sth = $dbh->prepare($datequery);
+    $date_sth->execute;
+    my ($datestyle) = $date_sth->fetchrow_array;
+    my %date_query = (
+        'mm/dd/yyyy' => 'set DateStyle to \'SQL, US\'',
+        'mm-dd-yyyy' => 'set DateStyle to \'POSTGRES, US\'',
+        'dd/mm/yyyy' => 'set DateStyle to \'SQL, EUROPEAN\'',
+        'dd-mm-yyyy' => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
+        'dd.mm.yyyy' => 'set DateStyle to \'GERMAN\''
+    );
+    $dbh->do( $date_query{ $datestyle } );
+}
+
+=head2 require_version($version)
+
+Requires a specific version (exactly).  Dies if doesn't match.
+
+=cut
+
+sub require_version {
+    my ($self, $expected_version) = @_;
+    $expected_version ||= $self; # handling ::require_version($version) syntax
+    my $version = LedgerSMB::Setting->get('version');
+    die LedgerSMB::App_State->Locale->text("Database is not the expected version.  Was $version, expected $expected_version.  Please re-run setup.pl against this database to correct.<a href='setup.pl'>setup.pl</a>")
+       unless $version eq $expected_version;
+    return 0;
+}
+
+=head1 COPYRIGHT
+
+Copyright (C) 2014 The LedgerSMB Core Team. 
+
+This file may be reused under the terms of the GNU General Public License, 
+version 2 or at your option any later version.  Please see the included
+LICENSE.txt for more information.
+
+=cut
+
+1;

Modified: trunk/LedgerSMB/Form.pm
===================================================================
--- trunk/LedgerSMB/Form.pm	2014-01-20 07:55:57 UTC (rev 6557)
+++ trunk/LedgerSMB/Form.pm	2014-01-20 10:49:13 UTC (rev 6558)
@@ -68,6 +68,9 @@
 use Log::Log4perl;
 use LedgerSMB::App_State;
 use LedgerSMB::Setting::Sequence;
+use Try::Tiny;
+use Carp;
+use DBI;
 
 use charnames qw(:full);
 use open ':utf8';
@@ -412,10 +415,10 @@
 
 sub error {
     my ( $self, $msg ) = @_;
-    die $msg;
+    Carp::croak $msg;
 }
 
-sub error {
+sub _error {
 
     my ( $self, $msg ) = @_;
 
@@ -1226,58 +1229,26 @@
 sub db_init {
     my ( $self, $myconfig ) = @_;
     $logger->trace("begin");
-
-    # Handling of HTTP Basic Auth headers
-    my $auth = $ENV{'HTTP_AUTHORIZATION'};
-	# Send HTTP 401 if the authorization header is missing
-    LedgerSMB::Auth::credential_prompt unless ($auth);
-	$auth =~ s/Basic //i; # strip out basic authentication preface
-    $auth = MIME::Base64::decode($auth);
-    my ($login, $password) = split(/:/, $auth);
-    LedgerSMB::Auth::credential_prompt() if $login eq 'logout';
-    $self->{login} = $login;
     if (!$self->{company}){ 
         $self->{company} = $LedgerSMB::Sysconfig::default_db;
     }
     my $dbname = $self->{company};
-    $self->{dbh} = DBI->connect(qq|dbi:Pg:dbname="$dbname"|, $login, $password,
-           { AutoCommit => 0 }) || LedgerSMB::Auth::credential_prompt();
-
-    $logger->debug("acquired dbh \$self->{dbh}=$self->{dbh}");
-    $self->{dbh}->{pg_server_prepare} = 0;
+    $self->{dbh} = LedgerSMB::DBH->connect($self->{company});
     my $dbh = $self->{dbh};
+    LedgerSMB::App_State::set_DBH($dbh);
+    LedgerSMB::DBH->set_datestyle;
 
-    my $datequery = 'select dateformat from user_preference join users using(id)
-                      where username = CURRENT_USER';
-    my $date_sth = $dbh->prepare($datequery);
-    $date_sth->execute;
-    my ($datestyle) = $date_sth->fetchrow_array;
-    my %date_query = (
-        'mm/dd/yy' => 'set DateStyle to \'SQL, US\'',
-        'mm-dd-yy' => 'set DateStyle to \'POSTGRES, US\'',
-        'dd/mm/yy' => 'set DateStyle to \'SQL, EUROPEAN\'',
-        'dd-mm-yy' => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
-        'dd.mm.yy' => 'set DateStyle to \'GERMAN\''
-    );
-    $self->{dbh}->do( $date_query{ $datestyle } );
+
     $self->{db_dateformat} = $myconfig->{dateformat};    #shim
 
-    # This is the general version check
-    my $sth = $dbh->prepare("
-            SELECT value FROM defaults 
-             WHERE setting_key = 'version'");
-    $sth->execute;
-    my ($dbversion) = $sth->fetchrow_array;
-    if ($dbversion ne $self->{dbversion}){
-        $self->error("Database is not the expected version.");
-    }
+    LedgerSMB::DBH->require_version($self->{version});
 
     my $query = "SELECT t.extends, 
 			coalesce (t.table_name, 'custom_' || extends) 
 			|| ':' || f.field_name as field_def
 		FROM custom_table_catalog t
 		JOIN custom_field_catalog f USING (table_id)";
-    $sth = $self->{dbh}->prepare($query);
+    my $sth = $self->{dbh}->prepare($query);
     $sth->execute;
     my $ref;
     while ( $ref = $sth->fetchrow_hashref('NAME_lc') ) {

Modified: trunk/LedgerSMB.pm
===================================================================
--- trunk/LedgerSMB.pm	2014-01-20 07:55:57 UTC (rev 6557)
+++ trunk/LedgerSMB.pm	2014-01-20 10:49:13 UTC (rev 6558)
@@ -159,7 +159,6 @@
 use LedgerSMB::PGNumber;
 use LedgerSMB::PGDate;
 use LedgerSMB::Sysconfig;
-use Data::Dumper;
 use LedgerSMB::App_State;
 use LedgerSMB::Auth;
 use LedgerSMB::Session;
@@ -168,6 +167,7 @@
 use LedgerSMB::User;
 use LedgerSMB::Setting;
 use LedgerSMB::Company_Config;
+use LedgerSMB::DBH;
 use Carp;
 use strict;
 use utf8;
@@ -175,6 +175,9 @@
 $CGI::Simple::POST_MAX = -1;
 
 package LedgerSMB;
+use Try::Tiny;
+use DBI;
+
 use base qw(LedgerSMB::Request);
 our $VERSION = '1.4.0';
 
@@ -620,13 +623,13 @@
 }
 
 sub finalize_request {
-    LedgerSMB::App_State->zero();
+    LedgerSMB::App_State->cleanup();
 }
 
 # To be replaced with a generic interface to an Error class
 sub error {
     my ($self, $msg) = @_;
-    die $msg;
+    Carp::croak $msg;
 }
 
 sub _error {
@@ -668,72 +671,29 @@
     my $self     = shift @_;
     my %args     = @_;
     (my $package,my $filename,my $line)=caller;
-    if($self->{dbh})
-    {
-     $logger->error("dbh already set \$self->{dbh}=$self->{dbh},called from $filename");
-    }
-
-    my $creds = LedgerSMB::Auth::get_credentials();
-    LedgerSMB::Auth::credential_prompt() if $creds->{login} eq 'logout';
-    return unless $creds->{login};
-  
-    $self->{login} = $creds->{login};
     if (!$self->{company}){ 
         $self->{company} = $LedgerSMB::Sysconfig::default_db;
     }
-    my $dbname = $self->{company};
 
-    # Note that we have to request the login/password again if the db
-    # connection fails since this probably means bad credentials are entered.
-    # Just in case, however, I think it is a good idea to include the DBI
-    # error string.  CT
-    $self->{dbh} = DBI->connect(
-        qq|dbi:Pg:dbname="$dbname"|, "$creds->{login}", "$creds->{password}", { AutoCommit => 0 }
-    ); 
-    #move dbi_trace further on , dbh may not have been acquired because of authentication error
+    $self->{dbh} = LedgerSMB::DBH->connect($self->{company})
+      || LedgerSMB::Auth::credential_prompt;
 
+    LedgerSMB::App_State::set_DBH($self->{dbh});
+    LedgerSMB::App_State::set_DBName($self->{company});
 
-    if (($self->{script} eq 'login.pl') && ($self->{action} eq 
-        'authenticate')){
-        if (!$self->{dbh}){
-            $self->{_auth_error} = $DBI::errstr;
-        }
-        return;
-    }
-    elsif (!$self->{dbh}){
-        $self->_get_password;
-    }
-
-    $logger->debug("DBI->connect dbh=$self->{dbh}");
-    my $dbi_trace=$LedgerSMB::Sysconfig::DBI_TRACE;
-    if($dbi_trace)
-    {
-     $logger->debug("\$dbi_trace=$dbi_trace");
-     $self->{dbh}->trace(split /=/,$dbi_trace,2);#http://search.cpan.org/~timb/DBI-1.616/DBI.pm#TRACING
-    }
-
-    $self->{dbh}->{pg_server_prepare} = 0;
-    $self->{dbh}->{pg_enable_utf8} = 1;
-    $LedgerSMB::App_State::DBH = $self->{dbh};
-    $LedgerSMB::App_State::DBName = $dbname;
-
-    # This is the general version check
+    try {
+        LedgerSMB::DBH->require_version($VERSION);
+    } catch {
+        $self->_error($_);
+    };
+    
     my $sth = $self->{dbh}->prepare("
             SELECT value FROM defaults 
-             WHERE setting_key = 'version'");
-    $sth->execute;
-    my ($dbversion) = $sth->fetchrow_array;
-    $sth = $self->{dbh}->prepare("
-            SELECT value FROM defaults 
              WHERE setting_key = 'role_prefix'");
     $sth->execute;
 
 
     ($self->{_role_prefix}) = $sth->fetchrow_array;
-    if ($dbversion ne $self->{dbversion}){
-        #$self->error("Database is not the expected version.  Was $dbversion, expected $self->{dbversion}.  Please re-run setup.pl against this database to correct.<a href='setup.pl'>setup.pl</a>");
-        $self->_error("Database is not the expected version.  Was $dbversion, expected $self->{dbversion}.  Please re-run setup.pl against this database to correct.<a href='setup.pl'>setup.pl</a>");
-    }
 
     $sth = $self->{dbh}->prepare('SELECT check_expiration()');
     $sth->execute;

Modified: trunk/lsmb-request.pl
===================================================================
--- trunk/lsmb-request.pl	2014-01-20 07:55:57 UTC (rev 6557)
+++ trunk/lsmb-request.pl	2014-01-20 10:49:13 UTC (rev 6558)
@@ -37,7 +37,7 @@
 use Log::Log4perl;
 use strict;
 
-LedgerSMB::App_State->zero();
+LedgerSMB::App_State->cleanup();
 
 my $logger = Log::Log4perl->get_logger('LedgerSMB::Handler');
 Log::Log4perl::init(\$LedgerSMB::Sysconfig::log4perl_config);

Modified: trunk/old-handler.pl
===================================================================
--- trunk/old-handler.pl	2014-01-20 07:55:57 UTC (rev 6557)
+++ trunk/old-handler.pl	2014-01-20 10:49:13 UTC (rev 6558)
@@ -219,7 +219,7 @@
   # when output terminates.  A mere 'die' will no longer trigger an automatic
   # error, but die 'foo' will map to $form->error('foo')
   # -- CT
-  $form->error("'$_'")  unless $_ =~ /^Died at/i; 
+  $form->_error("'$_'")  unless $_ =~ /^Died at/i; 
 } 
 ;
 

Modified: trunk/sql/modules/LOADORDER
===================================================================
--- trunk/sql/modules/LOADORDER	2014-01-20 07:55:57 UTC (rev 6557)
+++ trunk/sql/modules/LOADORDER	2014-01-20 10:49:13 UTC (rev 6558)
@@ -45,3 +45,4 @@
 Goods.sql
 Roles.sql
 Templates.sql
+Fixes.sql

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.


------------------------------------------------------------------------------
CenturyLink Cloud: The Leader in Enterprise Cloud Services.
Learn Why More Businesses Are Choosing CenturyLink Cloud For
Critical Workloads, Development Environments & Everything In Between.
Get a Quote or Start a Free Trial Today. 
http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk
_______________________________________________
Ledger-smb-commits mailing list
..hidden..
https://lists.sourceforge.net/lists/listinfo/ledger-smb-commits