Bug 32257: Fix capitalization - Patron Attribute
[koha-ffzg.git] / Koha / Database.pm
index 1da498f..376f910 100644 (file)
@@ -5,18 +5,18 @@ package Koha::Database;
 #
 # This file is part of Koha.
 #
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
 #
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with Koha; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 =head1 NAME
 
@@ -25,105 +25,140 @@ Koha::Database
 =head1 SYNOPSIS
 
   use Koha::Database;
-  my $database = Koha::Database->new();
-  my $schema = $database->schema();
+  my $schema = Koha::Database->schema();
 
 =head1 FUNCTIONS
 
 =cut
 
 use Modern::Perl;
-use Carp;
-use C4::Context;
-use base qw(Class::Accessor);
+use DBI;
+use Koha::Config;
 
-use vars qw($database);
+our $database;
 
-__PACKAGE__->mk_accessors(qw( ));
+=head2 new
 
-# _new_schema
-# Internal helper function (not a method!). This creates a new
-# database connection from the data given in the current context, and
-# returns it.
-sub _new_schema {
+    $schema = Koha::Database->new->schema;
 
-    require Koha::Schema;
+    FIXME: It is useless to have a Koha::Database object since all methods
+    below act as class methods
+    Koha::Database->new->schema is exactly the same as Koha::Database->schema
+    We should use Koha::Database->schema everywhere and remove the `new` method
 
-    my $context = C4::Context->new();
-
-    my $db_driver = $context->{db_driver};
-
-    my $db_name   = $context->config("database");
-    my $db_host   = $context->config("hostname");
-    my $db_port   = $context->config("port") || '';
-    my $db_user   = $context->config("user");
-    my $db_passwd = $context->config("pass");
-    my $tls = $context->config("tls");
-    my $tls_options;
-    if( $tls && $tls eq 'yes' ) {
-        my $ca = $context->config('ca');
-        my $cert = $context->config('cert');
-        my $key = $context->config('key');
-        $tls_options = ";mysql_ssl=1;mysql_ssl_client_key=".$key.";mysql_ssl_client_cert=".$cert.";mysql_ssl_ca_file=".$ca;
-    }
+=cut
+
+sub new { bless {}, shift }
+
+=head2 dbh
+
+    Returns a database handler without loading the DBIx::Class schema.
 
+=cut
+
+sub dbh {
+    my $config = Koha::Config->get_instance;
+    my $driver = db_scheme2dbi($config->get('db_scheme'));
+    my $user = $config->get("user"),
+    my $pass = $config->get("pass"),
+    my $dsn = sprintf(
+        'dbi:%s:database=%s;host=%s;port=%s',
+        $driver,
+        $config->get("database_test") || $config->get("database"),
+        $config->get("hostname"),
+        $config->get("port") || '',
+    );
 
+    my $attr = {
+        RaiseError => 1,
+        PrintError => 1,
+    };
 
-    my ( %encoding_attr, $encoding_query, $tz_query, $sql_mode_query );
-    my $tz = C4::Context->timezone;
-    $tz = q{} if ( $tz eq 'local' );
-    if ( $db_driver eq 'mysql' ) {
-        %encoding_attr = ( mysql_enable_utf8 => 1 );
-        $encoding_query = "set NAMES 'utf8mb4'";
-        $tz_query = qq(SET time_zone = "$tz") if $tz;
-        if ( $ENV{_} =~ m|prove| or C4::Context->config('strict_sql_modes') ) {
-            $sql_mode_query = q{SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'};
-        } else {
-            $sql_mode_query = q{SET sql_mode = 'IGNORE_SPACE,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'};
+    if ($driver eq 'mysql') {
+        my $tls = $config->get("tls");
+        if ($tls && $tls eq 'yes') {
+            $dsn .= sprintf(
+                ';mysql_ssl=1;mysql_ssl_client_key=%s;mysql_ssl_client_cert=%s;mysql_ssl_ca_file=%s',
+                $config->get('key'),
+                $config->get('cert'),
+                $config->get('ca'),
+            );
         }
+
+        $attr->{mysql_enable_utf8} = 1;
     }
-    elsif ( $db_driver eq 'Pg' ) {
-        $encoding_query = "set client_encoding = 'UTF8';";
-        $tz_query = qq(SET TIME ZONE = "$tz") if $tz;
-    }
-    my $schema = Koha::Schema->connect(
-        {
-            dsn => "dbi:$db_driver:database=$db_name;host=$db_host;port=$db_port".($tls_options? $tls_options : ""),
-            user => $db_user,
-            password => $db_passwd,
-            %encoding_attr,
-            RaiseError => $ENV{DEBUG} ? 1 : 0,
-            PrintError => 1,
-            unsafe => 1,
-            quote_names => 1,
-            on_connect_do => [
-                $encoding_query || (),
-                $tz_query || (),
-                $sql_mode_query || (),
-            ]
+
+    my $dbh = DBI->connect($dsn, $user, $pass, $attr);
+
+    if ($dbh) {
+        my @queries;
+        my $tz = $config->timezone;
+        $tz = '' if $tz eq 'local';
+
+        if ($driver eq 'mysql') {
+            push @queries, "SET NAMES 'utf8mb4'";
+            push @queries, qq{SET time_zone = "$tz"} if $tz;
+            if (   $config->get('strict_sql_modes')
+                || ( exists $ENV{_} && $ENV{_} =~ m|prove| )
+                || $ENV{KOHA_TESTING}
+            ) {
+                push @queries, q{
+                    SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
+                };
+            } else {
+                push @queries, q{SET sql_mode = 'IGNORE_SPACE,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'}
+            }
+        } elsif ($driver eq 'Pg') {
+            push @queries, qq{SET TIME ZONE = "$tz"} if $tz;
+            push @queries, q{set client_encoding = 'UTF8'};
         }
-    );
+
+        foreach my $query (@queries) {
+            $dbh->do($query);
+        }
+    }
+
+    return $dbh;
+}
+
+
+# _new_schema
+# Internal helper function (not a method!). This creates a new
+# database connection from the data given in the current context, and
+# returns it.
+sub _new_schema {
+
+    require Koha::Schema;
+
+    my $schema = Koha::Schema->connect({
+        dbh_maker => \&Koha::Database::dbh,
+        quote_names => 1,
+        auto_savepoint => 1,
+    });
 
     my $dbh = $schema->storage->dbh;
     eval {
-        $dbh->{RaiseError} = 1;
+        my $HandleError = $dbh->{HandleError};
         if ( $ENV{KOHA_DB_DO_NOT_RAISE_OR_PRINT_ERROR} ) {
-            $dbh->{RaiseError} = 0;
-            $dbh->{PrintError} = 0;
+            $dbh->{HandleError} = sub { return 1 };
         }
         $dbh->do(q|
             SELECT * FROM systempreferences WHERE 1 = 0 |
         );
-        $dbh->{RaiseError} = $ENV{DEBUG} ? 1 : 0;
+        $dbh->{HandleError} = $HandleError;
     };
-    $dbh->{RaiseError} = 0 if $@;
+
+    if ( $@ ) {
+        $dbh->{HandleError} = sub { warn $_[0]; return 1 };
+    }
 
     return $schema;
 }
 
 =head2 schema
 
-    $schema = $database->schema;
+    $schema = Koha::Database->schema;
+    $schema = Koha::Database->schema({ new => 1 });
 
 Returns a database handle connected to the Koha database for the
 current context. If no connection has yet been made, this method
@@ -137,8 +172,7 @@ possibly C<&set_schema>.
 =cut
 
 sub schema {
-    my $self = shift;
-    my $params = shift;
+    my ($class, $params) = @_;
 
     unless ( $params->{new} ) {
         return $database->{schema} if defined $database->{schema};
@@ -239,6 +273,22 @@ sub flush_schema_cache {
     return 1;
 }
 
+=head2 db_scheme2dbi
+
+    my $dbd_driver_name = Koha::Database::db_scheme2dbi($scheme);
+
+This routines translates a database type to part of the name
+of the appropriate DBD driver to use when establishing a new
+database connection.  It recognizes 'mysql' and 'Pg'; if any
+other scheme is supplied it defaults to 'mysql'.
+
+=cut
+
+sub db_scheme2dbi {
+    my $scheme = shift // '';
+    return $scheme eq 'Pg' ? $scheme : 'mysql';
+}
+
 =head2 EXPORT
 
 None by default.