#!/usr/bin/perl
# -*- perl -*-

# $yydebug = 1;


use Tibia;
import Tibia 'and', 'or';

require 'bool.pl';
require 'getopts.pl';

&Getopts('Vtnrd:');

if ($opt_V) {
    print "Version 1.2\n";
    exit 0;
}


$dir = $opt_d || '.';

$db = new Tibia $dir;
die "Couldn\'t open database in directory $dir: $!" unless $db;

if ($opt_n && $opt_r) {
  print STDERR <<EOM;
Options -n and -r are incompatible.
-n means to print only the number of matching records.
-r means to print entire records.
(Default behavior is to print the record numbers of matching records.)
EOM
    exit 1;
}

$start = time;
unless (@result = &bool_query($ARGV[0])) {
    &abort("Couldn\'t parse boolean expression $be.");
}
$end = time;

if ($opt_n) {
  print $#result+1, "\n";
} else {
  for ($i=0; $i < @result; $i++) {
    if ($opt_r) {
      local($rec);
      $rec = $db->get_record($result[$i]);
      print "$rec\n";
    } else {
      print "$result[$i]\n";
    }
  }
}
print STDERR "Elapsed time: ", $end - $start, " seconds.\n" if $opt_t;

exit ($#result < 0) ? 1 : 0;

sub abort {
  print STDERR "$_[0]\n";
  exit 1;
}



=head1 NAME

query-rel - sample Tibia query program

=head1 SYNOPSIS

    query-rel [-nr] [-d directory] expression

=head1 DESCRIPTION

F<query-rel> is a sample Tibia application that demonstrates
`boolean searching'.  The I<expression> argument to F<query-rel> is
a boolean expression describing what records to selsct from a Tibia
database.  F<query-rel> selects and displays the specified records.

The C<-d> option tells F<query-rel> where the Tibia database resides.
If omitted, F<query-rel> assmues the current directory.

By default, F<query-rel> prints the record identification numbers of
the selected records.  If you supply the C<-r> option, it prints the
entire matching records, and of you supply the C<-n> option, it prints
only the total number of matching records.

=head1 EXPRESSIONS

Boolean expressions have the following forms:

=item * 
( I<expression> )

Parentheses group expressions.

=item * 
I<expression> | I<expression> 

Selects records which satisfy either given expression.

=item *
I<expression> & I<expression> 

Selects records which satisfy both expressions.

=item *
$I<fieldname> I<relational-op> I<value>

Legal relational operators are: C<=>, C<E<lt>> C<E<gt>>, C<E<lt>=>,
C<E<gt>=>.

C<=> selects records where the specified field contains the specified
value.  The others perform the usual numeric comparisons between the
field contents and the specified value.


=item *
$I<fieldname> I<matching-op> I<pattern>

Legal relational operators are: C<~> to select records which match the
specified pattern and C<!~> to select records which do not match the
specified pattern.  Patterns are Perl regular expressions.  See
L<perlre> for full details.

=item *
$I<fieldname> IN [number..number]

Selects records where the specified value contains a number in the
specified range.  Either number may be omitted.

Relational and matching operators have highest precedence and do not
associate with one another.  C<&> has next highest precedence; C<|>
least.  C<&> and C<|> associate left-to-right.

=head1 BUGS

The parser is not very resilient.

If the query returns no records, F<query-rel> thinks that 
there was a parse error in the boolean expression.

The program is not actually very useful.  A more useful utility would
have project, select, and join operations and would manipulate more
than one database at a time.

=head1 Author

Deven Ullman, C<nesselrode@pobox.com>.

=head1 Copying

Tibia is distributed under the terms of version 2 of the GNU General
Public License.  See the file COPYING for full details.

=cut
