odbc datasource connection at runtime through delphi - delphi

can we create ODBC datasource connection at runtime? If yes then can you plz help regarding how to do it.
Currently I am created the ODBC datasource connection manually through Control Panel--> Administrative Tools --> Datasources.
But i want to create that at runtime when user run application.
thanks for the help.

You can use SQLConfigDataSource (Delphi example).

Yes, you can do it. As #TOndrej points out, you can create a ODBC datasource at runtime. But usually you don't need to. You might just create a Data Connection in runtime without an ODBC datasource.
Something like this, using ADO components to a MS Jet OLE DB ...
if ADOConnection1.connected then ADOConnection1.close;
ADOConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;'+
'Data Source='+filename+';'+
'Persist Security Info=False';
ADOConnection1.LoginPrompt:=false;
ADOQuery1.Connection:=ADOConnection1;
ADOConnection1.Open;
....

Related

How to enable wirecompression on Firebird 3.0

I work with Firebird and Delphi, I want to implement access via internet with wirecompression;
But I am unable to activate it.
I have followed the steps inside this document for the new parameter(one of the few I was able to find)
How to enable WireCompression on Firebird 3.0 using FireDAC
In the tests I use
Windows server 2012 R2
Firebird : Firebird-3.0.4.33054_0_Win32(32 bits)
Also copied to executable folder.
fbclient.dll
zlib1.dll (idem server and client)
created firebird.conf with wirecompression=true.
and I am giving wirecompression=true inside the Firedac of the application.
Why am I unable to activate the P15:CZ compression ?
Sending connection info for the example:
================================
Connection definition parameters
================================
DriverID=FB
Database=miservidor001:C:\sysdat\C100\gestdat03.fdb
User_Name=SYSDBA
PassWord=*****
WireCompression=true
================================
FireDAC info
================================
Tool = RAD Studio 10.2
FireDAC = 16.0.0 (Build 88974)
Platform = Windows 32 bit
Defines = FireDAC_NOLOCALE_META;FireDAC_MONITOR
================================
Client info
================================
Loading driver FB ...
Brand = Firebird
Client version = 300049900
Client DLL name = C:\APPS\WC01\fbclient.dll
================================
Session info
================================
Current catalog =
Current schema =
Server version = WI-V3.0.4.33054 Firebird 3.0
WI-V3.0.4.33054 Firebird 3.0/tcp (WIN-2012LAGO003)/P15:C
WI-V3.0.4.33054 Firebird 3.0/tcp (nucleo)/P15:C'
NOTE: I don't know Delphi nor FireDAC, this answer is based on the general behavior of Firebird and my experience with maintaining its JDBC driver (Jaybird). So it is possible that there is a better answer specifically for FireDAC/Delphi.
Enabling or disabling wire compression is entirely determined by the client, not by the server. This means that configuration of the server is not necessary nor has it any effect, except in cases where the server itself acts as a client, for example with execute statement ... on external datasource.
To be able to use wire compression, you need three things:
fbclient.dll
zlib1.dll (in the same location as fbclient.dll, or on the search path)
A configuration to enable wire compression for the client
Point 3 is likely your problem: I'm not sure if FireDAC has a connection property WireCompression that actually enables wire compression.
I know of two ways to enable wire compression for the client:
Create a firebird.conf in the same directory as the fbclient.dll used by your application. In this configuration file, put the requested configuration options (one per line):
WireCompression = true
# maybe other config lines (eg AuthClient, WireCrypt, etc)
Instead of creating a firebird.conf file, pass the configuration (with linebreaks separating config options) in the isc_dpb_config (int 87) database parameter item.
The value is the same as the content of the firebird.conf file in the previous option. This may run into size issues if the client is using the old database parameter buffer format (where strings are max 255 bytes) and you want to pass (a lot) more config options.
Option 1 is probably the simplest and will work for all frameworks. Option 2 depends on whether or not the framework or driver exposes the database parameter buffer or if it has a connection property that maps to isc_dpb_config.
For example in Java using Jaybird, you can enable compression (only when using native connections) using:
Properties props = new Properties();
props.setProperty("user", "sysdba");
props.setProperty("password", "masterkey");
props.setProperty("config", "WireCompression=true");
try (var connection = DriverManager.getConnection(
"jdbc:firebirdsql:native:localhost:D:/data/db/fb3/fb3testdatabase.fdb", props)) {
FirebirdConnection fbCon = connection.unwrap(FirebirdConnection.class);
FbDatabase fbDatabase = fbCon.getFbDatabase();
System.out.println(fbDatabase.getServerVersion());
} catch (SQLException e) {
e.printStackTrace();
}
This prints out WI-V3.0.4.33054 Firebird 3.0,WI-V3.0.4.33054 Firebird 3.0/tcp (host)/P15:CZ,WI-V3.0.4.33054 Firebird 3.0/tcp (host)/P15:CZ (note this is <server version>,<server protocol info>,<client protocol info>). The Z in P15:CZ means that the connection is zlib compressed (the C that the connection is encrypted).
Here, the config property is an alias for isc_dpb_config.
Mark's answer is the best (and probably the only) source of information about this problem in the entire internet. Good luck finding anything on Delphi, FireDAC or Firebird documentation about what he said.
Based on his answer, here is what you need to use Firebird wire compression with FireDAC:
You need Delphi Rio 10.3.1 (Update 1) or later. Only in this version the config low level parameter (see below) was added to FireDAC.
You must pass WireCompression=true to the low level config connection parameter. This is NOT TFDConnection.Params (high level).
To accomplish this you need to set the IBAdvanced property of TFDPhysFBConnectionDefParams to config=WireCompression=true (yeah! Go figure it!)
Code:
FDConnection1.DriverName := '​FB';
with FDConnection1.Params as TFDPhysFBConnectionDefParams do
begin
Server := '...';
Database := '...';
UserName := '...';
Password := '...';
IBAdvanced := 'config=WireCompression=true';
end;
FDConnection1.Connected := True;
Using a connection definition file:
[FB_Demo]
DriverID=FB
Server=...
Database=...
User_Name=...
Password=...
IBAdvanced=config=WireCompression=true
You need zlib1.dll in the same path of your fbclient.dll. The catch here is that Firebird distribution DOES NOT have the 32-bit version of zlib1.dll in its C:\Program Files\Firebird\Firebird_3_0\WOW64 folder. So:
If your application is 64-bit you are probably fine. Just use both fbclient.dll and zlib1.dll from your C:\Program Files\Firebird\Firebird_3_0 folder.
If your application is 32-bit you have to download the 32-bit version of zlib1.dll from the 32-bit Firebird distribution. Use it together with the fbclient.dll you find in your C:\Program Files\Firebird\Firebird_3_0\WOW64 (which contains 32-bit libraries).
In Firebird 3.0.4 or later you can use the WIRE_COMPRESSED context variable to check if the connection was established as you expected:
SELECT
RDB$GET_CONTEXT('SYSTEM', 'WIRE_COMPRESSED') wire_compressed
FROM
rdb$database
This will return TRUE if the current connection is compressed.

Synapse LDAPSend library requires username = Domain\User

I'm using Synapse LDAPSend.pas library to connect and authenticate in an Active Directory server. The code is pretty simple and direct, but the problem is that the username needs "DomainName\Username" or "Username#DomainName" format to bind command works correctly. Are there anyhow to make it work only with Username specified?
var
ldap: TLDAPsend;
begin
ldap:= TLDAPsend.Create;
try
ldap.TargetHost := '192.168.0.12';
ldap.UserName:= 'AD\Owner'; //here I need to specify only Owner
ldap.Password:= 'Password!';
if ldap.Login then
if ldap.Bind then
begin
//do stuff
ldap.Logout;
end;
finally
ldap.Free;
end;
end;
I was thinking maybe something like "*\Owner", or any other command from Active Directory to make it works? Or maybe a Synapse setting to make it.
If the current user is logged on to the domain there is a variety of options to retrieve the domain name. The easiest way is to read the environment variable USERDOMAIN using the function SysUtils.GetEnvironmentVariable. There are also the Windows API functions NetWkstaUserGetInfo available on Windows NT and better as well as GetUserNameEx introduced with Windows 2000 among a lot of others, which are usually harder to use.
If your version of Delphi does not contain declarations for these API functions please use the Jedi Windows API headers.

If I create a connection pooling in websphere Application server do I need to change anything in Java code?

I am using WAS and DB2 and my Application is coded in Java.
If I create a connection pooling in websphere Application server, then do I need to change anything in Java code? or Websphere will handle all connection pooling concept?
To take advantage of connection pooling provided by WebSphere Application Server, you need to obtain connections from data source. First configure the data source and assign a jndiName to it.
Then you can use resource injection to define a resource reference for it and inject into a Java EE component, for example,
#Resource(lookup = "jdbc/ds1", name = "java:comp/env/jdbc/ds1ref")
DataSource ds1;
or look it up in JNDI, for example,
DataSource ds = InitialContext.doLookup("java:comp/env/jdbc/ds1ref");
Always make sure to close connections that obtain from the data source when you are done with them so they can go back to the pool,
Connection con = ds.getConnection();
try {
...
} finally {
con.close();
}
If your application needs to access any JDBC vendor APIs (not part of the JDBC specification), use the JDBC wrapper pattern (unwrap method). For example,
OracleConnection oraCon = con.unwrap(OracleConnection.class);
Other than that, usage of connection pooling should be pretty much transparent.

Error using TADODataset component with MS Access

I am attempting to replace a InterBase DB with a MS Access DB as a test, I am connect to the MS Access DB using the TADOConnection component successfully; however when I try to connect to a table using the TADODataset, I am able to set the Connection property to the TADOConnection component but when I want to set the CommandText property I receive the following error:
The connectionstring is as follows: Provider=ADsDSOObject;User ID=admin;Encrypt Password=False;Data Source=C:\StudyTime\StudyTime.accdb;Mode=Read;Bind Flags=0;ADSI Flag=-2147483648;
Can someone please assist me?
You are using a wrong provider: ADsDSOObject for ms-access.
Use Provider=Microsoft.Jet.OLEDB.4.0 or Provider=Microsoft.ACE.OLEDB.12.0; instead.
e.g.
MdbFileName := 'C:\StudyTime\StudyTime.accdb';
ADOConnection1.ConnectionString := Format('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;', [MdbFileName]);
ADOConnection1.Open;

How to enable OLEDB resource pooling in a Delphi 7 app

What needs to be done to enable pooling in a Delphi 7 app? My connection string is:
Provider=SQLOLEDB.1;Initial Catalog=%s;Data Source=%s;Password=%s;User ID=%s;OLE Db Services=-1
I can tell that connection pooling is not being achieved by looking at the SQLServer:GeneralStatistics UserConnections performance counter - it fluctuates wildly when my application runs. With connection pooling I'd expect it to achieve a steady state. Also, I see that Logins/sec and Logouts/sec counters are both very high - if connection pooling were used Logouts/sec would be at or near zero.
In searching I found this article on resource pooling:
http://www.ddj.com/database/184416942
It suggests that "If you are working at the OLEDB SDK (or COM) level using ATL, you have to write some more code" (aside from adding OLE Db Services=-1 to the connection string) to get connection pooling:
CDataSource db;
CDBPropSet dbinit(DBPROPSET_DBINIT);
dbinit.AddProperty(DBPROP_AUTH_USERID, "MyName);
dbinit.AddProperty(DBPROP_INIT_DATASOURCE, "MyServer);
dbinit.AddProperty(DBPROP_INIT_CATALOG, "MyDb );
dbinit.AddProperty(DBPROP_INIT_PROMPT, (short)4);
dbinit.AddProperty(DBPROP_INIT_LCID, (long)1033);
dbinit.AddProperty(DBPROP_INIT_OLEDBSERVICES, (long)DBPROPVAL_OS_ENABLEALL);
HRESULT hr = db.OpenWithServiceComponents(_T("sqloledb"), &dbinit);
Unfortunately that code is Greek to me and I'm not sure how to translate that to Delphi (or if its even necessary).
I'm also careful not to change the connection string at all. Any suggestions on what else I might need to do to enable resource pooling?
You need to keep one instance of the connection open at all times...if it drops to zero, then ADO will re-establish the connection to authenticate the user.
You don't mention it, but are you using Delphi's ADO implementation (dbGo for Delphi 7, IIRC) for your data access? If so, are you connecting everything through the same TADOConnection? If so, it should be doing the pooling for your application (meaning that one running copy of your application is using one connection to the DB server).

Resources