#!/usr/bin/perl

use strict;
use Time::HiRes qw(tv_interval gettimeofday);
use Getopt::Std;
use DBI;
use vars qw/ $opt_d /;

getopt('d');

sleep 2;

if($opt_d eq 'mysql'){
	# MySQL (MyISAM)
	&bench("mysql", "database=test", "root", "mysql", "eijiro", 0, "MyISAM");
	&bench("mysql", "database=test", "root", "mysql", "eijiro", 1, "MyISAM");
	# MySQL (InnoDB)
	# &bench("mysql", "database=test", "root", "mysql", "eijiro_i", 0, "InnoDB");
	# &bench("mysql", "database=test", "root", "mysql", "eijiro_i", 1, "InnoDB");
}elsif($opt_d eq 'Pg'){
	# PostgreSQL
	&bench("Pg", "dbname=eijiro", "fujiwara", "", "eijiro", 0);
	&bench("Pg", "dbname=eijiro", "fujiwara", "", "eijiro", 1);
}elsif($opt_d eq 'SQLite'){
	# SQLite
	&bench("SQLite", "dbname=/home/fujiwara/tmp/sqlite.db", "", "", "eijiro", 0);
	&bench("SQLite", "dbname=/home/fujiwara/tmp/sqlite.db", "", "", "eijiro", 1);
}

sub bench
{
	my ($driver, $dsn, $user, $pass, $table, $order, $type, $op) = @_;

	my $t0 = [gettimeofday];
	my $dbh = DBI->connect("dbi:$driver:$dsn", $user, $pass,{ RaiseError => 1 });
	if($opt_d eq 'SQLite'){
		$dbh->do("PRAGMA synchronous = OFF");
	}

	my $tc = round(tv_interval($t0), 5);
	print "$driver(connect $tc) $type", $order ? ' (sorted) ' : '', "\n";

	my $sql_like = qq|SELECT * FROM $table WHERE word LIKE ?|;
	$sql_like .= qq| ORDER BY word DESC| if $order;

	my $sql_eq = qq|SELECT * FROM $table WHERE word = ?|;
	$sql_eq .= qq| ORDER BY word DESC| if $order;

	foreach my $where ('create %', 'table a%', '%text%', '%integer%', "computer", "performance"){
		my $count = 0;
		my ($t1, $sth, $t2, $t3, $t4);
		my $sql = ($where =~ /%/) ? $sql_like : $sql_eq;
		$t1 = [gettimeofday];
		$sth = $dbh->prepare($sql);
		$sth->execute($where);
		$t2 = round(tv_interval($t1), 5);
		while(my $result_arrayref = $sth->fetchrow_arrayref){
			$count ++;
			my @dummy = @{$result_arrayref};
		}
		$t3 = round(tv_interval($t1), 5);
		$t4 = round($t3 - $t2, 5);
		print "'$where'\t$t3 (select:fetch=$t2:$t4) $count rows\n";
	}
	$dbh->disconnect;
	print "\n";
	sleep 2;
}

sub round
{
  my ($num, $decimals) = @_;
  my ($format, $magic);
  $format = '%.' . $decimals . 'f';
  $magic = ($num > 0) ? 0.5 : -0.5;
  sprintf($format, int(($num * (10 ** $decimals)) + $magic) /
                   (10 ** $decimals));
}

exit;
