Ver Mensaje Individual
  #7  
Antiguo 19-07-2021
javicho_villa javicho_villa is offline
Miembro
 
Registrado: feb 2005
Ubicación: Lima - Perú
Posts: 99
Reputación: 20
javicho_villa Va por buen camino
Smile Uso de RTTI - Solución encaminada

Muchas gracias por todas sus respuestas anteriores, me han dado mucha luz por donde debo ir, y la solución que hasta va bien es usar RTTI.
El objetivo es crear funciones clasicas como ObjectInsert(Obj: TObject):String, de iguakl manera un ObjectUpdate; ObjectDelete y GetObject:TObject;

Para el caso de ObjectInsert, lo ha desarrolado un amigo y hasta funciona bien, pero lo estoy volviendo hacer para poder incorporar la opción de maestro/detalle y tambien que guarde en una tabla llamada BITACORA para poder controlar cualquier movimiento de los usuarios.

Código Delphi [-]
function TDm.ObjectInsert(Obj: TObject): String;
var
  MiProcedimiento: TFDStoredProc;
  MiError:String;
  Detalle : widestring;
  ListaProp: TStringList;
  ListaParam: TStringList;
  ListaMetaInfo : TStringList;
  NombreProc: string;
  NombreProp: string;
  NombreParam: string;
  TipoProp  : string;
  TipoDato  : string;
  TipoIO    : string;
  AnchoCampo: string;
  contexto : TRTTIContext;
  propiedad : TRTTIProperty;
  valor : TValue;
  I, J : word;

  function BuscaLong(B: string): string;
  var
    Encontrado : boolean;
    Nombre: string;
    Tipo : string;
    Ancho:string;
    J: Integer;
  begin
    Encontrado := False;
    for J := 0 to Pred(ListaMetaInfo.Count) do
    begin
       if B = Copy(ListaMetaInfo[J], 1, Length(B)) then
       begin  // := Copy(ListaMetaInfo[J], 1, Length(NombreBuscar)) then
         Encontrado := True;
         Break;
       end;
    end;
    if Encontrado then
      TLibreria.ParseMetaInfo(ListaMetaInfo[J], Nombre, Tipo, Ancho)
    else
      Ancho := '100';
    result := Ancho
  end;

  function BuscaProp(B: string): integer;
  var
    Encontrado : boolean;
    Nombre: string;
    Tipo : string;
    Ancho:string;
    J: Integer;
  begin
    Encontrado := False;
    for J:= 0 to Pred(ListaProp.Count) do
    begin
      if Copy(B, 2, Length(B)) = Copy(ListaProp[J], 2, Length(B)-1) then
      begin
        Encontrado := True;
        Break;
      end;
    end;
    if Encontrado then
      result := J
     else
       result := -1;
  end;

begin
  MiError := '';
  ListaProp  := TStringList.Create;
  ListaParam := TStringList.Create;

  if not Assigned(Obj) then
    exit;

  try
    MiProcedimiento := TFDStoredProc.Create(nil);
    MiProcedimiento.Connection := DM.EmpresaConnection;  // SislibroConnection

//  1- Carga los propiedades de la clase
    ListaProp := TLibreria.DaListaPropConTipo(Obj);

    try
      with MiProcedimiento do
      begin
        Close;
        Params.Clear;

//  2- Ubicar el store procedure de la tabla  + INSERTAR
        NombreProc := Copy(Obj.ClassName, 2, Length(Obj.ClassName)-1) + 'Insertar';
        StoredProcName := NombreProc;
        FetchOptions.Items := MiProcedimiento.FetchOptions.Items - [fiMeta]; // quitar fiMeta para insertar parametros manualmente

//  3- Conseguir los parametros del store procedure
//--   Para el caso de Sislibro se extrae del componente EmpresaConecction --//
       ListaParam := DM.DaListaParam(Dm.EmpresaConnection.Params.Database , NombreProc);

//  4- Obtiene los meta datos de la tabla
        ListaMetaInfo := TLibreria.DaListaMetaInfo(Copy(Obj.ClassName, 2, Length(Obj.ClassName)-1));

//  5- Crear los parametros en el FDStoredProc dinamico y pasa el valor a los parametros
        contexto := TRTTIContext.Create;

//        showmessage(IntToStr(ListaParam.Count));

        for I := 0 to Pred(ListaParam.Count) do
        begin
          TLibreria.ParseParam(ListaParam[i], NombreParam, TipoDato, TipoIO);  // separa nombre de tipo
          AnchoCampo := BuscaLong( Copy(NombreParam, 2, length(NombreParam)-1)); // Busca ancho de campo de la tabla
          if (TipoDato = 'varchar') And (StrToInt(AnchoCampo) = 8000) then   // si longitud de parametro = MAX
          begin                 {Wide}
            Params.CreateParam( ftWideString,  NombreParam, TLibreria.StrToParamType(TipoIO));  // se crea con widestring
            for J := 0 to Pred(ListaProp.Count) do // busca el tipo de la propiedad iDetalle
            begin
              TLibreria.ParseProp(ListaProp[J], NombreProp, TipoProp);        // separa nombre de tipo
              if TipoProp = 'TObjectList' then  // si es del tipo TObjectList
              begin  // obtiene string con datos y los pasa al paremetro
                Detalle := Dm.GetDetalleText(TObjectList(contexto.GetType(Obj.ClassType).GetProperty(NombreProp).GetValue(Obj).  AsObject));
                Params.ParamByName( NombreParam).Value :=  Detalle;
              end;
            end;
          end
          else // de lo contrario
          begin // procesa los demas campos
            Params.CreateParam( TLIbreria.StrToFieldType(TipoDato), NombreParam, TLibreria.StrToParamType(TipoIO)); // crea paramero
            if (Uppercase(NombreParam) = '@ERROR') then  // si es campo @Error
            begin // pasa datos en blanco
              Params.ParamByName( NombreParam).Value :=  '';
            end
            else   // sino
            begin  // procesa normal
              J := BuscaProp(NombreParam);  // busca parametro en lista de propiedades, obtiene la posicion
              TLibreria.ParseProp(ListaProp[J], NombreProp, TipoProp);        // separa nombre de tipo
              propiedad :=  contexto.GetType(Obj.ClassType).GetProperty(NombreProp); // tipo de la propiedad
              valor := propiedad.GetValue(Obj).ToString;            // obtiene valor
              Params.ParamByName( NombreParam).Value :=  valor.AsString;
            end;
          end;
        end;

        contexto.Free;

        if ParamCount > 0 then
        begin
//          Prepared := True;
          ExecProc;
          MiError := Params.ParamByName('@Error').AsString;
        end;
      end;

    finally
      MiProcedimiento.Free;
    end;
  finally
    result := MiError;
    ListaProp.Free;
    ListaParam.Free;
  end;
end;


hay varias funciones que las estoy depurando, cuando las tenga lista se las paso, me parece super interesante estas funciones básicas para cualquier tabla.

les reitero mi agradecimiento por el apoyo brindado.

un fuerte abrazo.
__________________
Javier Villa Sánchez
jvilla@andreaproducciones.com
Responder Con Cita