#!/usr/bin/perl

use strict;
use Time::HiRes qw(tv_interval gettimeofday);
use DBI;
sleep 2;

# 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");

# PostgreSQL
&bench("Pg", "dbname=eijiro", "fujiwara", "", "eijiro", 0);
&bench("Pg", "dbname=eijiro", "fujiwara", "", "eijiro", 1);

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

	my $t0 = [gettimeofday];
	my $dbh = DBI->connect("dbi:$driver:$dsn", $user, $pass,{ RaiseError => 1 });
	my $tc = round(tv_interval($t0), 5);
	print "$driver(connect $tc) $type", $order ? ' (sorted) ' : '', "\n";

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

	foreach my $where ('create %', 'table a%', '%text%', '%integer%'){
		my $count = 0;
		my $t1 = [gettimeofday];
		my $sth = $dbh->prepare($sql);
		$sth->execute($where);
		my $t2 = round(tv_interval($t1), 5);
		while(my $result_arrayref = $sth->fetchrow_arrayref){
			$count ++;
			my @dummy = @{$result_arrayref};
		}
		my $t3 = round(tv_interval($t1), 5);
		my $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;
