epic-ts
[kivitendo-erp.git] / SL / DBConnect.pm
index e67d8d0..9fcf7f4 100644 (file)
@@ -4,10 +4,18 @@ use strict;
 
 use DBI;
 use SL::DB;
+use SL::DBConnect::Cache;
 
-sub connect {
+my %dateformat_to_datestyle = (
+  'yy-mm-dd'   => 'ISO',
+  'yyyy-mm-dd' => 'ISO',
+  'mm/dd/yy'   => 'SQL, US',
+  'dd/mm/yy'   => 'SQL, EUROPEAN',
+  'dd.mm.yy'   => 'GERMAN'
+);
+
+sub _connect {
   my ($self, @args) = @_;
-  @args = $self->get_connect_args if !@args;
 
   return DBI->connect(@args) unless $::lx_office_conf{debug} && $::lx_office_conf{debug}->{dbix_log4perl};
 
@@ -22,13 +30,48 @@ sub connect {
   return DBIx::Log4perl->connect(@args);
 }
 
+sub connect {
+  my ($self, @args) = @_;
+  @args = $self->get_connect_args if !@args;
+  my $initial_sql = $self->get_initial_sql;
+
+  if (my $cached_dbh = SL::DBConnect::Cache->get(@args, $initial_sql)) {
+    return $cached_dbh;
+  }
+
+  my $dbh = $self->_connect(@args);
+  return undef if !$dbh;
+
+  if ($initial_sql) {
+    $dbh->do($initial_sql);
+    $dbh->commit if !$dbh->{AutoCommit};
+  }
+  SL::DBConnect::Cache->store($dbh, @args, $initial_sql);
+
+  return $dbh;
+}
+
+sub get_datestyle {
+  my ($self, $dateformat) = @_;
+  return $dateformat_to_datestyle{ $dateformat || $::myconfig{dateformat} // '' };
+}
+
+sub get_initial_sql {
+  my ($self) = @_;
+
+  return undef if !%::myconfig || !$::myconfig{dateformat};
+
+  my $datestyle = $self->get_datestyle;
+  return $datestyle ? qq|SET DateStyle to '${datestyle}'| : '';
+}
+
 sub get_connect_args {
   my ($self, @args)   = @_;
   my ($domain, $type) = SL::DB::_register_db(SL::DB->default_domain, 'KIVITENDO');
   my $db_cfg          = SL::DB->registry->entry(domain => $domain, type => $type) || { };
 
   return (
-    'dbi:' . $db_cfg->{dbi_driver} . ':dbname=' . $db_cfg->{database} . ';host=' . ($db_cfg->{host} || 'localhost') . ';port=' . ($db_cfg->{port} || 5432),
+    'dbi:Pg:dbname=' . $db_cfg->{database} . ';host=' . ($db_cfg->{host} || 'localhost') . ';port=' . ($db_cfg->{port} || 5432),
     $db_cfg->{username},
     $db_cfg->{password},
     $self->get_options(%{ $db_cfg->{connect_options} || {} }, @args),
@@ -38,7 +81,7 @@ sub get_connect_args {
 sub get_options {
   my $self    = shift;
   my $options = {
-    pg_enable_utf8 => $::locale->is_utf8,
+    pg_enable_utf8 => 1,
     @_
   };
 
@@ -76,7 +119,7 @@ optionally routing through DBIx::Log4perl
 
 Connects to the database. If the configuration parameter
 C<debug.dbix_log4perl> is set then the call is made through
-L<DBIx::Log4per/connect>. Otherwise L<DBI/connect> is called directly.
+L<DBIx::Log4perl/connect>. Otherwise L<DBI/connect> is called directly.
 
 In each case C<@dbi_args> is passed through as-is.
 
@@ -97,6 +140,19 @@ C<%options> are optional database options like C<AutoCommit> (fourth
 parameter to L<DBI/connect>). They're merged with default settings by
 filtering them through L/get_options>.
 
+=item C<get_datestyle [$dateformat]>
+
+Returns the appropriate value for the C<SET DateStyle to...> SQL call
+depending on C<$dateformat> (e.g. C<SQL, EUROPEAN> if C<$dateformat>
+equals C<dd.mm.yy>). If C<$dateformat> is not given then it defaults
+to C<$::myconfig{dateformat}>.
+
+=item C<get_initial_sql>
+
+Returns SQL commands that should be executed right after a connection
+has been established. This is usually the call to configure the
+C<DateStyle> format used by the database.
+
 =item C<get_options [%options]>
 
 Returns a hash reference of database options (fourth parameter to