Annotation of doc/build/loncapasqldatabase.html, revision 1.4

1.1       harris41    1: <HTML>
                      2: <HEAD>
                      3: <TITLE>LON-CAPA SQL Database Documentation</TITLE>
                      4: </HEAD>
                      5: <BODY>
                      6: <H1>LON-CAPA SQL Database Documentation</H1>
                      7: <P>
                      8: Scott Harrison
                      9: </P>
                     10: <P>
1.4     ! harris41   11: Last updated: 02/10/2001
1.1       harris41   12: </P>
1.2       harris41   13: <P>
1.1       harris41   14: This file describes issues associated with LON-CAPA
                     15: and a SQL database.
                     16: </P>
1.2       harris41   17: <H3>Latest HOWTO</H3>
                     18: <P>
1.4     ! harris41   19: <UL>
        !            20: <LI>Current status of documentation</LI>
        !            21: <LI>Current status of implementation</LI>
        !            22: <LI>Purpose within LON-CAPA</LI>
        !            23: <LI>Installation</LI>
        !            24: <LI>Installation from source</LI>
        !            25: <LI>Configuration (automated)</LI>
        !            26: <LI>Manual configuration</LI>
        !            27: <LI>Testing</LI>
        !            28: <LI>Example sections of code relevant to LON-CAPA</LI>
        !            29: </UL>
        !            30: </P>
        !            31: <H3>Current status of documentation</H3>
        !            32: <P>
1.2       harris41   33: I am going to begin documentation by inserting what notes
                     34: I have into this file.  I will be subsequently rearranging
1.4     ! harris41   35: them and editing them based on the tests that I conduct.
1.2       harris41   36: I am trying to make sure that documentation, installation,
                     37: and run-time issues are all consistent and correct.  The
                     38: current status of everything is that it works and has
                     39: been minimally tested, but things need to be cleaned up
                     40: and checked again!
                     41: </P>
1.4     ! harris41   42: <H3>Current status of implementation</H3>
        !            43: <P>
        !            44: Right now, a lot of "feasibility" work has been done.
        !            45: Recipes for manual installation and configuration have
        !            46: been gathered.  Network connectivity of lond->lonsql->lond->lonc
        !            47: type tests have been performed.  A binary installation
        !            48: has been compiled in an RPM (LON-CAPA-mysql).
        !            49: The most lacking test in terms of feasibility has
        !            50: been looking at benchmarks to analyze the load at which
        !            51: the SQL database can efficiently allow many users to
        !            52: make simultaneous requests of the metadata database.
        !            53: </P>
        !            54: <P>
        !            55: Documentation has been pieced together over time.  But,
        !            56: as mentioned in the previous section, it needs an
        !            57: overhaul.
        !            58: </P>
        !            59: <P>
        !            60: The binary installation has some quirks associated with it.
        !            61: Some of the user permissions are wrong, although this is
        !            62: benign.  Also, other options of binary installation (such
        !            63: as using binary RPMs put together by others) were dismissed
        !            64: given the difficulty of getting differing combinations of
        !            65: these external RPMs to work together.
        !            66: </P>
        !            67: <P>
        !            68: Most configuration questions have been initially worked out
        !            69: to the point of getting this SQL software component working,
        !            70: however there may be more optimal approaches than currently
        !            71: exist.
        !            72: </P>
        !            73: <H3>Purpose within LON-CAPA</H3>
        !            74: <P>
        !            75: LON-CAPA is meant to distribute A LOT of educational content
        !            76: to A LOT of people.  It is ineffective to directly rely on contents
        !            77: within the ext2 filesystem to be speedily scanned for 
        !            78: on-the-fly searches of content descriptions.  (Simply put,
        !            79: it takes a cumbersome amount of time to open, read, analyze, and
        !            80: close thousands of files.)
        !            81: </P>
        !            82: <P>
        !            83: The solution is to hash-index various data fields that are
        !            84: descriptive of the educational resources on a LON-CAPA server
        !            85: machine.  Descriptive data fields are referred to as
        !            86: "metadata".  The question then arises as to how this metadata
        !            87: is handled in terms of the rest of the LON-CAPA network
        !            88: without burdening client and daemon processes.  I now
        !            89: answer this question in the format of Problem and Solution
        !            90: below.
        !            91: </P>
        !            92: <P>
        !            93: <PRE>
        !            94: PROBLEM SITUATION:
        !            95: 
        !            96:   If Server A wants data from Server B, Server A uses a lonc process to
        !            97:   send a database command to a Server B lond process.
        !            98:     lonc= loncapa client process    A-lonc= a lonc process on Server A
        !            99:     lond= loncapa daemon process
        !           100: 
        !           101:                  database command
        !           102:     A-lonc  --------TCP/IP----------------> B-lond
        !           103: 
        !           104:   The problem emerges that A-lonc and B-lond are kept waiting for the
        !           105:   MySQL server to "do its stuff", or in other words, perform the conceivably
        !           106:   sophisticated, data-intensive, time-sucking database transaction.  By tying
        !           107:   up a lonc and lond process, this significantly cripples the capabilities
        !           108:   of LON-CAPA servers. 
        !           109: 
        !           110:   While commercial databases have a variety of features that ATTEMPT to
        !           111:   deal with this, freeware databases are still experimenting and exploring
        !           112:   with different schemes with varying degrees of performance stability.
        !           113: 
        !           114: THE SOLUTION:
        !           115: 
        !           116:   A separate daemon process was created that B-lond works with to
        !           117:   handle database requests.  This daemon process is called "lonsql".
        !           118: 
        !           119:   So,
        !           120:                 database command
        !           121:   A-lonc  ---------TCP/IP-----------------> B-lond =====> B-lonsql
        !           122:          <---------------------------------/                |
        !           123:            "ok, I'll get back to you..."                    |
        !           124:                                                             |
        !           125:                                                             /
        !           126:   A-lond  <-------------------------------  B-lonc   <======
        !           127:            "Guess what? I have the result!"
        !           128: 
        !           129:   Of course, depending on success or failure, the messages may vary,
        !           130:   but the principle remains the same where a separate pool of children
        !           131:   processes (lonsql's) handle the MySQL database manipulations.
        !           132: </PRE>
        !           133: </P>
        !           134: <H3>Installation</H3>
        !           135: <P>
        !           136: Installation of the LON-CAPA SQL database normally occurs
        !           137: by default when using the LON-CAPA installation CD
        !           138: (see http://install.lon-capa.org).  It is installed
        !           139: as the LON-CAPA-mysql RPM.  This RPM encodes for the MySQL
        !           140: engine and related perl interfaces (Perl::DBI, Perl::Msql-Mysql).
        !           141: </P>
        !           142: <P>
        !           143: The three components of a MySQL installation for the
        !           144: LON-CAPA system are further described immediately below.
        !           145: <TABLE BORDER="0">
        !           146: <TR><TD COLSPAN="2"><STRONG>Perl::DBI module</STRONG>-
        !           147: the API "front-end"...</TD></TR>
        !           148: <TR><TD WIDTH="10%"></TD><TD>database interface module for organizing generic
        !           149: database commands which are independent of specific
        !           150: database implementation (such as MySQL, mSQL, Postgres, etc).
        !           151: </TD></TR>
        !           152: <TR><TD COLSPAN="2"><STRONG>Perl::MySQL module</STRONG>-
        !           153: the API "mid-section"...</TD></TR>
        !           154: <TR><TD WIDTH="10%"></TD><TD>the module to directly interface with the actual
        !           155: MySQL database engine</TD></TR>
        !           156: <TR><TD COLSPAN="2"><STRONG>MySQL database engine</STRONG>-
        !           157: the "back-end"...</TD></TR>
        !           158: <TR><TD WIDTH="10%"></TD><TD>the binary installation (compiled either
        !           159: from source or pre-compiled file listings) which provides the
        !           160: actual MySQL functionality on the system</TD></TR>
        !           161: </TABLE>
        !           162: </P>
        !           163: <H3>Installation from source</H3>
        !           164: <P>
        !           165: The following set of tarballs was found to work together
        !           166: properly on a LON-CAPA RedHat 6.2 system:
        !           167: <UL>
        !           168: <LI>DBI-1.13.tar.gz
        !           169: <LI>Msql-Mysql-modules-1.2209.tar.gz
        !           170: <LI>mysql-3.22.32.tar.gz
        !           171: </UL>
        !           172: </P>
        !           173: <P>
        !           174: Installation was simply a matter of following the instructions
        !           175: and typing the several "make" commands for each 
        !           176: </P>
        !           177: <H3>Configuration (automated)</H3>
        !           178: <P>
        !           179: Not yet developed.  This will be part of an interface
        !           180: present on LON-CAPA systems that can be launched by
        !           181: entering the command <TT>/usr/sbin/loncapaconfig</TT>.
        !           182: </P>
        !           183: <H3>Manual configuration</H3>
        !           184: <P>
        !           185: This is not complete.
        !           186: </P>
        !           187: <P>
        !           188: <STRONG>Starting the mysql daemon</STRONG>: Login on the Linux
        !           189: system as user 'www'.  Enter the command
        !           190: <TT>/usr/local/bin/safe_mysqld &</TT>
        !           191: </P>
        !           192: <P>
        !           193: <STRONG>Set a password for 'root'</STRONG>:
        !           194: <TT>/usr/local/bin/mysqladmin -u root password 'new-password'</TT>
        !           195: </P>
        !           196: <P>
        !           197: <STRONG>Adding a user</STRONG>:  Start the mysql daemon.  Login to the
        !           198: mysql system as root (<TT>mysql -u root -p mysql</TT>)
        !           199: and enter the right password (for instance 'newmysql').  Add the user
        !           200: www
        !           201: <PRE>
        !           202: INSERT INTO user (Host, User, Password)
        !           203: VALUES ('localhost','www',password('newmysql'));
        !           204: </PRE>
        !           205: </P>
        !           206: <P>
        !           207: <STRONG>Granting privileges to user 'www'</STRONG>:
        !           208: <PRE>
        !           209: GRANT ALL PRIVILEGES ON *.* TO www@localhost;
        !           210: FLUSH PRIVILEGES;
        !           211: </PRE>
        !           212: </P>
        !           213: <P>
        !           214: <STRONG>Set the SQL server to start upon system startup</STRONG>:
        !           215: Copy support-files/mysql.server to the right place on the system
        !           216: (/etc/rc.d/...).
        !           217: </P>
        !           218: <H3>Testing</H3>
        !           219: <P>
        !           220: Not yet documented or formalized.
        !           221: </P>
        !           222: <H3>Example sections of code relevant to LON-CAPA</H3>
        !           223: <P>
        !           224: </P>
        !           225: 
        !           226: <H1>Old notes</H1>
        !           227: 
1.2       harris41  228: <H3>How to add a user to the SQL database</H3>
                    229: <P>
                    230: <PRE>
                    231: start the mysql daemon as /usr/local/bin/safe_mysqld &
                    232: Login as root: mysql -u root -p mysql
                    233: enter the password as newmysql
                    234: add the user www: grant all priveleges on *.* to www@localhost identified by 'newmysql' with grant option;
                    235: 
                    236: INSERT INTO user (Host, User, Password)
                    237: VALUES ('localhost','www',password('newmysql'));
                    238: 
                    239: GRANT ALL PRIVILEGES ON *.* TO www@localhost;
                    240: 
                    241: FLUSH PRIVILEGES;
                    242: 
                    243: Here the user www has the right to grant privileges to other users.
                    244: This can be changed if required with a simple update command on the grant tables
                    245: 
                    246: 
                    247: /home/httpd/perl/perlsql/lonsql
                    248: /usr/local/mysql/fakeclient
                    249: </PRE>
                    250: </P>
                    251: <H3>To do</H3>
                    252: <P>
                    253: <PRE>
                    254: This is the output from scripts/mysql_install_db...
                    255: still some todo things (like support-files/mysql.server)
                    256: 
                    257: Creating db table
                    258: Creating host table
                    259: Creating user table
                    260: Creating func table
                    261: Creating tables_priv table
                    262: Creating columns_priv table
                    263: 
                    264: To start mysqld at boot time you have to copy support-files/mysql.server
                    265: to the right place for your system
                    266: 
                    267: PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
                    268: This is done with:
                    269: /usr/local/bin/mysqladmin -u root password 'new-password'
                    270: See the manual for more instructions.
                    271: 
                    272: Please report any problems with the /usr/local/bin/mysqlbug script!
                    273: 
                    274: The latest information about MySQL is available on the web at http://www.mysql.com
                    275: Support MySQL by buying support/licenses at http://www.tcx.se/license.htmy.
                    276: </PRE>
                    277: </P>
                    278: <H3>Source Installation and Manual Configuration</H3>
1.1       harris41  279: <P>
1.2       harris41  280: <PRE>
                    281: August, 29 2000; Scott Harrison; LON-CAPA
                    282: 
                    283: These are notes related to a Perl interface and MySQL server installation
                    284: on Redhat 6.1 and 6.2 boxes.  (Guy Albertelli and Harsha Jagasia
                    285: contributed significantly to this.)
                    286: 
                    287: ********************
                    288: * MySQL COMPONENTS *
                    289: ********************
                    290: 
                    291: There are three components to an effective MySQL installation for the
                    292: LON-CAPA system.
                    293: 
                    294: Perl::DBI module- the API "front-end"...
                    295:                   database interface module for organizing generic
                    296:                   database commands which are independent of specific
                    297:                   database implementation (such as MySQL, mSQL, Postgres, etc).
                    298: 
                    299: Perl::MySQL module- the API "mid-section"...
                    300:                     the module to directly interface with the actual
                    301:                     MySQL database engine
                    302: 
                    303: MySQL database engine- the "back-end"...
                    304:                        the binary installation (compiled either from source
                    305:                        or pre-compiled file listings) which provides the
                    306:                        actual MySQL functionality on the system
                    307: 
                    308: RedHat Installation-
                    309: 
                    310: Initially done from source:
                    311: DBI-1.13.tar.gz  Msql-Mysql-modules-1.2209.tar.gz  mysql-3.22.32.tar.gz
                    312: 
                    313: I am now using pre-compiled file listings.
                    314: 
                    315: There were problems with using the RedHat packages since the three
                    316: different RedHat packages were somewhat noncompatible with each other
                    317: in terms of expected file locations. (The Debian linux distribution,
                    318: on the other hand, has a working set of these packages).
                    319: 
                    320: Regardless of how we install these three components, there still remain
                    321: certain things which need to happen for the configuration.
                    322: 
                    323: *****************
                    324: * CONFIGURATION *
                    325: *****************
                    326: 
                    327: (Note: SOMEPASSWORD is actually set to another text string on the current
                    328: LON-CAPA systems.)
                    329: 
                    330: Configuration is needed to generate the necessary functionality for the
                    331: MySQL system with LON-CAPA.
                    332: 
                    333: The functionality needed can be understood from this example line
                    334: of perl code from "lonsql".
                    335: 
                    336:    $dbh = DBI->connect(	"DBI:mysql:loncapa",
                    337: 			"www",
                    338: 			"SOMEPASSWORD",
                    339: 			{ RaiseError =>0,PrintError=>0});
                    340: 
                    341: There is an obvious need to CONNECT to the database, and in order to do
                    342: this, there must be:
                    343:   a RUNNING mysql daemon;
                    344:   a DATABASE named "loncapa";
                    345:   a USER named "www";
                    346:   and an ABILITY for LON-CAPA on one machine to access
                    347:        SQL database on another machine;
                    348:   
                    349: So, here are some notes on implementing these configurations.
                    350: 
                    351: ** RUNNING mysql daemon (safe_mysqld method)
                    352: 
                    353: The recommended way to run the MySQL daemon is as a non-root user
                    354: (probably www)...
                    355: 
                    356: so, 1) login as user www on the linux machine
                    357:     2) start the mysql daemon as /usr/local/bin/safe_mysqld &
                    358: 
                    359: safe_mysqld only works if the local installation of MySQL is set to the
                    360: right directory permissions which I found to be:
                    361: chown www:users /usr/local/var/mysql
                    362: chown www:users /usr/local/lib/mysql
                    363: chown -R www:users /usr/local/mysql
                    364: chown www:users /usr/local/include/mysql
                    365: chown www:users /usr/local/var
                    366: 
                    367: ** DATABASE named "loncapa"
                    368: 
                    369: As user www, run this command
                    370:     mysql -u root -p mysql
                    371: enter the password as SOMEPASSWORD
                    372: 
                    373: This allows you to manually enter MySQL commands.
                    374: The MySQL command to generate the loncapa DATABASE is:
                    375: 
                    376: CREATE DATABASE 'loncapa';
                    377: 
                    378: ** USER named "www"
                    379: 
                    380: As user www, run this command
                    381:     mysql -u root -p mysql
                    382: enter the password as SOMEPASSWORD
                    383: 
                    384: To add the user www to the MySQL server, and grant all
                    385: privileges on *.* to www@localhost identified by 'SOMEPASSWORD'
                    386: with grant option;
                    387: 
                    388: INSERT INTO user (Host, User, Password)
                    389: VALUES ('localhost','www',password('SOMEPASSWORD'));
                    390: 
                    391: GRANT ALL PRIVILEGES ON *.* TO www@localhost;
                    392: 
                    393: FLUSH PRIVILEGES;
                    394: 
                    395: ** ABILITY for LON-CAPA machines to communicate with SQL databases on
                    396:    other LON-CAPA machines
                    397: 
                    398: This is a little more intricate than might first be expected (and I probably
                    399: won't do a perfect job reciting everything in this short synopsis).  Because
                    400: LON-CAPA machines will likely be handling many SQL requests at a time,
                    401: there were some problems with current MySQL capabilities.
                    402: 
                    403: PROBLEM SITUATION:
                    404: 
                    405:   If Server A wants data from Server B, Server A uses a lonc process to
                    406:   send a database command to a Server B lond process.
                    407:     lonc= loncapa client process    A-lonc= a lonc process on Server A
                    408:     lond= loncapa daemon process
                    409: 
                    410:                  database command
                    411:     A-lonc  --------TCP/IP----------------> B-lond
                    412: 
                    413:   The problem emerges that A-lonc and B-lond are kept waiting for the
                    414:   MySQL server to "do its stuff", or in other words, perform the conceivably
                    415:   sophisticated, data-intensive, time-sucking database transaction.  By tying
                    416:   up a lonc and lond process, this significantly cripples the capabilities
                    417:   of LON-CAPA servers. 
                    418: 
                    419:   While commercial databases have a variety of features that ATTEMPT to
                    420:   deal with this, freeware databases are still experimenting and exploring
                    421:   with different schemes with varying degrees of performance stability.
                    422: 
                    423: THE SOLUTION:
                    424: 
                    425:   A separate daemon process was created that B-lond works with to
                    426:   handle database requests.  This daemon process is called "lonsql".
                    427: 
                    428:   So,
                    429:                 database command
                    430:   A-lonc  ---------TCP/IP-----------------> B-lond =====> B-lonsql
                    431:          <---------------------------------/                |
                    432:            "ok, I'll get back to you..."                    |
                    433:                                                             |
                    434:                                                             /
                    435:   A-lond  <-------------------------------  B-lonc   <======
                    436:            "Guess what? I have the result!"
                    437: 
                    438:   Of course, depending on success or failure, the messages may vary,
                    439:   but the principle remains the same where a separate pool of children
                    440:   processes (lonsql's) handle the MySQL database manipulations.
                    441: 
                    442: Here are excerpts of code which implement the above handling:
                    443: 
                    444: **LONSQL
                    445: 
                    446: A subroutine from "lonsql" which establishes a child process for handling
                    447: database interactions.
                    448: 
                    449: sub make_new_child {
                    450:     my $pid;
                    451:     my $sigset;
                    452:     
                    453:     # block signal for fork
                    454:     $sigset = POSIX::SigSet->new(SIGINT);
                    455:     sigprocmask(SIG_BLOCK, $sigset)
                    456:         or die "Can't block SIGINT for fork: $!\n";
                    457:     
                    458:     die "fork: $!" unless defined ($pid = fork);
                    459:     
                    460:     if ($pid) {
                    461:         # Parent records the child's birth and returns.
                    462:         sigprocmask(SIG_UNBLOCK, $sigset)
                    463:             or die "Can't unblock SIGINT for fork: $!\n";
                    464:         $children{$pid} = 1;
                    465:         $children++;
                    466:         return;
                    467:     } else {
                    468:         # Child can *not* return from this subroutine.
                    469:         $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before
                    470:     
                    471:         # unblock signals
                    472:         sigprocmask(SIG_UNBLOCK, $sigset)
                    473:             or die "Can't unblock SIGINT for fork: $!\n";
                    474: 	
                    475: 	
                    476:         #open database handle
                    477: 	# making dbh global to avoid garbage collector
                    478: 	unless (
                    479: 		$dbh = DBI->connect("DBI:mysql:loncapa","www","SOMEPASSWORD",{ RaiseError =>0,PrintError=>0})
                    480: 		) { 
                    481: 	            my $st=120+int(rand(240));
                    482: 		    &logthis("<font color=blue>WARNING: Couldn't connect to database  ($st secs): $@</font>");
                    483: 		    print "database handle error\n";
                    484: 		    sleep($st);
                    485: 		    exit;
                    486: 
                    487: 	  };
                    488: 	# make sure that a database disconnection occurs with ending kill signals
                    489: 	$SIG{TERM}=$SIG{INT}=$SIG{QUIT}=$SIG{__DIE__}=\&DISCONNECT;
                    490: 
                    491:         # handle connections until we've reached $MAX_CLIENTS_PER_CHILD
                    492:         for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
                    493:             $client = $server->accept()     or last;
                    494:             
                    495:             # do something with the connection
                    496: 	    $run = $run+1;
                    497: 	    my $userinput = <$client>;
                    498: 	    chomp($userinput);
                    499: 	    	    
                    500: 	    my ($conserver,$querytmp)=split(/&/,$userinput);
                    501: 	    my $query=unescape($querytmp);
                    502: 
                    503:             #send query id which is pid_unixdatetime_runningcounter
                    504: 	    $queryid = $thisserver;
                    505: 	    $queryid .="_".($$)."_";
                    506: 	    $queryid .= time."_";
                    507: 	    $queryid .= $run;
                    508: 	    print $client "$queryid\n";
                    509: 	    
                    510:             #prepare and execute the query
                    511: 	    my $sth = $dbh->prepare($query);
                    512: 	    my $result;
                    513: 	    unless ($sth->execute())
                    514: 	    {
                    515: 		&logthis("<font color=blue>WARNING: Could not retrieve from database: $@</font>");
                    516: 		$result="";
                    517: 	    }
                    518: 	    else {
                    519: 		my $r1=$sth->fetchall_arrayref;
                    520: 		my @r2; map {my $a=$_; my @b=map {escape($_)} @$a; push @r2,join(",", @b)} (@$r1);
                    521: 		$result=join("&",@r2) . "\n";
                    522: 	    }
                    523:             &reply("queryreply:$queryid:$result",$conserver);
                    524: 
                    525:         }
                    526:     
                    527:         # tidy up gracefully and finish
                    528: 	
                    529:         #close the database handle
                    530: 	$dbh->disconnect
                    531: 	   or &logthis("<font color=blue>WARNING: Couldn't disconnect from database  $DBI::errstr ($st secs): $@</font>");
                    532:     
                    533:         # this exit is VERY important, otherwise the child will become
                    534:         # a producer of more and more children, forking yourself into
                    535:         # process death.
                    536:         exit;
                    537:     }
                    538: }
                    539: 
                    540: ** LOND enabling of MySQL requestsw
                    541: 
                    542:   This code is part of every lond child process in the way that it parses command request syntax
                    543:   sent to it from lonc processes.  querysend corresponds to B-lonc sending the result of the query.
                    544:   queryreply corresponds to B-lond indicating that it has received the request and will start the
                    545:   database transaction (it returns "ok" to A-lonc ($client)).
                    546: 
                    547: # ------------------------------------------------------------------- querysend
                    548:                    } elsif ($userinput =~ /^querysend/) {
                    549:                        my ($cmd,$query)=split(/:/,$userinput);
                    550: 		       $query=~s/\n*$//g;
                    551:                      print $client sqlreply("$hostid{$clientip}\&$query")."\n";
                    552: # ------------------------------------------------------------------ queryreply
                    553:                    } elsif ($userinput =~ /^queryreply/) {
                    554:                        my ($cmd,$id,$reply)=split(/:/,$userinput); 
                    555: 		       my $store;
                    556:                        my $execdir=$perlvar{'lonDaemons'};
                    557:                        if ($store=IO::File->new(">$execdir/tmp/$id")) {
                    558: 			   print $store $reply;
                    559: 			   close $store;
                    560: 			   print $client "ok\n";
                    561: 		       }
                    562: 		       else {
                    563: 			   print $client "error:$!\n";
                    564: 		       }
                    565: 
                    566: 
                    567: 
                    568: ** TEST the database connection with my current tester.pl code which mimics what command will eventually be
                    569:    sent through lonc.
1.1       harris41  570: 
1.2       harris41  571: $reply=reply(
                    572:     "querysend:SELECT * FROM general_information WHERE Id='AAAAA'",$lonID);
                    573: </PRE>
1.1       harris41  574: </P>
                    575: </BODY>
1.3       harris41  576: </HTML>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>