#
# mysql.pl
# Joel Uckelman (uckelman@nomic.net)
# 28 February 2001
#

#
# handles all queries to the mysql server
#
sub query {
	my ($query) = @_;

   # prepare query
	lock_tables(get_used_tables($query));
	my $sh = $db->prepare($query) or die "\n$prog: failed to prepare query: $DBI::errstr";
	$sh->execute or die "\n$prog: failed to execute query: $DBI::errstr";

	my (@tmp, @data) = ();

	# return a one-dimensional array for one column, two-dimensional for more than one column
	if ($sh->{NUM_OF_FIELDS} == 1) { push @data, @tmp while (@tmp = $sh->fetchrow_array); }
	else { push @data, [ @tmp ] while (@tmp = $sh->fetchrow_array); }

	$sh->finish or die "\n$prog: failed to release handle: $DBI::errstr";

	return @data ;
}

#
# locks tables 
#
sub lock_tables {
	my $tables = join ', ', @_;

	# prevent changes to tables while extracting data
	$tables =~ s/(,|$)/ write$1/g;
	$db->do("lock tables $tables") or die "\n$prog: unable to lock tables: $DBI::errstr";
   return 1;
}

#
# extracts used tables from queries
#
sub get_used_tables (@) {
	my (@table, $query, $tmp) = ();
	my $clause = '( where| group by| having| order by| limit| procedure|$)';

	# make a list of unique tables queried
	foreach $query (@_) {
		unless ($query eq '') {
			$query =~ m/from ([a-zA-Z0-9 ,]+?)$clause/ or die "\n$prog: bad query '$query'";
			foreach $tmp (split /, /, $1) { push @table, $tmp unless grep /^$tmp$/, @table; }
		}
	}

	return @table;
}

# Do not remove the last line. File must return true.
1

