home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 October / Chip_2001-10_cd1.bin / zkuste / delphi / nastroje / d23456 / SPLBASE.ZIP / Splbase / Include / Splinc.pas next >
Pascal/Delphi Source File  |  2001-08-05  |  34KB  |  1,389 lines

  1. (*********** SplitBase Data Management Systems ***********
  2.  *                                                       *
  3.  *           Copyright (c) 2001 Leon O. Romain           *
  4.  *                                                       *
  5.  *                     leon@kafou.com                    *
  6.  *                                                       *
  7.  *********************************************************)
  8.  
  9. {
  10. This program is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU General Public License
  12. as published by the Free Software Foundation; either version 2
  13. of the License, or (at your option) any later version.
  14.  
  15. This program is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. GNU General Public License for more details.
  19.  
  20. You should have received a copy of the GNU General Public License
  21. along with this program; if not, write to the Free Software
  22. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  23. }
  24.  
  25. const
  26.    spllen = 26;   {Length of index field}
  27.    splmax = 2000; {Maximum number of records before split}
  28.    fldmax = 100;  {Maximum number of fields in record}
  29.  
  30. type
  31.   Splitrec = record          {SplitBase index structure}
  32.     data : string[spllen];   {Actual index field value}
  33.     ptr : longint;           {Pointer to record containing index}
  34.   end;
  35.  
  36.   splitbox = record          {Full SplitBase index structure}
  37.      state : byte;           {0 = empty}
  38.      count : longint;        {number of index fields in SplitBase index}
  39.      index :                 {All indexes values within SplitBase index}
  40.              array [1..splmax] of Splitrec;
  41.   end;
  42.  
  43.   recdef = record            {Record definition for DB}
  44.      size : integer;         {Total number of fields}
  45.      recout : longint;       {Number of deleted record}
  46.      indout : longint;       {Number of indexes deleted}
  47.      SplID : longint;        {SplitBase Identifier}
  48.      rsv101,                 {Reserved}
  49.      rsv102,                 {Reserved}
  50.      rsv103,                 {Reserved}
  51.      rsv104 : longint;       {Reserved}
  52.      def :                   {Size of each field}
  53.             array [1..fldmax] of string[3]
  54.   end;
  55.  
  56.   splerror = record          {Error definition structure}
  57.      recnum : integer;       {Error number}
  58.      recstr : string;        {Error description}
  59.   end;
  60.  
  61. var
  62.    topbox,   {First or top index holder}
  63.    varbox :  {Variable or current index holder}
  64.             ^splitbox;
  65.    allrec :  {Definition for all fields in record}
  66.             recdef;
  67.    curtop :  {Pointer to current position within top index}
  68.             longint;
  69.    curind,   {Value of current index}
  70.    curdtb :  {Name of current database}
  71.             string;
  72.    cursub,   {Pointer to current subindex}
  73.    curpos,   {Pointer to current data in SplitBase index}
  74.    currec :  {Pointer to current record within DB}
  75.             longint;
  76.    rechld : {Holder for all fields in record}
  77.             ansistring;
  78.    splerr : {Holds number and description of last error}
  79.             splerror;
  80.    recmax,  {Maximum number of record in DB. Useful if the
  81.              Database must be limited to a specific number
  82.              of records to avoid overflow}
  83.    limrec : {Limits the number of recors that can entered
  84.              by comparison to recmax}
  85.             Longint;
  86.  
  87. function initspl : boolean;
  88. {Initialize spliter system by reserving space in memory
  89.  for the top and curent SplitBase indexes. Return false if
  90.  process fails}
  91. var
  92.    b : boolean;
  93. begin
  94.    recmax := ( splmax div 2 ) * splmax;
  95.    b := true;
  96.    try
  97.       new ( topbox );
  98.       new ( varbox );
  99.    except
  100.       on EOutOfMemory do b := false;
  101.    end;
  102.    if b = false then
  103.    begin
  104.       splerr.recnum := 0;
  105.       splerr.recstr := 'Unable to allocate system memory';
  106.    end;
  107.    initspl := b;
  108. end;
  109.  
  110. function releasespl : boolean;
  111. {Releases memory allocated to spliter system by disposing
  112.  of that memory. The function returns false if
  113.  process fails}
  114. var
  115.    b : boolean;
  116. begin
  117.    b := true;
  118.    try
  119.       dispose ( topbox );
  120.       dispose ( varbox );
  121.    except
  122.       on EInvalidPointer do b := false
  123.    end;
  124.    if b = false then
  125.    begin
  126.       splerr.recnum := 28;
  127.       splerr.recstr := 'No SplitBase Sytem to unload';
  128.    end;
  129.    releasespl := b;
  130. end;
  131.  
  132. function initbase : boolean;
  133. {Initializes all variables of SplitBase DB before creating
  134.  a new Database or opening one.}
  135. var
  136.    b : boolean;
  137.    s : string;
  138. begin
  139.    b := false;
  140.    try
  141.       topbox.state := 0;
  142.       topbox.count := 0;
  143.       varbox.state := 0;
  144.       varbox.count := 0;
  145.    except
  146.       b := false;
  147.    end;
  148.    allrec.size := 0;
  149.    allrec.recout := 0;
  150.    allrec.indout := 0;
  151.    s := 'SB10';
  152.    move ( s[1], allrec.SplID, 4 );
  153.    curind := '';
  154.    curdtb := '';
  155.    currec := 0;
  156.    rechld := '';
  157.    limrec := 0;
  158.    initbase := b;
  159. end;
  160.  
  161. function activedb : boolean;
  162. {This function checks if there is an active DB}
  163. var
  164.    b : boolean;
  165. begin
  166.    b := true;
  167.    if curdtb = '' then
  168.       b := false;
  169.    activedb := b
  170. end;
  171.  
  172. function activerec : boolean;
  173. {This function checks if there is an active record}
  174. var
  175.    b : boolean;
  176. begin
  177.    b := true;
  178.    if currec = 0 then
  179.       b := false;
  180.    activerec := b
  181. end;
  182.  
  183. function dbempty : boolean;
  184. {This function checks if DB is empty}
  185. var
  186.    b : boolean;
  187. begin
  188.    b := true;
  189.    if activedb then
  190.    begin
  191.       if topbox^.count > 0 then
  192.          b := false;
  193.    end;
  194.    dbempty := b
  195. end;
  196.  
  197. function reccount : longint;
  198. {Returns the number of records in database}
  199. var
  200.    l1, l2 : longint;
  201.    f : file;
  202. begin
  203.    l1 := sizeof ( splitbox );
  204.    assignfile ( f, curdtb );
  205.    {$I-}
  206.    reset ( f, 1 );
  207.    l2 := filesize ( f );
  208.    closefile ( f );
  209.    {$I+}
  210.    if ioresult = 0 then
  211.    begin
  212.       if topbox^.count > 0 then
  213.       begin
  214.          l1 := ( l2 - sizeof ( allrec ) - ( l1 *
  215.                ( topbox^.count + 1 ) ) ) div allrec.size;
  216.          l1 := l1 - allrec.recout - ( allrec.indout *
  217.                ( sizeof ( splitbox ) ) );
  218.       end
  219.       else
  220.          l1 := 0;
  221.    end
  222.    else
  223.       l1 := 0;
  224.    reccount := l1;
  225. end;
  226.  
  227. function createspl ( splname : string ) : boolean;
  228. {Creates a new SplitBase DB and saves it to disk. This
  229.  function will return false if process fails}
  230. var
  231.    b : boolean;
  232.    f : file;
  233.    s : string;
  234. begin
  235.    b := true;
  236.    s := splname + '.spd';
  237.    if fileexists ( s ) then
  238.    begin
  239.       b := false;
  240.       splerr.recnum := 1;
  241.       splerr.recstr := 'File already exits.';
  242.    end
  243.    else
  244.    if allrec.size <= 0 then
  245.    begin
  246.       b := false;
  247.       splerr.recnum := 31;
  248.       splerr.recstr := 'Record structure not defined.';
  249.    end
  250.    else
  251.    begin
  252.       assignfile ( f, s );
  253.       {$I-}
  254.       rewrite ( f, 1 );
  255.       {$I+}
  256.       if ioresult = 0 then
  257.       begin
  258.          {initbase;}
  259.          {$I-}
  260.          blockwrite ( f, topbox^, sizeof ( splitbox ) );
  261.          blockwrite ( f, allrec, sizeof ( allrec ) );
  262.          blockwrite ( f, varbox^, sizeof ( splitbox ) );
  263.          {$I+}
  264.          if ioresult <> 0 then
  265.          begin
  266.             b := false;
  267.             splerr.recnum := 3;
  268.             splerr.recstr := 'Unable to write SplitBase file.';
  269.          end;
  270.          {$I-}
  271.          closefile ( f );
  272.          {$I+}
  273.          if ioresult <> 0 then
  274.          begin
  275.             b := false;
  276.             splerr.recnum := 4;
  277.             splerr.recstr := 'Unable to close SplitBase file.';
  278.          end;
  279.       end
  280.       else
  281.       begin
  282.          b := false;
  283.          splerr.recnum := 2;
  284.          splerr.recstr := 'Unable to create SplitBase file.';
  285.       end;
  286.    end;
  287.    if b then
  288.    begin
  289.       curdtb := splname + '.spd';
  290.       setlength ( rechld, allrec.size );
  291.    end
  292.    else
  293.       curdtb := '';
  294.    createspl := b
  295. end;
  296.  
  297. function openspl ( splname : string ) : boolean;
  298. {Opens an existing SplitBase DB from disk. This
  299.  function will return false if process fails}
  300. var
  301.    b : boolean;
  302.    f : file;
  303.    s : string;
  304. begin
  305.    b := true;
  306.    s := splname + '.spd';
  307.    assignfile ( f, s );
  308.    {$I-}
  309.    reset ( f, 1 );
  310.    {$I+}
  311.    if ioresult = 0 then
  312.    begin
  313.       {$I-}
  314.       blockread ( f, topbox^, sizeof ( splitbox ) );
  315.       blockread ( f, allrec, sizeof ( allrec ) );
  316.       blockread ( f, varbox^, sizeof ( splitbox ) );
  317.       {$I+}
  318.       if ioresult = 0 then
  319.       begin
  320.          s := '    ';
  321.          move ( allrec.SplID, s[1], 4 );
  322.          if s <> 'SB10' then
  323.          begin
  324.             b := false;
  325.             splerr.recnum := 100;
  326.             splerr.recstr := 'Not a SplitBase file.';
  327.          end
  328.       end
  329.       else
  330.       begin
  331.          b := false;
  332.          splerr.recnum := 6;
  333.          splerr.recstr := 'Unable to read SplitBase file.';
  334.       end;
  335.       {$I-}
  336.       closefile ( f );
  337.       {$I+}
  338.       if ioresult <> 0 then
  339.       begin
  340.          b := false;
  341.          splerr.recnum := 7;
  342.          splerr.recstr := 'Unable to close SplitBase file.';
  343.       end;
  344.    end
  345.    else
  346.    begin
  347.       b := false;
  348.       splerr.recnum := 5;
  349.       splerr.recstr := 'Unable to open SplitBase file.';
  350.    end;
  351.    if b then
  352.    begin
  353.       curdtb := splname + '.spd';
  354.       setlength ( rechld, allrec.size );
  355.    end
  356.    else
  357.       curdtb := '';
  358.    openspl := b
  359. end;
  360.  
  361. function putdef : boolean;
  362. {Updates DB definition record}
  363. var
  364.    b : boolean;
  365.    f : file;
  366. begin
  367.    b := true;
  368.    if activedb then
  369.    begin
  370.       assignfile ( f, curdtb );
  371.       {$I-}
  372.       reset ( f, 1 );
  373.       seek ( f, sizeof ( splitbox ) );
  374.       blockwrite ( f, allrec, sizeof ( allrec ) );
  375.       closefile ( f );
  376.       {$I+}
  377.       if ioresult <> 0 then
  378.       begin
  379.          b := false;
  380.          splerr.recnum := 49;
  381.          splerr.recstr := 'Unable to close SplitBase file.';
  382.       end
  383.    end
  384.    else
  385.       b := false;
  386.    putdef := b;
  387. end;
  388.  
  389. Function getsubindex (ind : longint) : boolean;
  390. {Locates and loads the current secondary index into memory}
  391. var
  392.    b : boolean;
  393.    f : file;
  394. begin
  395.    b := true;
  396.    assignfile ( f, curdtb );
  397.    {$I-}
  398.    reset ( f, 1 );
  399.    seek ( f, ind );
  400.    {$I+}
  401.    if ioresult = 0 then
  402.    begin
  403.       {$I-}
  404.       blockread ( f, varbox^, sizeof ( splitbox ) );
  405.       {$I+}
  406.       if ioresult <> 0 then
  407.       begin
  408.          b := false;
  409.          splerr.recnum := 9;
  410.          splerr.recstr := 'Unable to read SplitBase file.';
  411.       end;
  412.       {$I-}
  413.       closefile ( f );
  414.       {$I+}
  415.       if ioresult <> 0 then
  416.       begin
  417.          b := false;
  418.          splerr.recnum := 10;
  419.          splerr.recstr := 'Unable to close SplitBase file.';
  420.       end;
  421.    end
  422.    else
  423.    begin
  424.       b := false;
  425.       splerr.recnum := 12;
  426.       splerr.recstr := 'Unable to open SplitBase file.';
  427.    end;
  428.    if b then
  429.       cursub := ind;
  430.    getsubindex := b;
  431. end;
  432.  
  433. function findpos (idx : string) : boolean;
  434. {Finds the position of the search field within the
  435.  secondary index or subindex}
  436. var
  437.    b : boolean;
  438.    cnt, l, l1, l2 : longint;
  439.    s : string;
  440. begin
  441.    cnt := varbox^.count;
  442.    b := true;
  443.    l := 0;
  444.    currec := 0;
  445.    if cnt > 0 then
  446.    begin
  447.       if cnt > 1 then
  448.       begin
  449.          l1 := 1;
  450.          l2 := cnt;
  451.          while l1 <= l2 do
  452.          begin
  453.             l := (l2 - l1) div 2 + l1;
  454.             s := varbox^.index[l].data;
  455.             if ansicomparetext ( idx, s ) > 0 then
  456.                l1 := l + 1
  457.             else if ansicomparetext ( idx, s ) < 0 then
  458.                l2 := l - 1
  459.             else
  460.                l2 := l1 - 1
  461.          end
  462.       end
  463.       else
  464.          l := 1;
  465.       s := varbox^.index[l].data;
  466.       {ind := varbox^.index[l].ptr;}
  467.       currec := varbox^.index[l].ptr;
  468.       curind := s;
  469.       curpos := l
  470.    end;
  471.    findpos := b
  472. end;
  473.  
  474. function findsubindex (idx : string) : boolean;
  475. {Locates the secondary index that may contain the
  476.  search field}
  477. var
  478.    b : boolean;
  479.    l1, l2, l, cnt, ind : longint;
  480.    s : string;
  481. begin
  482.    cnt := topbox^.count;
  483.    l := 0;
  484.    if cnt > 0 then
  485.    begin
  486.       if cnt > 1 then
  487.       begin
  488.          l1 := 1;
  489.          l2 := cnt;
  490.          while l1 <= l2 do
  491.          begin
  492.             l := (l2 - l1) div 2 + l1;
  493.             s := topbox^.index[l].data;
  494.             if ansicomparetext ( idx, s ) > 0 then
  495.                l1 := l + 1
  496.             else if ansicomparetext ( idx, s ) < 0 then
  497.                l2 := l - 1
  498.             else
  499.                l2 := l1 - 1
  500.          end
  501.       end
  502.       else
  503.          l := 1;
  504.       s := topbox^.index[l].data;
  505.       if ansicomparetext ( idx, s ) < 0 then
  506.          l := l - 1;
  507.       if l = 0 then
  508.          l := 1;
  509.       s := topbox^.index[l].data;
  510.       ind := topbox^.index[l].ptr;
  511.       curtop := l;
  512.  
  513.       if ind > 0 then
  514.       begin
  515.          b := getsubindex(ind)
  516.       end
  517.       else
  518.       begin
  519.          b := false;
  520.          splerr.recnum := 11;
  521.          splerr.recstr := 'Illegal SplitBase index value.';
  522.       end;
  523.  
  524.       if b then
  525.       begin
  526.          b := findpos (idx)
  527.       end
  528.  
  529.    end
  530.    else
  531.    begin
  532.       b := false;
  533.       splerr.recnum := 8;
  534.       splerr.recstr := 'SplitBase index is empty.';
  535.    end;
  536.    if b = false then
  537.       currec := 0;
  538.    findsubindex := b;
  539. end;
  540.  
  541. function pullrec : boolean;
  542. {Reads record into memory}
  543. var
  544.    b : boolean;
  545.    f : file;
  546. begin
  547.    b := true;
  548.    assignfile ( f, curdtb );
  549.    {$I-}
  550.    reset ( f, 1 );
  551.    seek ( f, currec );
  552.    {$I+}
  553.    if ioresult = 0 then
  554.    begin
  555.       {$I-}
  556.       setlength ( rechld, allrec.size );
  557.       blockread ( f, rechld[1], allrec.size );
  558.       {$I+}
  559.       if ioresult <> 0 then
  560.       begin
  561.          b := false;
  562.          splerr.recnum := 32;
  563.          splerr.recstr := 'Unable to read record.';
  564.       end;
  565.       {$I-}
  566.       closefile ( f );
  567.       {$I+}
  568.       if ioresult <> 0 then
  569.       begin
  570.          b := false;
  571.          splerr.recnum := 33;
  572.          splerr.recstr := 'Unable to close SplitBase file.';
  573.       end;
  574.    end
  575.    else
  576.    begin
  577.       b := false;
  578.       splerr.recnum := 34;
  579.       splerr.recstr := 'Unable to open SplitBase file.';
  580.    end;
  581.    pullrec := b;
  582. end;
  583.  
  584. function getrec (idx : string) : boolean;
  585. {Loads the found record into memory}
  586. var
  587.    b : boolean;
  588.    f : file;
  589. begin
  590.    b := true;
  591.    if findsubindex (idx) then
  592.    begin
  593.       if comparetext (idx, curind) = 0 then
  594.       begin
  595.          assignfile ( f, curdtb );
  596.          {$I-}
  597.          reset ( f, 1 );
  598.          seek ( f, currec );
  599.          {$I+}
  600.          if ioresult = 0 then
  601.          begin
  602.             {$I-}
  603.             setlength ( rechld, allrec.size );
  604.             blockread ( f, rechld[1], allrec.size );
  605.             {$I+}
  606.             if ioresult <> 0 then
  607.             begin
  608.                b := false;
  609.                splerr.recnum := 14;
  610.                splerr.recstr := 'Unable to read record.';
  611.             end;
  612.             {$I-}
  613.             closefile ( f );
  614.             {$I+}
  615.             if ioresult <> 0 then
  616.             begin
  617.                b := false;
  618.                splerr.recnum := 15;
  619.                splerr.recstr := 'Unable to close SplitBase file.';
  620.             end;
  621.          end
  622.          else
  623.          begin
  624.             b := false;
  625.             splerr.recnum := 13;
  626.             splerr.recstr := 'Unable to open SplitBase file.';
  627.          end;
  628.       end
  629.       else
  630.       begin
  631.          b := false;
  632.          splerr.recnum := 16;
  633.          splerr.recstr := 'Data not found';
  634.       end;
  635.    end
  636.    else
  637.       b := false;
  638.    if b = false then
  639.       currec := 0; 
  640.    getrec := b;
  641. end;
  642.  
  643. function putrec : boolean;
  644. {Saves the new record within DB}
  645. var
  646.    b : boolean;
  647.    f : file;
  648.    l : longint;
  649. begin
  650.    b := true;
  651.    assignfile ( f, curdtb );
  652.    {$I-}
  653.    reset ( f, 1 );
  654.    l := filesize ( f );
  655.    seek ( f, l );
  656.    {$I+}
  657.    if ioresult = 0 then
  658.    begin
  659.       {$I-}
  660.       blockwrite ( f, rechld[1], allrec.size );
  661.       {$I+}
  662.       if ioresult <> 0 then
  663.       begin
  664.          b := false;
  665.          splerr.recnum := 18;
  666.          splerr.recstr := 'Unable to save record.';
  667.       end;
  668.       {$I-}
  669.       closefile ( f );
  670.       {$I+}
  671.       if ioresult <> 0 then
  672.       begin
  673.          b := false;
  674.          splerr.recnum := 19;
  675.          splerr.recstr := 'Unable to close SplitBase file.';
  676.       end;
  677.    end
  678.    else
  679.    begin
  680.       b := false;
  681.       splerr.recnum := 17;
  682.       splerr.recstr := 'Unable to open SplitBase file.';
  683.    end;
  684.    if b then
  685.       currec := l
  686.    else
  687.       currec := 0;
  688.    putrec := b;
  689. end;
  690.  
  691. Function putsubindex (ind : longint) : boolean;
  692. {Saves the secondary index within DB}
  693. var
  694.    b : boolean;
  695.    f : file;
  696. begin
  697.    b := true;
  698.    assignfile ( f, curdtb );
  699.    {$I-}
  700.    reset ( f, 1 );
  701.    seek ( f, ind );
  702.    {$I+}
  703.    if ioresult = 0 then
  704.    begin
  705.       {$I-}
  706.       blockwrite ( f, varbox^, sizeof ( splitbox ) );
  707.       {$I+}
  708.       if ioresult <> 0 then
  709.       begin
  710.          b := false;
  711.          splerr.recnum := 20;
  712.          splerr.recstr := 'Unable to write SplitBase file.';
  713.       end;
  714.       {$I-}
  715.       closefile ( f );
  716.       {$I+}
  717.       if ioresult <> 0 then
  718.       begin
  719.          b := false;
  720.          splerr.recnum := 21;
  721.          splerr.recstr := 'Unable to close SplitBase file.';
  722.       end;
  723.    end
  724.    else
  725.    begin
  726.       b := false;
  727.       splerr.recnum := 22;
  728.       splerr.recstr := 'Unable to open SplitBase file.';
  729.    end;
  730.    putsubindex := b;
  731. end;
  732.  
  733. function puttop : boolean;
  734. {Saves main SplitBase index into DB. This
  735.  function will return false if process fails}
  736. var
  737.    b : boolean;
  738.    f : file;
  739. begin
  740.    b := true;
  741.    assignfile ( f, curdtb );
  742.    {$I-}
  743.    reset ( f, 1 );
  744.    {$I+}
  745.    if ioresult = 0 then
  746.    begin
  747.       {$I-}
  748.       blockwrite ( f, topbox^, sizeof ( splitbox ) );
  749.       {$I+}
  750.       if ioresult <> 0 then
  751.       begin
  752.          b := false;
  753.          splerr.recnum := 25;
  754.          splerr.recstr := 'Unable top index.';
  755.       end;
  756.       {$I-}
  757.       closefile ( f );
  758.       {$I+}
  759.       if ioresult <> 0 then
  760.       begin
  761.          b := false;
  762.          splerr.recnum := 26;
  763.          splerr.recstr := 'Unable to close SplitBase file.';
  764.       end;
  765.    end
  766.    else
  767.    begin
  768.       b := false;
  769.       splerr.recnum := 27;
  770.       splerr.recstr := 'Unable to open SplitBase file.';
  771.    end;
  772.    puttop := b;
  773. end;
  774.  
  775. function splitit : boolean;
  776. {Saves the index field within the main or secondary index
  777.  and splits secondary index}
  778. var
  779.    b : boolean;
  780.    l1, l2 : longint;
  781.    f : file;
  782.    s : string;
  783. begin
  784.    b := true;
  785.    l1 := varbox^.count div 2;
  786.    l2 := varbox^.count - l1;
  787.    varbox^.count := l1;
  788.    putsubindex ( cursub );
  789.    move ( varbox^.index[l1 + 1], varbox^.index[1],
  790.           l2 * sizeof ( Splitrec ) );
  791.    varbox^.count := l2;
  792.    assignfile ( f, curdtb );
  793.    {$I-}
  794.    reset ( f, 1 );
  795.    cursub := filesize ( f );
  796.    close ( f );
  797.    {$I+}
  798.    if ioresult = 0 then
  799.    begin
  800.       if putsubindex ( cursub ) then
  801.       begin
  802.          s := varbox.index[1].data;
  803.          if comparetext ( topbox^.index[ curtop ].data,
  804.                            s ) < 0 then
  805.             curtop := curtop + 1;
  806.          move ( topbox^.index[curtop],
  807.                 topbox^.index[curtop + 1],
  808.                 (splmax - curtop) * sizeof (Splitrec) );
  809.          topbox^.index[curtop].data :=
  810.             varbox.index[1].data;
  811.          topbox^.index[curtop].ptr := cursub;
  812.          topbox^.count := topbox^.count + 1;
  813.          if not (puttop) then
  814.             b := false;
  815.       end
  816.       else
  817.       begin
  818.          b := false;
  819.          splerr.recnum := 24;
  820.          splerr.recstr := 'Unable to split subindex.';
  821.       end
  822.    end
  823.    else
  824.    begin
  825.       b := false;
  826.       splerr.recnum := 23;
  827.       splerr.recstr := 'Unable to size SplitBase file.';
  828.    end;
  829.    splitit := b
  830. end;
  831.  
  832. function addrec (idx : string) : boolean;
  833. {Adds a new record to DB}
  834. var
  835.    b : boolean;
  836.    l : longint;
  837. begin
  838.    b := true;
  839.    if activedb then
  840.    begin
  841.       {if topbox.count = splmax then}
  842.       if limrec >= recmax then
  843.       begin
  844.          b := false;
  845.          splerr.recstr := 'Maximum records exceeded';
  846.       end
  847.    end
  848.    else
  849.    begin
  850.       b := false;
  851.       splerr.recstr := 'No active database.';
  852.    end;
  853.    if b then
  854.    begin
  855.       if findsubindex (idx) then
  856.       begin
  857.          if ansicomparetext ( idx, curind ) > 0 then
  858.             l := curpos + 1
  859.          else
  860.             l := curpos;
  861.          if putrec then
  862.          begin
  863.             move ( varbox^.index[l], varbox^.index[l + 1],
  864.                    (splmax - l) * sizeof ( Splitrec ) );
  865.             varbox^.index[l].data := idx;
  866.             varbox^.index[l].ptr := currec;
  867.             varbox^.count := varbox^.count + 1;
  868.             if varbox^.count = splmax then
  869.             begin
  870.                if splitit = false then
  871.                   b := false
  872.             end
  873.             else
  874.             begin
  875.                if not (putsubindex ( cursub )) then
  876.                   b := false
  877.             end;
  878.             if (l = 1) and (b) then
  879.             begin
  880.                topbox^.index[1].data := varbox.index[1].data;
  881.                if not (puttop) then
  882.                   b := false;
  883.             end;
  884.          end
  885.       end
  886.       else
  887.       begin
  888.          if splerr.recnum = 8 then
  889.          begin
  890.             if putrec then
  891.             begin
  892.                topbox^.state := 1;
  893.                topbox^.count := 1;
  894.                topbox^.index[1].data := idx;
  895.                topbox^.index[1].ptr := sizeof ( splitbox ) +
  896.                                        sizeof ( recdef );
  897.                cursub := sizeof ( splitbox ) +
  898.                          sizeof ( recdef );
  899.                if puttop then
  900.                begin
  901.                   varbox^.index[1].data := idx;
  902.                   varbox^.index[1].ptr := currec;
  903.                   varbox^.count := 1;
  904.                   if not (putsubindex ( cursub )) then
  905.                      b := false
  906.                end
  907.                else
  908.                   b := false
  909.             end
  910.             else
  911.                b := false
  912.          end
  913.          else
  914.             b := false;
  915.       end;
  916.    end
  917.    else
  918.       splerr.recnum := 50;
  919.    if b then
  920.       limrec := limrec + 1;
  921.    addrec := b;
  922. end;
  923.  
  924. function setspl ( spldat : string ) : boolean;
  925. {Automated record definition through a string. The string
  926.  contains the length of each field starting with the first
  927.  and defined by three digits. If the field length is less
  928.  than three digits fill the left part with zeroes.}
  929. var
  930.    b : boolean;
  931.    x, y, len : integer;
  932.    s : string;
  933. begin
  934.    b := true;
  935.    x := length ( spldat );
  936.    if ( x mod 3 = 0 ) and ( x > 0 ) then
  937.    begin
  938.       x := x div 3;
  939.       len := 0;
  940.       for y := 0 to x - 1 do
  941.       begin
  942.          s := copy ( spldat, (y * 3) + 1, 3 );
  943.          if strtoint ( s ) > 0 then
  944.          begin
  945.             len := len + strtoint ( s );
  946.             allrec.def [ y + 1 ] := s
  947.          end
  948.          else
  949.          begin
  950.             b := false;
  951.             splerr.recnum := 29;
  952.             splerr.recstr := 'Illegal definition data';
  953.          end;
  954.       end;
  955.       if b then
  956.       begin
  957.          allrec.size := len;
  958.          setlength ( rechld, len );
  959.       end
  960.    end
  961.    else
  962.    begin
  963.       b := false;
  964.       splerr.recnum := 30;
  965.       splerr.recstr := 'Illegal definition data';
  966.    end;
  967.    setspl := b;
  968. end;
  969.  
  970. function addfield ( recdat : string; pos : integer ) :
  971.          boolean;
  972. {Adds a field to a record in DB}
  973. var
  974.    x, y : integer;
  975.    b : boolean;
  976. begin
  977.    b := true;
  978.    y := 0;
  979.    x := 1;
  980.    while x < pos do
  981.    begin
  982.       y := y + strtoint ( allrec.def[x] );
  983.       x := x + 1;
  984.    end;
  985.    x := strtoint ( allrec.def[pos] );
  986.    while length ( recdat ) < x do
  987.       recdat := recdat + ' ';
  988.    setlength ( recdat, x );
  989.    rechld := copy ( rechld, 1, y ) + recdat +
  990.              copy ( rechld, y + x + 1, length ( rechld ) -
  991.                     ( x + y ) );
  992.    addfield := b;
  993. end;
  994.  
  995. function getfield ( pos : integer ) : string;
  996. {Retreives a field from a record in DB}
  997. var
  998.    x, y : integer;
  999.    s : string;
  1000. begin
  1001.    y := 0;
  1002.    x := 1;
  1003.    s := '';
  1004.    while x < pos do
  1005.    begin
  1006.       y := y + strtoint ( allrec.def[x] );
  1007.       x := x + 1;
  1008.    end;
  1009.    x := strtoint ( allrec.def[pos] );
  1010.    s := copy ( rechld, y + 1, x );
  1011.    getfield := s;
  1012. end;
  1013.  
  1014. function delrec: boolean;
  1015. {Deletes the current record from the database}
  1016. var
  1017.    b : boolean;
  1018.    l : longint;
  1019. begin
  1020.    b := true;
  1021.    if activedb then
  1022.    begin
  1023.       if not (dbempty) then
  1024.       begin
  1025.          if not (activerec) then
  1026.          begin
  1027.             splerr.recstr := 'No active record.';
  1028.             b := false
  1029.          end
  1030.       end
  1031.       else
  1032.       begin
  1033.          splerr.recstr := 'Empty database.';
  1034.          b := false
  1035.       end
  1036.    end
  1037.    else
  1038.    begin
  1039.       splerr.recstr := 'No active database';
  1040.       b := false
  1041.    end;
  1042.    if b then
  1043.    begin
  1044.       l := curpos;
  1045.       move ( varbox^.index[l + 1], varbox^.index[l],
  1046.            (splmax - l) * sizeof ( Splitrec ) );
  1047.       varbox^.count := varbox^.count - 1;
  1048.       if varbox^.count > 0 then
  1049.       begin
  1050.          if putsubindex ( cursub ) then
  1051.          begin
  1052.             allrec.recout := allrec.recout + 1;
  1053.             if not (putdef) then
  1054.                b := false;
  1055.             if l = 1 then
  1056.             begin
  1057.                topbox^.index[curtop].data :=
  1058.                   varbox.index[1].data;
  1059.                if not (puttop) then
  1060.                   b := false;
  1061.             end;
  1062.          end
  1063.          else
  1064.             b := false;
  1065.       end
  1066.       else
  1067.       begin
  1068.          move ( topbox^.index[curtop + 1],
  1069.                 varbox^.index[curtop],
  1070.                 (splmax - curtop) * sizeof ( Splitrec ) );
  1071.          topbox^.count := topbox^.count - 1;
  1072.          allrec.indout := allrec.indout + 1;
  1073.          allrec.recout := allrec.recout + 1;
  1074.          if puttop then
  1075.          begin
  1076.             if not (putdef) then
  1077.                b := false;
  1078.          end
  1079.          else
  1080.             b := false
  1081.       end;
  1082.    end
  1083.    else
  1084.       splerr.recnum := 48;
  1085.    if b then
  1086.       limrec := limrec - 1;
  1087.    if limrec < 0 then
  1088.       limrec := 0;
  1089.    delrec := b;
  1090. end;
  1091.  
  1092. function modrec ( idx : string ) : boolean;
  1093. {This function replaces the current record by a new one}
  1094. var
  1095.    b : boolean;
  1096. begin
  1097.    b := true;
  1098.    if delrec then
  1099.    begin
  1100.       if not ( addrec ( idx ) ) then
  1101.          b := false
  1102.    end
  1103.    else
  1104.       b := false;
  1105.    modrec := b
  1106. end;
  1107.  
  1108. function firstrec : boolean;
  1109. {This function locates and loads the first record in DB}
  1110. var
  1111.    l, ind : longint;
  1112.    s : string;
  1113.    b : boolean;
  1114. begin
  1115.    b := true;
  1116.    if activedb then
  1117.    begin
  1118.       if dbempty then
  1119.       begin
  1120.          splerr.recstr := 'Empty database.';
  1121.          b := false
  1122.       end
  1123.    end
  1124.    else
  1125.    begin
  1126.       splerr.recstr := 'No active database';
  1127.       b := false
  1128.    end;
  1129.    if b then
  1130.    begin
  1131.       curtop := 1;
  1132.       l := 1;
  1133.       s := topbox^.index[l].data;
  1134.       ind := topbox^.index[l].ptr;
  1135.  
  1136.       if ind > 0 then
  1137.       begin
  1138.          if getsubindex(ind) then
  1139.          begin
  1140.             s := varbox^.index[1].data;
  1141.             currec := varbox^.index[1].ptr;
  1142.             curind := s;
  1143.             curpos := 1;
  1144.             if not (pullrec) then
  1145.             begin
  1146.                b := false;
  1147.                splerr.recnum := 35;
  1148.                splerr.recstr := 'Unable to load record';
  1149.             end;
  1150.          end
  1151.          else
  1152.          begin
  1153.             b := false;
  1154.             splerr.recnum := 36;
  1155.             splerr.recstr := 'Error loading subindex';
  1156.          end;
  1157.       end
  1158.    end
  1159.    else
  1160.       splerr.recnum := 47;
  1161.    firstrec := b;
  1162. end;
  1163.  
  1164. function lastrec : boolean;
  1165. {This function locates and loads the last record in DB}
  1166. var
  1167.    l, ind : longint;
  1168.    s : string;
  1169.    b : boolean;
  1170. begin
  1171.    b := true;
  1172.    if activedb then
  1173.    begin
  1174.       if dbempty then
  1175.       begin
  1176.          splerr.recstr := 'Empty database.';
  1177.          b := false
  1178.       end
  1179.    end
  1180.    else
  1181.    begin
  1182.       splerr.recstr := 'No active database';
  1183.       b := false
  1184.    end;
  1185.    if b then
  1186.    begin
  1187.       curtop := topbox^.count;
  1188.       l := topbox^.count;
  1189.       s := topbox^.index[l].data;
  1190.       ind := topbox^.index[l].ptr;
  1191.  
  1192.       if ind > 0 then
  1193.       begin
  1194.          if getsubindex(ind) then
  1195.          begin
  1196.             s := varbox^.index[varbox^.count].data;
  1197.             currec := varbox^.index[varbox^.count].ptr;
  1198.             curind := s;
  1199.             curpos := varbox^.count;
  1200.             if not (pullrec) then
  1201.             begin
  1202.                b := false;
  1203.                splerr.recnum := 37;
  1204.                splerr.recstr := 'Unable to load record.';
  1205.             end;
  1206.          end
  1207.          else
  1208.          begin
  1209.             b := false;
  1210.             splerr.recnum := 38;
  1211.             splerr.recstr := 'Error loading subindex';
  1212.          end;
  1213.       end
  1214.    end
  1215.    else
  1216.       splerr.recnum := 46;
  1217.    lastrec := b;
  1218. end;
  1219.  
  1220. function nextrec : boolean;
  1221. {This function locates and loads the next record in DB}
  1222. var
  1223.    l, ind : longint;
  1224.    s : string;
  1225.    b : boolean;
  1226. begin
  1227.    b := true;
  1228.    if activedb then
  1229.    begin
  1230.       if not (dbempty) then
  1231.       begin
  1232.          if not (activerec) then
  1233.          begin
  1234.             splerr.recstr := 'No active record.';
  1235.             b := false
  1236.          end
  1237.       end
  1238.       else
  1239.       begin
  1240.          splerr.recstr := 'Empty database.';
  1241.          b := false
  1242.       end
  1243.    end
  1244.    else
  1245.    begin
  1246.       splerr.recstr := 'No active database';
  1247.       b := false
  1248.    end;
  1249.    if b then
  1250.    begin
  1251.       l := curpos + 1;
  1252.       if l > varbox^.count then
  1253.       begin
  1254.          if curtop < topbox^.count then
  1255.          begin
  1256.             curtop := curtop + 1;
  1257.             l := curtop;
  1258.             s := topbox^.index[l].data;
  1259.             ind := topbox^.index[l].ptr;
  1260.             if ind > 0 then
  1261.             begin
  1262.                if getsubindex(ind) then
  1263.                begin
  1264.                   s := varbox^.index[1].data;
  1265.                   currec := varbox^.index[1].ptr;
  1266.                   curind := s;
  1267.                   curpos := 1;
  1268.                   if not (pullrec) then
  1269.                   begin
  1270.                      b := false;
  1271.                      splerr.recnum := 39;
  1272.                      splerr.recstr := 'Error accesing fields';
  1273.                   end;
  1274.                end
  1275.                else
  1276.                begin
  1277.                   b := false;
  1278.                   splerr.recnum := 40;
  1279.                   splerr.recstr := 'Error loading subindex';
  1280.                end;
  1281.             end
  1282.          end
  1283.       end
  1284.       else
  1285.       begin
  1286.          s := varbox^.index[l].data;
  1287.          currec := varbox^.index[l].ptr;
  1288.          curind := s;
  1289.          curpos := l;
  1290.          if not (pullrec) then
  1291.          begin
  1292.             b := false;
  1293.             splerr.recnum := 41;
  1294.             splerr.recstr := 'Error loading record';
  1295.          end;
  1296.       end
  1297.    end
  1298.    else
  1299.       splerr.recnum := 45;
  1300.    nextrec := b
  1301. end;
  1302.  
  1303. function prevrec : boolean;
  1304. {This function locates and loads the previous record in DB}
  1305. var
  1306.    l, ind : longint;
  1307.    s : string;
  1308.    b : boolean;
  1309. begin
  1310.    b := true;
  1311.    if activedb then
  1312.    begin
  1313.       if not (dbempty) then
  1314.       begin
  1315.          if not (activerec) then
  1316.          begin
  1317.             splerr.recstr := 'No active record.';
  1318.             b := false
  1319.          end
  1320.       end
  1321.       else
  1322.       begin
  1323.          splerr.recstr := 'Empty database.';
  1324.          b := false
  1325.       end
  1326.    end
  1327.    else
  1328.    begin
  1329.       splerr.recstr := 'No active database';
  1330.       b := false
  1331.    end;
  1332.    if b then
  1333.    begin
  1334.       l := curpos - 1;
  1335.       if l = 0 then
  1336.       begin
  1337.          if curtop > 1 then
  1338.          begin
  1339.             curtop := curtop - 1;
  1340.             l := curtop;
  1341.             s := topbox^.index[l].data;
  1342.             ind := topbox^.index[l].ptr;
  1343.             if ind > 0 then
  1344.             begin
  1345.                if getsubindex(ind) then
  1346.                begin
  1347.                   s := varbox^.index[varbox^.count].data;
  1348.                   currec := varbox^.index[varbox^.count].ptr;
  1349.                   curind := s;
  1350.                   curpos := varbox^.count;
  1351.                   if not (pullrec) then
  1352.                   begin
  1353.                      b := false;
  1354.                      splerr.recnum := 42;
  1355.                      splerr.recstr := 'Error loading record';
  1356.                   end;
  1357.                end
  1358.                else
  1359.                begin
  1360.                   b := false;
  1361.                   splerr.recnum := 43;
  1362.                   splerr.recstr := 'Error loading subindex';
  1363.                end;
  1364.             end
  1365.          end
  1366.       end
  1367.       else
  1368.       begin
  1369.          s := varbox^.index[l].data;
  1370.          currec := varbox^.index[l].ptr;
  1371.          curind := s;
  1372.          curpos := l;
  1373.          if not (pullrec) then
  1374.          begin
  1375.             b := false;
  1376.             splerr.recnum := 41;
  1377.             splerr.recstr := 'Error loading record';
  1378.          end;
  1379.       end
  1380.    end
  1381.    else
  1382.       splerr.recnum := 44;
  1383.    prevrec := b
  1384. end;
  1385.  
  1386. (******* End of SplitBase Data Management Program *******)
  1387.  
  1388.  
  1389.