# -*- cperl -*-
# -----------------------------------------------------------------------------
package Celaenito::DB;
use strict;
use warnings;
use DBI;
use Celaenito::Logger;
use Kibibyte qw(kibibyte_format);
use version;
use constant PROSPECTED_PACKET_SIZE_LIMIT => 15 * 1024 * 1024;
require Exporter;
our @ISA = qw(Exporter);
our $AUTOLOAD;
our $DB;
our $MAX_ALLOWED_PACKET;
our @EXPORT = qw(&DB);

BEGIN {
    use vars qw($DB_TYPE $DB_NAME $DB_USER $DB_PASS);
    do {
	no strict;
	no warnings;
	do 'celaenito.conf';
    };
}

sub config {
    return {
	TYPE => $DB_TYPE,
	NAME => $DB_NAME,
	USER => $DB_USER,
	PASS => $DB_PASS,
    };
}

sub detach {
    $DB = undef;
}

sub sizelimit {
    $MAX_ALLOWED_PACKET;
}

sub DB {
    if (!$DB or !$DB->ping) {
	my $source = do {
	    if ($DB_TYPE eq 'mysql') {
		"DBI:mysql:$DB_NAME";
	    }
	    else {
		die 'Unsupported $DB_TYPE: ' . $DB_TYPE;
	    }
	};
	
	$DB = DBI->connect(
	    $source,
	    $DB_USER,
	    $DB_PASS,
	    {
		RaiseError      => 1,
		AutoCommit      => 1,
		#InactiveDestroy => 1,
	    });

	# max_allowed_packetの確認
	(undef, $MAX_ALLOWED_PACKET) = $DB->selectrow_array(
	    q{SHOW VARIABLES LIKE "max_allowed_packet"});
	if (!$MAX_ALLOWED_PACKET) {
	    logemerg "MySQL variable `max_allowed_packet' is not available. Is this really MySQL? abort...";
	    die "variable `max_allowed_packet' is not available";
	}

	if ($MAX_ALLOWED_PACKET < PROSPECTED_PACKET_SIZE_LIMIT) {
	    logwarn sprintf "Warning: MySQL variable `max_allowed_packet' is too small. ".
	      "Increase it at least %s (%d bytes), or the Celaenito system runs slowly.",
		kibibyte_format('%.2f %s', PROSPECTED_PACKET_SIZE_LIMIT),
		PROSPECTED_PACKET_SIZE_LIMIT;
	}

	# MySQLのバージョンを確認
	my (undef, $mysqlver) = $DB->selectrow_array(
	    q{SHOW VARIABLES LIKE "version"});
	if (!$mysqlver) {
	    logemerg "MySQL variable `version' is not available. Is this really MySQL? abort...";
	    die "variable `version' is not available";
	}
	
	if (qv($mysqlver) < qv('4.0.8') and $MAX_ALLOWED_PACKET >= 16 * 1024 * 1024) {
	    logwarn "Warning: This MySQL $mysqlver (< 4.0.8) doesn't support ".
	      "max_allowed_packet over 16 Mib. Limiting to 15.9 Mib internally...";
	    $MAX_ALLOWED_PACKET = 16 * 1024 * 1024 - 1;
	}

	logdebug sprintf "connected to the MySQL.\n".
	  "version           : %s\n".
	  "max_allowed_packet: %s (%d bytes)",
	    $mysqlver,
	    kibibyte_format('%.2f %s', $MAX_ALLOWED_PACKET),
	    $MAX_ALLOWED_PACKET;
    }
    $DB;
}

1;
