%
%   DataBase Management Library
%
%     Andrew Marc Greene
%     MIT Project Athena
%     July 1989
%
%
%
\def\fields #1\endfields{\numfields=0\parsefields #1,*\endfields}
%
\def\parsefields #1,#2\endfields{%
\global\advance\numfields by 1
\put{\gdef}{FIELDS}{\numfields}{#1}%
\begingroup\if*#2\gdef\recurse{\relax}%
\else\gdef\recurse{\parsefields #2\endfields}%
\aftergroup\recurse\fi
\endgroup}
%
\newcount\numfields
\newcount\fieldnumber
\newcount\numrecords
\newcount\recordnumber
%
\def\readdatabase #1{%
\recordnumber=0\numrecords=0\relax
\openin6=#1\relax
\read6 to \totalrecords
\numrecords=\totalrecords
\readdatabaserecords
\closein6}
%
\def\writedatabase #1{%
\recordnumber=0
\immediate\openout6=#1
\immediate\write6{\number\totalrecords}
\writedatabaserecords
\immediate\closeout6}
%
\def\readdatabaserecords{%
\begingroup\ifnum\recordnumber<\numrecords
\global\advance\recordnumber by 1\relax
\global\fieldnumber=0\relax
\readdatabaserecord
\aftergroup\readdatabaserecords
\fi\endgroup}
%
\def\writedatabaserecords{%
\begingroup\ifnum\recordnumber<\numrecords
\global\advance\recordnumber by 1
\global\fieldnumber=0
\writedatabaserecord
\aftergroup\writedatabaserecords
\fi\endgroup}
%
\def\readdatabaserecord{%
\begingroup\ifnum\fieldnumber<\numfields
\global\advance\fieldnumber by 1\relax
\read6 to \fieldvalue
\putt{\xdef}{DATABASE}{\recordnumber}{\fieldnumber}{\fieldvalue}\relax
\aftergroup\readdatabaserecord%
\fi\endgroup}
%
\def\writedatabaserecord{%
\begingroup\ifnum\fieldnumber<\numfields
\global\advance\fieldnumber by 1
\immediate\write6{\gett{DATABASE}{\recordnumber}{\fieldnumber}}
\aftergroup\writedatabaserecord
\fi\endgroup}
%
\def\gotorecord #1{%
\global\recordnumber=#1
\global\fieldnumber=0
\getnextfield}
%
\def\getnextfield{%
\begingroup\ifnum\fieldnumber<\numfields
\global\advance\fieldnumber by 1
\expandafter\xdef\csname\get{FIELDS}\fieldnumber\endcsname%
{\gett{DATABASE}{\recordnumber}{\fieldnumber}}
\aftergroup\getnextfield
\fi\endgroup}
%
\def\gotonextrecord{%
\ifnum\recordnumber<\numrecords
\global\advance\recordnumber by 1
\fieldnumber=0
\getnextfield
\fi}
%
\def\foreachrecord{\long\def\FOREACHRECORD}
\def\nextrecord{\global\recordnumber=0\loopforallrecords}
\def\loopforallrecords{%
\begingroup\ifnum\recordnumber<\numrecords
\gotonextrecord
\FOREACHRECORD
\aftergroup\loopforallrecords
\fi\endgroup}
%
\def\deffield#1{\fieldnumberof{#1}%
\putt{\xdef}{DATABASE}{\recordnumber}{\fieldnumber}}
%
\def\fieldnumberloop{%
\begingroup
\ifnum\fieldnumber>\numfields
\message{Field does not exist.  Sorry.}
\else\edef\fieldtestb{\get{FIELDS}{\fieldnumber}}%
\ifx\fieldtesta\fieldtestb
\relax
\else
\global\advance\fieldnumber by 1
\aftergroup\fieldnumberloop
\fi\fi
\endgroup
}
\def\fieldnumberof#1{
\def\fieldtesta{#1}
\global\fieldnumber=1
\fieldnumberloop
}
%
\def\saverecord{%
\fieldnumber=0
\putnextfield}
%
\def\putnextfield{%
\begingroup\ifnum\fieldnumber<\numfields
\global\advance\fieldnumber by 1
\putt{\xdef}{DATABASE}{\recordnumber}{\fieldnumber}%
{\csname\get{FIELDS}{\fieldnumber}\endcsname}
\aftergroup\putnextfield
\fi\endgroup}
%
\def\newrecord{%
\global\advance\numrecords by 1
\recordnumber=\numrecords}
%
\def\put#1#2#3{%   Put into an array
\expandafter #1\csname #2.\if\relax #3\the\fi #3\endcsname}
%
\def\get#1#2{\csname #1.\if\relax #2\the\fi#2\endcsname}
%
\def\putt#1#2#3#4{\expandafter #1%    \def -- but first find the AINAME
\csname #2%                          begin the \csname and use the arrayname
.\if\relax #3\the\fi #3.%            first index
\if\relax #4\the\fi #4\endcsname }%  second index and end the \csname
%
\def\gett#1#2#3{\csname #1%           same as above....
.\if\relax #2\the\fi #2%
.\if\relax #3\the\fi #3%
\endcsname}
%
