Есть ли инструмент, который может извлечь все строки команд SQL из файлов форм Delphi? - PullRequest
9 голосов
/ 25 марта 2010

Для документации и дальнейшей проверки я хотел бы запустить «извлечение строк» ​​во всех файлах DFM во многих проектах, чтобы найти все операторы SQL. Существуют ли инструменты командной строки, которые могут это сделать? Все файлы DFM представлены в текстовом формате.

Ответы [ 4 ]

3 голосов
/ 25 марта 2010

В зависимости от типа компонента запроса, который вы используете, я думаю, вы могли бы сделать это с помощью командной строки grep (или любого другого инструмента текстового поиска) в папках вашего проекта. В DFM для обычных компонентов, похожих на TQuery, вы будете иметь что-то вроде

   SQL.Strings=( 'select * from mytable' )

или, возможно, (у меня нет Delphi для проверки, радости быть дома!)

   SQL.Text=( 'select * from mytable' )

Учитывая, как эти строки могут распределяться по нескольким «строкам» внутри DFM, и учитывая, что может быть несколько вариантов, которые вам нужно проверить, лично я бы написал для этого небольшой кусочек Delphi.

Основная идея была бы; перебирайте все файлы / подпапки в данном каталоге, ищите все файлы DFM и для каждого читайте его в TStringList, проверяйте любые интересующие вас свойства SQL TQuery (и т. д.) и пишите Результаты (имя компонента, имя файла, фактическая строка SQL) в файл результатов. На самом деле работа не должна занимать больше часа или двух.

Если у вас есть хранимые процедуры, которые вы вызываете с использованием чего-то другого, чем компонент типа TQuery, вам сначала нужно будет заглянуть внутрь DFM и посмотреть, как выглядит SQL; это, вероятно, будет по линии

   CommandText=( 'exec mysproc :id, :value' )

и т.д.

редактировать: После обсуждения в комментариях, вот пример из одного из моих DFM;

    (other properties)
    SQL.Strings = (
      'SELECT D.*, '
      'C.DESCRIPTION AS CLASS_DESCRIPTION, '
      'C.CHQ_NUM_THRESHOLD AS CLASS_CHQ_NUM_THRESHOLD,'
      'C.CREDIT_LIMIT AS CLASS_CREDIT_LIMIT,'
      'A.REF AS ACCOUNT_REF,'
      'A.SORT_CODE AS ACCOUNT_SORT_CODE,'
      'A.ACCOUNT_NUMBER AS ACCOUNT_ACCOUNT_NUMBER,'
      'A.PREFERRED_ACCOUNT AS ACCOUNT_PREFERRED_ACCOUNT'
      'FROM '
      'DRAWER_ACCOUNTS A LEFT JOIN DRAWERS D '
      'ON D.REF=A.DRAWER_REF'
      'LEFT JOIN REF_DRAWER_CLASSES C'
      'ON D.DRAWER_CLASS = C.CLASS_ID'
      'WHERE A.SORT_CODE=:PSORT AND A.ACCOUNT_NUMBER=:PACC')
    (other properties)

Так что все, что мне действительно нужно сделать, это определить бит SQL.Strings = (, затем прочитать остаток строки и все последующие строки, удалив начальную и конечную ', пока я не доберусь до строки, которая заканчивается ')' - на этом я закончил. Какой бы интересный SQL (и комментарии) ни содержался в кавычках в каждой строке, на самом деле не имеет значения. Вы хотите прочитать каждую интересующую вас строку и вырезать текст между первой и последней цитатой в каждой строке. Это должно работать, потому что я не могу понять, как Delphi будет транслировать это любым другим способом, он не может «прочитать» содержимое строки - он просто работает на основе того, что список строк (возможно) разбит на строки и каждую строку ограничивается в DFM открытием и закрытием ', а все содержимое списка строк содержится в паре скобок.

Это имеет смысл, или я все еще что-то упускаю? : -)

1 голос
/ 26 марта 2010

Вот парсер DFM от Феликса Колибри

DFM Parser

Вот интересный инструмент для подобных вещей

YACC

0 голосов
/ 26 марта 2010

Большое спасибо за ответы! Другое решение, которое я попробую, - это инструмент извлечения строк, включенный в " GNU Gettext для Delphi и C ++ Builder ".

.po-файлы включают в себя не только весь текст компонента, но и все строки ресурсов (другое место, где хранятся команды SQL), вместе со ссылками на источник (файл pas или dfm, имя свойства компонента), и это очень простой список "имя = значение" уже.

С помощью файла .po будет легко отсортировать все SQL.Text из файлов .pas и всех строк ресурсов с именами, такими как «SQL _...» во всех файлах.

0 голосов
/ 25 марта 2010

Поскольку DFM в основном в формате name = value, вы можете просто загрузить его в tStringlist, а затем перебрать каждую строку в поисках конкретных имен свойств, которые вас интересуют:

var
  slDfm : tStringList;
  Item : String;
  ix : integer;
begin
  slDFM := tStringlist.create;
  try
    slDFM.LoadFromFile( filename );
    for ix := 0 to slDfm.Count-1 do
      begin
        slDfm.Strings[ix] := Trim(slDfm.Strings[ix]);
        if SameText(Trim(slDfm.Names[ix]),'CommandText') then
          memo1.Lines.Add('"'+Trim(slDfm.ValueFromIndex[ix])+'"');
      end;
  finally
    slDFM.free;
  end;
end;
...