2010-03-25 14 views
9

Para la documentación y la inspección adicional, me gustaría ejecutar un 'extraer cadenas' en todos los archivos DFM en muchos proyectos para encontrar todas las declaraciones SQL. ¿Hay herramientas de línea de comandos que pueden hacer esto? Los archivos DFM están todos en formato de texto.¿Hay alguna herramienta que pueda extraer todas las cadenas de comandos SQL de los archivos de formularios Delphi?

+1

Estoy en lo correcto suponer que una El archivo "DFM" es la versión de Delphi de un archivo de recursos? – lexu

+0

@lexu sí, contienen información de diseño y enlace para 'forms', 'frames' y 'datamodules'. – mjn

+0

@lexe pero no sé si serán técnicamente terminados como recursos normales de la aplicación en los binarios – mjn

Respuesta

1

Aquí está DFM un Analizador de Felix Colibri

DFM Parser

Aquí es una interesante herramienta para hacer cosas como esta

YACC

+2

¡Es un enlace interesante, gracias! – robsoft

3

Dependiendo del tipo de componente de consulta que esté utilizando, me imagino que podría hacerlo utilizando un grep de línea de comando (o cualquier otra herramienta de búsqueda de texto) en las carpetas de proyectos. En el DFM, por componentes normales TQuery-igual, vas a tener algo en la línea de

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

o posiblemente (no tengo Delphi a mano para comprobar, las alegrías de estar en casa!)

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

Teniendo en cuenta cómo estas cadenas pueden repartidas en varias 'líneas' en el interior del DFM, y dada la forma en que podría haber algunas variaciones que había necesidad de comprobar si, en lo personal me gustaría escribir un pequeño trozo de Delphi para hacer esta.

La idea básica sería; iterar a través de todos los archivos/subcarpetas en un directorio determinado, buscar todos los archivos DFM y, para cada uno, leerlos en una TStringList, buscar cualquiera de las propiedades SQL de TQuery (etc.) que le interesen, y escribir el resultados (nombre del componente, nombre del archivo, cadena de SQL real) a un archivo de resultados. Realmente no debería ser más de una o dos horas de trabajo como máximo.

Si tiene procs almacenados, a los que llama usando algo que no sea un componente TQuery-type, primero tendrá que echar un vistazo dentro de un DFM y ver cómo aparece el SQL; es probable que sea a lo largo de las líneas de

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

etc.

edición: Tras el debate en los comentarios, he aquí una muestra de una de mis DFms;

 
    (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) 

Así que todo lo que realmente tiene que hacer es detectar el bit SQL.Strings = (, a continuación, leer el resto de la línea y todas las líneas siguientes, la eliminación de la anterior y posterior ', hasta que llegue a una línea que termina en ')' - en ese punto he terminado. Cualquiera que sea el contenido interesante de SQL (y comentarios) que pueda haber contenido dentro de las comillas en cada línea es irrelevante, en realidad. Desea leer cada línea que le interese y recortar el texto entre la primera y la última cita de cada línea. Esto debe funcionar porque no puedo ver cómo Delphi podría transmitir esto de otra manera, no puede 'leer' el contenido de la cadena, simplemente está trabajando sobre la base de que la lista de cadenas se divide (posiblemente) en líneas y cada línea está delimitado en el DFM con una apertura y un cierre ', y los contenidos completos de la lista de cadenas están contenidos dentro de un par de corchetes.

¿Tiene sentido, o todavía me falta algo?:-)

+0

Los comandos SQL pueden incluir (y) (y comentarios (incluyendo (y))) entonces el análisis será un poco difícil, porque) también termina el SQL Str ing ... Y qué tal Unicode, si el Texto SQL contiene caracteres especiales en los comentarios o valores de campo. Pero supongo que será la parte divertida y fácil: P – mjn

+0

Muy cierto ... pero si empiezas a analizar primero y cuentas cuántos niveles de presupuesto estás "entrando" a medida que avanzas, deberías Estar bien. Al final del día, el analizador Delphi DFM debe ser capaz de dar sentido a la cadena de manera que comience y termine con una cita. El Texto SQL no puede contener unicode a menos que el archivo DFM sea unicode (¡a menos que me falte algo sobre cadenas en DFM!) Para poder probar primero un archivo Unicode - Aquí tengo algún código en SO en algún lugar que verifica un archivo para ver si es unicode Como dices, ¡todo es parte de la diversión! :-) – robsoft

+0

Delphi no es ideal para esto a menos que use la biblioteca RegExp. Recomendaría escribir un script PERL para analizar el DFM y extraer el SQL. Hice algo similar para convertir los componentes de TTable/TQuery a los "equivalentes" de DOA y eso implicó mantener sincronizado el pas y el dfm a medida que modificaba los archivos. Utilice la herramienta adecuada para el trabajo. En este caso, un lenguaje de scripting con una buena implementación de expresiones regulares. PERL podría no ser tu taza de té pero deberías ser capaz de encontrar algo que te guste Python, Ruby? – mcottle

0

Desde el DFM es básicamente en formato nombre = valor, usted podría cargar en un TStringList, a continuación, recorrer cada línea en busca de los nombres de las propiedades específicas de su interesado en:

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

Muchas gracias por las respuestas! Otra solución que intentaré es la herramienta 'extraer cadenas' incluida en "GNU Gettext for Delphi and C++ Builder".

Los archivos .po incluyen no solo todo el texto del componente sino también todas las cadenas de recursos (otro lugar donde se almacenan comandos SQL), completo con referencias al origen (qué archivo pas o dfm, qué nombre de propiedad del componente) y una lista muy simple de "nombre = valor" ya.

Con un archivo .po que será fácil de resolver todos los archivos de SQL.Text .pas y todas resourcestrings con nombres como 'SQL _..." en todos los archivos.

Cuestiones relacionadas