Configurar os parâmetro na conexão DataBase Arquivo Ini DbExpress

Quem é que nunca precisou , nunca utilizou um Arquivo Ini para carregar os parâmetros de uma conexão no DbExpress . Tudo muito bonito e prático , sem ter que recompilar a aplicação , só alterando o database no Arquivo Ini . Mas não se pode falar de parâmetros de conexão do DbExpress sem entender as propriedades LoadParamsOnConnect , DriveName  , connectionName e os métodos Params.LoadFromFile e LoadParamsFromIniFile … Existe uma mágica por trás disso , e na maioria das vezes fazemos sem entender ou não querermos entender o que esta passando , bem ao estilo : ” já que deu certo é assim que eu vou fazer “. E vamos “simbora” para o mundo dos sem “Tempo” . Mas agora é a hora de mudar isto e evitar dores de cabeça no futuro . 

No delphi  crie novo projeto e adicione ao Form um Componente TButton. todos os exemplo abaixo poderão estar sendo programados no evento Onclick .

Declare na Uses da secção Interface ou implementation os namespaces  DB, SqlExpr,dbxfirebird; Pois esteremos instanciando e configurando um objeto sqlconexao (tSqlConnection) em rumTime e precisaremos dessas unidades .

 Obs) Aqui eu estarei utilizando o Delphi2010 .Para uma versão anterior do Delphi2010 a diferença esta no Nome do Driver e da respectiva Unidade que o Driver foi definido . Pode-se fazer todos os Teste escolhendo o DiverName Interbase (Nativo do Delphi) e definindo na Uses a Unidade DBXpress no lugar do dbxfirebird

 Vamos começar com a propriedade LoadParamsOnConnect . Esta propriedade esta no Objecto inspector , e tem um impacto importante neste processo. O Padrão desta propriedade é False , mas quando cetada para True , o SqnConnection carrega para a propriedade params o Driver que esta definido na propriedade ConnectionName . Para isto este Driver deve existir no Arquivo dbxconnections.ini . Veja o exemplo abaixo

 1)Exemplo com a Propriedade LoadParamsOnConnect cetada em True 

var
   sqlConexao:TSQLConnection;
 begin
   sqlConexao:=TSQLConnection.Create(nil);
     try
       sqlconexao.Close;
       sqlconexao.ConnectionName:='EMPLOYEE_2_1.FDB';
       sqlconexao.DriverName:='FIREBIRD';
       sqlconexao.LoadParamsOnConnect:=true;
       sqlconexao.LoginPrompt:=false;
       sqlconexao.Open;
       showmessage(sqlconexao.Params.Text); //faça o Exemplo
    finally
       sqlConexao.Free;
    end;
end;

ps)no meu caso particular eu tenho um Driver de Nome [EMPLOYEE_2_1.FDB] no Arquivo  dbxconnections.ini

Perceba que o SqlConexao , procurou no Arquivo DBXCONNECTIOS.INI  a definição do driver EMPLOYEE_2_1.FDB  e carregou na propriedade params do SqlConexao . Alterando agora , esta propriedade para False , será nossa a responsabilidade de passar um Arquivo Ini Válido , para isto iremos carregar este Arquivo ini para a propriedade params do SqlConexao . Para fazer isto temos os métodos Params.LoadFromFile ou LoadParamsFromIniFile . Há uma diferença sutil e significativa entre eles .  No diretorio do exe da aplicação defina um Arquivo Ini com as seguintes configuração  . Salve este Arquivo com o Nome de Config.ini . Veja que este Driver tem um Nome , que no caso é [EXEMPLO.FDB] . “Guarde este nome pois iremos precisar dele”

 


[EXEMPLO.FDB]
 drivername=FIREBIRD
blobsize=-1
commitretain=False
Database=Coloque aqui um diretorio válido
localecode=0000
password=masterkey
rolename=RoleName
sqldialect=3
isolationlevel=ReadCommitted
user_name=sysdba
waitonlocks=True
trim char=False

 Definido oArquivo Config.ini vamos as diferenças entre os métodos 

2)Utilizando o Params.LoadFromFile


var
  sqlConexao:TSQLConnection;
begin
  sqlConexao:=TSQLConnection.Create(nil);
    try
      sqlconexao.Close;
      sqlconexao.ConnectionName:='Qualquer_Nome';//não pode deixar em branco
      sqlconexao.DriverName:='FIREBIRD';
      sqlconexao.LoadParamsOnConnect:=False;
      sqlconexao.Params.LoadFromFile('Config.ini'); //Arquivo Ini
      sqlconexao.LoginPrompt:=false;
      sqlconexao.Open;
      showmessage(sqlconexao.Params.Text);
    finally
      sqlConexao.Free;
    end;
end;

 3)Utilizando o LoadParamsFromIniFile(‘config.ini’);

var
 sqlConexao:TSQLConnection;
begin
 sqlConexao:=TSQLConnection.Create(nil);
   try
     sqlconexao.Close;
     sqlconexao.ConnectionName:='Exemplo.FDB'; //Nome do Driver válido ***
     sqlconexao.DriverName:='FIREBIRD';
     sqlconexao.LoadParamsOnConnect:=False;
     sqlconexao.LoadParamsFromIniFile('config.ini');
     sqlconexao.LoginPrompt:=false;
     sqlconexao.Open;
     showmessage(sqlconexao.Params.Text);
   finally
      sqlConexao.Free;
   end;
end;

 

 perceba que a diferença é que o método LoadParamsFromIniFile so carrega para o Params se o Nome do Driver , que no nosso caso é [EXEMPLO.FDB] , for válido , Isto é , se existir o Alias [EXEMPLO.FDB]  no Arquivo Config.Ini . Mas atenção , além desse quesito de “segurança” , existe ainda uma caracteristica mais importante neste método , que é a possibilidade de carregar para o params um Driver especifico . Vc pode ter no Arquivo Config.ini vários drivers criados  definidos por vc , e em tempo de execução , escolher qual o driver que vc quer se conectar , so alterando o valor do sqlconexao.ConnectionName. Recapitulando : Assim como no Dbxconnections.ini tem vários drivers definidos , podemos ter também no config.ini varios drivers e escolher qual deles acessar com a propriedade  sqlconexao.ConnectionName e carregando com o método LoadParamsFromIniFile .

Vamos agora entender a propriedade DriveName do SqlConnection . A principio é o nome do Driver que estamos utilizando , porém introduz no params algumas propriedades característica do Driver

Mas internamente qnd se atribui um nome de um Driver para esta propriedade , o delphi no método procedure TSQLConnection.SetDriverName(Value: string);  faz uma série de operações  , atribuições , comparações ,  de modo que ele “recria” o Params do Sqlconnection .

Agora PENSE e tente escolher qual das duas situações é mais indicado

var
 sqlConexao:TSQLConnection;
begin
 sqlConexao:=TSQLConnection.Create(nil);
   try
     sqlconexao.Close;
     sqlconexao.ConnectionName:='Exemplo.FDB';
     sqlconexao.LoadParamsOnConnect:=False;
     sqlconexao.DriverName:='FIREBIRD';//Antes de carregar o Params
     sqlconexao.LoadParamsFromIniFile('config.ini');
     sqlconexao.LoginPrompt:=false;
     sqlconexao.Open;
     showmessage(sqlconexao.Params.Text);
   finally
      sqlConexao.Free;
   end;
end;

e/ou

var
 sqlConexao:TSQLConnection;
begin
 sqlConexao:=TSQLConnection.Create(nil);
   try
     sqlconexao.Close;
     sqlconexao.ConnectionName:='Exemplo.FDB';
     sqlconexao.LoadParamsOnConnect:=False;
     sqlconexao.LoadParamsFromIniFile('config.ini');
     sqlconexao.DriverName:='FIREBIRD';//Depois de carregar o Params
     sqlconexao.LoginPrompt:=false;
     sqlconexao.Open;
     showmessage(sqlconexao.Params.Text);
   finally
     sqlConexao.Free;
   end;
end;

Ao fazermos Sqlconexao.DriverName:=’FIREBIRD’ após termos carregado o params por um dos métodos anteriores (LoadParamsFromIniFile  , params.LoadFromFile) , estaremos recriando o params e com isto algumas definições serão sobre escritas . Por isto Sugerimos que a atribuição do Nome do Driver Ocorra antes de carregar os parâmetros com o Arquivo Ini , conforme estamos fazendo desde o inicio

Consideraçoes finais:

  • A propriedade LoadParamsOnConnect em true o Driver carregado será do Arquivo dbxconnections       
  • A propriedade LoadParamsOnConnect em False o Driver carregado será definido por nos e carregado por um dos métodos  (LoadParamsFromIniFile  e/ou params.LoadFromFile)
  • A diferença além da segurança entre o método LoadParamsFromIniFile do params.LoadFromFile é que o primeiro temos conduções de escolher qual o Driver que queremos acessar , basta definir corretamente a propriedade connectionName
  • Por último vimos que o Nome do driver deve vir antes de carregar o params do sqnconection

Com isto terminamos este artigo ,  Lembrando que qualquer dúvida , opinião , manifestação estaremos de prontidão e aptos para receber qualquer tipo de crítica .espero ter sido útil agradeço a paciência , meu muito obrigado e atê a próxima .

Sobre marcosalles

Delphiano de Coração Desenvolvo FreeLancer e presto Consultoria Orientação Online DataSnap DbX ClientDataSet , POO , Padrões de Projeto e dúvidas de Delphi em Geral
Esse post foi publicado em Dicas e marcado , , , , , , , . Guardar link permanente.

27 respostas para Configurar os parâmetro na conexão DataBase Arquivo Ini DbExpress

  1. Fernando Filho disse:

    Cara, parabéns pelo post. foi a melhor explicação para conectar com dbexpress no delphi 2010. vinha apanhando ,esse detalhe do LoadParamsOnConnect foi fundamental. parabéns!!

  2. marcosalles disse:

    Olá Fernando tudo bem . Obrigado pela gentileza do feedback , fico feliz em ter lhe sido útil

  3. Rosimario disse:

    Cara melhor tuto que eu ja vim show de bola, cara gostaria de saber no caso em que estou me conectando com zeos e mysql com fazer esta confuguração, se puder me ajudar agradeço muito

    • marcosalles disse:

      Ola Rosimario, quando conheci o DbEXpress no Delphi, investi todas as minhas fichas nele e não me arrempendi pois tem driver ate para o AZURE (atualissimo) e DataSnap . A evolução continua e cresecente do Dbexpress, me fez antenar cada vez mais para o seu aprendizado , não restando-me escolha em testar outras tecnologias de acesso. Sei que o Dbexpress tem algumas difiuldades com o mysql e o Zeos surgiu como alternativa , mas eu não instalei e nen baixei a biblioteca do Zeos. Me disponibilizo a prestar dentro das minhas limitações informaçoes sobre o Dbexpress , mas infelismente nada tenho a acrescentar sobre o Zeos . Muito obrigado e disponha

  4. Sergio Braga disse:

    Olá MarcoSalles! De fato, parabéns não apenas pela didática e conhecimento mas, também pela maneira como direcionou o raciocínio e lógica do assunto mostrado. Mto bom, mesmo. Gostaria de aproveitar para perguntar-lhe o seguinte:
    É possível, antes de Applcation.run, capturar o path da instalaçao feita pelo cliente e passar para o parâmetro do Database do connection.ini ou exemplo.ini.
    É que gostaria de evitar que o cliente tivesse liberdade de instalar livremente o aplicativo e não precisasse configurar (ainda que fosse em um formulario de connection.database) os parâmetros em exemplo.ini

    Muito obrigado.

    Sergio Braga

    • marcosalles disse:

      Obrigado Sergio Braga a parte que me toca . Pois bem , quando vc se refere a path da aplicação vc esta se referindo ao caminho do executável certo ? Então a partir do delphi 2007 temos a variável
      gsAppPath ( uses SWSystem delphi 2007 ,2009 , 2010 e Uses IWSystem delphiXe) . Para Alterar o DataBase do Arquivo Config.Ini que será posteriormente carregado pelo metodos LoadFromFile /ou LoadParamsFromIniFile com a propriedade LoadParamsOnConnect cetada em False , deveremos ler deste Arquivo ( Config.Ini ) esta propriedade . Para isto o delphi disponibiliza a classe TIniFile definida na uses IniFiles com propriedades e métodos (ReadString e WriteString) para estas e outras finalidades. A única ressalva que eu faço (pelo que eu entendi da sua dúvida inicial ) vc esta querendo colocar no dpr da Aplicação algo que verificasse e/ou modificasse o Valor do Database . Pois bem , não se deve dar mais responsabilidade a esta classe PROGRAM daquilo que ela foi inicialmete projetada . O que se faz e o que se recomenda em POO é criar uma classe especifica com esta tarefa. Tipo mais ou menos assim

      begin
        Application.Initialize;
        Application.MainFormOnTaskbar := True;
           if TConfigDefault.Default then
                begin
                   Application.CreateForm(TForm7, Form7);
                   Application.Run;
             end;
      

      Esta classe TConfigDefault é uma classe que tem um método Default com a responsabilidade de cetar o Valor do dataBase do Arquivo Config.Ini para o Valor definido por vc e caso de erro abortar a execução do programa ou comunicar através de mensagems possiveis error ..

      Espeto ter entendido a sua dúvida , muito obrigado pelo feedback e caso vc tenha dificuldade em criar esta classe TConfigDefault eu tenho um exemplo desta classe pronta e posso estar lhe enviando
      Não o faço aqui por motivo de espaço . att…

  5. Danilo disse:

    Ótimo artigo Marco Salles, mas estou com uma duvida, como faria pra encriptar a senha de acesso ao bando e se possivel encriptar tbm o localhost para que o user não tenha acesso. Vou explicar, é que hospedo os bancos de alguns de meus sistemas em um serviço de hospedagem, por conta disso eu deixo essas infos estaticas para que o user nao tenha acesso à essas infos (ja q se ele tiver a senha ele poderia acessar pelo painel de controle, tendo em vista que é a mesma senha, ao menos no uolhost é assim), estou tentando implementar uma criptografia ao menos para a senha. Vi que no FrameWork da Aquasoft eles tem essa funcionalidade, mas ainda nao consegui compreender para implementar no meu. valew pelo artigo.

    • marcosalles disse:

      Boa tarde Danilo , tudo bem? Então . antes de mais nada agradeço o seu apoio e seu incentivo .Sobre sua dúvida não é dificil conseguir a criptografia
      Supondo que vc esteja no seguinte com a propriedade LoadParamsOnConnect cetada em False , e ao carregar as propriedades vc faz as alterações que julgar conveniente utilizando a intrução

      SQLConnection1.Params.Values[‘Database’] := TClasseDescriptografa (SQLConnection1.Params.Values[‘Database’]);

      Esta classe TClasseDescriptografa vc vai ter que desenvolver , ou procurar na net algo pronto … Mas a função dela é transformar o valor criptografado em um caminho um diretório válido

      ps) Utilize a instrução entes de abrir a conexão

      Resta para finalizar ao meu ver tres observações .
      Nesta estrutura vc perde o poder de escrever diretamente no arquivo Ini a não ser que vc escreva de modo criptografado , o que acho impossivel ou no minimo muito dificil
      Toda vez que for escrever no Arquivo ini vc tem que faze-lo utilizando a classe TClasseEncripografa , para que se possa descriptografa-lo depois
      Vc pode fazer este processo para todas as outras variáveis mencionadas por vc como foi comentado sobre a senha
      Tb há de se lembrar que muitas destas propriedades e paâmetros podem vir previamente carregadas junto no executável , sem ter que estar presentes no Ini
      porém pode ser que com a engenharia reversa esses valores possam ser encontrados e acessados
      Espero que vc tenha entendido e que eu possa ter sido claro. Se tiver alguma dúvida na implementação destas idéias ou não concorde ou tenha outro tipo de racicíneo esteja a vontade para opinir
      []sds

      • Danilo disse:

        Boa tarde Marco, muito válido seu comentário, mas sabe o que eu fiz, usei sua dica 2) Utilizando o Params.LoadFromFile normalmente, mas criei uma pequena aplicação que encripta todo o arquivo (estou usando um arquivo xml), essa pequena aplicação fica a nivel de software house ou com o Administrador da empresa, assim os users não tem acesso ao conteudo do arquivo. O que eu fiz… antes de conectar eu chamo uma função que Decripta o arquivo xml.. e após a conexão no Finally ele Encripta novamente… funcionou legal.. agora para alterar algum parâmetro tem q usar a tal aplicaçãozinha “administrativa”, até achei interessante que podemos incluir nessa aplicação administradora outras configurações que ficam por conta da software house ou do Administrador do sistema… ficou ótimo… vlw

  6. Carlos Luner disse:

    Valeu pela dica muito bom

  7. MarquimParambu disse:

    Aonde eu escrevo estas linhas

  8. Pingback: Definir em RumTime ou passar como parâmetro o Caminho do Banco em DataSnap / DbxReader / DBX4 | Marco Salles

  9. Leonardo disse:

    Tentei por alto adaptar do Cliente para o Servidor de DataSnap porem da o erro: “Item not found” e “argument out of range”

    meu Config.ini esta assim:

    [Exemplo.DataSnap]
    DriverUnit=Data.DBXDataSnap
    DriverAssemblyLoader=Borland.Data.TDBXClientDriverLoader,Borland.Data.DbxClientDriver,Versi

    on=19.0.0.0,Culture=neutral,PublicKeyToken=91d62ebb5b0d1b1b
    Port=211
    HostName=127.0.0.1
    CommunicationProtocol=tcp/ip
    DatasnapContext=datasnap/
    Filters={“ZLibCompression”:{“CompressMoreThan”:”1024″}}

    e meu botao esta assim:

    procedure TForm1.Button1Click(Sender: TObject);
    var
    sqlConexao:TSQLConnection;
    begin
    sqlConexao:=TSQLConnection.Create(nil);
    try
    sqlconexao.Close;
    sqlconexao.ConnectionName:=’Exemplo.DataSnap’;
    sqlconexao.LoadParamsOnConnect:=False;
    sqlconexao.LoadParamsFromIniFile(‘config.ini’);
    sqlconexao.DriverName:=’DataSnap’;//Depois de carregar o Params
    sqlconexao.LoginPrompt:=false;
    sqlconexao.Open;
    showmessage(sqlconexao.Params.Text);
    finally
    sqlConexao.Free;
    end;
    end;

    Aonde estou errando?

    • marcosalles disse:

      Vc tem que declara a Uses Data.SqlExpr, Data.DBXDataSnap ,IndyPeerImpl; para delphixe2

      ps ) Meu Arquivo ini esta assim

      [Exemplo.DataSnap]
      drivername=DATASNAP
      port=211
      communicationprotocol=tcp/ip
      hostname=localhost

      Mas mesmo assim , testei com o seu Arquivo ini

      [Exemplo.DataSnap]
      DriverUnit=Data.DBXDataSnap
      DriverAssemblyLoader=Borland.Data.TDBXClientDriverLoader,Borland.Data.DbxClientDriver,Versi
      on=19.0.0.0,Culture=neutral,PublicKeyToken=91d62ebb5b0d1b1b
      Port=211
      HostName=127.0.0.1
      CommunicationProtocol=tcp/ip
      DatasnapContext=datasnap/
      Filters={“ZLibCompression”:{“CompressMoreThan”:”1024″}}

      e funcionou sem problemas ..

      Não esqueça que o servidor tem que estar RODANDO

      []sds e qq dúvida volte a postar

  10. Leonardo disse:

    Não funcionou ainda, porem em vez de dar os 2 erros mencionados, so da o primeiro “Item not found” e fiz mais um teste, eu adicionei um sqlconnection no form e configurei o driver para datasnap e compilei e ele adicionou mais essas duas “IPPeerClient, Data.DBXCommon”, mas mesmo assim nao funciona!

    • marcosalles disse:

      Entendo … Mas vc testou com o config do modo tradicional do delphi com essas configurações

      [Exemplo.DataSnap]
      DriverUnit=Data.DBXDataSnap
      Port=211
      HostName=127.0.0.1
      CommunicationProtocol=tcp/ip

      refis meus teste com este config e continuou sem erro

      Por gentileza , refaça os teste e nos comunique

      []sds

      • Leonardo disse:

        Sim fiz desse modo tambem, agora outra coisa que ficou mais estranho foi que eu peguei um sqlconnection e deixei ele todo configurado e quando eu testo a conexao dele com o server datasnap dentro do delphi ela conecta ok, ae se eu pegar da um F9 do jeito que ta quando abre o programa sem eu simplesmente executar qualquer comando ele da o erro que desde o inicio eu estou mencionando, so que no meu projeto mesmo que tem o clientmodule esta ok so q a conexao não é dinamica, é fixa. nesse projeto que fiz so pra teste mesmo so deixo o server rodando e criei um projeto em branco e adicionei os codigos conforme o artigo!

      • Leonardo disse:

        So mais uma coisa eu uso delphi XE5!!

  11. Leonardo disse:

    Aleluia, até que enfim consegui resolver… descobri o que era, como vc falou que tinha que adicionar nas Uses , eu fui e adicionei aquelas que vc falou e mesmo assim nao tinha dado certo… porem como no servidor eu adicionei filtros eu percebi que no meu projeto no ClientModule tinha adicionado essa aqui: DBXCompressionFilter. depois que coloquei ela parou de dar o erro, se não tivesse falado a respeito das Uses jamais imaginaria que poderia ser, muito obrigado pelo artigo que foi de muita valia e pela paciência em me ajudar!!!

  12. arturindio disse:

    Olá,

    queria tirar uma duvida, se eu já coloco o componente no DataModule em qual evento eu coloco para carregar o arquivo INI? É possivel carrega pelo INI nome do SGDB e nome da conexão? Uso MySQL?

    Agradeço desde já, tirou muitas duvidas.

      • marcosalles disse:

        Bem , depende muito do sua arquitetura … Já tentou no momento da criação do DataModulo ??? OnCreate ????
        []sds e obg

      • arturindio disse:

        Olá consegui colocando no oncreate, colocando sqlconexao.LoadParamsFromIniFile(‘config.ini’);
        , carrego o driver, nome da conexão, etc. Porém tive que deixar a opção sqlconexao.LoadParamsOnConnect:=False;

      • marcosalles disse:

        Ok …

        sqlconexao.LoadParamsOnConnect:=False conforme sugerido pelo artigo ???

        Olhe as considerações finais

        ◾A propriedade LoadParamsOnConnect em true o Driver carregado será do Arquivo dbxconnections
        ◾A propriedade LoadParamsOnConnect em False o Driver carregado será definido por nos e carregado por um dos métodos (LoadParamsFromIniFile e/ou params.LoadFromFile)

        Se LoadParamsOnConnect em true o Driver já deve ser pre compilado junto ao executável .. OK ???

      • arturindio disse:

        Olá Marco deixe eu explicar direito, minha arquitetura é em multitier com o datasnap. Estou tentando carregar minhas configurações ini utilizando LoadParamsFromIniFile, se eu deixar as propriedades do sqlconexao sem nada e colocar no oncreate do datamodule para carregar via ini, simplesmente ele da aviso e pede as informações, isso com o LoadParamsOnConnect:=False ou True. Se eu colocar no sqlconexao apenas o nome da conexão e deixar LoadParamsOnConnect:=TRUE o arquivo ini é carregado, e não o dbxconnections, se deixar false da erro novamente. Então o que queria era carregar tudo via ini até o nome da conexão.

Deixe um comentário