Преглед на файлове

Script/comparison: initial support for domain collation. No support for character set yet.

Reinier Olislagers преди 11 години
родител
ревизия
8888a22347
променени са 4 файла, в които са добавени 53 реда и са изтрити 23 реда
  1. 20 8
      comparison.pas
  2. 5 4
      main.pas
  3. 11 6
      scriptdb.pas
  4. 17 5
      systables.pas

+ 20 - 8
comparison.pas

@@ -308,6 +308,7 @@ var
   SPOwner: string;
   ModuleName, EntryPoint, Params: string;
   Line: string;
+  Collation: string;
   DomainType, DefaultValue: string;
   DomainSize: Integer;
   ATableName, AIndexName: string;
@@ -318,6 +319,8 @@ var
   IsPrimary: Boolean;
   ConstraintName: string;
 begin
+  //todo: if posssible merge this with create object statements generated
+  // in scriptdb code
   InitializeQueryWindow;
   ScriptList:= TStringList.Create;
   FieldsList:= TStringList.Create;
@@ -434,7 +437,8 @@ begin
       if (x = 8) and cxDomains.Checked then // Domains
       for i:= 0 to dbObjectsList[x].Count - 1 do
       begin
-        dmSysTables.GetDomainInfo(fdbIndex, dbObjectsList[x].Strings[i], DomainType, DomainSize, DefaultValue);
+        dmSysTables.GetDomainInfo(fdbIndex, dbObjectsList[x].Strings[i], DomainType, DomainSize, DefaultValue, Collation);
+        //todo: add support for collations and character sets.
 
         Line:= 'Create Domain ' + dbObjectsList[x].Strings[i] + ' as ' + DomainType;
           if Pos('CHAR', DomainType) > 0 then
@@ -976,11 +980,12 @@ end;
 procedure TfmComparison.CheckModifiedDomains;
 var
   i: Integer;
+  Collation: string;
   DomainName: string;
   DomainType, DefaultValue: string;
+  CCollation: string;
   CDomainType, CDefaultValue: string;
   DomainSize, CDomainSize: Integer;
-
 begin
   meLog.Lines.Add('');
   meLog.Lines.Add('Modified domains');
@@ -996,17 +1001,19 @@ begin
     DomainName:= dbExistingObjectsList[8][i];
 
     // Read all domain properties
-    dmSysTables.GetDomainInfo(fdbIndex, DomainName, DomainType, DomainSize, DefaultValue);
-    dmSysTables.GetDomainInfo(cbComparedDatabase.ItemIndex, DomainName, CDomainType, CDomainSize, CDefaultValue);
+    dmSysTables.GetDomainInfo(fdbIndex, DomainName, DomainType, DomainSize, DefaultValue, Collation);
+    dmSysTables.GetDomainInfo(cbComparedDatabase.ItemIndex, DomainName, CDomainType, CDomainSize, CDefaultValue,CCollation);
 
     // Compare
-    if (DomainType <> CDomainType) or (DomainSize <> CDomainSize) or (DefaultValue <> CDefaultValue) then
+    if (DomainType <> CDomainType) or
+       (DomainSize <> CDomainSize) or
+       (DefaultValue <> CDefaultValue) or
+       (Collation <> CCollation) then
     begin
       meLog.Lines.Add(' ' + DomainName);
       ModifiedDomainsList.Add(DomainName);
       Inc(DiffCount);
     end;
-
   end;
 
 end;
@@ -1523,11 +1530,13 @@ end;
 procedure TfmComparison.ScriptModifiedDomains;
 var
   i: Integer;
+  Collation: string;
   DomainName: string;
   DomainType, DefaultValue: string;
   DomainSize: Integer;
   Line: string;
 begin
+  //todo: align this with regular script code for domains, including collations
   if ModifiedDomainsList.Count > 0 then
   begin
     fQueryWindow.meQuery.Lines.Add('');
@@ -1537,13 +1546,17 @@ begin
   for i:= 0 to ModifiedDomainsList.Count - 1 do
   begin
     DomainName:= ModifiedDomainsList[i];
-    dmSysTables.GetDomainInfo(fdbIndex, DomainName, DomainType, domainSize, DefaultValue);
+    dmSysTables.GetDomainInfo(fdbIndex, DomainName, DomainType, domainSize, DefaultValue, Collation);
     fQueryWindow.meQuery.Lines.Add('');
     Line:= 'Alter DOMAIN ' + DomainName + ' type ' + DomainType;
     if Pos('char', LowerCase(DomainType)) > 0 then
       Line:= Line + '(' + IntToStr(DomainSize) + ')';
     fQueryWindow.meQuery.Lines.Add(Line);
 
+    // todo: verify if this is correct
+    if Trim(Collation) <> '' then
+      FQueryWindow.meQuery.Lines.Add('collation '+Trim(Collation));
+
     if Trim(DefaultValue) <> '' then
     begin
       if (Pos('char', LowerCase(DomainType)) > 0) and (Pos('''', DefaultValue) = 0) then
@@ -1554,7 +1567,6 @@ begin
     else
       fQueryWindow.meQuery.Lines.Add('set DEFAULT NULL;');
 
-
     fQueryWindow.meQuery.Lines.Add('');
 
 

+ 5 - 4
main.pas

@@ -352,7 +352,6 @@ begin
         ShowMessage('User (' + edUserName.Text + ') will not appear in users list unless you grant it a permission');
       lmRefresh.Click;
     end;
-
   except
     on e: exception do
     begin
@@ -2409,6 +2408,7 @@ procedure TfmMain.lmViewDomainClick(Sender: TObject);
 var
   SelNode: TTreeNode;
   ADomainName: string;
+  Collation: string;
   DomainType: string;
   DomainSize: Integer;
   ADomainForm: TFmViewDomain;
@@ -2439,15 +2439,16 @@ begin
       ATab:= ADomainForm.Parent as TTabSheet;
     PageControl1.ActivePage:= ATab;
 
-
     dbIndex:= SelNode.Parent.Parent.OverlayIndex;
-    dmSysTables.GetDomainInfo(dbIndex, ADomainName, DomainType, DomainSize, DefaultValue);
+    dmSysTables.GetDomainInfo(dbIndex, ADomainName, DomainType, DomainSize, DefaultValue, Collation);
     ATab.Tag:= dbIndex;
     if Pos('default', LowerCase(DefaultValue)) = 1 then
       DefaultValue:= Trim(Copy(DefaultValue, 8, Length(DefaultValue)));
-    if Pos('CHAR', DomainType) > 0 then
+    if (Pos('CHAR', DomainType) > 0) or
+      (Pos('CSTRING', DomainType) >0) then
       DomainType:= DomainType + '(' + IntToStr(DomainSize) + ')';
 
+    //todo: how to present character set/collation
     // Fill ViewDomain form
     with ADomainForm do
     begin

+ 11 - 6
scriptdb.pas

@@ -150,23 +150,28 @@ function ScriptAllDomains(dbIndex: Integer; var List: TStringList): Boolean;
 var
   Count: Integer;
   i: Integer;
+  Collation: string;
   DomainType: string;
   DomainSize: Integer;
   DefaultValue: string;
 begin
+  //todo: add support for character set
   List.CommaText:= dmSysTables.GetDBObjectNames(dbIndex, 8, Count);
   // Get domains in dependency order (if dependencies can exist between domains)
   dmSysTables.SortDependencies(List);
   for i:= 0 to List.Count - 1 do
   begin
-    dmSysTables.GetDomainInfo(dbIndex, List[i], DomainType, DomainSize, DefaultValue);
+    dmSysTables.GetDomainInfo(dbIndex, List[i], DomainType, DomainSize, DefaultValue, Collation);
 
     List[i]:= 'Create Domain ' + List[i] + ' as ' + DomainType;
-    if Pos('CHAR', DomainType) > 0 then
-      List[i]:= List[i] + '(' + IntToStr(DomainSize) + ')'
-    else
-      List[i]:= List[i] ;
-    List[i]:= List[i] + ' ' + DefaultValue + ';';
+    if (Pos('CHAR', DomainType) > 0) or (Pos('CSTRING', DomainType) > 0) then
+      List[i]:= List[i] + '(' + IntToStr(DomainSize) + ')';
+    List[i]:= List[i] + ' ' + DefaultValue;
+    // Collation for text types:
+    if Collation <> '' then
+      List[i]:= List[i] + ' COLLATE ' +  Collation;
+    // Close off create clause:
+    List[i]:= List[i] + ' ;';
   end;
   Result:= List.Count > 0;
 end;

+ 17 - 5
systables.pas

@@ -61,8 +61,9 @@ type
     // Gets information about exception.
     // Returns CREATE EXCEPTION statement in SQLQuery.
     function GetExceptionInfo(ExceptionName: string; var Msg, Description, SqlQuery: string): Boolean;
+    // Gets information about domain
     procedure GetDomainInfo(dbIndex: Integer; DomainName: string; var DomainType: string;
-      var DomainSize: Integer; var DefaultValue: string);
+      var DomainSize: Integer; var DefaultValue: string; var Collation: string);
     function GetConstraintForeignKeyFields(AIndexName: string; SqlQuery: TSQLQuery): string;
 
     function GetDBUsers(dbIndex: Integer; ObjectName: string = ''): string;
@@ -594,11 +595,21 @@ end;
 (************  View Domain info  ***************)
 
 procedure TdmSysTables.GetDomainInfo(dbIndex: Integer; DomainName: string; var DomainType: string;
-  var DomainSize: Integer; var DefaultValue: string);
+  var DomainSize: Integer; var DefaultValue: string; var Collation: string);
+const
+  // Select domain and associated collation (if text type domain)
+  // note weird double join fields required...
+  Template= 'select f.*, '+
+    'c.rdb$collation_name '+
+    'from rdb$fields as f '+
+    'left join rdb$collations as c on '+
+    'f.rdb$collation_id=c.rdb$collation_id and '+
+    'f.rdb$character_set_id=c.rdb$character_set_id '+
+    'where f.rdb$field_name=''%s'' ';
 begin
   Init(dbIndex);
   sqQuery.Close;
-  sqQuery.SQL.Text:= 'select * from RDB$FIELDS where RDB$Field_Name = ''' + UpperCase(DomainName) + '''';
+  sqQuery.SQL.Text:= format(Template, [UpperCase(DomainName)]);
   sqQuery.Open;
 
   if sqQuery.RecordCount > 0 then
@@ -609,6 +620,7 @@ begin
       sqQuery.FieldByName('RDB$FIELD_SCALE').AsInteger);
     DomainSize:= sqQuery.FieldByName('RDB$FIELD_LENGTH').AsInteger;
     DefaultValue:= sqQuery.FieldByName('RDB$DEFAULT_SOURCE').AsString;
+    Collation:= sqQuery.FieldByName('rdb$collation_name').AsString;
   end
   else
     DomainSize:= 0;
@@ -820,9 +832,9 @@ end;
 
 function TdmSysTables.GetDomainTypeSize(dbIndex: Integer; DomainTypeName: string): Integer;
 var
-  DomainType, DefaultValue: string;
+  DomainType, DefaultValue, COllation: string;
 begin
-  GetDomainInfo(dbIndex, DomainTypeName, DomainType, Result, DefaultValue);
+  GetDomainInfo(dbIndex, DomainTypeName, DomainType, Result, DefaultValue, Collation);
 end;