2010-03-25 15 views
9

對於文檔和進一步檢查,我想在許多項目的所有DFM文件上運行「提取字符串」以查找所有SQL語句。有沒有可以做到這一點的命令行工具? DFM文件全部採用文本格式。有沒有可以從Delphi窗體文件中提取所有SQL命令字符串的工具?

+1

我是正確的假設,一個「DFM」文件是德爾福版本的資源文件? – lexu 2010-03-25 06:31:13

+0

@lexu是它們包含'窗體','框架'和'數據模塊'的佈局和綁定信息。 – mjn 2010-03-25 06:39:54

+0

@lexe但我不知道它們是否會在技術上最終作爲正常的應用程序資源在二進制文件中 – mjn 2010-03-25 06:50:49

回答

1

這裏從菲利克斯科利柏

DFM Parser

這裏,DFM解析器是做這樣的東西

一個有趣的工具

+2

這是一個有趣的鏈接,謝謝! – robsoft 2010-03-26 09:52:51

3

根據您使用的查詢組件的類型,我想可以使用命令行grep(或任何其他文本搜索工具)在您的項目文件夾中執行此操作。在DFM,對於正常的TQuery酷似組件,你將不得不沿着

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

或可能線的東西(我不德爾福用手去檢查,賓至如歸的樂趣!)

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

鑑於這些字符串是如何遍佈DFM內幾個「線」,並給出瞭如何有可能是你需要檢查的幾個變化,我個人會寫一小塊德爾福做這個。

基本的想法是;遍歷給定目錄中的所有文件/子文件夾,查找所有DFM文件,併爲每個文件讀取TStringList,檢查您感興趣的任何TQuery(等)SQL屬性,然後編寫結果(組件名稱,文件名,實際的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中以'開頭和結尾分隔,並且整個字符串列表內容本身都包含在一對括號內。

這是否有道理,還是我仍然失去了一些東西?:-)

+0

SQL命令可以包括(和)(和註釋(包括(和)))所以解析會有點困難,因爲)也會終止SQL Str ing ...以及如果SQL文本在註釋或字段值中包含特殊字符,那麼Unicode如何呢?但我想這將是一個有趣而又簡單的部分:P – mjn 2010-03-25 14:05:18

+0

非常真實......但如果你首先開始解析,並且隨時隨地記錄你的「多少級別」,那麼你應該沒問題。在這一天結束時,Delphi DFM解析器必須能夠理解字符串,以便以引用開始和結束。除非DFM文件本身是unicode,否則SQL文本不能包含unicode(除非我錯過了DFM中的字符串!),所以你可以先測試一個unicode文件 - 我在這裏有一些代碼來檢查一個文件看看它是否是unicode。就像你說的,這是樂趣的一部分! :-) – robsoft 2010-03-25 15:07:18

+0

除非你使用RegExp庫,否則Delphi對此並不理想。我會建議編寫一個PERL腳本來解析DFM並提取SQL。我做了類似的操作,將TTable/TQuery組件轉換爲DOA「等價物」,並且包括在修改文件時保持pas&dfm同步。 爲作業使用正確的工具。在這種情況下,一種腳本語言可以很好地實現正則表達式。 PERL可能不是你的一杯茶,但你應該能夠找到你喜歡Python,Ruby的東西? – mcottle 2010-03-26 07:13:41

0

由於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; 
0

非常感謝您的答覆!我將嘗試的另一個解決方案是「GNU Gettext for Delphi and C++ Builder」中包含的「提取字符串」工具。

.po文件不僅包含所有組件文本,還包括所有的資源行(存儲SQL命令的另一個位置),並且引用了原點(哪個pas或dfm文件,哪個組件屬性名稱),並且它是已經有一個非常簡單的「name = value」列表。

隨着.po文件將很容易理清從.PAS文件的所有SQL.Text,並像所有文件「SQL _...」的名字都resourcestrings。

相關問題