Hellow fellow monks!

Let me start out with admitting that the code you are about to see is most likely horrible, messy, and overly complicated. Ok, with that out of the way, I wrote a Major Search script for the University and it works, however I am interested in cleaning up the code and learning what not to do in the future. I think a good way are to have some bored monks take a look at it and tell me what I did thats wrong.

Ok, on the what the search does. It searches a database that has a few fields, such as the major name, the description of the major, and a few links where you can find faq sheets online. I have the script first try to find a match in the title, and if it does I weigh that heavily. Next, I find a whole word match in the description, and I weight that a bit less. Finally, I find any partial matches in the description and weigh that even less. I add it all up and sort them by the weighted hit count. You can find it at this page (link removed by Ovid until the security hole is fixed).

Finally, the important part. The code. Please do not be gentle with it, I am prepared to have it ripped apart. Thanks in advance monks!
#!E:/perl/bin/perl.exe -w use strict; use DBI; use CGI; use HTML::Template; use Data::Dumper; use Text::ParseWords; use CGI::Carp qw(fatalsToBrowser); my @results; my $searchStuff; my $start; my $major; my %nav; my $even = 0; my @mini; my $description; my $booleanflag = 1; my $SCRIPTLOC = 'http://...'; my $dbh = _connectToDB(); getParameters(); searchDatabase(); displayResults( $searchStuff ); sub getParameters { my $query = new CGI; print $query->header(-type=>'text/html'); $searchStuff = $query->param('search'); $start = $query->param('start') || 0; } sub _connectToDB { use Pass::PassInterface; my $interface = newDB PassInterface(); my $SQL_SERVER = 'hydrogen\\devcgi'; my $TCPIP = '192.168.31.154:1343'; my $USERNAME = 'Web_Team'; my $PASSWORD = $interface->getPass($USERNAME); my $DATABASE = 'Steve'; my $DBH; #DBI->trace(2, 'DBIDebug.txt'); die ('Couldn\'t open database.' . $DBI::errstr. $@ ) unless (eval ('$DBH = DBI->connect( \'dbi:ODBC:driver={SQL Ser +ver};server='.$SQL_SERVER.';tcpip='.$TCPIP.';database='.$DATABASE.';u +id='.$USERNAME.';pwd='.$PASSWORD.';\',\''.$USERNAME.'\',\''.$PASSWORD +.'\',{\'LongTruncOk\' => 0, LongReadLen => 512 * 1024 } );')); return $DBH; } sub searchDatabase { my @words = shellwords($searchStuff); my $searchstring = 'SELECT * from MajorSearch WHERE '; my $onlyonce = 1; foreach my $tempword ( @words ) { if ( $onlyonce == 1 ) { $searchstring .= "MajorDescription LIKE '%$tempword%' OR M +ajorName LIKE '%$tempword%'"; $onlyonce = 0; } else { $searchstring .= " OR MajorDescription LIKE '%$tempword%' +OR MajorName LIKE '%$tempword%'"; } } my $sth = $dbh->prepare( $searchstring); $sth->execute() or die "Couldn't execute: '$DBI::errstr'"; my $results = $sth->fetchall_arrayref({}); my $hits; my $titlehits; my $weightedhits; @words = shellwords($searchStuff); foreach my $result ( @$results ) { foreach my $currentword ( @words ) { $hits += ($$result{'MajorDescription'} =~ s/($currentword) +/$1/gi); $weightedhits += ($$result{'MajorDescription'} =~ s/\b($cu +rrentword\b)/$1/gi) * 25; $hits += $weightedhits; $titlehits += ($$result{'MajorName'} =~ s/($currentword)/$ +1/gi) * 50; $hits += $titlehits; $$result{ 'hits'} += $hits; $hits = 0; $titlehits = 0; $weightedhits = 0 } } for ( my $i = scalar(@$results) - 1; $i >= 0; $i-- ) { for ( my $j = 1; $j <= $i; $j++) { if ( $$results[$j - 1]{'hits'} < $$results[$j]{'hits'} ) { my $temp = $$results[$j - 1]; $$results[$j - 1] = $$results[$j]; $$results[$j] = $temp; } } } $nav{'xCount'} = @$results; if ( $nav{'xCount'} <= 10 ) { $nav{'viewStart'} = $nav{'xCount'} < 1 ? 0 : 1; $nav{'viewEnd'} = $nav{'xCount'}; } else { $nav{'viewStart'} = $start > $nav{'xCount'} ? $nav{'xCount'} : + $start <= 0 ? 1 : $start ? $start : 1; $nav{'viewEnd'} = $nav{'viewStart'} + 9 > $nav{'xCount'} ? $ +nav{'xCount'} : $nav{'viewStart'} + 9; $nav{'previousStart'} = $nav{'viewStart'} <= 1 ? undef : $nav{ +'viewStart'} > 10 ? $nav{'viewStart'} - 10 : 1; $nav{'nextStart'} = $nav{'viewEnd'} >= $nav{'xCount'} ? undef +: $nav{'viewEnd'} + 1; $nav{'previous'} = $nav{'viewStart'} - $nav{'previousStart'} i +f ( $nav{'previousStart'} ); $nav{'next'} = $nav{'nextStart'} + 9 > $nav{'xCount'} ? $nav{' +xCount'} - $nav{'nextStart'} + 1 : 10 if ( $nav{'nextStart'} ); } if ( ($nav{'viewEnd'} - $nav{'viewStart'} + 1) % 2 == 1 ) { $even = 1; } else { $even = 0; } if ( $nav{'xCount'} > 0 ) { if ( $nav{'xCount'} > 10 ) { @mini = splice( @$results , $nav{'viewStart'} - 1 , $nav{' +viewEnd'} - $nav{'viewStart'} + 1 ); } else { @mini = @$results; } } else { @mini = @$results; $booleanflag = 0; } for ( my $i = 0; $i < scalar(@mini) ; $i++ ) { delete $mini[$i]{'MajorDescription'}; delete $mini[$i]{'MajorKey'}; delete $mini[$i]{'hits'}; } } sub displayResults { my ( $foundMessage ) = @_; my $template = HTML::Template->new(filename => 'out.tmpl', loop_co +ntext_vars => 1); my $lessthanten = $nav{'xCount'} >= 10 ? 1 : 0; $template->param( viewStart => $nav{'viewStart'} , viewEnd => $nav{'viewEnd'} , xCount => $nav{'xCount'} , previousStart => $nav{'previousStart'} , previous => $nav{'previous'} , next => $nav{'next'} , nextStart => $nav{'nextStart'} , SCRIPTLOC => $SCRIPTLOC , searchStuff => $searchStuff , MATCHES => \@mini , results => $booleanflag, even => $even, lessthanten => $lessthanten ); print $template->output; }

Edited 2003-09-18 by Ovid. Removed link to Web site until security hole can be fixed. I hate censoring posts, but I think this one is important. See my post below.

Edit by tye, add READMORE, remove other copy of URL, IP address


In reply to Search engine code critique by ruhk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.