|
@@ -29,6 +29,7 @@ function ScriptAllTriggers(dbIndex: Integer; var List: TStringList): Boolean;
|
|
|
// Scripts all non-primary key indexes for a database
|
|
|
function ScriptAllSecIndices(dbIndex: Integer; var List: TStringList): Boolean;
|
|
|
// Scripts all constraints (e.g. foreign key constraints) for tables in a database
|
|
|
+// For now, seems to only cover foreign keys. Todo: verify/confirm
|
|
|
function ScriptAllConstraints(dbIndex: Integer; var List: TStringList): Boolean;
|
|
|
function ScriptObjectPermission(dbIndex: Integer; ObjName, UserName: string; var ObjType: Integer;
|
|
|
List: TStrings; NewUser: string = ''): Boolean;
|
|
@@ -45,6 +46,13 @@ implementation
|
|
|
|
|
|
uses SysTables, Main;
|
|
|
|
|
|
+// Tries to guess if a constraint name is system-generated.
|
|
|
+// todo: find a way to search the system tables and make sure.
|
|
|
+function SystemGeneratedConstraint(ConstraintName: string): boolean;
|
|
|
+begin
|
|
|
+ result:=(pos('INTEG_',uppercase(Trim(ConstraintName)))=1);
|
|
|
+end;
|
|
|
+
|
|
|
(******************** Script Roles ***********************)
|
|
|
|
|
|
function ScriptAllRoles(dbIndex: Integer; var List: TStringList): Boolean;
|
|
@@ -169,7 +177,7 @@ end;
|
|
|
procedure ScriptTableAsCreate(dbIndex: Integer; ATableName: string; ScriptList: TStringList);
|
|
|
var
|
|
|
i: Integer;
|
|
|
- PKeyName: string;
|
|
|
+ PKeyIndexName: string;
|
|
|
PKFieldsList: TStringList;
|
|
|
FieldLine: string;
|
|
|
Skipped: Boolean;
|
|
@@ -251,11 +259,16 @@ begin
|
|
|
|
|
|
// Primary Keys
|
|
|
PKFieldsList:= TStringList.Create;
|
|
|
- PKeyName:= fmMain.GetPrimaryKeyIndexName(dbIndex, ATableName, ConstraintName);
|
|
|
- if PKeyName <> '' then
|
|
|
+ PKeyIndexName:= fmMain.GetPrimaryKeyIndexName(dbIndex, ATableName, ConstraintName);
|
|
|
+ if PKeyIndexName <> '' then
|
|
|
begin
|
|
|
- fmMain.GetConstraintFields(ATableName, PKeyName, PKFieldsList);
|
|
|
- FieldLine:= 'constraint ' + PKeyName + ' primary key (';
|
|
|
+ fmMain.GetConstraintFields(ATableName, PKeyIndexName, PKFieldsList);
|
|
|
+ // Follow isql -x (not FlameRobin) by omitting system-generated
|
|
|
+ // constraint names and let the system generate its own names
|
|
|
+ if SystemGeneratedConstraint(ConstraintName) then
|
|
|
+ FieldLine:= ' primary key ('
|
|
|
+ else // User-specified, so explicilty mention constraint name
|
|
|
+ FieldLine:= 'constraint ' + ConstraintName + ' primary key (';
|
|
|
for i:= 0 to PKFieldsList.Count - 1 do
|
|
|
FieldLine:= FieldLine + PKFieldsList[i] + ', ';
|
|
|
if PKFieldsList.Count > 0 then
|
|
@@ -469,16 +482,38 @@ var
|
|
|
OtherFieldName, OtherTableName, DeleteRule, UpdateRule: string;
|
|
|
var List: TStringList);
|
|
|
const
|
|
|
+ { isql -x outputs DDL like this here:
|
|
|
+ ALTER TABLE DEPARTMENT ADD FOREIGN KEY (MNGR_NO) REFERENCES EMPLOYEE (EMP_NO);
|
|
|
+ i.e. does not mention constraint name.
|
|
|
+ This avoids name conflicts with autogenerated constraint names (which
|
|
|
+ FlameRobin also suffers from)
|
|
|
+ We're going to try follow this and find out what is a system-generated
|
|
|
+ constraint name and what is user-generated so we don't lose information
|
|
|
+ }
|
|
|
Template= 'alter table %s' +
|
|
|
' add constraint %s' +
|
|
|
' foreign key (%s)'+
|
|
|
' references %s' +
|
|
|
' (%s)';
|
|
|
+ TemplateNoName= 'alter table %s' +
|
|
|
+ ' add foreign key (%s)'+
|
|
|
+ ' references %s' +
|
|
|
+ ' (%s)';
|
|
|
var
|
|
|
Line: string;
|
|
|
begin
|
|
|
- Line:= format(Template,[TableName,ConstraintName,CurrentFieldName,
|
|
|
- OtherTableName, OtherFieldName]);
|
|
|
+ if SystemGeneratedConstraint(ConstraintName) then
|
|
|
+ begin
|
|
|
+ // If system-generated, don't specify constraint name
|
|
|
+ Line:= format(TemplateNoName,[TableName,CurrentFieldName,
|
|
|
+ OtherTableName, OtherFieldName]);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ // Do spell out constraint name
|
|
|
+ Line:= format(Template,[TableName,ConstraintName,CurrentFieldName,
|
|
|
+ OtherTableName, OtherFieldName]);
|
|
|
+ end;
|
|
|
if UpdateRule <> 'RESTRICT' then
|
|
|
Line:= Line + ' on update ' + UpdateRule;
|
|
|
if DeleteRule <> 'RESTRICT' then
|