home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip_2001-12_cd1.bin / zkuste / delphi / kompon / d123456 / ANRMLB.ZIP / objects / mlb2sql.pas < prev    next >
Pascal/Delphi Source File  |  2001-09-04  |  14KB  |  415 lines

  1. (*******************************************************************
  2. MY LITTLE BASE 2.0.0 Experimantal mono-table little sql delphi source code
  3. CopyRights owned by S.A.R.L ANIROM Multimedia Marseille FRANCE
  4. http://www.anirom.com
  5. MLB official website is http://www.mylittlebase.org
  6.  
  7. This source code is Freeware
  8. You can copy it and use it freely for any purpose (even commercial)
  9. but you must add in the about box of your program that it uses
  10. MyLittleBase source code (http://www.mylittlebase.org)
  11. You can freely distribute this unmodified source code containing
  12. this copyright notice
  13. You can modify it for your own purposes, but you cannot distribute
  14. the modified code as mylittlebase without the written consent from ANIROM
  15. You can write external modules using this unmodified source code
  16. and distribute them
  17.  
  18. ANIROM Multimedia assumes no liability of any kind
  19. use this code at your own risks or do not use it
  20. *******************************************************************)
  21. unit mlb2sql;
  22.  
  23. interface
  24.  
  25. uses mlb2;
  26.  
  27. type
  28.   TMlb2Sql = class(TObject)
  29.   private
  30.          base: TMlb2;
  31.          dynaset: TMlb2;
  32.          complement: TMlb2;
  33.          sql_string: string;
  34.          sql_index: integer;
  35.          concorde: TConcordances;
  36.          
  37.          function ReadToken: string;
  38.          function ReadOperator: string;
  39.          function IsOperator(c: char): boolean;
  40.          function IsSeparator(c: char): boolean;
  41.          procedure Recalage;
  42.          function CharAt(k: integer): char;
  43.          function ReachedEnd: boolean;
  44.      function IsString(v1: String): boolean;
  45.      function sansel(s1: String): string;
  46.          function FloatValue(v1: String): Extended;
  47.          function expression: boolean;
  48.          function terme: boolean;
  49.          function facteur: boolean;
  50.   public
  51.         constructor Create(m: TMlb2);
  52.         destructor Destroy; override;
  53.         function MySubString(source1: string; bindex, eindex: integer): string;
  54.         function Execute(sql1: String): boolean;
  55.         function GetDynaset: TMlb2;
  56.         function GetComplement: TMlb2;
  57.   end;
  58.  
  59. implementation
  60.  
  61. function TMlb2Sql.GetDynaset: TMlb2;
  62. begin
  63.      Result := Dynaset;
  64. end;
  65.  
  66. function TMlb2Sql.GetComplement: TMlb2;
  67. begin
  68.      Result := Complement;
  69. end;
  70.  
  71. function TMlb2Sql.expression: boolean;
  72. var b1, b2: boolean;
  73.     op: String;
  74. begin
  75.     b1 := false;
  76.     b2 := false;
  77.     if (ReachedEnd) then begin
  78.     end else begin
  79.             b1 := terme;
  80.             Recalage;
  81.             op := ReadToken;
  82.             if (op= 'OR') then begin
  83.                     b2 := expression;
  84.             end else if (op=')') then begin
  85.                     b2 := false;
  86.             end else begin
  87.                     b2 := false;
  88.             end;
  89.     end;
  90.     Result := b1 or b2;
  91. end;
  92.  
  93. function TMlb2Sql.terme: boolean;
  94. var k: integer;
  95.     b1, b2: boolean;
  96.     op: String;
  97. begin
  98.     b1 := false;
  99.     b2 := false;
  100.     if (ReachedEnd) then begin
  101.        Result := True;
  102.        Exit;
  103.     end else begin
  104.             b1 := facteur;
  105.             Recalage;
  106.             k := sql_index;
  107.             op := ReadToken;
  108.             if (op = 'AND') then begin
  109.                 b2 := terme;
  110.             end else begin
  111.                 sql_index := k;
  112.                 b2 := true;
  113.             end;
  114.     end;
  115.     Result := (b1 and b2);
  116. end;
  117.  
  118. function TMlb2Sql.facteur: boolean;
  119. var SAtom, VAtom, myatom, myvalue, myop: String;
  120.     myfatom, myfvalue: Extended;
  121.     b: boolean;
  122. begin
  123.     b := false;
  124.     myatom := ReadToken;
  125.     Recalage;
  126.     if (myatom='(') then begin
  127.             b := expression;
  128.     end else begin
  129.             myop := ReadOperator;
  130.             Recalage;
  131.             myvalue := ReadToken;
  132.             Recalage;
  133.             if (IsString(myvalue)) then begin
  134.                     SAtom := base.GetData(myatom);
  135.                     VAtom := sansel(myvalue);
  136.                     if (myop='=') then begin
  137.                             b := SAtom = VAtom;
  138.                     end else if (myop ='<=') then begin
  139.                             b := SAtom <= VAtom;
  140.                     end else if (myop ='>=') then begin
  141.                             b := SAtom >= VAtom;
  142.                     end else if (myop ='<') then begin
  143.                             b := SAtom < VAtom;
  144.                     end else if (myop ='>') then begin
  145.                             b := SAtom > VAtom;
  146.                     end else if (myop ='<>') then begin
  147.                             b := SAtom <> VAtom;
  148.                     end else if (myop ='~=') then begin
  149.                             concorde.case_matching := False;
  150.                             concorde.space_matching := False;
  151.                             concorde.like_matching := True;
  152.                             b := concorde.SI_VERIFICATION(VAtom, SAtom);
  153.                     end else begin
  154.                     end;
  155.             end else begin
  156.                     myfvalue := FloatValue(myvalue);
  157.                     myfatom := FloatValue(base.GetData(myatom));
  158.                     if (myop='=') then begin
  159.                             b := (myfatom = myfvalue);
  160.                     end else if (myop ='<=') then begin
  161.                             b := (myfatom <= myfvalue);
  162.                     end else if (myop ='>=') then begin
  163.                             b := (myfatom >= myfvalue);
  164.                     end else if (myop ='<') then begin
  165.                             b := (myfatom < myfvalue);
  166.                     end else if (myop ='>') then begin
  167.                             b := (myfatom > myfvalue);
  168.                     end else if (myop ='<>') then begin
  169.                             b := (myfatom <> myfvalue);
  170.                     end else if (myop ='~=') then begin
  171.                     end else begin
  172.                     end;
  173.             end;
  174.     end;
  175.     Result := b;
  176. end;
  177.  
  178. function TMlb2Sql.Execute(sql1: String): boolean;
  179. var i: integer;
  180.     fois: integer;
  181.     tfois: integer;
  182.     Sselect: String;
  183.     Sdistinct: String;
  184.     Sfields: String;
  185.     Swhere: String;
  186.     b: boolean;
  187. begin
  188.     fois := 0;
  189.     tfois := 0;
  190.     b := false;
  191.     sql_string := sql1;
  192.     sql_index := 0;
  193.     Sselect := ReadToken;
  194.     if (Sselect = 'SELECT') then begin
  195.             Recalage;
  196.             Dynaset.Init;
  197.             Complement.Init;
  198.             Sdistinct := ReadToken;
  199.             Recalage;
  200.             if (Sdistinct = 'DISTINCT') then begin
  201.                     Dynaset.Distinct := true;
  202.                     Complement.Distinct := true;
  203.                     Sfields := ReadToken;
  204.                     Recalage;
  205.             end else begin
  206.                     base.Distinct := false;
  207.                     Sfields := Sdistinct;
  208.             end;
  209.             if (Sfields = '*') then begin
  210.                     for i:=1 to base.FieldCount do begin
  211.                             Dynaset.AddField(base.FieldName[i]);
  212.                             Complement.AddField(base.FieldName[i]);
  213.                     end;
  214.                     Swhere := ReadToken;
  215.                     Recalage;
  216.             end else begin
  217.                     while (not ReachedEnd) and (Sfields <> 'WHERE') do begin
  218.                             Dynaset.AddField(Sfields);
  219.                             Complement.AddField(Sfields);
  220.                             Sfields := ReadToken;
  221.                             Recalage;
  222.                     end;
  223.                     Swhere := Sfields;
  224.             end;
  225.             if (Swhere = 'WHERE') then begin
  226.                     b := true;
  227.                     sql_string := MySubString(sql1, sql_index, length(sql1));
  228.                     sql_index := 0;
  229.                     Recalage;
  230.                     if (base.GoFirst) then begin
  231.                             repeat
  232.                                     Inc(tfois, 1);
  233.                                     sql_index := 0;
  234.                                     if (expression) then begin
  235.                                             Inc(fois, 1);
  236.                                             Dynaset.AddRow;
  237.                                             for i:=1 to Dynaset.FieldCount do begin
  238.                                                     Dynaset.SetDataByIndex(i, base.GetData(Dynaset.FieldName[i]));
  239.                                             end;
  240.                                     end else begin
  241.                                             Complement.AddRow;
  242.                                             for i:=1 to Complement.FieldCount do begin
  243.                                                     Complement.SetDataByIndex(i, base.GetData(Complement.FieldName[i]));
  244.                                             end;
  245.                                     end;
  246.                             until not base.GoNext;
  247.                             if (Dynaset.Distinct) then begin
  248.                                     Dynaset.MakeDistinct;
  249.                             end;
  250.                             if (Complement.Distinct) then begin
  251.                                     Complement.MakeDistinct;
  252.                             end;
  253.                     end else begin
  254.                     end;
  255.             end else begin
  256.             end;
  257.     end else begin
  258.     end;
  259.     Result := b and (tfois >= 0) and (fois >= 0);
  260. end;
  261.  
  262. constructor TMlb2Sql.Create(m: TMlb2);
  263. begin
  264.      inherited Create;
  265.      base := m;
  266.      dynaset := TMlb2.Create;
  267.      complement := TMlb2.Create;
  268.      concorde := TConcordances.Create;
  269. end;
  270.  
  271. destructor TMlb2Sql.Destroy;
  272. begin
  273.      concorde.Free;
  274.      complement.Free;
  275.      dynaset.Free;
  276.      inherited Destroy;
  277. end;
  278.  
  279. function TMlb2Sql.FloatValue(v1: String): Extended;
  280. begin
  281.      Result := base.RobustStrToFloat(v1);
  282. end;
  283.  
  284. function TMlb2Sql.IsString(v1: String): boolean;
  285. begin
  286.       Result := v1[1] = '''';
  287. end;
  288.  
  289. function TMlb2Sql.sansel(s1: String): String;
  290. var   i: integer;
  291.       sr: String;
  292.       source: String;
  293. begin
  294.       sr := '';
  295.       source := MySubString(s1, 1, length(s1)-1);
  296.       i := 0;
  297.       while (i<length(source)) do begin
  298.               if (source[i+1] = '''') then begin
  299.                       if (i<length(source)) then begin
  300.                               if (source[i+1+1] = '''') then begin
  301.                                       Inc(i, 1);
  302.                                       sr := sr + '''';
  303.                               end else begin
  304.                               end;
  305.                       end;
  306.               end else begin
  307.                       sr := sr + source[i+1];
  308.               end;
  309.               Inc(i, 1);
  310.       end;
  311.       Result := sr;
  312. end;
  313.  
  314. function TMlb2Sql.MySubString(source1: string; bindex, eindex: integer): string;
  315. begin
  316.     if (bindex<0) then bindex := 0;
  317.     if (bindex>=length(source1)) then bindex := length(source1);
  318.     if (eindex>=length(source1)) then eindex := length(source1);
  319.     try
  320.             Result := Copy(source1, bindex+1, eindex-bindex);
  321.     except
  322.             Result := source1;
  323.     end;
  324. end;
  325.  
  326. function TMlb2Sql.IsOperator(c: char): boolean;
  327. begin
  328.      Result := (c in ['=', '<', '>', '~']);
  329. end;
  330.  
  331. function TMlb2Sql.IsSeparator(c: char): boolean;
  332. begin
  333.      Result := (c in [' ', ',']);
  334. end;
  335.  
  336. function TMlb2Sql.CharAt(k: integer): char;
  337. begin
  338.      Result := sql_string[k+1];
  339. end;
  340.  
  341. procedure TMlb2Sql.Recalage;
  342. begin
  343.     while (sql_index<length(sql_string)) and IsSeparator(CharAt(sql_index)) do begin
  344.           Inc(sql_index, 1);
  345.     end;
  346. end;
  347.  
  348. function TMlb2Sql.ReadToken: string;
  349. var tbegin: integer;
  350.     fin: boolean;
  351. begin
  352.     fin := false;
  353.     Recalage;
  354.     tbegin := sql_index;
  355.     if (MySubString(sql_string, tbegin, tbegin+1) = '''')  then begin
  356.        Inc(sql_index, 1);
  357.        while (sql_index<length(sql_string)) and  not fin do begin
  358.              fin := charAt(sql_index)='''';
  359.              if (sql_index<(length(sql_string)-1)) then begin
  360.                 if fin and (charAt(sql_index+1)='''') then begin
  361.                    fin := false;
  362.                    Inc(sql_index, 1);
  363.                 end else begin
  364.                 end;
  365.              end;
  366.              Inc(sql_index, 1);
  367.        end;
  368.        Result := MySubString(sql_string, tbegin, sql_index);
  369.        Exit;
  370.     end else if (MySubString(sql_string, tbegin, tbegin+1) = '(') then begin
  371.         Inc(sql_index, 1);
  372.         Result := '(';
  373.         Exit;
  374.     end else if (MySubString(sql_string, tbegin, tbegin+1) = ')') then begin
  375.         Inc(sql_index, 1);
  376.         Result := ')';
  377.         Exit;
  378.     end else begin
  379.         while (sql_index<length(sql_string)) do begin
  380.               if IsOperator(charAt(sql_index)) then begin
  381.                   Result := MySubString(sql_string, tbegin, sql_index);
  382.                   Exit;
  383.               end else if IsSeparator(charAt(sql_index)) then begin
  384.                   Result := MySubString(sql_string, tbegin, sql_index);
  385.                   Exit;
  386.               end else if (charAt(sql_index) = ')') or (charAt(sql_index) = '(') then begin
  387.                   Result := MySubString(sql_string, tbegin, sql_index);
  388.                   Exit;
  389.               end else begin
  390.               end;
  391.               Inc(sql_index, 1);
  392.         end;
  393.     end;
  394.     Result := MySubString(sql_string, tbegin, sql_index);
  395.     Exit;
  396. end;
  397.  
  398. function TMlb2Sql.ReadOperator: string;
  399. var tbegin: integer;
  400. begin
  401.     Recalage;
  402.     tbegin := sql_index;
  403.     while (sql_index<length(sql_string)) and IsOperator(charAt(sql_index)) do begin
  404.             Inc(sql_index, 1);
  405.     end;
  406.     Result := MySubString(sql_string, tbegin, sql_index);
  407. end;
  408.  
  409. function TMlb2Sql.ReachedEnd: boolean;
  410. begin
  411.      Result := sql_index>=length(sql_string);
  412. end;
  413.  
  414. end.
  415.