Advertisement
Guest User

Untitled

a guest
Jan 7th, 2012
331
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 11.02 KB | None | 0 0
  1. const
  2.   CR  = #13;
  3.   LF  = #10;
  4.   TAB = #9;
  5.  
  6.   SPACES = [' ', CR, LF, TAB];
  7.   QUOTES = ['"', '''', '´', '`'];
  8.  
  9. function EOF: Boolean;
  10. begin
  11.   Result := P^ = #0;
  12. end;
  13.  
  14. function NEOF: Boolean;
  15. begin
  16.   Result := not EOF;
  17. end;
  18.  
  19. function Skip(const CS: TSysCharSet = SPACES): Boolean; overload;
  20. begin
  21.   while NEOF and CharInSet(P^, CS) do Inc(P);
  22.   Result := NEOF;
  23. end;
  24.  
  25. function Skip(const C: Char): Boolean; overload;
  26. begin
  27.   while NEOF and (P^ = C) do Inc(P);
  28.   Result := NEOF;
  29. end;
  30.  
  31. function SkipTo(const CS: TSysCharSet): Boolean; overload;
  32. begin
  33.   while NEOF and not CharInSet(P^, CS) do Inc(P);
  34.   Result := NEOF;
  35. end;
  36.  
  37. function SkipTo(const C: Char): Boolean; overload;
  38. begin
  39.   while NEOF and (P^ <> C) do Inc(P);
  40.   Result := NEOF;
  41. end;
  42.  
  43. procedure SkipQuotes;
  44. var
  45.   C: Char;
  46.   Q: PChar;
  47.   N: Integer;
  48. begin
  49.   C := P^;
  50.   Inc(P);
  51.   while NEOF do
  52.   begin
  53.     if P^ = C then
  54.     begin
  55.       Q := P - 1;
  56.       N := 0;
  57.       while Q^ = '\' do
  58.       begin
  59.         Inc(N);
  60.         Dec(Q);
  61.       end;
  62.       if not Odd(N) then Break;
  63.     end;
  64.     Inc(P);
  65.   end;
  66. end;
  67.  
  68. function Read(const CS: TSysCharSet): string; overload;
  69. var
  70.   Q: PChar;
  71. begin
  72.   Q := P;
  73.   while NEOF and CharInSet(P^, CS) do Inc(P);
  74.   SetString(Result, Q, P - Q);
  75. end;
  76.  
  77. function Read(const C: Char): string; overload;
  78. var
  79.   Q: PChar;
  80. begin
  81.   Q := P;
  82.   while NEOF and (P^ = C) do Inc(P);
  83.   SetString(Result, Q, P - Q);
  84. end;
  85.  
  86. function ReadTo(const CS: TSysCharSet = SPACES): string; overload;
  87. var
  88.   Q: PChar;
  89. begin
  90.   Q := P;
  91.   while NEOF and not CharInSet(P^, CS) do Inc(P);
  92.   SetString(Result, Q, P - Q);
  93. end;
  94.  
  95. function ReadTo(const C: Char): string; overload;
  96. var
  97.   Q: PChar;
  98. begin
  99.   Q := P;
  100.   while NEOF and (P^ <> C) do Inc(P);
  101.   SetString(Result, Q, P - Q);
  102. end;
  103.  
  104. function ReadToQ: string; overload;
  105. var
  106.   Q: PChar;
  107. begin
  108.   Q := P;
  109.   SkipQuotes;
  110.   SetString(Result, Q + 1, P - Q - 1);
  111.   if NEOF then Inc(P);
  112. end;
  113.  
  114. function ReadN(N: Integer): string;
  115. var
  116.   Q: PChar;
  117. begin
  118.   Q := P;
  119.   while NEOF and (N > 0) do
  120.   begin
  121.     Inc(P);
  122.     Dec(N);
  123.   end;
  124.   SetString(Result, Q, P - Q);
  125. end;
  126.  
  127. function ReadQuoted(var S: string; const CS: TSysCharSet = SPACES;
  128.   ASkipQuotes: Boolean = False): Boolean;
  129. var
  130.   C: Char;
  131. begin
  132.   C := P^;
  133.   if CharInSet(C, QUOTES) then
  134.   begin
  135.     if ASkipQuotes then
  136.       S := ReadToQ
  137.     else
  138.     begin
  139.       Inc(P);
  140.       if NEOF then
  141.       begin
  142.         S := ReadTo(C);
  143.         if NEOF then Inc(P);
  144.       end;
  145.     end;
  146.   end
  147.   else
  148.     S := ReadTo(CS);
  149.   Result := NEOF;
  150. end;
  151.  
  152. function IsNext(const S: string): Boolean;
  153. var
  154.   Q: PChar;
  155. begin
  156.   Q := P;
  157.   Result := SameText(S, ReadN(Length(S))){ and NEOF};
  158.   if not Result and (Q <> P) then P := Q;
  159. end;
  160.  
  161. function SkipA(const A: Array of string): Boolean;
  162. var
  163.   Q: PChar;
  164.   B: Boolean;
  165.   I: Integer;
  166. begin
  167.   Q := P;
  168.   B := True;
  169.   for I := Low(A) to High(A) do
  170.   begin
  171.     if not B then Break;
  172.     B := IsNext(A[I]);
  173.     if B then
  174.     begin
  175.       B := NEOF;
  176.       if B then Skip;
  177.     end
  178.   end;
  179.   if not B and (Q <> P) then P := Q;
  180.   Result := NEOF;
  181. end;
  182.  
  183. procedure SkipComments;
  184. begin
  185.   case P^ of
  186.     '/':
  187.     begin
  188.       if ((P + 1)^ <> #0) and ((P + 1)^ = '*') then
  189.       begin
  190.         Inc(P, 2);
  191.         while NEOF do
  192.         begin
  193.           if ((P + 1)^ <> #0) and (P^ = '*') and ((P + 1)^ = '/') then
  194.           begin
  195.             Inc(P);
  196.             Break;
  197.           end;
  198.           Inc(P);
  199.         end;
  200.       end;
  201.     end;
  202.  
  203.     '-':
  204.     begin
  205.       if ((P + 1)^ <> #0) and ((P + 1)^ = '-') then
  206.       begin
  207.         Inc(P, 2);
  208.         while NEOF do
  209.         begin
  210.           if ((P + 1)^ <> #0) and (P^ = CR) and ((P + 1)^ = LF) then
  211.           begin
  212.             Inc(P);
  213.             Break;
  214.           end
  215.           else if (P^ = LF) or (P^ = CR) then
  216.             Break;
  217.           Inc(P);
  218.         end;
  219.       end;
  220.     end;
  221.  
  222.     '#':
  223.     begin
  224.       Inc(P);
  225.       while NEOF do
  226.       begin
  227.         if ((P + 1)^ <> #0) and (P^ = CR) and ((P + 1)^ = LF) then
  228.         begin
  229.           Inc(P);
  230.           Break;
  231.         end
  232.         else if (P^ = LF) or (P^ = CR) then
  233.           Break;
  234.         Inc(P);
  235.       end;
  236.     end;
  237.   end;
  238. end;
  239.  
  240. procedure RipTableColumnNames(const S: string);
  241. var
  242.   T  : string;
  243.   TCN: TTableColumnNames;
  244. begin
  245.   P := Pointer(S);
  246.   if P <> nil then
  247.     while NEOF do
  248.     begin
  249.       case P^ of
  250.         '"', '''', '´', '`': SkipQuotes;
  251.         '/', '-', '#'      : SkipComments;
  252.         'c', 'C':
  253.         begin
  254.           if IsNext('CREATE') and
  255.              Skip and
  256.              SkipA(['OR', 'REPLACE']) and
  257.              IsNext('TABLE') and
  258.              Skip and
  259.              SkipA(['IF', 'NOT', 'EXISTS']) and
  260.              ReadQuoted(T, SPACES + ['(']) and
  261.              Skip and
  262.              (P^ = '(') then
  263.           begin
  264.             TCN.TableName := T;
  265.             TCN.ColumnNames := TStringList.Create;
  266.  
  267.             Inc(P);
  268.             while Skip and (P^ <> ';') do
  269.             begin
  270.               if P^ = ')' then Break;
  271.  
  272.               if ReadQuoted(T, SPACES + [')']) then
  273.               begin
  274.                 if IsGoodColumnName(T) then TCN.ColumnNames.Add(T);
  275.  
  276.                 if Skip then
  277.                 begin
  278.                   while NEOF and not CharInSet(P^, [',', ';']) do
  279.                   begin
  280.                     case P^ of
  281.                       '"', '''', '´', '`': SkipQuotes;
  282.                       '(':
  283.                       begin
  284.                         Inc(P);
  285.                         if not SkipTo(')') then Break;
  286.                       end;
  287.                     end;
  288.                     Inc(P);
  289.                   end;
  290.  
  291.                   if NEOF and (P^ = ',') then Inc(P);
  292.                 end;
  293.               end;
  294.             end;
  295.  
  296.             TableColumnNames.Add(TCN);
  297.           end;
  298.         end;
  299.       end;
  300.       if NEOF then Inc(P);
  301.     end;
  302. end;
  303.  
  304. procedure RipTableRows(const S: string; const ATableName: string;
  305.   ARipToFile: Boolean = False; AFileStream: TFileStream = nil;
  306.     const ARowDelimiter: string = '');
  307. var
  308.   IL  : TList<Integer>;
  309.   SL  : TStringList;
  310.  
  311.   function GetColumnNameIndex(const AColumnName: string): Integer;
  312.   var
  313.     I: Integer;
  314.   begin
  315.     Result := -1;
  316.     for I := 0 to Pred(SL.Count) do
  317.       if SameText(SL[I], AColumnName) then
  318.       begin
  319.         Result := I;
  320.         Break;
  321.       end;
  322.   end;
  323.  
  324.   function IsIndexAvailable: Boolean;
  325.   var
  326.     I: Integer;
  327.   begin
  328.     Result := False;
  329.     for I := 0 to Pred(IL.Count) do
  330.       if IL[I] > -1 then
  331.       begin
  332.         Result := True;
  333.         Break;
  334.       end;
  335.   end;
  336.  
  337. var
  338.   T   : string;
  339.   I, N: Integer;
  340. begin
  341.   IL := TList<Integer>.Create;
  342.   SL := TStringList.Create;
  343.  
  344.   P := Pointer(S);
  345.   if P <> nil then
  346.     while NEOF do
  347.     begin
  348.       case P^ of
  349.         '"', '''', '´', '`': SkipQuotes;
  350.         '/', '-', '#'      : SkipComments;
  351.         'i', 'I':
  352.         begin
  353.           if IsNext('INSERT') and
  354.              Skip and
  355.              SkipA(['IGNORE']) and
  356.              SkipA(['OR', 'IGNORE']) and
  357.              IsNext('INTO') and
  358.              Skip and
  359.              ReadQuoted(T, SPACES + ['(']) and
  360.              Skip and
  361.              SameText(T, ATableName) then
  362.           begin
  363.             IL.Clear;
  364.  
  365.             if P^ = '(' then
  366.             begin
  367.               SL.Clear;
  368.  
  369.               Inc(P);
  370.               while Skip and
  371.                     (P^ <> ')') and
  372.                     (ReadQuoted(T, SPACES + [',', ')'])) and
  373.                     Skip do
  374.               begin
  375.                 SL.Add(T);
  376.                 if Skip and (P^ = ',') then Inc(P);
  377.               end;
  378.  
  379.               if Skip and (P^ = ')') then Inc(P);
  380.  
  381.               for I := 0 to Pred(ColumnNamesIndexes.Count) do
  382.                 IL.Add(GetColumnNameIndex(ColumnNamesIndexes[I].ColumnName));
  383.             end;
  384.  
  385.             if Skip and IsNext('VALUES') then
  386.             begin
  387.               while Skip and (P^ <> ';') do
  388.               begin
  389.                 if P^ = '(' then
  390.                 begin
  391.                   SL.Clear;
  392.                   Inc(P);
  393.                   while Skip and
  394.                         (P^ <> ')') and
  395.                         ReadQuoted(T, SPACES + [',', ')'], True) and
  396.                         Skip do
  397.                   begin
  398.                     SL.Add(T);
  399.                     if Skip and (P^ = ',') then Inc(P);
  400.                   end;
  401.  
  402.                   if Skip and (P^ = ')') then Inc(P);
  403.                   if Skip and (P^ = ',') then Inc(P);
  404.  
  405.                   N := SL.Count;
  406.                  
  407.                   if IL.Count > 0 then
  408.                   begin
  409.                     if IsIndexAvailable then
  410.                     begin
  411.                       if ARipToFile then
  412.                       begin
  413.                         T := '';
  414.                         for I := 0 to Pred(IL.Count) do
  415.                           if IL[I] = -1 then
  416.                             T := T + ARowDelimiter
  417.                           else if IL[I] < N then
  418.                             T := T + SL[IL[I]] + ARowDelimiter;
  419.                         T := T + sLineBreak;
  420.                         AFileStream.WriteBuffer(Pointer(AnsiString(T))^,
  421.                           Length(T));
  422.                       end
  423.                       else
  424.                       begin
  425.                         TableRows.Add(TStringList.Create);
  426.  
  427.                         for I := 0 to Pred(IL.Count) do
  428.                           if IL[I] = -1 then
  429.                             TableRows[iTableRowCounter].Add('')
  430.                           else if IL[I] < N then
  431.                             TableRows[iTableRowCounter].Add(SL[IL[I]]);
  432.  
  433.                         Inc(iTableRowCounter);
  434.                       end;
  435.                     end;
  436.                   end
  437.                   else
  438.                   begin
  439.                     if ARipToFile then
  440.                     begin
  441.                       T := '';
  442.                       for I := 0 to Pred(ColumnNamesIndexes.Count) do
  443.                         if ColumnNamesIndexes[I].ColumnIndex < N then
  444.                           T := T + SL[ColumnNamesIndexes[I].ColumnIndex] +
  445.                             ARowDelimiter;
  446.                       T := T + sLineBreak;
  447.                       AFileStream.WriteBuffer(Pointer(AnsiString(T))^,
  448.                         Length(T));
  449.                     end
  450.                     else
  451.                     begin
  452.                       TableRows.Add(TStringList.Create);
  453.  
  454.                       for I := 0 to Pred(ColumnNamesIndexes.Count) do
  455.                         if ColumnNamesIndexes[I].ColumnIndex < N then
  456.                           TableRows[iTableRowCounter].Add(
  457.                             SL[ColumnNamesIndexes[I].ColumnIndex]);
  458.  
  459.                       Inc(iTableRowCounter);
  460.                     end;
  461.                   end;
  462.                 end
  463.                 else
  464.                   Break;
  465.               end;
  466.             end;
  467.           end;
  468.         end;
  469.       end;
  470.       if NEOF then Inc(P);
  471.     end;
  472.  
  473.   IL.Free;
  474.   SL.Free;
  475. end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement