TvPlanIt: Improved handling of Firebird AutoInc field in ZEOS datastore.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8258 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2022-04-20 23:01:29 +00:00
parent fb53f95eaf
commit b0badc1cb4
2 changed files with 35 additions and 10 deletions

View File

@ -4,8 +4,8 @@ unit Unit1;
// Activate ONE of the following defines for the database system to be used: // Activate ONE of the following defines for the database system to be used:
{$DEFINE sqlite3} {.$DEFINE sqlite3}
{.$DEFINE firebird3} {$DEFINE firebird3}
interface interface

View File

@ -20,6 +20,7 @@ type
FEventsTable: TZTable; FEventsTable: TZTable;
FResourceTable: TZTable; FResourceTable: TZTable;
FTasksTable: TZTable; FTasksTable: TZTable;
procedure CreateAutoInc_Firebird(ATableName, AIdFieldName: String);
procedure SetConnection(const AValue: TZConnection); procedure SetConnection(const AValue: TZConnection);
protected protected
@ -126,8 +127,8 @@ begin
protocol := Lowercase(FConnection.Protocol); protocol := Lowercase(FConnection.Protocol);
if protocol = 'firebird' then if protocol = 'firebird' then
begin begin
FIdFieldTypeNameInSQL := 'INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; // This is for Firebird v3 // FIdFieldTypeNameInSQL := 'INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; // This can be used in Firebird v3 to replace the trigger and generator
// FIdFieldTypeNameInSQL := 'INTEGER NOT NULL PRIMARY KEY'; // This might work for firebird v2.x FIdFieldTypeNameInSQL := 'INTEGER NOT NULL PRIMARY KEY'; // This works for firebird v2.x and v3 when triggers & generators are provided
FBoolFieldTypenameInSQL := 'BOOLEAN'; FBoolFieldTypenameInSQL := 'BOOLEAN';
end else end else
if protocol = 'postgresql' then if protocol = 'postgresql' then
@ -166,6 +167,27 @@ begin
end; end;
end; end;
{ Create generator and trigger for Firebird in order to autoincrement the values
in field AIdFieldName of table ATableName.
http://firebirdfaq.org/faq29/ }
procedure TVpZeosDatastore.CreateAutoInc_Firebird(ATableName, AIdFieldName: String);
begin
FConnection.ExecuteDirect(Format(
'CREATE GENERATOR gen_%s_id;', [ATableName]
));
FConnection.ExecuteDirect(Format(
'SET GENERATOR gen_%s_id TO 0;', [ATableName]
));
FConnection.ExecuteDirect(Format(
'CREATE TRIGGER %0:s_BI FOR %0:s ' +
'ACTIVE BEFORE INSERT POSITION 0 ' +
'AS ' +
'BEGIN ' +
'if (NEW.%1:s is NULL) then NEW.%1:s = GEN_ID(GEN_%0:s_ID, 1); ' +
'END', [ATableName, AIdFieldName]
));
end;
procedure TVpZeosDatastore.CreateTable(const ATableName: String; procedure TVpZeosDatastore.CreateTable(const ATableName: String;
CreateIndex: Boolean = true); CreateIndex: Boolean = true);
var var
@ -249,6 +271,8 @@ begin
'CREATE INDEX ContactsCompany_idx ON Contacts(Company)' 'CREATE INDEX ContactsCompany_idx ON Contacts(Company)'
); );
end; end;
if Lowercase(FConnection.Protocol) = 'firebird' then
CreateAutoInc_Firebird('Contacts', 'RecordID');
end else end else
if ATableName = EventsTableName then begin if ATableName = EventsTableName then begin
FConnection.ExecuteDirect( FConnection.ExecuteDirect(
@ -292,6 +316,8 @@ begin
'CREATE INDEX EventsEndTime_idx ON Events(EndTime)' 'CREATE INDEX EventsEndTime_idx ON Events(EndTime)'
); );
end; end;
if Lowercase(FConnection.Protocol) = 'firebird' then
CreateAutoInc_Firebird('Events', 'RecordID');
end else end else
if ATableName = ResourceTableName then begin if ATableName = ResourceTableName then begin
FConnection.ExecuteDirect( FConnection.ExecuteDirect(
@ -312,6 +338,8 @@ begin
'UserField8 VARCHAR(100), '+ 'UserField8 VARCHAR(100), '+
'UserField9 VARCHAR(100) )' 'UserField9 VARCHAR(100) )'
); );
if Lowercase(FConnection.Protocol) = 'firebird' then
CreateAutoInc_Firebird('Resources', 'ResourceID');
end else end else
if ATableName = TasksTableName then begin if ATableName = TasksTableName then begin
FConnection.ExecuteDirect( FConnection.ExecuteDirect(
@ -347,6 +375,8 @@ begin
FConnection.ExecuteDirect( FConnection.ExecuteDirect(
'CREATE INDEX TasksCompletedOn_idx ON Tasks(CompletedOn)' 'CREATE INDEX TasksCompletedOn_idx ON Tasks(CompletedOn)'
); );
if Lowercase(FConnection.Protocol) = 'firebird' then
CreateAutoInc_Firebird('Tasks', 'RecordID');
end; end;
end; end;
end; end;
@ -463,12 +493,7 @@ end;
autoincrement fields. } autoincrement fields. }
function TVpZeosDatastore.GetNextID(TableName: string): integer; function TVpZeosDatastore.GetNextID(TableName: string): integer;
begin begin
{ Result := -1;
if (FConnection.Protocol = 'firebird') then // Optionally use this for firebird 2.x
Result := random(maxInt)
else
}
Result := -1;
end; end;
function TVpZeosDatastore.GetResourceTable : TDataset; function TVpZeosDatastore.GetResourceTable : TDataset;