home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 270.img / FORUM25C.ZIP / DATABASE.PAS < prev    next >
Pascal/Delphi Source File  |  1988-12-27  |  14KB  |  628 lines

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