[patch_done] Firebird 2.1 driver

Code samples and contributions from users for ZeosLib's DBOs of version 6.x

Moderators: gto, cipto_kh, EgonHugeist, mdaems

seawolf
Zeos Dev Team *
Zeos Dev Team *
Posts: 385
Joined: 04.06.2008, 19:50
Contact:

[patch_done] Firebird 2.1 driver

Post by seawolf »

Starting from version 2.1, Firebird deprecate function isc_interprete to fb_interpret (which is claimed to be more reliable)

In order to use that driver correctly it necessary to do some changes:

Unit ZDbcInterbase6;

TZInterbase6Driver = class(TZAbstractDriver)
private
FInterbase6PlainDriver: IZInterbase6PlainDriver;
FInterbase5PlainDriver: IZInterbase5PlainDriver;
FFirebird10PlainDriver: IZFirebird10PlainDriver;
FFirebird15PlainDriver: IZFirebird15PlainDriver;
FFirebird20PlainDriver: IZFirebird20PlainDriver;
FFirebird21PlainDriver: IZFirebird21PlainDriver;
// embedded drivers
FFirebirdD15PlainDriver: IZFirebird15PlainDriver;
FFirebirdD20PlainDriver: IZFirebird20PlainDriver;
FFirebirdD21PlainDriver: IZFirebird21PlainDriver;

constructor TZInterbase6Driver.Create;
begin
FInterbase6PlainDriver := TZInterbase6PlainDriver.Create;
FInterbase5PlainDriver := TZInterbase5PlainDriver.Create;
FFirebird10PlainDriver := TZFirebird10PlainDriver.Create;
FFirebird15PlainDriver := TZFirebird15PlainDriver.Create;
FFirebird20PlainDriver := TZFirebird20PlainDriver.Create;
FFirebird21PlainDriver := TZFirebird21PlainDriver.Create;

// embedded drivers
FFirebirdD15PlainDriver := TZFirebirdD15PlainDriver.Create;
FFirebirdD20PlainDriver := TZFirebirdD20PlainDriver.Create;
FFirebirdD21PlainDriver := TZFirebirdD21PlainDriver.Create;
end;

function TZInterbase6Driver.GetPlainDriver(
const Url: string): IZInterbasePlainDriver;
var
Protocol: string;
begin
Protocol := ResolveConnectionProtocol(Url, GetSupportedProtocols);

if Protocol = FInterbase5PlainDriver.GetProtocol then
Result := FInterbase5PlainDriver
else if Protocol = FInterbase6PlainDriver.GetProtocol then
Result := FInterbase6PlainDriver
else if Protocol = FFirebird10PlainDriver.GetProtocol then
Result := FFirebird10PlainDriver
else if Protocol = FFirebird15PlainDriver.GetProtocol then
Result := FFirebird15PlainDriver
else if Protocol = FFirebird20PlainDriver.GetProtocol then
Result := FFirebird20PlainDriver
else if Protocol = FFirebird21PlainDriver.GetProtocol then
Result := FFirebird21PlainDriver
// embedded drivers
else if Protocol = FFirebirdD15PlainDriver.GetProtocol then
Result := FFirebirdD15PlainDriver
else if Protocol = FFirebirdD20PlainDriver.GetProtocol then
Result := FFirebirdD20PlainDriver
else if Protocol = FFirebirdD21PlainDriver.GetProtocol then
Result := FFirebirdD21PlainDriver

// Generic driver
else Result := FInterbase6PlainDriver;
Result.Initialize;
end;

function TZInterbase6Driver.GetSupportedProtocols: TStringDynArray;
begin
SetLength(Result, 9);
Result[0] := 'interbase-5';
Result[1] := 'interbase-6';
Result[2] := 'firebird-1.0';
Result[3] := 'firebird-1.5';
Result[4] := 'firebird-2.0';
Result[5] := 'firebird-2.1';
// embedded drivers
Result[6] := 'firebirdd-1.5';
Result[7] := 'firebirdd-2.0';
Result[8] := 'firebirdd-2.1';
end;

Inside the attached zip you found 2 files:
ZplainDriver21.pas is the new driver file
ZPlainFirebirdDriver.pas I added the IZFirebird21PlainDriver,IZFirebirdD21PlainDriver classes

Moreover it is necessary add

ZPlainFirebird21 in '..\..\src\plain\ZPlainFirebird21.pas';

on all Zplain.dpk
You do not have the required permissions to view the files attached to this post.
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Thanks Seawolf!

Committed to Testing branch (SVN rev 519).

I'm checking with Michael if we should also add this one to 6.6.X.

Mark
Image
SlavoF
Junior Boarder
Junior Boarder
Posts: 29
Joined: 12.02.2009, 15:31
Location: Nitra, Slovakia
Contact:

Post by SlavoF »

ZEOSLIB_TESTING_REV617.zip
D2009
Firebird 2.1

ZPlainFirebirdDriver.pas:
function TZFirebird21PlainDriver.isc_interprete(buffer: PAnsiChar;
status_vector: PPISC_STATUS): ISC_STATUS;
var
bufsize : integer;
begin
bufsize := 0;
Result := FIREBIRD_API.fb_interpret(buffer, bufsize, status_vector);
end;

Result is always = 0

in project:
ZConnection.Connected is true , also DB file not exists

if take isc_interprete from TZFirebirdBaseDriver:

begin
Inherited;
// bufsize := 0;
// Result := FIREBIRD_API.fb_interpret(buffer, bufsize, status_vector);
end;

all is OK
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Seawolf?

Do you have trouble with this version? My test suite runs with this testing branch version without trouble.

Mark
Image
seawolf
Zeos Dev Team *
Zeos Dev Team *
Posts: 385
Joined: 04.06.2008, 19:50
Contact:

Post by seawolf »

Yes, I have the same problem. I'm currently debugging a test application which should raise an error. Unfortunately fb_interpret does not report any error. If I change this

function TZFirebird21PlainDriver.isc_interprete(buffer: PAnsiChar;
status_vector: PPISC_STATUS): ISC_STATUS;
var
bufsize : integer;
begin
bufsize := 0;
Result := FIREBIRD_API.fb_interpret(buffer, bufsize, status_vector);
end;

to this

function TZFirebird21PlainDriver.isc_interprete(buffer: PAnsiChar;
status_vector: PPISC_STATUS): ISC_STATUS;
begin
Result := FIREBIRD_API.isc_interprete(bufsize, status_vector);
end;

All works fine. Anyway as soon as possible i send you an update to fix that problem
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

So this means there's something wrong with the fb_interprete call or it should be used in an other way?

Mark
Image
seawolf
Zeos Dev Team *
Zeos Dev Team *
Posts: 385
Joined: 04.06.2008, 19:50
Contact:

Post by seawolf »

I've tried with fb 2.1.1 and 2.1.2 but fb_interpret function seems not work as expected. So, for the moment, i suggest you to change that function as yuo can see below. I wrote to the Firebird dev team in order to understand why isc_interprete works as expected and fb_interpret no. As soon as I will have a response I send yo a patch.

function TZFirebird21PlainDriver.isc_interprete(buffer: PAnsiChar;
status_vector: PPISC_STATUS): ISC_STATUS;
//var
//bufsize : integer;
begin
inherited;
//bufsize := 0;
//Result := FIREBIRD_API.fb_interpret(buffer, bufsize, status_vector);
end;
seawolf
Zeos Dev Team *
Zeos Dev Team *
Posts: 385
Joined: 04.06.2008, 19:50
Contact:

Post by seawolf »

Please forget previous post. You have to change

ZdbcInterbase6Utils

procedure CheckInterbase6Error(PlainDriver: IZInterbasePlainDriver;
StatusVector: TARRAY_ISC_STATUS; LoggingCategory: TZLoggingCategory = lcOther;
SQL: string = '');
var
Msg: array[0..1024] of AnsiChar;
PStatusVector: PISC_STATUS;
ErrorMessage, ErrorSqlMessage: string;
ErrorCode: LongInt;
begin
if (StatusVector[0] = 1) and (StatusVector[1] > 0) then
begin
ErrorMessage := '';
PStatusVector := @StatusVector;
PlainDriver.isc_interprete(Msg, @PStatusVector);
// while PlainDriver.isc_interprete(Msg, @PStatusVector) > 0 do
// ErrorMessage := ErrorMessage + ' ' + StrPas(Msg);


ErrorCode := PlainDriver.isc_sqlcode(@StatusVector);
PlainDriver.isc_sql_interprete(ErrorCode, Msg, 1024);
ErrorMessage := StrPas(Msg);
// ErrorSqlMessage := StrPas(Msg);


{$IFDEF INTERBASE_EXTENDED_MESSAGES}
if SQL <> '' then
SQL := Format(' The SQL: %s; ', [SQL]);
{$ENDIF}

if ErrorMessage <> '' then
begin
DriverManager.LogError(LoggingCategory, PlainDriver.GetProtocol,
ErrorMessage, ErrorCode, ErrorSqlMessage + SQL);

{$IFDEF INTERBASE_EXTENDED_MESSAGES}
raise EZSQLException.CreateWithCode(ErrorCode,
Format('SQL Error: %s. Error Code: %d. %s',
[ErrorMessage, ErrorCode, ErrorSqlMessage]) + SQL);
{$ELSE}
raise EZSQLException.CreateWithCode(ErrorCode,
Format('SQL Error: %s. Error Code: %d. %s',
[ErrorMessage, ErrorCode, ErrorSqlMessage]));
{$ENDIF}
end;
end;
end;

isc_interprete returns StatusVector which is parsed by isc_sqlcode and isc_sql_interprete

so Msg is always equal to ErrorSqlMessage because the error message is contained in StatusVector
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Why call
PlainDriver.isc_interprete(Msg, @PStatusVector);
AND
ErrorCode := PlainDriver.isc_sqlcode(@StatusVector); PlainDriver.isc_sql_interprete(ErrorCode, Msg, 1024);
?
When reading API docs you should need only one of them, with the second version prefered when using the dsql interface (as I believe we do)

Mark
Image
SlavoF
Junior Boarder
Junior Boarder
Posts: 29
Joined: 12.02.2009, 15:31
Location: Nitra, Slovakia
Contact:

Post by SlavoF »

Mark, seawolf
Thanks
but I still waiting
changes in ZdbcInterbase6Utils don't help me
by me FB 2.1 work so far better with 2.0 driver
seawolf
Zeos Dev Team *
Zeos Dev Team *
Posts: 385
Joined: 04.06.2008, 19:50
Contact:

Post by seawolf »

Sorry for the mess. Some days ago I wrote to the Firebird-support team and this is the response

Taking a look at this word

Because you passed zero bufsize into fb_interpret. It just did nothing.

function TZFirebird21PlainDriver.isc_interprete(buffer: PAnsiChar;
status_vector: PPISC_STATUS): ISC_STATUS;
var
bufsize : integer;
begin
// bufsize := 0; <--- remove or comment it
Result := FIREBIRD_API.fb_interpret(buffer, bufsize, status_vector);
end;
SlavoF
Junior Boarder
Junior Boarder
Posts: 29
Joined: 12.02.2009, 15:31
Location: Nitra, Slovakia
Contact:

Post by SlavoF »

hmm... :roll:
why not initialized ? then too equals 0 , or not ?
and what is expected to be the value of bufsize ?

result = "Out of memory"
seawolf
Zeos Dev Team *
Zeos Dev Team *
Posts: 385
Joined: 04.06.2008, 19:50
Contact:

Post by seawolf »

First of all is a local variable, but I think it is possible to set it to 255 (but in this case message will be truncated after 255 chars)

Bufsize is the size of the output buffer
SlavoF
Junior Boarder
Junior Boarder
Posts: 29
Joined: 12.02.2009, 15:31
Location: Nitra, Slovakia
Contact:

Post by SlavoF »

yes, now it's works correctly
:thanks:
User avatar
mdaems
Zeos Project Manager
Zeos Project Manager
Posts: 2766
Joined: 20.09.2005, 15:28
Location: Brussels, Belgium
Contact:

Post by mdaems »

Hi,

Seems like setting it to 1024 makes more sense because that's the buffersize definede in CheckInterbase6Error. Or is there some fpc call that can find this buffer input parameter length automatically?

Mark
Image
Post Reply