[patch_done] Firebird 2.1 driver
Moderators: gto, cipto_kh, EgonHugeist, mdaems
[patch_done] Firebird 2.1 driver
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
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.
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
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
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
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
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;
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;
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
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
- mdaems
- Zeos Project Manager
- Posts: 2766
- Joined: 20.09.2005, 15:28
- Location: Brussels, Belgium
- Contact:
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
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
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;
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;