【问题标题】:Is there a tool which can extract all SQL command strings from Delphi form files?是否有可以从 Delphi 表单文件中提取所有 SQL 命令字符串的工具?
【发布时间】:2010-03-25 06:26:24
【问题描述】:

对于文档和进一步检查,我想对许多项目中的所有 DFM 文件运行“提取字符串”以查找所有 SQL 语句。有没有可以做到这一点的命令行工具? DFM 文件均为文本格式。

【问题讨论】:

  • 我认为“DFM”文件是 Delphi 版本的资源文件是否正确?
  • @lexu 是的,它们包含“表单”、“框架”和“数据模块”的布局和绑定信息。
  • @lexe 但我不知道它们是否会在技术上最终成为二进制文件中的普通应用程序资源
  • 是的,他们有,但作为资源类型 RC_DATA,IIRC。 Delphi 在内部与实际形式等相互转换。

标签: sql delphi extract dfm


【解决方案1】:

根据您使用的查询组件类型,我想您可以在项目文件夹中使用命令行 grep(或任何其他文本搜索工具)来执行此操作。在 DFM 中,对于普通的类似 TQuery 的组件,您将拥有类似于

的内容 SQL.Strings=('select * from mytable')

或者可能(我没有 Delphi 可以检查,在家的乐趣!)

SQL.Text=('从我的表中选择 *')

考虑到这些字符串如何分布在 DFM 内的多个“行”上,并且考虑到您可能需要检查多个变化,我个人会编写一小段 Delphi 来执行此操作。

基本的想法是;遍历给定目录中的所有文件/子文件夹,查找所有 DFM 文件,并将每个文件读入 TStringList,检查您感兴趣的任何 TQuery (etc) SQL 属性,然后编写结果(组件名称、文件名、实际 SQL 字符串)输出到结果文件。真的不应该超过一两个小时的工作。

如果您已经存储了过程,您使用非 TQuery 类型的组件调用,您必须先查看 DFM 内部并查看 SQL 是如何显示的;大概是这样的

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

等等

编辑: 在 cmets 中的讨论之后,这是我的一个 DFM 的示例;

(其他属性) SQL.Strings = ( '选择 D.*,' 'C.DESCRIPTION 作为 CLASS_DESCRIPTION, ' 'C.CHQ_NUM_THRESHOLD 作为 CLASS_CHQ_NUM_THRESHOLD,' 'C.CREDIT_LIMIT 作为 CLASS_CREDIT_LIMIT,' 'A.REF 作为 ACCOUNT_REF,' 'A.SORT_CODE 作为 ACCOUNT_SORT_CODE,' 'A.ACCOUNT_NUMBER 作为 ACCOUNT_ACCOUNT_NUMBER,' 'A.PREFERRED_ACCOUNT AS ACCOUNT_PREFERRED_ACCOUNT' '从 ' 'DRAWER_ACCOUNTS A LEFT JOIN DRAWERS D' 'ON D.REF=A.DRAWER_REF' 'LEFT JOIN REF_DRAWER_CLASSES C' '在 D.DRAWER_CLASS = C.CLASS_ID' 'WHERE A.SORT_CODE=:PSORT AND A.ACCOUNT_NUMBER=:PACC') (其他属性)

所以我真正需要做的就是找出SQL.Strings = ( 位,然后读取该行的其余部分和所有后续行,删除前导和尾随',直到我到达以@ 结尾的行987654323@ - 至此我完成了。每行的引号中可能包含的任何有趣的 SQL(和 cmets)实际上都无关紧要。您想阅读您感兴趣的每一行,并在每行的第一个和最后一个引号之间剪掉文本。这必须有效,因为我看不到 Delphi 将如何以任何其他方式传输它,它不可能“读取”字符串内容 - 它只是在 stringlist (可能)分成几行和每一行的基础上工作在 DFM 中以 ' 开头和结尾分隔,整个字符串列表内容本身包含在一对括号内。

这有意义吗,还是我仍然错过了什么? :-)

【讨论】:

  • SQL 命令可以包含 (and ) (和 cmets (包括 (and ))),所以解析会有点困难,因为 ) 也会终止 SQL 字符串...那么 Unicode 怎么样,如果SQL 文本在 cmets 或字段值中包含特殊字符。但我想这将是有趣和简单的部分:P
  • 非常正确...但是如果您从第一个 ' 开始解析,并随时计算您“进入”的引用级别,那么您应该没问题。归根结底,Delphi DFM 解析器必须能够理解字符串,以便它确实以引号开头和结尾。除非 DFM 文件本身是 unicode,否则 SQL 文本不能包含 unicode(除非我遗漏了有关 DFM 中的字符串的某些内容!)因此您可以先测试 unicode 文件 - 我在某处有一些代码可以检查文件看看它是否是unicode。就像你说的,这都是乐趣的一部分! :-)
  • 除非你使用 RegExp 库,否则 Delphi 不适合这个。我建议编写一个 PERL 脚本来解析 DFM 并提取 SQL。我做了类似的事情来将 TTable/TQuery 组件转换为 DOA“等效项”,并且在修改文件时保持 pas 和 dfm 同步。为工作使用正确的工具。在这种情况下,脚本语言具有良好的正则表达式实现。 PERL 可能不是你的最爱,但你应该能够找到你喜欢的 Python、Ruby?
  • @robsoft:一个简单的/* :-) */ 会打破计数,cmets 也需要正确处理。而且 SQL 注释语法不规范。也许复制Delphi的流代码来读取DFM更容易?
  • @mjustin - 好点,我昨晚正在考虑这个问题。但我认为每一行总是以'开头和结尾,所以不是解析SQL,你实际上只是从SQL.Text =('开始的点获取文本,并从其中删除前导和尾随'所有后续字符串,直到你得到一个不以'开头的字符串 - 这将是下一个属性或组件的开始。然后你必须记住也删除最终字符串上的右括号。我想的越多现在关于这个,我越想如果你开始解析你迷路的 SQL!:-)
【解决方案2】:

这是来自 Felix Colibri 的 DFM 解析器

DFM Parser

这是一个有趣的工具来做这样的事情

YACC

【讨论】:

  • 范围:Delphi 1 到 2005 for Windows,Kylix。我认为它不兼容 Unicode
【解决方案3】:

我创建了自己的 DFM 解析器,并使用来自 RAD Studio 和我工作的公司的 600 个源文件进行了测试。解析器是用 Go 编写的。

https://github.com/gonutz/dfm

您可以使用它解析 DFM 文件并递归检查内存中的对象,查找 dfm.String 类型的属性。

【讨论】:

    【解决方案4】:

    由于 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;
    

    【讨论】:

      【解决方案5】:

      非常感谢您的回答!我将尝试的另一个解决方案是“GNU Gettext for Delphi and C++ Builder”中包含的“提取字符串”工具。

      .po 文件不仅包括所有组件文本,还包括所有资源字符串(存储 SQL 命令的另一个地方),以及对源的引用(哪个 pas 或 dfm 文件,哪个组件属性名称),它是已经非常简单的“名称=值”列表。

      使用 .po 文件,可以轻松地从 .pas 文件中分出所有 SQL.Text 以及所有文件中名称为“SQL_...”的所有资源字符串。

      【讨论】:

        猜你喜欢
        • 2011-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-06
        • 1970-01-01
        • 1970-01-01
        • 2012-01-25
        相关资源
        最近更新 更多