package Slim::Schema::Storage;

# $Id: Storage.pm 11972 2007-05-12 07:32:19Z kdf $

# SlimServer Copyright (c) 2001-2007 Logitech.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License,
# version 2.

# Shim to get a backtrace out of throw_exception

use strict;
use base qw(DBIx::Class::Storage::DBI::mysql);

use Carp::Clan qw/DBIx::Class/;
use File::Slurp;
use File::Spec;

use Slim::Utils::Misc;
use Slim::Utils::MySQLHelper;
use Slim::Utils::Prefs;

our $dbAccess = Slim::Utils::PerfMon->new('Database Access', [0.002, 0.005, 0.01, 0.015, 0.025, 0.05, 0.1, 0.5, 1, 5], 1);

sub dbh {
	my $self = shift;

	eval { $self->ensure_connected };

	# Try and bring up the database if we can't connect.
	if ($@ && $@ =~ /Connection failed/) {

		my $lockFile = File::Spec->catdir(Slim::Utils::Prefs::get('cachedir'), 'mysql.startup');

		if (!-f $lockFile) {

			write_file($lockFile, 'starting');

			errorMsg("Unable to connect to the database - trying to bring it up!\n");

			$@ = '';

			if (Slim::Utils::MySQLHelper->init) {

				eval { $self->ensure_connected };

				if ($@) {
					errorMsg("Unable to connect to the database - even tried restarting it twice!\n");
					errorMsg("Check the event log for errors on Windows. Fatal. Exiting.\n");
					exit;
				}
			}

			unlink($lockFile);
		}

	} elsif ($@) {

		return $self->throw_exception($@);
	}

	return $self->_dbh;
}

sub throw_exception {
	my ($self, $msg) = @_;

	errorMsg($msg);
	errorMsg("Backtrace follows:\n");
	bt();

	# Need to propagate the real error so that DBIx::Class::Storage will
	# do the right thing and reconnect to the DB.
	croak($msg);
}

sub select { 
	my $self = shift;

	$::perfmon && (my $now = Time::HiRes::time());

	my @ret = $self->next::method(@_);

	$::perfmon && $dbAccess->log(Time::HiRes::time() - $now) && msg("    DBIx select\n", undef, 1);

	return wantarray ? @ret : $ret[0];
}

sub select_single { 
	my $self = shift;

	$::perfmon && (my $now = Time::HiRes::time());

	my @ret = $self->next::method(@_);

	$::perfmon && $dbAccess->log(Time::HiRes::time() - $now) && msg("    DBIx select_single\n", undef, 1);

	return wantarray ? @ret : $ret[0];
}

1;

__END__
