Can I change the way the values for the primary key are generated?

Hello

I using DataAbstract 10.0.0.1469 for Delphi,
Firebird Database with IBDac driver.

I need to change default behavior for IB_GetNextAutoinc/IB_GetLastAutoinc
I need to make some segmentation for IDKey without to manage start value for each generator.
I want to change curent SQL to some like that:
‘SELECT MyGen_id(%s,1) FROM RDB$Database’
Or I register a new version /call back for IB_GetNextAutoinc.

What do you think is the best way to do this without modifying DataAbstract sources codes?

Thank you

Hi,

Create a your own driver that has TDAEIBDACDriver as ancestor and put it to say, uMyDAIBDACDriver.pas:

TMyDAEIBDACDriver = class(TDAEIBDACDriver)
protected
  function GetConnectionClass: TDAEConnectionClass; override;
end;
...

function TMyDAEIBDACDriver.GetConnectionClass: TDAEConnectionClass;
begin
  result := TMyDAEIBDACConnection;
end;

and connection class based on TDAEIBDACConnection:

TMyDAEIBDACConnection = class(TDAEIBDACConnection, IDAUseGenerators, IDAUseGenerators2)
protected
  function GetNextAutoinc(const GeneratorName: string): integer; {$IFNDEF FPC_SAFECALL_BUG}safecall;{$ENDIF}
  function GetNextAutoinc2(const GeneratorName: string): variant; {$IFNDEF FPC_SAFECALL_BUG}safecall;{$ENDIF}
end;

...

function TMyDAIBBaseConnection.GetNextAutoinc(const GeneratorName: string): integer;
begin
  Result:= MyProc;// your method that get PK
end;

function TMyDAIBBaseConnection.GetNextAutoinc2(
  const GeneratorName: string): variant;
begin
  Result:= MyProc; // your method that get PK
end;

also you need to unregister existing driver and register your own:

function GetDriverObject: IDADriver; stdcall;

implementation
var
  _driver: TDAEDriver = nil;

function GetDriverObject: IDADriver;
begin
  if (_driver = nil) then _driver := TMyDAEIBDACDriver.Create(nil);
  result := _driver;
end;

initialization
  _driver := nil;
  UnregisterDriverProc(uDAIBDACDriver.GetDriverObject); // unregisted existing IBDAC driver
  RegisterDriverProc(GetDriverObject); // replace it
finalization
  UnregisterDriverProc(GetDriverObject);
  FreeOrDisposeOfAndNil(_driver);
end.

finally, you should use uMyDAIBDACDriver.pas instead of uDAIBDACDriver.pas in your server project.
New driver will replace IBDAC so new other changes are required.

1 Like

Thank you very much.
It works like a charm.