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:
{$DEFINE sqlite3}
{.$DEFINE firebird3}
{.$DEFINE sqlite3}
{$DEFINE firebird3}
interface

View File

@ -20,6 +20,7 @@ type
FEventsTable: TZTable;
FResourceTable: TZTable;
FTasksTable: TZTable;
procedure CreateAutoInc_Firebird(ATableName, AIdFieldName: String);
procedure SetConnection(const AValue: TZConnection);
protected
@ -126,8 +127,8 @@ begin
protocol := Lowercase(FConnection.Protocol);
if protocol = 'firebird' then
begin
FIdFieldTypeNameInSQL := 'INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; // This is for Firebird v3
// FIdFieldTypeNameInSQL := 'INTEGER NOT NULL PRIMARY KEY'; // This might work for firebird v2.x
// 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 works for firebird v2.x and v3 when triggers & generators are provided
FBoolFieldTypenameInSQL := 'BOOLEAN';
end else
if protocol = 'postgresql' then
@ -166,6 +167,27 @@ begin
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;
CreateIndex: Boolean = true);
var
@ -249,6 +271,8 @@ begin
'CREATE INDEX ContactsCompany_idx ON Contacts(Company)'
);
end;
if Lowercase(FConnection.Protocol) = 'firebird' then
CreateAutoInc_Firebird('Contacts', 'RecordID');
end else
if ATableName = EventsTableName then begin
FConnection.ExecuteDirect(
@ -292,6 +316,8 @@ begin
'CREATE INDEX EventsEndTime_idx ON Events(EndTime)'
);
end;
if Lowercase(FConnection.Protocol) = 'firebird' then
CreateAutoInc_Firebird('Events', 'RecordID');
end else
if ATableName = ResourceTableName then begin
FConnection.ExecuteDirect(
@ -312,6 +338,8 @@ begin
'UserField8 VARCHAR(100), '+
'UserField9 VARCHAR(100) )'
);
if Lowercase(FConnection.Protocol) = 'firebird' then
CreateAutoInc_Firebird('Resources', 'ResourceID');
end else
if ATableName = TasksTableName then begin
FConnection.ExecuteDirect(
@ -347,6 +375,8 @@ begin
FConnection.ExecuteDirect(
'CREATE INDEX TasksCompletedOn_idx ON Tasks(CompletedOn)'
);
if Lowercase(FConnection.Protocol) = 'firebird' then
CreateAutoInc_Firebird('Tasks', 'RecordID');
end;
end;
end;
@ -463,12 +493,7 @@ end;
autoincrement fields. }
function TVpZeosDatastore.GetNextID(TableName: string): integer;
begin
{
if (FConnection.Protocol = 'firebird') then // Optionally use this for firebird 2.x
Result := random(maxInt)
else
}
Result := -1;
Result := -1;
end;
function TVpZeosDatastore.GetResourceTable : TDataset;