瀏覽代碼

Add support for scripting columns that are domain types - part of issue #16. Speed up table fields metadata queries.

Reinier Olislagers 11 年之前
父節點
當前提交
bc0fb5f7d2
共有 3 個文件被更改,包括 74 次插入40 次删除
  1. 14 2
      main.pas
  2. 30 20
      scriptdb.pas
  3. 30 18
      systables.pas

+ 14 - 2
main.pas

@@ -267,9 +267,13 @@ type
     procedure setTransactionIsolation(Params: TStringList);
   end;
 
+
 var
   fmMain: TfmMain;
 
+// Tries to guess if an RDB$RELATION_FIELDS.RDB$FIELD_SOURCE domain name for a column is system-generated.
+function SystemGeneratedFieldDomain(FieldSource: string): boolean;
+
 implementation
 
 
@@ -281,6 +285,13 @@ uses CreateDb, ViewView, ViewTrigger, ViewSProc, ViewGen, NewTable, NewGen,
      PermissionManage, CopyTable, About, NewEditField, dbInfo, Comparison;
 
 
+function SystemGeneratedFieldDomain(FieldSource: string): boolean;
+begin
+  { todo: find a way to search the system tables and make sure the constraint name
+  is system-generated}
+  result:=(pos('RDB$',uppercase(Trim(FieldSource)))=1);
+end;
+
 procedure TfmMain.mnExitClick(Sender: TObject);
 begin
   Close;
@@ -2471,10 +2482,11 @@ const
     ' coll.RDB$COLLATION_NAME AS field_collation, ' +
     ' cset.RDB$CHARACTER_SET_NAME AS field_charset, ' +
     ' f.RDB$COMPUTED_Source AS Computed_Source, ' +
-    ' dim.RDB$UPPER_BOUND AS Array_Upper_Bound ' +
+    ' dim.RDB$UPPER_BOUND AS Array_Upper_Bound, ' +
+    ' r.RDB$FIELD_SOURCE AS field_source ' {domain if field based on domain}+
     ' FROM RDB$RELATION_FIELDS r ' +
     ' LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME ' +
-    ' LEFT JOIN RDB$COLLATIONS coll ON f.RDB$COLLATION_ID = coll.RDB$COLLATION_ID ' +
+    ' LEFT JOIN RDB$COLLATIONS coll ON f.RDB$COLLATION_ID = coll.RDB$COLLATION_ID and f.rdb$character_set_id=coll.rdb$character_set_id ' +
     ' LEFT JOIN RDB$CHARACTER_SETS cset ON f.RDB$CHARACTER_SET_ID = cset.RDB$CHARACTER_SET_ID ' +
     ' LEFT JOIN RDB$FIELD_DIMENSIONS dim ON f.RDB$FIELD_NAME = dim.RDB$FIELD_NAME ' +
     ' WHERE r.RDB$RELATION_NAME=''%s'' ' +

+ 30 - 20
scriptdb.pas

@@ -229,29 +229,39 @@ begin
         // Field Name
         FieldLine:= Trim(FieldByName('Field_Name').AsString) + ' ';
 
-        // Field type
-        FieldLine:= FieldLine + fmMain.GetFBTypeName(FieldByName('Field_Type_Int').AsInteger,
-          FieldByName('Field_Sub_Type').AsInteger,
-          FieldByName('Field_Length').AsInteger,
-          FieldByName('Field_Precision').AsInteger,
-          FieldByName('Field_Scale').AsInteger);
-
-        if (FieldByName('Field_Type_Int').AsInteger) in [CharType, CStringType, VarCharType] then
-          FieldLine:= FieldLine + '(' + FieldByName('CharacterLength').AsString + ') ';
+        if (FieldByName('field_source').IsNull) or
+          (trim(FieldByName('field_source').AsString)='') or
+          (SystemGeneratedFieldDomain(trim(FieldByname('field_source').AsString))) then
+        begin
+          // Field type is not based on a domain but a standard SQL type
+          // Field type
+          FieldLine:= FieldLine + fmMain.GetFBTypeName(FieldByName('Field_Type_Int').AsInteger,
+            FieldByName('Field_Sub_Type').AsInteger,
+            FieldByName('Field_Length').AsInteger,
+            FieldByName('Field_Precision').AsInteger,
+            FieldByName('Field_Scale').AsInteger);
+
+          if (FieldByName('Field_Type_Int').AsInteger) in [CharType, CStringType, VarCharType] then
+            FieldLine:= FieldLine + '(' + FieldByName('CharacterLength').AsString + ') ';
+
+          if (FieldByName('Field_Type_Int').AsInteger = BlobType) then
+          begin
+            BlobSubType:= fmMain.GetBlobSubTypeName(FieldByName('Field_Sub_Type').AsInteger);
+            if BlobSubType<>'' then
+              FieldLine:= FieldLine + ' ' + BlobSubType;
+          end;
 
-        if (FieldByName('Field_Type_Int').AsInteger = BlobType) then
+          // Rudimentary support for array datatypes (only covers 0 dimension types):
+          {todo: expand to proper array type detection (low priority as arrays are
+           virtually unused}
+          if not(FieldByName('Array_Upper_Bound').IsNull) then
+            FieldLine:= FieldLine + ' [' + FieldByName('Array_Upper_Bound').AsString + '] ';
+        end
+        else
         begin
-          BlobSubType:= fmMain.GetBlobSubTypeName(FieldByName('Field_Sub_Type').AsInteger);
-          if BlobSubType<>'' then
-            FieldLine:= FieldLine + ' ' + BlobSubType;
+          // Field is based on a domain
+          FieldLine:= FieldLine + ' ' + trim(FieldByName('field_source').AsString);
         end;
-
-        // Rudimentary support for array datatypes (only covers 0 dimension types):
-        {todo: expand to proper array type detection (low priority as arrays are
-         virtually unused}
-        if not(FieldByName('Array_Upper_Bound').IsNull) then
-          FieldLine:= FieldLine + ' [' + FieldByName('Array_Upper_Bound').AsString + '] ';
-
         // Default value
         DefaultValue:= Trim(FieldByName('Field_Default_Source').AsString);
         if DefaultValue <> '' then

+ 30 - 18
systables.pas

@@ -896,10 +896,11 @@ begin
     ' coll.RDB$COLLATION_NAME AS field_collation, ' +
     ' cset.RDB$CHARACTER_SET_NAME AS field_charset, ' +
     ' f.RDB$COMPUTED_Source AS Computed_Source, ' +
-    ' dim.RDB$UPPER_BOUND AS Array_Upper_Bound ' +
+    ' dim.RDB$UPPER_BOUND AS Array_Upper_Bound, ' +
+    ' r.RDB$FIELD_SOURCE AS field_source ' {domain if field based on domain} +
     ' FROM RDB$RELATION_FIELDS r ' +
     ' LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME ' +
-    ' LEFT JOIN RDB$COLLATIONS coll ON f.RDB$COLLATION_ID = coll.RDB$COLLATION_ID ' +
+    ' LEFT JOIN RDB$COLLATIONS coll ON f.RDB$COLLATION_ID = coll.RDB$COLLATION_ID and f.rdb$character_set_id=coll.rdb$character_set_id ' +
     ' LEFT JOIN RDB$CHARACTER_SETS cset ON f.RDB$CHARACTER_SET_ID = cset.RDB$CHARACTER_SET_ID ' +
     ' LEFT JOIN RDB$FIELD_DIMENSIONS dim on f.RDB$FIELD_NAME = dim.RDB$FIELD_NAME '+
     ' WHERE r.RDB$RELATION_NAME=''' + TableName + '''  and Trim(r.RDB$FIELD_NAME) = ''' + UpperCase(FieldName) + ''' ' +
@@ -910,23 +911,34 @@ begin
   begin
     with sqQuery do
     begin
-      FieldType:= fmMain.GetFBTypeName(FieldByName('Field_Type').AsInteger,
-        FieldByName('field_sub_type').AsInteger,
-        FieldByName('field_length').AsInteger,
-        FieldByName('field_precision').AsInteger,
-        FieldByName('field_scale').AsInteger);
-      // Array should really be [lowerbound:upperbound] (if dimension is 0)
-      // but for now don't bother as arrays are not supported anyway
-      // Assume 0 dimension, 1 lower bound; just fill in upper bound
-      if not(FieldByName('Array_Upper_Bound').IsNull) then
-        FieldType := FieldType +
-          ' [' +
-          FieldByName('Array_Upper_Bound').AsString +
-          ']';
-      if FieldByName('Field_Type_int').AsInteger = VarCharType then
-        FieldSize:= FieldByName('CharacterLength').AsInteger
+      if (FieldByName('field_source').IsNull) or
+        (trim(FieldByName('field_source').AsString)='') or
+        (SystemGeneratedFieldDomain(trim(FieldByname('field_source').AsString))) then
+      begin
+        // Field type is not based on a domain but a standard SQL type
+        FieldType:= fmMain.GetFBTypeName(FieldByName('Field_Type').AsInteger,
+          FieldByName('field_sub_type').AsInteger,
+          FieldByName('field_length').AsInteger,
+          FieldByName('field_precision').AsInteger,
+          FieldByName('field_scale').AsInteger);
+        // Array should really be [lowerbound:upperbound] (if dimension is 0)
+        // but for now don't bother as arrays are not supported anyway
+        // Assume 0 dimension, 1 lower bound; just fill in upper bound
+        if not(FieldByName('Array_Upper_Bound').IsNull) then
+          FieldType := FieldType +
+            ' [' +
+            FieldByName('Array_Upper_Bound').AsString +
+            ']';
+        if FieldByName('Field_Type_int').AsInteger = VarCharType then
+          FieldSize:= FieldByName('CharacterLength').AsInteger
+        else
+          FieldSize:= FieldByName('Field_Length').AsInteger;
+      end
       else
-        FieldSize:= FieldByName('Field_Length').AsInteger;
+      begin
+        // Field is based on a domain
+        FieldType:= trim(FieldByName('field_source').AsString);
+      end;
       NotNull:= FieldByName('Field_not_null_constraint').AsString = '1';
       DefaultValue:= FieldByName('Field_Default_Source').AsString;
       Description:= FieldByName('Field_Description').AsString;