# - pointer to config class
sub new {
my $class = shift;
+
my $self = {};
# bless mysqlf
bless($self, $class);
# define own variables
# db connection
$self->{db_connection} = undef;
+ # configuration data
+ $self->{config} = {};
# return reference
return $self;
}
-# DESTROY()
+# set_config()
#
-# destructor
+# set a configuration parameter
#
# parameter:
-# - self
+# - class name ($self)
+# - key name
+# - value name
# return:
# none
-sub DESTROY {
+sub set_config {
my $self = shift;
+ my $key = shift;
+ my $value = shift;
+
+ $self->{config}->{$key} = $value;
+}
+
+
+# verify_config()
+#
+# verify database connection (if all required parameters are set)
+#
+# parameter:
+# - class name ($self)
+# return:
+# - 0/1
+sub verify_config {
+ my $self = shift;
+
+ if (!defined($self->{config}->{'name'})) {
+ return 0;
+ }
+ if (!defined($self->{config}->{'host'})) {
+ return 0;
+ }
+ if (!defined($self->{config}->{'port'})) {
+ return 0;
+ }
+ if (!defined($self->{config}->{'username'})) {
+ return 0;
+ }
+ if (!defined($self->{config}->{'password'})) {
+ return 0;
+ }
+ if (!defined($self->{config}->{'schema'})) {
+ return 0;
+ }
+ return 1;
}
+# open_db_connection()
+#
+# open database connection
+#
+# parameter:
+# - class name ($self)
+# return:
+# - 0/1
sub open_db_connection {
my $self = shift;
- my $DSN = "dbi:Pg:dbname=$main::db_name";
- if ($main::db_host) {
- $DSN .= ";host=$main::db_host";
+ if (!$self->verify_config()) {
+ return 0;
}
- if ($main::db_port) {
- $DSN .= ";port=$main::db_port";
+
+ if ($self->{db_connection}) {
+ # Note: do not try to ping the database here, this will create an endless loop
+ return 1;
+ }
+
+ my $db_name = $self->{config}->{'name'};
+ my $db_host = $self->{config}->{'host'};
+ my $db_port = $self->{config}->{'port'};
+ my $db_username = $self->{config}->{'username'};
+ my $db_password = $self->{config}->{'password'};
+ my $db_schema = $self->{config}->{'schema'};
+
+
+ my $DSN = "dbi:Pg:dbname=$db_name";
+ if ($db_host) {
+ $DSN .= ";host=$db_host";
+ }
+ if ($db_port) {
+ $DSN .= ";port=$db_port";
}
my $dbh = DBI->connect_cached(
$DSN,
- $main::db_user,
- $main::db_pass,
+ $db_username,
+ $db_password,
{
"RaiseError" => 0,
"PrintError" => 0,
);
unless ($dbh) {
- print_msg("Can't connect to database - $DBI::errstr\n", ERROR);
+ main::print_msg("Can't connect to database - $DBI::errstr\n", ERROR);
return 0;
}
$dbh->{RaiseError} = 1;
- if ($main::db_schema) {
- $dbh->do("SET search_path = '$main::db_schema'");
+ if ($db_schema) {
+ $dbh->do("SET search_path = '$db_schema'");
$dbh->commit();
}
$self->{db_connection} = $dbh;
+ $main::statistics{'database_connects'}++;
+
+ return 1;
+}
+
+
+# reconnect_db_connection()
+#
+# reconnect the database connection
+#
+# parameter:
+# - class name ($self)
+# return:
+# - 0/1
+sub reconnect_db_connection {
+ my $self = shift;
+
+ $self->close_db_connection();
+ if (!$self->open_db_connection()) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+# close_db_connection()
+#
+# close database connection
+#
+# parameter:
+# - class name ($self)
+# return:
+# none
+sub close_db_connection {
+ my $self = shift;
+
+ if (defined($self->{db_connection})) {
+ $self->{db_connection}->disconnect;
+ undef($self->{db_connection});
+ }
+}
+
+
+# test_database()
+#
+# test database connectivity
+#
+# parameter:
+# - class name ($self)
+# return:
+# - 0/1
+sub test_database {
+ my $self = shift;
+
+ if (!$self->ping()) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+# ping()
+#
+# execute a test query
+#
+# parameter:
+# - class name ($self)
+# return:
+# - 0/1
+sub ping {
+ my $self = shift;
+
+ my $query = 'SELECT 1';
+ if (!$self->do($query)) {
+ # ping failed, reconnect the database
+ $self->reconnect_db_connection();
+ if (!$self->do($query)) {
+ # reconnect failed
+ return 0;
+ }
+ }
return 1;
}
+# do()
+#
+# execute a query
+#
+# parameter:
+# - class name ($self)
+# - query
+# return:
+# - 0/1
+sub do {
+ my $self = shift;
+ my $query = shift;
+
+ main::print_msg("Execute database query: $query", DEBUG2);
+
+ if (!defined($self->{db_connection})) {
+ main::print_msg("Database not connected", ERROR);
+ return 0;
+ }
+
+ my $result = $self->{db_connection}->do($query);
+ if (!$result) {
+ main::print_msg("Could not execute database query", ERROR);
+ return 0;
+ }
+ $main::statistics{'database_queries'}++;
+
+ return 1;
+}
+
+
+# query()
+#
+# execute a query and return the result set
+#
+# parameter:
+# - class name ($self)
+# - query
+# return:
+# - pointer to query result, or undef
+sub query {
+ my $self = shift;
+ my $query = shift;
+
+ main::print_msg("Execute database query: $query", DEBUG2);
+
+ if (!defined($self->{db_connection})) {
+ main::print_msg("Database not connected", ERROR);
+ return undef;
+ }
+
+ my $st = $self->{db_connection}->prepare($query);
+ if (!$st->execute) {
+ main::print_msg("Could not execute database query", ERROR);
+ return undef;
+ }
+ $main::statistics{'database_queries'}++;
+
+ return $st;
+}
+
+
+# DESTROY()
+#
+# destructor
+#
+# parameter:
+# - self
+# return:
+# none
+sub DESTROY {
+ my $self = shift;
+
+ $self->close_db_connection();
+}
+
+
# finish module
1;
}
+init_database();
init_sessions();
$main::statistics{'database_queries'} = 0;
$main::statistics{'connects'} = 0;
-
}
+# init_database()
+#
+# init configuration
+#
+# parameter:
+# none
+# return:
+# none
+sub init_database {
+ print_msg("Init database configuration and connection", DEBUG);
+
+ # create database class
+ $main::db = docbot::db->new();
+ # fill in the configuration
+ $main::db->set_config('name', config_get_key2('database', 'name'));
+ $main::db->set_config('host', config_get_key2('database', 'host'));
+ $main::db->set_config('port', (config_get_key2('database', 'port')) ? config_get_key2('database', 'port') : '5432');
+ $main::db->set_config('username', config_get_key2('database', 'username'));
+ $main::db->set_config('password', config_get_key2('database', 'password'));
+ $main::db->set_config('schema', (config_get_key2('database', 'schema')) ? config_get_key2('database', 'schema') : 'public');
+
+ # validate formal database configuration
+ if (!$main::db->verify_config()) {
+ die("Database configuration is incomplete!\n");
+ }
+ # open database connection
+ if (!$main::db->open_db_connection()) {
+ die("Could not open database connection!\n");
+ }
+ # and test connectivity
+ if (!$main::db->test_database()) {
+ die("Could not test database connection!\n");
+ }
+}
+
# init_config()
#
# return:
# none
sub maintenance {
- if (!test_database()) {
+ if (!$main::db->test_database()) {
print_msg("Database not connected!", ERROR);
}