Ver Mensaje Individual
  #3  
Antiguo 09-05-2018
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Reputación: 21
gatosoft Va camino a la fama
Buen día Soa,

Bien ha hecho Casimiro en hacerte seguimiento con los hilos que has creado respecto al mismo tema, ya en uno de esos hilos te habia mostrado un enlace muy bueno que hablaba de los LifeCycles de DataSnap y creo que allí está muy claro lo que necesitas. Pero como no hemos visto código tuyo o algo que nos ayude a indicar donde está el error pues nos toca a nosotros suponer y hacer la tarea... (Lo digo de la forma mas amistosa)

Creo que tu problema es el lugar donde este ubicando tus componentes de base de datos y la clave está en el componente TServerMethods, asi:

Del lado del server:
===============
*) Create tu servidor normal.

*) Tienes un ServerMethodsUnit y Un ServerContainerUnit, el primero tiene la clase y la funcionalidad que vas a exportar y el segundo tiene los componentes de conexión y transporte (normal)

*) Verifica que en el SeverContainer tu componente DSServerClass1 tenga la propiedad LifeCycle = 'Session' (ese es el valor por defecto).

*) En algún lugar de tu programa debes tener tus componentes de BD. Para este caso, yo creo un TDataModule, y ahi ubico mi componente Connection y mi componente Query. Configuras y pruebas la conexión (Normal)

*) Volvemos al serverMehds y allí creamos una variable de tipo TDatamule que acabas de crear.

*) Defines el constructor y el destructor heredados del TServerMethods y creas dos funciones, una es para Conectar a la BD, y le vas a pasar como parámetro el ID de la BD que quieras.. tu defines como identifias tus BDs, la otra función es para probar la conexión trayendo una consulta: (Y utilizo los componentes UniDac)

Código Delphi [-]
unit ServerMethodsUnit1;

interface

uses System.SysUtils, System.Classes, Datasnap.DSServer, Datasnap.DSAuth, uDTM;

type
{$METHODINFO ON}
  TServerMethods1 = class(TComponent)
  private
    { Private declarations }
    FSoyUnID: String;
    FDtm: TDataModule1;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    Destructor Destroy; Override;
    function getID: String;
    Function ConectarBD(pBaseID: String): String;
    Function Consultar: String;
  end;
{$METHODINFO OFF}

implementation


uses System.StrUtils;

function TServerMethods1.ConectarBD(pBaseID: String): String;
begin
  Result:= 'Conectado';
  Try
    FDtm.UniConnection1.Connected:= False;
    if pBaseID.ToUpper = 'BASE1' then //Si el parametro es BASE1 conecta a TEST, o sino a QA
       FDtm.UniConnection1.Database:= 'BaseTEST'  //Aqui configuras lo que tengas que configurar para conectarte (usuario, pwd, puerto, base)
    else
       FDtm.UniConnection1.Database:= 'BaseQA';
    FDtm.UniConnection1.Connected:= True;
  Except
    On E: Exception do
       Result:= E.Message;
  End;
end;

function TServerMethods1.Consultar: String;
begin
  //pues eso.... consulta un query... las dos BDs tiene la misma estructura de tablas pero diferente data
  Try
    Fdtm.UniQuery1.Close;
    Fdtm.UniQuery1.SQL.Text:= 'Select * from prueba1';
    FDtm.Clientdataset1.Close;
    FDtm.Clientdataset1.Open;
    Result:= FDtm.ClientDataSet1.XMLData;
  Except
    On E:Exception do
       Result:= 'ERROR '+e.Message;
  End;

end;

constructor TServerMethods1.Create(AOwner: TComponent);
begin
  inherited;
  Randomize;
  FSoyUnId:= Random(10000).ToString;//esto es emulando lo del ejemplo del link que te di...
  FDtm:= TDataModule1.Create(Self); //Aqui creas tu DTM
end;

destructor TServerMethods1.Destroy;
begin
  FDtm.UniConnection1.Connected:= False;
  FDtm.Free; //Aqui destruyes el dtm
  inherited;
end;

function TServerMethods1.getID: String;
begin
  Result:= FSoyUnId; //basura...
end;

end.

En el cliente:
==========

*) Tengo un memo para escribir mensajes
*) un grid, un clientdataset (que recibe la consulta del server enviada como XML), el datasource por supuesto
*) tres botones: "getId", para traer el Id de la sesion (no es relevante), "Conectar", en donde enviamos el parametro para configurar y conectar la DB y "consultar" para traer la consulta del server (No Utilizo el DSProviderConnection paar simplificar el tema)

Código Delphi [-]
unit frmPrincipalCLI;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DBXDataSnap,
  Data.DBXCommon, IPPeerClient, Data.DB, Data.SqlExpr, ProxyDS,
  Datasnap.DBClient, Vcl.Grids, Vcl.DBGrids;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    SQLConnection1: TSQLConnection;
    Button2: TButton;
    Edit1: TEdit;
    Button3: TButton;
    DBGrid1: TDBGrid;
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    aClient: TServerMethods1Client;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}


procedure TForm2.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Add(aClient.GetID); //obtiene el Id de la session
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
 Memo1.Lines.Add( aClient.ConectarBD(Edit1.Text)); //conecta a la BD y muestra el mensaje "conectado" o un error si lo hubo
end;

procedure TForm2.Button3Click(Sender: TObject);
Var vXML: String;
begin
  vXML:= aClient.Consultar; //Trae el XML desde el server y lo asigna al CDS
  Try
    ClientDataSet1.Close;
    ClientDataSet1.XMLData:= vXML;
    ClientDataSet1.Open;
  Except
    Memo1.Lines.Add(vXML); //si hubo error muestra el xml enviado por el server
  End;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 aClient.Free; //libera el proxyDS
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  if not SQLConnection1.Connected then
     SQLConnection1.Connected:= True; //conecta el server datasap

  aClient := TServerMethods1Client.Create(SQLConnection1.DBXConnection); crea el proxyDS
end;

end.

y ya.. despues de eso obtines lo que quieres...

el punto es que el ServerMethods es el componente que se aisla y todo loq ue se defina ahi se va a comportar dependiendo de LifeCycle que definas (Servr, Session o invocación)

y cuando recuerde como subir una imagen al foro, te adjunto el resultado de mi prueba...

editado: aqui la imagen

Saludo,

Última edición por gatosoft fecha: 09-05-2018 a las 05:45:30. Razón: se agrega el link de la imagen
Responder Con Cita