Apenas 1 SQLConnection na aplicação Servidora, como faço?
Fala galera!!...seguinte: como faço para ter apenas 1 SQLConnection na minha aplicação servidora?...para depois na aplicação cliente ter apenas 1
SocketConnection?...Explicando melhor, numa aplicação cliente/servidor, isto é facil, basta ter um datamodule central e adicionar nele um componente de conexão (como SQLConnection)...e depois os demais datamodules conterão as queryes ligadas ao dm central. Agora queria saber como faço para organizar os componentes nesse sentido para uma aplicação multicamadas. Fui aconselhado a ter em cada Remote Data Module que criar, ter um componente SQLConnection, mas e depois na aplicação cliente?....vai ficar ruim pois tb terei que ter um SocketConnection para cada SQLConnection....queria fazer algo que seguisse o mesmo modelo da aplicação cliente/servidor..ou seja, centralizar os componentes de conexão.
se alguém puder me ajudar!!....brigadão!!!
T++ pessoal
Marcelo
SocketConnection?...Explicando melhor, numa aplicação cliente/servidor, isto é facil, basta ter um datamodule central e adicionar nele um componente de conexão (como SQLConnection)...e depois os demais datamodules conterão as queryes ligadas ao dm central. Agora queria saber como faço para organizar os componentes nesse sentido para uma aplicação multicamadas. Fui aconselhado a ter em cada Remote Data Module que criar, ter um componente SQLConnection, mas e depois na aplicação cliente?....vai ficar ruim pois tb terei que ter um SocketConnection para cada SQLConnection....queria fazer algo que seguisse o mesmo modelo da aplicação cliente/servidor..ou seja, centralizar os componentes de conexão.
se alguém puder me ajudar!!....brigadão!!!
T++ pessoal
Marcelo
Tchelllo
Curtidas 0
Respostas
Cristiam
17/05/2005
Crie uma classe para fazer isso. ;)
GOSTEI 0
Tchelllo
17/05/2005
Olá Cristiam....será que vc pode ser mais detalhado ?....a classe que vc diz seria criar outro Remote Data Module e colocar no uses o RDM principal que contem o SQLConnection?....pois se for, na aplicação cliente como faço para enxergar o RDM que contem as DataSets?
vlwww!!
vlwww!!
GOSTEI 0
Kotho
17/05/2005
dá uma olhada neste tópico [url]http://forum.clubedelphi.net/viewtopic.php?t=42509[/url]
GOSTEI 0
Tchelllo
17/05/2005
Olá Kotho....analisei seu forum...mas não entendi algumas passagens...como por ex.
function TRDM.Get_RDMRelatorio: IRDMRelatorio;
begin
Result := RDMRelatorioFactory.CreateCOMObject(nil) as IRDMRelatorio;
Result.RDM := Self;
Result.SQLConnection := Integer(SQLConnection1);
end;
O que esse RDMRelatorioFactory que vc colocou ?....não seria somente RDMRelatorio ?....não entendi essa parte.
function TRDMRelatorio.Get_RDM: IRDM;
begin
Result := FRDM;
end;
procedure TRDMRelatorio.Set_RDM(const Value: IRDM);
begin
FRDM := Value;
end;
function TRDMRelatorio.Get_SQLConnection: Integer;
begin
Result := Integer(FRDM.SQLConnection);
end;
e nessas...o que seria FRDM ?...tb n]ao entendi.....e mais uma coisa...isso tb funciona qdo se usa Transaction Data Modules ?
vlww pela atenção meu caro!!!..obrigado!
Marcelo
function TRDM.Get_RDMRelatorio: IRDMRelatorio;
begin
Result := RDMRelatorioFactory.CreateCOMObject(nil) as IRDMRelatorio;
Result.RDM := Self;
Result.SQLConnection := Integer(SQLConnection1);
end;
O que esse RDMRelatorioFactory que vc colocou ?....não seria somente RDMRelatorio ?....não entendi essa parte.
function TRDMRelatorio.Get_RDM: IRDM;
begin
Result := FRDM;
end;
procedure TRDMRelatorio.Set_RDM(const Value: IRDM);
begin
FRDM := Value;
end;
function TRDMRelatorio.Get_SQLConnection: Integer;
begin
Result := Integer(FRDM.SQLConnection);
end;
e nessas...o que seria FRDM ?...tb n]ao entendi.....e mais uma coisa...isso tb funciona qdo se usa Transaction Data Modules ?
vlww pela atenção meu caro!!!..obrigado!
Marcelo
GOSTEI 0
Kotho
17/05/2005
Vamos ver se consigo exclarecer todas as dúvidas, ok?
---
Quando se cria um novo RemoteDataModule ou TransactionDataModule, ele utiliza este trecho no inicialization do DataModule...
Por isso é preciso usar o mesmo método para instanciar os DataModules no DataModule principal...
Foi bom você ter tido essas dúvidas, porque tem que se mudar mais algumas coisas (eu tinha dito que era chatinho), e que eu tinha esquecido...
ele também define a variavel RDMRelatorio: TRDMRelatorio;
é preciso mudar para RDMRelatorioFactory: TComponentFactory;
e no inicialization
Isso, eu creio, que sirva para que o DataModule não seja criado sozinho, mas que o DataModule Principal o crie...
---
As procedures Get´s e Set´s são, automaticamente, usadas pelo SharedConnection (que fica no Client), para fazer a instância dos DataModules.
---
Cada DataModule deve ter uma variável (privada) declarada... no meu caso eu fiz...
FRDM: IRDM
onde RDM é o meu DataModule principal. IRDM é a interface (no arquivo TLB)...
---
Bom... quando se usa essa forma, quando um client se conecta ao server, ele cria uma nova Thread, com a cópia do DataModule Principal e dos demais... com isso, a propriedade SQLConnection pode ser perdida... por isso tem que se usar os GetSQLConnection, para atribui-lo aos componentes... para fazer isso, é preciso serializar o componente, por isso o Integer(FRDM.SQLConnection).
---
Para ser bem simplista, no DataModule Principal são instanciados os DataModules secundários... e nos secundários, é referenciada (através de interface) o Principal, assim como o SQLConneciton.
Isto, porque, não se consegue referenciar um DataModule no outro de forma direta (declarando na uses)... é preciso passar a referencia do objeto de um para o outro.
E tudo isso, quem ajuda, é o SharedConnection no Client...
---
Eu sei que pode parecer confuso... mas eu vou tentar ajudar, da forma que eu puder...
---
Quando se cria um novo RemoteDataModule ou TransactionDataModule, ele utiliza este trecho no inicialization do DataModule...
initialization TComponentFactory.Create(ComServer, TRDM, Class_RDM, ciMultiInstance, tmApartment); end.
Por isso é preciso usar o mesmo método para instanciar os DataModules no DataModule principal...
Foi bom você ter tido essas dúvidas, porque tem que se mudar mais algumas coisas (eu tinha dito que era chatinho), e que eu tinha esquecido...
ele também define a variavel RDMRelatorio: TRDMRelatorio;
é preciso mudar para RDMRelatorioFactory: TComponentFactory;
e no inicialization
RDMRelatorioFactory := TComponentFactory.Create(ComServer, TRDMRelatorio, Class_RDMRelatorio, ciInternal, tmApartment);
Isso, eu creio, que sirva para que o DataModule não seja criado sozinho, mas que o DataModule Principal o crie...
---
As procedures Get´s e Set´s são, automaticamente, usadas pelo SharedConnection (que fica no Client), para fazer a instância dos DataModules.
---
Cada DataModule deve ter uma variável (privada) declarada... no meu caso eu fiz...
FRDM: IRDM
onde RDM é o meu DataModule principal. IRDM é a interface (no arquivo TLB)...
---
Bom... quando se usa essa forma, quando um client se conecta ao server, ele cria uma nova Thread, com a cópia do DataModule Principal e dos demais... com isso, a propriedade SQLConnection pode ser perdida... por isso tem que se usar os GetSQLConnection, para atribui-lo aos componentes... para fazer isso, é preciso serializar o componente, por isso o Integer(FRDM.SQLConnection).
---
Para ser bem simplista, no DataModule Principal são instanciados os DataModules secundários... e nos secundários, é referenciada (através de interface) o Principal, assim como o SQLConneciton.
Isto, porque, não se consegue referenciar um DataModule no outro de forma direta (declarando na uses)... é preciso passar a referencia do objeto de um para o outro.
E tudo isso, quem ajuda, é o SharedConnection no Client...
---
Eu sei que pode parecer confuso... mas eu vou tentar ajudar, da forma que eu puder...
GOSTEI 0
Tchelllo
17/05/2005
Então Kotho...veja o que estou fazendo de errado, pois não consegui ainda...
nessa function...
function TRDM.Get_RDMRelatorio: IRDMRelatorio;
begin
Result := RDMRelatorioFactory.CreateCOMObject(nil) as IRDMRelatorio;
Result.RDM := Self;
Result.SQLConnection := Integer(SQLConnection1);
end;
como faço para obter esse valor....Result.RDM := Self; e
Result.SQLConnection := Integer(SQLConnection1); ????.....pois aqui só me aparece os métodos de IRDMRelatorio quando digito Result.
e nessa..
function TRDMRelatorio.Get_SQLConnection: Integer;
begin
Result := Integer(FRDM.SQLConnection);
end;
declarei na área private a variável como vc explicou...
FRDM : IRDM;
mas tb só me aparecem os métodos e não a propriedade SQLConnection....
O que estou fazendo de errado ?
nessa function...
function TRDM.Get_RDMRelatorio: IRDMRelatorio;
begin
Result := RDMRelatorioFactory.CreateCOMObject(nil) as IRDMRelatorio;
Result.RDM := Self;
Result.SQLConnection := Integer(SQLConnection1);
end;
como faço para obter esse valor....Result.RDM := Self; e
Result.SQLConnection := Integer(SQLConnection1); ????.....pois aqui só me aparece os métodos de IRDMRelatorio quando digito Result.
e nessa..
function TRDMRelatorio.Get_SQLConnection: Integer;
begin
Result := Integer(FRDM.SQLConnection);
end;
declarei na área private a variável como vc explicou...
FRDM : IRDM;
mas tb só me aparecem os métodos e não a propriedade SQLConnection....
O que estou fazendo de errado ?
GOSTEI 0
Kotho
17/05/2005
Esse SQLConnection é uma property criada lá no TLB... no tópico que eu passei eu descrevi como está a estrutura do meu TLB... como está a sua???
GOSTEI 0
Tchelllo
17/05/2005
//**********************************************************//
// The Class CoServerVendas provides a Create and CreateRemote method to
// create instances of the default interface IServerVendas exposed by
// the CoClass ServerVendas. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary. ************************************************************//
CoServer = class
class function Create: IServer;
class function CreateRemote(const MachineName: string): IServer;
end;
aqui no meu _TLB não tem nada a ver com o que vc passou....peguei essa parte...mas não sei se é esta que vc ker...o restante abaixo dessas linhas estão as class functios etc...
// The Class CoServerVendas provides a Create and CreateRemote method to
// create instances of the default interface IServerVendas exposed by
// the CoClass ServerVendas. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary. ************************************************************//
CoServer = class
class function Create: IServer;
class function CreateRemote(const MachineName: string): IServer;
end;
aqui no meu _TLB não tem nada a ver com o que vc passou....peguei essa parte...mas não sei se é esta que vc ker...o restante abaixo dessas linhas estão as class functios etc...
GOSTEI 0
Kotho
17/05/2005
Não...não... após abrir o TLB, clique em F12. Irá abrir uma tela gráfica com a estrutura do TLB... não mexa no código...
GOSTEI 0
Tchelllo
17/05/2005
typelib Server
[ uuid ´{E202BF71-1734-4220-87D4-C96ABF49DDA5}´,
version 1.0,
helpstring ´ServerSis Library´ ];
uses midas.dll, stdole2.tlb, stdvcl40.dll, stdvcl40.dll;
IServer = interface(IAppServer)
[ uuid ´{D3EF78A2-8A5B-4388-AE45-35F95A9FBFED}´,
version 1.0,
helpstring ´Dispatch interface for Server Object´,
dual,
oleautomation ]
function Get_SQLConn: Integer [dispid $0000012D]; safecall;
function Get_tdmCliente: ItdmClientes [dispid $0000012E]; safecall;
end;
Server = coclass(IServer [default] )
[ uuid ´{3834B633-6E50-40CA-983E-417D819B7CAF}´,
version 1.0,
helpstring ´Server Object´,
custom ´{17093CC8-9BD2-11CF-AA4F-304BF89C0001}´ 0 ];
peguei isso da aba Text da tela gráfica que se abriu....é isso?
[ uuid ´{E202BF71-1734-4220-87D4-C96ABF49DDA5}´,
version 1.0,
helpstring ´ServerSis Library´ ];
uses midas.dll, stdole2.tlb, stdvcl40.dll, stdvcl40.dll;
IServer = interface(IAppServer)
[ uuid ´{D3EF78A2-8A5B-4388-AE45-35F95A9FBFED}´,
version 1.0,
helpstring ´Dispatch interface for Server Object´,
dual,
oleautomation ]
function Get_SQLConn: Integer [dispid $0000012D]; safecall;
function Get_tdmCliente: ItdmClientes [dispid $0000012E]; safecall;
end;
Server = coclass(IServer [default] )
[ uuid ´{3834B633-6E50-40CA-983E-417D819B7CAF}´,
version 1.0,
helpstring ´Server Object´,
custom ´{17093CC8-9BD2-11CF-AA4F-304BF89C0001}´ 0 ];
peguei isso da aba Text da tela gráfica que se abriu....é isso?
GOSTEI 0
Kotho
17/05/2005
no lado esquerdo da tela gráfica tem um TreeView... essa é a estrutura... ela é formada de CoClass, Interfaces, Propertys (read e/ou write) e Mathods...
GOSTEI 0
Tchelllo
17/05/2005
A estrutura está assim: (vou descrevê-la como se fosse o proprio TreeView pra vc ver)
-ServerSis
-IServer
Get_SQLConnetion (method)
+Server
-ItdmClientes --> Este é outro Transaction Data Module
... outros methods
+tdmClientes
espero ter sido claro.
-ServerSis
-IServer
Get_SQLConnetion (method)
+Server
-ItdmClientes --> Este é outro Transaction Data Module
... outros methods
+tdmClientes
espero ter sido claro.
GOSTEI 0
Kotho
17/05/2005
Blz... agora começamos a falar a mesma lingua...
no seu IServer, você tem que criar algumas propriedades...
SQLConnection - do tipo long - read
tdmClientes - do tipo ItdmClientes - read
no seu ItdmClientes...
SQLConnection - do tipo long - read/write
Server - do tipo IServer - read/write
--
Se você quizer facilitar o trabalho para não ter que criar as propriedades nos DataModules secundários, você pode criar uma interface base... eu chamei a minha de IBaseRDM... ai você cria as propriedades nessa interface... depois, na sua ItdmClientes, você muda a propriedade (do lado direito) Parent Interface para essa Interface Base, e não precisa criar as mesmas propriedades... Só precisará implementar as procedures/functions nos DataModules
--
detalhe... sempre que você alterar o TLB, e clicar no botão de refresh, as procedures/functions serão criadas nos DataModules, só faltando implementar...
---
aproveitando o post... como está a seção inicialization (fica no final da unit) dos seus DataModules???
no seu IServer, você tem que criar algumas propriedades...
SQLConnection - do tipo long - read
tdmClientes - do tipo ItdmClientes - read
no seu ItdmClientes...
SQLConnection - do tipo long - read/write
Server - do tipo IServer - read/write
--
Se você quizer facilitar o trabalho para não ter que criar as propriedades nos DataModules secundários, você pode criar uma interface base... eu chamei a minha de IBaseRDM... ai você cria as propriedades nessa interface... depois, na sua ItdmClientes, você muda a propriedade (do lado direito) Parent Interface para essa Interface Base, e não precisa criar as mesmas propriedades... Só precisará implementar as procedures/functions nos DataModules
--
detalhe... sempre que você alterar o TLB, e clicar no botão de refresh, as procedures/functions serão criadas nos DataModules, só faltando implementar...
---
aproveitando o post... como está a seção inicialization (fica no final da unit) dos seus DataModules???
GOSTEI 0
Tchelllo
17/05/2005
Está assim:
initialization
TComponentFactory.Create(ComServer, TServer,
Class_Server, ciMultiInstance, tmApartment);
para o TDM Server, e...
initialization
tdmClientes := TComponentFactory.Create(ComServer, TtdmClientes,
Class_tdmClientes, ciMultiInstance, tmApartment);
para o outro...o TDMClientes
testei e deu certo agora....só que na aplicação cliente estou usando Socket...e quando coloco um SharedConnection a prop. ChildName fica em branco, não me retorna nada.....pq será que está acontecendo isso?....antes estava dando erro de Classe inválida....e agora isso...não aparece nada.
initialization
TComponentFactory.Create(ComServer, TServer,
Class_Server, ciMultiInstance, tmApartment);
para o TDM Server, e...
initialization
tdmClientes := TComponentFactory.Create(ComServer, TtdmClientes,
Class_tdmClientes, ciMultiInstance, tmApartment);
para o outro...o TDMClientes
testei e deu certo agora....só que na aplicação cliente estou usando Socket...e quando coloco um SharedConnection a prop. ChildName fica em branco, não me retorna nada.....pq será que está acontecendo isso?....antes estava dando erro de Classe inválida....e agora isso...não aparece nada.
GOSTEI 0
Kotho
17/05/2005
Você implementou as procedure/functions?
no DataModule principal (Server):
--GetSQLConnection
--GetTdmCliente
e no secundário (tdmCliente):
--GetSQLConnection
--SetSQLConnection
--GetServer
--SetServer
no DataModule principal (Server):
--GetSQLConnection
--GetTdmCliente
e no secundário (tdmCliente):
--GetSQLConnection
--SetSQLConnection
--GetServer
--SetServer
GOSTEI 0
Tchelllo
17/05/2005
Quando se cria as propertys, automaticamente são criadas as function/procedures certo?...
no meu ficou assim:
No Server:
function TServer.Get_SQLConnection: Integer;
begin
// o Integer serve para serializar o componente
Result := Integer(sqlConnEmp); // nome do meu SQLConnection
end;
function TServer.Get_ItdmClientes: ItdmClientes;
begin
Result := tdmClientes.CreateCOMObject(nil) as ItdmClientes;
Result.Server := Self;
Result.SQLConnection := Integer(sqlConnEmp);
end;
e no tdmClientes:
function TtdmClientes.Get_Server: IServer;
begin
Result := FServer;
end;
procedure TtdmClientes.Set_Server(const Value: IServer);
begin
FServer := Value;
end;
function TtdmClientes.Get_SQLConnection: Integer;
begin
Result := Integer(FServer.SQLConnection);
end;
procedure TtdmClientes.Set_SQLConnection(Value: Integer);
var
x: integer;
begin
for x:=0 to ComponentCount -1 do
if Components[x] is TCustomSQLDataSet then
TSQLDataSet(Components[x]).SQLConnection := TSQLConnection(Value);
end;
Como vc me explicou, criei um Interface base com os Get´s e Set´s acima (não todos, apenas as 4 acima)...e depois alterei o Parent Interface de ItdmClientes para a base criada.
está algo errado ?
no meu ficou assim:
No Server:
function TServer.Get_SQLConnection: Integer;
begin
// o Integer serve para serializar o componente
Result := Integer(sqlConnEmp); // nome do meu SQLConnection
end;
function TServer.Get_ItdmClientes: ItdmClientes;
begin
Result := tdmClientes.CreateCOMObject(nil) as ItdmClientes;
Result.Server := Self;
Result.SQLConnection := Integer(sqlConnEmp);
end;
e no tdmClientes:
function TtdmClientes.Get_Server: IServer;
begin
Result := FServer;
end;
procedure TtdmClientes.Set_Server(const Value: IServer);
begin
FServer := Value;
end;
function TtdmClientes.Get_SQLConnection: Integer;
begin
Result := Integer(FServer.SQLConnection);
end;
procedure TtdmClientes.Set_SQLConnection(Value: Integer);
var
x: integer;
begin
for x:=0 to ComponentCount -1 do
if Components[x] is TCustomSQLDataSet then
TSQLDataSet(Components[x]).SQLConnection := TSQLConnection(Value);
end;
Como vc me explicou, criei um Interface base com os Get´s e Set´s acima (não todos, apenas as 4 acima)...e depois alterei o Parent Interface de ItdmClientes para a base criada.
está algo errado ?
GOSTEI 0
Kotho
17/05/2005
Tem uma coisinha que eu estou percebendo... no TLB, na Interface do Server, você criou a propriedade ItdmClientes do tipo ItdmClientes... na verdade, o nome da propriedade (no meu entender) deve ter o mesmo nome do DataModule...
ficaria tdmClientes do tipo ItdmClientes
Modifique isso, e avisa se deu certo
ficaria tdmClientes do tipo ItdmClientes
Modifique isso, e avisa se deu certo
GOSTEI 0
Tchelllo
17/05/2005
Ainda está em branco....estou fazendo testes com uma máquina remota...nela configurei na COM+ a DLL gerada no Delphi...está da seguinte forma:
-TESTE // nome da aplicação no catálogo
-Componentes
+ServerSis.Server
+ServerSis.tdmClientes
não está nada errado nao é?
-TESTE // nome da aplicação no catálogo
-Componentes
+ServerSis.Server
+ServerSis.tdmClientes
não está nada errado nao é?
GOSTEI 0
Kotho
17/05/2005
Eu estava olhando melhor as suas configurações e comparando com as minhas... no tdmClientes, a Inicialization sua está ciMultInstance, e o meu está ciInternal... Só o principal deve estar ciMultInstance...
Cara, eu não entendi uma coisa... você está fazendo o Servidor como COM+ certo??? e o Cliente como Socket??? Por que???
Tenta colocar um DComConnection... no ServerName, selecione o Server... Coloque um SharedConnection... atribua o DComConnection no ParentConnection... ai é para aparecer o tdmClientes na lista do ChildName... Seleciona e pronto...
Acho que estas alterações serão suficientes para resolver... mas qualquer problemas, já sabe... estamos aqui...
Cara, eu não entendi uma coisa... você está fazendo o Servidor como COM+ certo??? e o Cliente como Socket??? Por que???
Tenta colocar um DComConnection... no ServerName, selecione o Server... Coloque um SharedConnection... atribua o DComConnection no ParentConnection... ai é para aparecer o tdmClientes na lista do ChildName... Seleciona e pronto...
Acho que estas alterações serão suficientes para resolver... mas qualquer problemas, já sabe... estamos aqui...
GOSTEI 0
Tchelllo
17/05/2005
Particularmente prefiro usar o SocketConnection...é igual o DCOMConnection só muda algumas propriedades como o Host, que não tem no DCom...
e sobre o SharedConnection, ainda está em branco :/....já tinha feito as alterações para ciInternal e nada.....
mas me deixe perguntar uma coisa....as functios/procedures não precisam ser executadas?...ou só precisam estar inseridas e implementadas?...não preciso tipo, colocá-las no onCreate do TDM e executá-las certo?
e sobre o SharedConnection, ainda está em branco :/....já tinha feito as alterações para ciInternal e nada.....
mas me deixe perguntar uma coisa....as functios/procedures não precisam ser executadas?...ou só precisam estar inseridas e implementadas?...não preciso tipo, colocá-las no onCreate do TDM e executá-las certo?
GOSTEI 0
Kotho
17/05/2005
Não precisa não... o SharedConnection vai executa-los...
Eu tentei fazer uma conexão usando Socket, mas não está funcionando não... está me retornando um exception dizendo que a máquina de destino recusou...
eu fiz assim... coloquei o nome da máquina que o server está instalado no Host, depois tentei selecionar o ServerName... aí dá o erro...
Tchello, eu volto a insistir, usa o DComConnection... pelo menos faz um teste... o campo Host do Socket é similar ao ComputerName do DCom...
Coloque o nome da máquina (ou ip) no ComputerName, depois selecione o ServerName... é bem simples...
Eu tentei fazer uma conexão usando Socket, mas não está funcionando não... está me retornando um exception dizendo que a máquina de destino recusou...
eu fiz assim... coloquei o nome da máquina que o server está instalado no Host, depois tentei selecionar o ServerName... aí dá o erro...
Tchello, eu volto a insistir, usa o DComConnection... pelo menos faz um teste... o campo Host do Socket é similar ao ComputerName do DCom...
Coloque o nome da máquina (ou ip) no ComputerName, depois selecione o ServerName... é bem simples...
GOSTEI 0
Tchelllo
17/05/2005
Então Kotho, já fiz o teste com o DCom, mas tb fica em branco a propriedade....não sei oq pode ser...:/
tem uma coisa que tá estranho....nessa passagem...
function TtdmClientes.Get_SQLConnection: Integer;
begin
Result := Integer(FServer.SQLConnection);
end;
quando compilo não dá erro nenhum....mas....quando digito FServer (que é a variável privada) e digito .(ponto)....não aparece a property SQLConnection...o que aparece de property é só a tdmClientes....deveria aparecer não é?
tem uma coisa que tá estranho....nessa passagem...
function TtdmClientes.Get_SQLConnection: Integer;
begin
Result := Integer(FServer.SQLConnection);
end;
quando compilo não dá erro nenhum....mas....quando digito FServer (que é a variável privada) e digito .(ponto)....não aparece a property SQLConnection...o que aparece de property é só a tdmClientes....deveria aparecer não é?
GOSTEI 0
Kotho
17/05/2005
Não aparece mesmo...
Uma pergunta... quando você mudou o nome da propriedade de ItdmClientes para tdmClientes... você clicou no refresh... quando se faz isso, ele cria novas functions/procedures... dá uma olhada nisso...
talvez ele não tenha apagado as antigas... você deve passar o código para as novas functions/procedures...
Espero o retorno
Uma pergunta... quando você mudou o nome da propriedade de ItdmClientes para tdmClientes... você clicou no refresh... quando se faz isso, ele cria novas functions/procedures... dá uma olhada nisso...
talvez ele não tenha apagado as antigas... você deve passar o código para as novas functions/procedures...
Espero o retorno
GOSTEI 0
Tchelllo
17/05/2005
Quando eu alterei o nome, as funções tb foram alteradas, mas não criadas novamente. O delphi apenas mudou o nome de Get_ItdmClientes para Get_tdmClientes.
Ah, quando vc tentou usar o SocketConnection, deu akele erro pois ele precisa de um .exe rodando na maquina hospedeira da aplicação...o exe chama-se scktsrvr.exe....fica nos diretorios do Delphi....
será que eu preciso apagá-las e criá-las de novo?...só por causa do nome...creio que não né...pois o delphi alterou pra mim....
e tb como está o relacionamento dos seus Tdm´s ?....vc colocou eles na cláusula uses?.....como está o seu ?
Ah, quando vc tentou usar o SocketConnection, deu akele erro pois ele precisa de um .exe rodando na maquina hospedeira da aplicação...o exe chama-se scktsrvr.exe....fica nos diretorios do Delphi....
será que eu preciso apagá-las e criá-las de novo?...só por causa do nome...creio que não né...pois o delphi alterou pra mim....
e tb como está o relacionamento dos seus Tdm´s ?....vc colocou eles na cláusula uses?.....como está o seu ?
GOSTEI 0
Tchelllo
17/05/2005
Sobe
A propósito Kotho, testei com RemoteDataModules. Como ele gera um .exe, tentei acessá-lo através de um Client e ele abriu a aplicação servidora....não é normal isso nao é?......nunca trabalhei com RemoteDataModules...por isso as dúvidas....kra...to ficando com os nervos a flor da pele....não consigo resolver esse problema!!...:/
A propósito Kotho, testei com RemoteDataModules. Como ele gera um .exe, tentei acessá-lo através de um Client e ele abriu a aplicação servidora....não é normal isso nao é?......nunca trabalhei com RemoteDataModules...por isso as dúvidas....kra...to ficando com os nervos a flor da pele....não consigo resolver esse problema!!...:/
GOSTEI 0
Kotho
17/05/2005
A uses, eu só defini no RDM (principal) os Secundários...
Cara, era para estar tudo funcionando (fiz o teste com socket e funcionou)... muito estranho... vou colocar os trechos de código para a gente comparar ok?
RDM (DataModulePrincipal)
RDMConsulta (Secundário)
Cara, era para estar tudo funcionando (fiz o teste com socket e funcionou)... muito estranho... vou colocar os trechos de código para a gente comparar ok?
RDM (DataModulePrincipal)
... function Get_SQLConnection: Integer; safecall; function Get_RDMConsulta: IRDMConsulta; safecall; ... function TRDM.Get_SQLConnection: Integer; begin Result := Integer(Amplast); end; function TRDM.Get_RDMConsulta: IRDMConsulta; begin Result := RDMConsultaFactory.CreateCOMObject(nil) as IRDMConsulta; Result.RDM := Self; Result.SQLConnection := Integer(Amplast); Result.ADOConnection := Integer(ZIM); end; ... initialization TComponentFactory.Create(ComServer, TRDM, Class_RDM, ciMultiInstance, tmBoth);
RDMConsulta (Secundário)
... function Get_RDM: IRDM; safecall; procedure Set_RDM(const Value: IRDM); safecall; function Get_SQLConnection: Integer; safecall; procedure Set_SQLConnection(Value: Integer); safecall; ... function TRDMConsulta.Get_RDM: IRDM; begin Result := FRDM; end; procedure TRDMConsulta.Set_RDM(const Value: IRDM); begin FRDM := Value; end; function TRDMConsulta.Get_SQLConnection: Integer; begin Result := Integer(FRDM.SQLConnection); end; procedure TRDMConsulta.Set_SQLConnection(Value: Integer); var x: Integer; begin for x := 0 to ComponentCount -1 do if Components[x] is TCustomSQLDataSet then TCustomSQLDataSet(Components[x]).SQLConnection := TSQLConnection(Value); end; ... initialization RDMConsultaFactory := TComponentFactory.Create(ComServer, TRDMConsulta, Class_RDMConsulta, ciInternal, tmApartment);
GOSTEI 0
Tchelllo
17/05/2005
Kotho, estou usando TransacationDataModules....e como vc está usando RemoteDataModules...será que não é por isso que não estou conseguindo ?...ou vc já testou com TDM´s e funcionou ?
GOSTEI 0
Kotho
17/05/2005
Apesar do RDM... eu tbem utilizo Transactional... é que eu converti depois...
Os trechos estão iguais (trocando os nomes, é claro)???
Dá uma olhada na sua MP
Os trechos estão iguais (trocando os nomes, é claro)???
Dá uma olhada na sua MP
GOSTEI 0
Tchelllo
17/05/2005
Boas é más notícias Kotho...
Boa: Consegui fazer aparecer o bendito tdmClientes!!....aeeeeee
Ruim: Quando vou setar a propriedade ProviderName do meu ClientDataSet na aplicação Cliente com o DataSetProvider da aplicação servidora, dá o seguinte erro:
Catastrophic failure
já aconteceu isso com vc?
Boa: Consegui fazer aparecer o bendito tdmClientes!!....aeeeeee
Ruim: Quando vou setar a propriedade ProviderName do meu ClientDataSet na aplicação Cliente com o DataSetProvider da aplicação servidora, dá o seguinte erro:
Catastrophic failure
já aconteceu isso com vc?
GOSTEI 0
Kotho
17/05/2005
Cara... fala ae o que tava errado...
Você ainda não desistiu de usar Sockets??? hehe... brincadeira...
Esse erro já aconteceu comigo sim... É um erro que dá na aplicação servidora, só que o Server não consegue repassar para o Client...
Um detalhe muito importante em aplicações n-tier, é sempre verificar se não ficou algum componente conectado... isso pode causar erro...
Se não for nada disso, você terá que debugar o servidor
olha esse post [url]http://forum.clubedelphi.net/viewtopic.php?t=62922[/url], só que no seu caso, você terá que abrir o Delphi 2 vezes, conectar com o Server (manualmente), dai começar a debugar (o server), depois tentar selecionar o DataSetProvider...
Você ainda não desistiu de usar Sockets??? hehe... brincadeira...
Esse erro já aconteceu comigo sim... É um erro que dá na aplicação servidora, só que o Server não consegue repassar para o Client...
Um detalhe muito importante em aplicações n-tier, é sempre verificar se não ficou algum componente conectado... isso pode causar erro...
Se não for nada disso, você terá que debugar o servidor
olha esse post [url]http://forum.clubedelphi.net/viewtopic.php?t=62922[/url], só que no seu caso, você terá que abrir o Delphi 2 vezes, conectar com o Server (manualmente), dai começar a debugar (o server), depois tentar selecionar o DataSetProvider...
GOSTEI 0
Tchelllo
17/05/2005
Kotho, descobri o porque do erro...
estava seguindo o demo SharedConnection do delphi, e no RDM principal ele usa um TSession, (não sei se vc chegou a abrir esse demo)...e na propriedade Session da IBaseRDM, ele define o tipo como WideString para pegar o nome do componente. E eu, no embalo, também programei para pegar o nome do SQLConnection e não o Integer como vc tinha me dito, daí o erro ´Catastrophic failure´ no momento da conexão.
E sobre a prop. ChildName, não sei o porque que deu certo agora...pois o q fiz foi refazer o servidor do zero, criei os TDM´s (principal e secundários)...criei e implementei suas propriedades, depois inseri no catálogo COM+ a dll, conectei o client e quando cliquei sobre a prop. ChildName, lá estava o tdmClientes!!.
Bom...felizmente consegui resolver, e espero que outras pessoas com as mesmas dúvidas consigam também, e concerteza esse tópico irá ajudar bastante!.
Muito obrigado pela super atenção e ajuda Kotho. valeu mesmo!!!
Abraços
estava seguindo o demo SharedConnection do delphi, e no RDM principal ele usa um TSession, (não sei se vc chegou a abrir esse demo)...e na propriedade Session da IBaseRDM, ele define o tipo como WideString para pegar o nome do componente. E eu, no embalo, também programei para pegar o nome do SQLConnection e não o Integer como vc tinha me dito, daí o erro ´Catastrophic failure´ no momento da conexão.
E sobre a prop. ChildName, não sei o porque que deu certo agora...pois o q fiz foi refazer o servidor do zero, criei os TDM´s (principal e secundários)...criei e implementei suas propriedades, depois inseri no catálogo COM+ a dll, conectei o client e quando cliquei sobre a prop. ChildName, lá estava o tdmClientes!!.
Bom...felizmente consegui resolver, e espero que outras pessoas com as mesmas dúvidas consigam também, e concerteza esse tópico irá ajudar bastante!.
Muito obrigado pela super atenção e ajuda Kotho. valeu mesmo!!!
Abraços
GOSTEI 0
Seu_madruga
17/05/2005
Pessoal, aproveitando o tópico de vcs, que é muito interessante por sinal, porém não entendi quase nada. A idéia que eu quero é mais ou menos a de vcs, não sei ao certo.
Bom, na minha aplicação Servidora, tenho um RemoteDataModule e tbém um DataModule, pois no Servidor de Aplicação preciso acessar o banco de dados para poder cadastrar alguns registros. Bom, não sei o porque mas o RemoteDataModule não é enxergado no servidor, acho que porque ele sendo um RemotoDataModule, só é enxergado remotamente certo? E tbém o RemoteDAtaModule não se comunica com o DetaModule tbém. O que eu queria é, já que o RemoteDataModule não é enxergado na aplciação servidora, coloquei um DataModule nele, e como o SQLConnection está no RemoteDataModule, para conectar ao BD no DataModule, precisei colocar outro SQLconection identico no nele. A Pergunta é:
Realmente o remoteDataModule é incomunicável na aplicação local? Ele só pode ser acesado remotamente?
Bom, na minha aplicação Servidora, tenho um RemoteDataModule e tbém um DataModule, pois no Servidor de Aplicação preciso acessar o banco de dados para poder cadastrar alguns registros. Bom, não sei o porque mas o RemoteDataModule não é enxergado no servidor, acho que porque ele sendo um RemotoDataModule, só é enxergado remotamente certo? E tbém o RemoteDAtaModule não se comunica com o DetaModule tbém. O que eu queria é, já que o RemoteDataModule não é enxergado na aplciação servidora, coloquei um DataModule nele, e como o SQLConnection está no RemoteDataModule, para conectar ao BD no DataModule, precisei colocar outro SQLconection identico no nele. A Pergunta é:
Realmente o remoteDataModule é incomunicável na aplicação local? Ele só pode ser acesado remotamente?
GOSTEI 0
Tchelllo
17/05/2005
Seu_madruga, faça o seguinte:
Coloque o SQLConnection no DataModule comum do seu servidor e não no RemoteDataModule.
No Create do seu RemoteDataModule, crie o DataModule comum e faça um loop aos seus SQLDataSets do RemoteDataModule, conforme o código abaixo:
Isso faz com que seus SQLDataSets usem o SQLConnection do DataModule comum.
Esse código no create do RemoteDataModule não é necessário, mas é bom implementá-lo pois já tive problemas da propriedade SQLConnection ser perdida nos SQLDataSets no momento da execução da aplicação.
Também há outras formas de acessar o RemoteDataModule através de TSharedConnection, mas fazendo dessa forma acima, funciona.
Coloque o SQLConnection no DataModule comum do seu servidor e não no RemoteDataModule.
No Create do seu RemoteDataModule, crie o DataModule comum e faça um loop aos seus SQLDataSets do RemoteDataModule, conforme o código abaixo:
procedure TSeuRemoteDataModule.RemoteDataModuleCreate(Sender: TObject); var i: word; begin if DataModule = nil then DataModule := TDataModule.Create(DataModule); for i := 0 to ComponentCount - 1 do if Components[i] is TSQLDataSet then if (Components[i] as TSQLDataSet).Tag = 0 then (Components[i] as TSQLDataSet).SQLConnection := DataModule.SQLConnection; end;
Isso faz com que seus SQLDataSets usem o SQLConnection do DataModule comum.
Esse código no create do RemoteDataModule não é necessário, mas é bom implementá-lo pois já tive problemas da propriedade SQLConnection ser perdida nos SQLDataSets no momento da execução da aplicação.
Também há outras formas de acessar o RemoteDataModule através de TSharedConnection, mas fazendo dessa forma acima, funciona.
GOSTEI 0