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