use strict;
use warnings;
use DBI;

# Das Verzeichnis, in dem die HTML-Dateien liegen
my $DATA_DIR = 'Data/';

my $username = 'john';     # Datenbank-Daten
my $password = 'geheim';   # ggf. in Config-Datei auslagern
my $database = 'Search';

# Zusammenbauen der Datasource: DBI/Modul/Datenbank/Host
my $dsn = 'DBI:mysql:'.$database.':localhost';  

# Nun der Connect
my $dbh = DBI->connect($dsn, $username, $password,
	  	                   { RaiseError => 1,
		                       PrintError => 1, 
		                       AutoCommit => 1}
		                    ) or die "Oops: $DBI::errstr\n";		                     
		                    
# Suchstring von der Kommandozeile uebernehmen
my $search = $ARGV[0];
# Suchstring parsen
my $sql1 = ParseQuery('Words', 'Word', $search);
# Suche ausführen
my $sth1 = $dbh->prepare($sql1);
$sth1->execute();

# Fuer jede Fundstelle die Dateiinfo holen
while(my ($word, $fileref, $rank) = $sth1->fetchrow_array())
  {
  # print "DEBUG: $word, $fileref, $rank\n";
  my $sql2 = "SELECT Name, Title, Description, Size FROM Files WHERE Id='$fileref';";
  my $sth2 = $dbh->prepare($sql2);
  $sth2->execute();
  # ganz einfache Ergebnisausgabe
  while(my ($name, $title, $desc, $size) = $sth2->fetchrow_array())
    {
    print "$DATA_DIR$name ($size KByte)\n$title\n$desc\n\n";
    # beliebig erweiterbar. z. B. als HTML oder mit Perl-TK ...
    }
  $sth2->finish();  
  } 
$sth1->finish();
$dbh->disconnect();


sub ParseQuery # (Tabellenname, Key, Abfrage)
  {
  my($table, $key, $query) = @_;  # Parameter holen
  my $part = '';              # fuer geklammerte Ausdruecke
  my $first = 1;              # entscheidet ob 'not' oder 'and not' 
                              # verwendet werden soll
  # Der Anfang des SQL-Kommandos
  my $sqlcmd = "SELECT * FROM $table WHERE ";
  $query = lc($query);        # alles in Kleinbuchstaben
  $query =~ s/Ä/ä/gs;         # Ä,Ö,Ü wird von lc() nicht behandelt
  $query =~ s/Ö/ö/gs;
  $query =~ s/Ü/ü/gs;
  $query =~ s/ß/ss/gs;
  # Abfrage moeglichst entgiften
  $query =~ tr|-+a-zäöü0-9$%*(),_| |cs;
  $query =~ s|\s+| |g; 
  $query =~ s|\(| ( |g;       # sicherstellen, dass Klammern separat stehen
  $query =~ s|\)| ) |g;       # und somit als "Token" erkannt werden
  $query =~ s|\+| and |g;     # erlaubt  +word +word ...  fuer 'and'
  $query =~ s|,| or |g;       # erlaubt   word,word, ...  fuer 'or'
  $query =~ s|\*|\%|g;        # erlaubt  '*' als Jokerzeichen
  # Ausdruck aufbrechen
  for (split(/\s+/, $query)) 
    {
    next if /^$/;             # Leerzeile
    if ($_ eq ")")   { $sqlcmd .= $_; next; }
    if ($_ eq "(")   { $sqlcmd .= "$part$_"; $part = ""; $first = 1; next; }
    if ($_ eq "not") { $part = ($first)?" NOT ":" AND NOT "; next; }
    if ($_ eq "or" ) { $part = " OR "; next; }
    if ($_ eq "and") { $part = " AND "; next; }
    if ($_ =~ /\%/)
      { $sqlcmd .= "$part $key LIKE '$_'"; }
    else
      { $sqlcmd .= "$part $key='$_'"; }
    $part = " AND ";	# default to AND joins
    $first = 0;
    }
  $sqlcmd =~ s|\s+| |g;  
  return $sqlcmd . ';';
  }