home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 276.img / FORUM21S.ZIP / DATABASE.PAS < prev    next >
Pascal/Delphi Source File  |  1988-02-13  |  14KB  |  620 lines

  1. {$R-,S-,I-,D-,T-,F-,V-,B-,N-,L+ }
  2. {$M 65500,0,0 }
  3.  
  4. unit database;
  5.  
  6. interface
  7.  
  8. uses gentypes,gensubs,subs1,subs2,overret1;
  9.  
  10. procedure datamenu;
  11.  
  12. implementation
  13.  
  14. procedure datamenu;
  15. var curbase:baserec;
  16.     curbasenum:integer;
  17.  
  18. procedure packentry (var p:parsedentry; var a:anystr);
  19. var cnt:integer;
  20. begin
  21.   a:='';
  22.   for cnt:=1 to curbase.numcats do
  23.     if length(a)+length(p[cnt])>254 then begin
  24.       writeln ('Entry to big, truncated.');
  25.       exit
  26.     end else a:=a+p[cnt]+#1
  27. end;
  28.  
  29. procedure parseentry (var oa:anystr; var p:parsedentry);
  30. var d,cnt:integer;
  31.     a:anystr;
  32. begin
  33.   a:=oa;
  34.   for cnt:=1 to curbase.numcats do begin
  35.     d:=pos(#1,a);
  36.     if d=0
  37.       then p[cnt]:=''
  38.       else
  39.         begin
  40.           p[cnt]:=copy(a,1,d-1);
  41.           a:=copy(a,d+1,255)
  42.         end
  43.   end
  44. end;
  45.  
  46. procedure makenewbase;
  47.  
  48.   function getnumber (r1,r2:integer; txt:mstr):integer;
  49.   var t:integer;
  50.   begin
  51.     repeat
  52.       writestr (txt+':');
  53.       t:=valu(input);
  54.       if (t<r1) or (t>r2) then
  55.         writeln ('Sorry, must be from ',r1,' to ',r2,'.')
  56.     until (t>=r1) and (t<=r2);
  57.     getnumber:=t
  58.   end;
  59.  
  60. var n,cnt:integer;
  61.     b:baserec;
  62.     p:parsedentry;
  63. begin
  64.   n:=filesize(ddfile)+1;
  65.   writehdr ('Create database number '+strr(n));
  66.   writestr ('Database name:');
  67.   if length(input)=0 then exit;
  68.   b.basename:=input;
  69.   writestr ('Access level:');
  70.   if length(input)=0
  71.     then b.level:=1
  72.     else b.level:=valu(input);
  73.   b.numcats:=getnumber (1,maxcats,'Number of categories');
  74.   b.numents:=0;
  75.   for cnt:=1 to b.numcats do begin
  76.     writestr ('Category #'+strr(cnt)+' name:');
  77.     if length(input)=0 then exit;
  78.     p[cnt]:=input
  79.   end;
  80.   curbase:=b;
  81.   packentry (p,b.catnames);
  82.   seek (ddfile,n-1);
  83.   write (ddfile,b);
  84.   writeln ('Database created!');
  85.   writelog (7,2,b.basename);
  86.   curbase:=b;
  87.   curbasenum:=n
  88. end;
  89.  
  90. procedure nobases;
  91. begin
  92.   rewrite (ddfile);
  93.   writeln ('No databases exist!');
  94.   if not issysop then exit;
  95.   writestr ('Create first database now? *');
  96.   if not yes then exit;
  97.   makenewbase
  98. end;
  99.  
  100. procedure openddfile;
  101. begin
  102.   assign (ddfile,'DataDir');
  103.   reset (ddfile);
  104.   if ioresult<>0
  105.     then nobases
  106.     else begin
  107.       reset (ddfile);
  108.       if filesize (ddfile)=0 then begin
  109.         close (ddfile);
  110.         nobases
  111.       end
  112.     end
  113. end;
  114.  
  115. procedure writecurbase;
  116. begin
  117.   seek (ddfile,curbasenum-1);
  118.   write (ddfile,curbase)
  119. end;
  120.  
  121. procedure readcurbase;
  122. begin
  123.   seek (ddfile,curbasenum-1);
  124.   read (ddfile,curbase)
  125. end;
  126.  
  127. procedure openefile;
  128. var i:integer;
  129. begin
  130.   readcurbase;
  131.   if isopen(efile) then close(efile);
  132.   i:=ioresult;
  133.   assign (efile,'Database.'+strr(curbasenum));
  134.   reset (efile);
  135.   if ioresult<>0 then rewrite (efile);
  136.   curbase.numents:=filesize(efile);
  137.   writecurbase
  138. end;
  139.  
  140. function getparsedentry (var p:parsedentry):boolean;
  141. var cnt:integer;
  142.     pr:parsedentry;
  143.     nonblank:boolean;
  144. begin
  145.   nonblank:=false;
  146.   parseentry (curbase.catnames,pr);
  147.   writeln ('(*=',unam,')');
  148.   for cnt:=1 to curbase.numcats do begin
  149.     writestr (pr[cnt]+': &');
  150.     if length(input)>0 then nonblank:=true;
  151.     if input='*'
  152.       then p[cnt]:=unam
  153.       else p[cnt]:=input
  154.   end;
  155.   getparsedentry:=nonblank
  156. end;
  157.  
  158. function getentry (var a:anystr):boolean;
  159. var p:parsedentry;
  160. begin
  161.   getentry:=getparsedentry (p);
  162.   packentry (p,a)
  163. end;
  164.  
  165. const shownumbers:boolean=false;
  166. procedure showparsedentry (var p:parsedentry);
  167. var cnt:integer;
  168.     pr:parsedentry;
  169. begin
  170.   parseentry (curbase.catnames,pr);
  171.   for cnt:=1 to curbase.numcats do begin
  172.     if shownumbers then write (cnt,'. ');
  173.     writeln (pr[cnt],': '^S,p[cnt]);
  174.     if break then exit
  175.   end;
  176.   shownumbers:=false
  177. end;
  178.  
  179. procedure showentry (var a:anystr);
  180. var p:parsedentry;
  181. begin
  182.   parseentry (a,p);
  183.   showparsedentry (p)
  184. end;
  185.  
  186. procedure showentrynum (var a:anystr; num:integer);
  187. begin
  188.   writeln (^M,num,':');
  189.   showentry (a)
  190. end;
  191.  
  192. function noentries:boolean;
  193. begin
  194.   if curbase.numents>0
  195.     then noentries:=false
  196.     else
  197.       begin
  198.         writeln ('Sorry, database is empty!');
  199.         noentries:=true
  200.       end
  201. end;
  202.  
  203. procedure changeentryrec (var e:entryrec);
  204. var p:parsedentry;
  205.     c:integer;
  206.     done:boolean;
  207. begin
  208.   parseentry (e.data,p);
  209.   repeat
  210.     shownumbers:=true;
  211.     showparsedentry (p);
  212.     writestr (^M'Category number to change [CR to exit]:');
  213.     done:=length(input)=0;
  214.     if not done then begin
  215.       c:=valu(input);
  216.       if (c>0) and (c<=curbase.numcats) then begin
  217.         writestr ('New value [*=Your name, CR to leave unchanged]: &');
  218.         if length(input)<>0 then
  219.           if input='*'
  220.             then p[c]:=unam
  221.             else p[c]:=input
  222.       end
  223.     end
  224.   until done;
  225.   packentry (p,e.data)
  226. end;
  227.  
  228. procedure adddata;
  229. var e:entryrec;
  230. begin
  231.   writehdr ('Add an entry');
  232.   if not getentry (e.data) then begin
  233.     writeln ('Blank entry!');
  234.     exit
  235.   end;
  236.   writestr (^M'Make changes (Y/N/X)? *');
  237.   if length(input)<>0 then
  238.     case upcase(input[1]) of
  239.       'X':begin
  240.             writestr ('Entry not added.');
  241.             exit
  242.           end;
  243.       'Y':changeentryrec (e)
  244.     end;
  245.   e.when:=now;
  246.   e.addedby:=unum;
  247.   seek (efile,curbase.numents);
  248.   write (efile,e);
  249.   curbase.numents:=curbase.numents+1;
  250.   writecurbase
  251. end;
  252.  
  253. procedure listdata;
  254. var cnt,f,l:integer;
  255.     e:entryrec;
  256. begin
  257.   if noentries then exit;
  258.   writeln;
  259.   parserange (curbase.numents,f,l);
  260.   if f=0 then exit;
  261.   writeln;
  262.   for cnt:=f to l do begin
  263.     seek (efile,cnt-1);
  264.     read (efile,e);
  265.     showentrynum (e.data,cnt);
  266.     if break then exit
  267.   end
  268. end;
  269.  
  270. function getdatanum (txt:mstr):integer;
  271. var n:integer;
  272. begin
  273.   getdatanum:=0;
  274.   if noentries then exit;
  275.   repeat
  276.     writestr (^M'Entry to '+txt+' [?=list]:');
  277.     if length(input)=0 then exit;
  278.     if input='?' then begin
  279.       listdata;
  280.       input:=''
  281.     end
  282.   until length(input)>0;
  283.   n:=valu(input);
  284.   if (n>0) and (n<=curbase.numents) then getdatanum:=n
  285. end;
  286.  
  287. function notuseradded (var e:entryrec):boolean;
  288. var b:boolean;
  289. begin
  290.   b:=not ((e.addedby=unum) or issysop);
  291.   notuseradded:=b;
  292.   if b then writestr ('You didn''t add this entry!')
  293. end;
  294.  
  295. procedure changedata;
  296. var n:integer;
  297.     e:entryrec;
  298. begin
  299.   n:=getdatanum ('change');
  300.   if n=0 then exit;
  301.   seek (efile,n-1);
  302.   read (efile,e);
  303.   if notuseradded (e) then exit;
  304.   writelog (8,3,copy(e.data,1,pos(#1,e.data)-1));
  305.   changeentryrec (e);
  306.   seek (efile,n-1);
  307.   write (efile,e);
  308. end;
  309.  
  310. procedure deletedata;
  311. var n,cnt:integer;
  312.     e:entryrec;
  313.     p:parsedentry;
  314. begin
  315.   n:=getdatanum ('delete');
  316.   if n=0 then exit;
  317.   seek (efile,n-1);
  318.   read (efile,e);
  319.   if notuseradded(e) then exit;
  320.   parseentry (e.data,p);
  321.   writelog (8,6,p[1]);
  322.   curbase.numents:=curbase.numents-1;
  323.   writecurbase;
  324.   for cnt:=n to curbase.numents do begin
  325.     seek (efile,cnt);
  326.     read (efile,e);
  327.     seek (efile,cnt-1);
  328.     write (efile,e)
  329.   end;
  330.   seek (efile,curbase.numents);
  331.   truncate (efile)
  332. end;
  333.  
  334. procedure listbases;
  335. var cnt:integer;
  336.     b:baserec;
  337. begin
  338.   writehdr ('List of Databases');
  339.   if break then exit;
  340.   for cnt:=1 to filesize (ddfile) do begin
  341.     seek (ddfile,cnt-1);
  342.     read (ddfile,b);
  343.     if b.level<=ulvl then writeln (cnt,'. ',b.basename);
  344.     if break then exit
  345.   end
  346. end;
  347.  
  348. procedure selectdata;
  349. var n:integer;
  350.     b:baserec;
  351. begin
  352.   if length(input)>1 then input:=copy(input,2,255) else
  353.     repeat
  354.       writestr ('Database number [?=list]:');
  355.       if length(input)=0 then exit;
  356.       if input='?' then begin
  357.         listbases;
  358.         input:=''
  359.       end
  360.     until length(input)>0;
  361.   n:=valu(input);
  362.   if (n<1) or (n>filesize(ddfile)) then begin
  363.     writeln ('No such database: '^S,n);
  364.     if not issysop then exit;
  365.     n:=filesize(ddfile)+1;
  366.     writestr ('Create database #'+strr(n)+'? *');
  367.     if yes then begin
  368.       writecurbase;
  369.       makenewbase;
  370.       openefile
  371.     end;
  372.     exit
  373.   end;
  374.   seek (ddfile,n-1);
  375.   read (ddfile,b);
  376.   if b.level>ulvl then begin
  377.     reqlevel (b.level);
  378.     exit
  379.   end;
  380.   writecurbase;
  381.   curbasenum:=n;
  382.   openefile
  383. end;
  384.  
  385. procedure searchdata;
  386. var cnt,f,en:integer;
  387.     e:entryrec;
  388.     pattern:anystr;
  389.     p:parsedentry;
  390. begin
  391.   if noentries then exit;
  392.   writestr ('Search pattern:');
  393.   if length(input)=0 then exit;
  394.   pattern:=input;
  395.   for cnt:=1 to length(pattern) do pattern[cnt]:=upcase(pattern[cnt]);
  396.   for en:=1 to curbase.numents do begin
  397.     seek (efile,en-1);
  398.     read (efile,e);
  399.     parseentry (e.data,p);
  400.     for f:=1 to curbase.numcats do begin
  401.       for cnt:=1 to length(p[f]) do p[f][cnt]:=upcase(p[f][cnt]);
  402.       if pos(pattern,p[f])<>0 then showentrynum (e.data,en)
  403.     end
  404.   end;
  405.   writeln (^M'Search complete')
  406. end;
  407.  
  408. const beenaborted:boolean=false;
  409.  
  410. function aborted:boolean;
  411. begin
  412.   if beenaborted then begin
  413.     aborted:=true;
  414.     exit
  415.   end;
  416.   aborted:=xpressed or hungupon;
  417.   if xpressed then begin
  418.     beenaborted:=true;
  419.     writeln (^B'Newscan aborted!')
  420.   end
  421. end;
  422.  
  423. procedure newscan;
  424. var first,cnt:integer;
  425.     nd:boolean;
  426.     e:entryrec;
  427. begin
  428.   beenaborted:=false;
  429.   first:=curbase.numents;
  430.   nd:=true;
  431.   while (first>0) and nd do begin
  432.     seek (efile,first-1);
  433.     read (efile,e);
  434.     nd:=e.when>laston;
  435.     if nd then first:=first-1
  436.   end;
  437.   for cnt:=first+1 to curbase.numents do begin
  438.     seek (efile,cnt-1);
  439.     read (efile,e);
  440.     if aborted then exit;
  441.     showentrynum (e.data,cnt)
  442.   end
  443. end;
  444.  
  445. procedure newscanall;
  446. begin
  447.   writehdr ('New-scanning... Press [X] to abort.');
  448.   curbasenum:=1;
  449.   while curbasenum<=filesize(ddfile) do begin
  450.     if aborted then exit;
  451.     openefile;
  452.     if curbase.level<=ulvl then begin
  453.       writeln (^B^M'Scanning ',curbase.basename,^M);
  454.       newscan;
  455.       if aborted then exit
  456.     end;
  457.     curbasenum:=curbasenum+1
  458.   end;
  459.   curbasenum:=1;
  460.   openefile;
  461.   writeln (^B'Newscan complete!')
  462. end;
  463.  
  464. procedure killdatabase;
  465. var b:baserec;
  466.     cnt:integer;
  467. begin
  468.   writestr ('Kill database:  Are you sure? *');
  469.   if not yes then exit;
  470.   writecurbase;
  471.   close (efile);
  472.   erase (efile);
  473.   for cnt:=curbasenum to filesize(ddfile)-1 do begin
  474.     seek (ddfile,cnt);
  475.     read (ddfile,b);
  476.     seek (ddfile,cnt-1);
  477.     write (ddfile,b);
  478.     assign (efile,'Database.'+strr(cnt+1));
  479.     rename (efile,'Database.'+strr(cnt))
  480.   end;
  481.   seek (ddfile,filesize(ddfile)-1);
  482.   truncate (ddfile);
  483.   writelog (8,5,'');
  484.   if filesize(ddfile)>0 then begin
  485.     curbasenum:=1;
  486.     openefile
  487.   end
  488. end;
  489.  
  490. procedure reorderdata;
  491. var numd,curd,newd:integer;
  492.     b1,b2:baserec;
  493.     f1,f2:file;
  494.     fn1,fn2:sstr;
  495. label exit;
  496. begin
  497.   writecurbase;
  498.   writehdr ('Re-order databases');
  499.   writelog (8,1,'');
  500.   numd:=filesize (ddfile);
  501.   writeln ('Number of database: ',numd);
  502.   for curd:=0 to numd-2 do begin
  503.     repeat
  504.       writestr ('New database #'+strr(curd+1)+' [?=List, CR to quit]:');
  505.       if length(input)=0 then goto exit;
  506.       if input='?'
  507.         then
  508.           begin
  509.             listbases;
  510.             newd:=-1
  511.           end
  512.         else
  513.           begin
  514.             newd:=valu(input)-1;
  515.             if (newd<0) or (newd>=numd) then begin
  516.               writeln ('Not found!  Please re-enter...');
  517.               newd:=-1
  518.             end
  519.           end
  520.     until (newd>0);
  521.     seek (ddfile,curd);
  522.     read (ddfile,b1);
  523.     seek (ddfile,newd);
  524.     read (ddfile,b2);
  525.     seek (ddfile,curd);
  526.     write (ddfile,b2);
  527.     seek (ddfile,newd);
  528.     write (ddfile,b1);
  529.     fn1:='Database.';
  530.     fn2:=fn1+strr(newd+1);
  531.     fn1:=fn1+strr(curd+1);
  532.     assign (f1,fn1);
  533.     assign (f2,fn2);
  534.     rename (f1,'Temp$$$$');
  535.     rename (f2,fn1);
  536.     rename (f1,fn2)
  537.   end;
  538.   exit:
  539.   curbasenum:=1;
  540.   openefile
  541. end;
  542.  
  543. procedure renamedata;
  544. begin
  545.   writeln ('Current name: '^S,curbase.basename);
  546.   writestr ('Enter new name:');
  547.   if length(input)>0 then begin
  548.     curbase.basename:=input;
  549.     writecurbase;
  550.     writelog (8,2,input)
  551.   end
  552. end;
  553.  
  554. procedure setlevel;
  555. begin
  556.   writeln ('Current level: '^S,curbase.level);
  557.   writestr ('Enter new level:');
  558.   if length(input)>0 then begin
  559.     curbase.level:=valu(input);
  560.     writecurbase;
  561.     writelog (8,4,strr(curbase.level))
  562.   end
  563. end;
  564.  
  565. procedure sysopcommands;
  566. var q:integer;
  567. begin
  568.   writelog (7,1,curbase.basename);
  569.   repeat
  570.     q:=menu('Database Sysop','DSYSOP','QCDEKOR');
  571.     case q of
  572.       2:changedata;
  573.       3:deletedata;
  574.       4:setlevel;
  575.       5:killdatabase;
  576.       6:reorderdata;
  577.       7:renamedata
  578.     end
  579.   until (q=1) or hungupon or (filesize(ddfile)=0)
  580. end;
  581.  
  582. var q:integer;
  583. begin
  584.   cursection:=databasesysop;
  585.   openddfile;
  586.   if filesize(ddfile)=0 then exit;
  587.   curbasenum:=1;
  588.   seek (ddfile,0);
  589.   read (ddfile,curbase);
  590.   if curbase.level>ulvl then begin
  591.     reqlevel (curbase.level);
  592.     close (ddfile);
  593.     exit
  594.   end;
  595.   openefile;
  596.  
  597.   repeat
  598.     writeln (^B^M'Active:  '^S,curbase.basename);
  599.     writeln ('Entries: '^S,curbase.numents);
  600.     q:=menu('Database','DATA','QA*SLVNH%@CD');
  601.     case q of
  602.       2:adddata;
  603.       3:selectdata;
  604.       4:searchdata;
  605.       5:listdata;
  606.       6:newscan;
  607.       7:newscanall;
  608.       8:help ('Database.hlp');
  609.       9:sysopcommands;
  610.       10:changedata;
  611.       11:deletedata
  612.     end
  613.   until hungupon or (q=1) or (filesize(ddfile)=0);
  614.   close (ddfile);
  615.   close (efile)
  616. end;
  617.  
  618. begin
  619. end.
  620.