mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2026-03-13 09:24:25 +08:00
Issue #885: Move types of table keys from global scope constants to class constants in TTableKey definition, to make them stable against mix-ups
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
const
|
||||
|
||||
// Line breaks
|
||||
// TODO: use sLineBreak instead
|
||||
CRLF = #13#10;
|
||||
LB_UNIX = #10;
|
||||
LB_MAC = #13;
|
||||
@@ -102,12 +103,6 @@ const
|
||||
MsgInvalidColumn: String = 'Column #%d not available. Query returned %d columns and %d rows.';
|
||||
SPortableLockFile: String = 'portable.lock';
|
||||
|
||||
PKEY = 'PRIMARY';
|
||||
KEY = 'KEY';
|
||||
UKEY = 'UNIQUE';
|
||||
FKEY = 'FULLTEXT';
|
||||
SKEY = 'SPATIAL';
|
||||
|
||||
SYNCOMPLETION_PATTERN = '\image{%d}\hspace{5}\color{clGrayText}%s\column{}\color{clWindowText}%s\color{clGrayText}%s';
|
||||
|
||||
HELPERNODE_COLUMNS = 0;
|
||||
|
||||
@@ -62,6 +62,12 @@ type
|
||||
end;
|
||||
|
||||
TTableKey = class(TPersistent)
|
||||
const
|
||||
PRIMARY = 'PRIMARY';
|
||||
KEY = 'KEY';
|
||||
UNIQUE = 'UNIQUE';
|
||||
FULLTEXT = 'FULLTEXT';
|
||||
SPATIAL = 'SPATIAL';
|
||||
private
|
||||
FConnection: TDBConnection;
|
||||
function GetImageIndex: Integer;
|
||||
@@ -4821,7 +4827,7 @@ begin
|
||||
NewKey.Name := KeyQuery.Col('CONSTRAINT_NAME');
|
||||
NewKey.OldName := NewKey.Name;
|
||||
if KeyQuery.Col('CONSTRAINT_TYPE').ToLowerInvariant.StartsWith('primary') then
|
||||
NewKey.IndexType := 'PRIMARY'
|
||||
NewKey.IndexType := TTableKey.PRIMARY
|
||||
else
|
||||
NewKey.IndexType := KeyQuery.Col('CONSTRAINT_TYPE');
|
||||
NewKey.OldIndexType := NewKey.IndexType;
|
||||
@@ -4850,13 +4856,13 @@ begin
|
||||
NewKey.Name := KeyQuery.Col('Key_name');
|
||||
NewKey.OldName := NewKey.Name;
|
||||
if NewKey.Name.ToLowerInvariant = 'primary' then
|
||||
NewKey.IndexType := 'PRIMARY'
|
||||
NewKey.IndexType := TTableKey.PRIMARY
|
||||
else if KeyQuery.Col('Non_unique') = '0' then
|
||||
NewKey.IndexType := 'UNIQUE'
|
||||
NewKey.IndexType := TTableKey.UNIQUE
|
||||
else if KeyQuery.Col('Index_type').ToLowerInvariant = 'fulltext' then
|
||||
NewKey.IndexType := 'FULLTEXT'
|
||||
NewKey.IndexType := TTableKey.FULLTEXT
|
||||
else
|
||||
NewKey.IndexType := 'KEY';
|
||||
NewKey.IndexType := TTableKey.KEY;
|
||||
// Todo: spatial keys
|
||||
NewKey.OldIndexType := NewKey.IndexType;
|
||||
if ExecRegExpr('(BTREE|HASH)', KeyQuery.Col('Index_type')) then
|
||||
@@ -4888,7 +4894,7 @@ begin
|
||||
' ),'+
|
||||
' ndx_cols AS ('+
|
||||
' SELECT pg_class.relname, UNNEST(i.indkey) AS col_ndx,'+
|
||||
' CASE i.indisprimary WHEN true THEN '+EscapeString('PRIMARY')+' ELSE CASE i.indisunique WHEN true THEN '+EscapeString('UNIQUE')+' ELSE '+EscapeString('KEY')+' END END AS CONSTRAINT_TYPE,'+
|
||||
' CASE i.indisprimary WHEN true THEN '+EscapeString(TTableKey.PRIMARY)+' ELSE CASE i.indisunique WHEN true THEN '+EscapeString(TTableKey.UNIQUE)+' ELSE '+EscapeString(TTableKey.KEY)+' END END AS CONSTRAINT_TYPE,'+
|
||||
' pg_class.oid'+
|
||||
' FROM pg_class'+
|
||||
' JOIN pg_index i ON (pg_class.oid = i.indexrelid)'+
|
||||
@@ -4954,7 +4960,7 @@ begin
|
||||
Result.Add(NewKey);
|
||||
NewKey.Name := 'PRIMARY';
|
||||
NewKey.OldName := NewKey.Name;
|
||||
NewKey.IndexType := 'PRIMARY';
|
||||
NewKey.IndexType := TTableKey.PRIMARY;
|
||||
NewKey.OldIndexType := NewKey.IndexType;
|
||||
end;
|
||||
NewKey.Columns.Add(ColQuery.Col('name'));
|
||||
@@ -4969,7 +4975,7 @@ begin
|
||||
Result.Add(NewKey);
|
||||
NewKey.Name := KeyQuery.Col('name');
|
||||
NewKey.OldName := NewKey.Name;
|
||||
NewKey.IndexType := IfThen(KeyQuery.Col('unique')='0', 'KEY', 'UNIQUE');
|
||||
NewKey.IndexType := IfThen(KeyQuery.Col('unique')='0', TTableKey.KEY, TTableKey.UNIQUE);
|
||||
NewKey.OldIndexType := NewKey.IndexType;
|
||||
ColQuery := GetResults('SELECT * FROM pragma_index_info('+EscapeString(NewKey.Name)+')');
|
||||
while not ColQuery.Eof do begin
|
||||
@@ -5948,13 +5954,13 @@ begin
|
||||
// Find best key for updates
|
||||
// 1. round: find a primary key
|
||||
for Key in Keys do begin
|
||||
if Key.IndexType = PKEY then
|
||||
if Key.IndexType = TTableKey.PRIMARY then
|
||||
Result.Assign(Key.Columns);
|
||||
end;
|
||||
if Result.Count = 0 then begin
|
||||
// no primary key available -> 2. round: find a unique key
|
||||
for Key in Keys do begin
|
||||
if Key.IndexType = UKEY then begin
|
||||
if Key.IndexType = TTableKey.UNIQUE then begin
|
||||
// We found a UNIQUE key - better than nothing. Check if one of the key
|
||||
// columns allows NULLs which makes it dangerous to use in UPDATES + DELETES.
|
||||
AllowsNull := False;
|
||||
@@ -8906,11 +8912,11 @@ end;
|
||||
function TTableKey.GetImageIndex: Integer;
|
||||
begin
|
||||
// Detect key icon index for specified index
|
||||
if IndexType = PKEY then Result := ICONINDEX_PRIMARYKEY
|
||||
else if IndexType = KEY then Result := ICONINDEX_INDEXKEY
|
||||
else if IndexType = UKEY then Result := ICONINDEX_UNIQUEKEY
|
||||
else if IndexType = FKEY then Result := ICONINDEX_FULLTEXTKEY
|
||||
else if IndexType = SKEY then Result := ICONINDEX_SPATIALKEY
|
||||
if IndexType = TTableKey.PRIMARY then Result := ICONINDEX_PRIMARYKEY
|
||||
else if IndexType = TTableKey.KEY then Result := ICONINDEX_INDEXKEY
|
||||
else if IndexType = TTableKey.UNIQUE then Result := ICONINDEX_UNIQUEKEY
|
||||
else if IndexType = TTableKey.FULLTEXT then Result := ICONINDEX_FULLTEXTKEY
|
||||
else if IndexType = TTableKey.SPATIAL then Result := ICONINDEX_SPATIALKEY
|
||||
else Result := -1;
|
||||
end;
|
||||
|
||||
@@ -8922,10 +8928,10 @@ begin
|
||||
// Supress SQL error trying index creation with 0 column
|
||||
if Columns.Count = 0 then
|
||||
Exit;
|
||||
if IndexType = PKEY then
|
||||
if IndexType = TTableKey.PRIMARY then
|
||||
Result := Result + 'PRIMARY KEY '
|
||||
else begin
|
||||
if IndexType <> KEY then
|
||||
if IndexType <> TTableKey.KEY then
|
||||
Result := Result + IndexType + ' ';
|
||||
Result := Result + 'INDEX ' + FConnection.QuoteIdent(Name) + ' ';
|
||||
end;
|
||||
|
||||
@@ -700,7 +700,7 @@ begin
|
||||
// Drop indexes, also changed indexes, which will be readded below
|
||||
for i:=0 to DeletedKeys.Count-1 do begin
|
||||
Mainform.ProgressStep;
|
||||
if DeletedKeys[i] = PKEY then
|
||||
if DeletedKeys[i] = TTableKey.PRIMARY then
|
||||
IndexSQL := 'PRIMARY KEY'
|
||||
else
|
||||
IndexSQL := 'INDEX ' + Conn.QuoteIdent(DeletedKeys[i]);
|
||||
@@ -710,7 +710,7 @@ begin
|
||||
for i:=0 to FKeys.Count-1 do begin
|
||||
Mainform.ProgressStep;
|
||||
if FKeys[i].Modified and (not FKeys[i].Added) then begin
|
||||
if FKeys[i].OldIndexType = PKEY then
|
||||
if FKeys[i].OldIndexType = TTableKey.PRIMARY then
|
||||
IndexSQL := 'PRIMARY KEY'
|
||||
else
|
||||
IndexSQL := 'INDEX ' + Conn.QuoteIdent(FKeys[i].OldName);
|
||||
@@ -1139,7 +1139,7 @@ begin
|
||||
// Do not allow NULL, and force NOT NULL, on primary key columns
|
||||
Result := True;
|
||||
for i:=0 to FKeys.Count-1 do begin
|
||||
if (FKeys[i].IndexType = PKEY) and (FKeys[i].Columns.IndexOf(Col.Name) > -1) then begin
|
||||
if (FKeys[i].IndexType = TTableKey.PRIMARY) and (FKeys[i].Columns.IndexOf(Col.Name) > -1) then begin
|
||||
if Col.AllowNull then begin
|
||||
Col.AllowNull := False;
|
||||
Col.Status := esModified;
|
||||
@@ -1236,7 +1236,7 @@ begin
|
||||
Col := Sender.GetNodeData(Node);
|
||||
// Bold font for primary key columns
|
||||
for i:=0 to FKeys.Count-1 do begin
|
||||
if (FKeys[i].IndexType = PKEY) and (FKeys[i].Columns.IndexOf(Col.Name) > -1) then begin
|
||||
if (FKeys[i].IndexType = TTableKey.PRIMARY) and (FKeys[i].Columns.IndexOf(Col.Name) > -1) then begin
|
||||
TargetCanvas.Font.Style := TargetCanvas.Font.Style + [fsBold];
|
||||
break;
|
||||
end;
|
||||
@@ -1535,7 +1535,7 @@ begin
|
||||
TblKey := TTableKey.Create(DBObject.Connection);
|
||||
TblKey.Name := _('Index')+' '+IntToStr(FKeys.Count+1);
|
||||
TblKey.OldName := TblKey.Name;
|
||||
TblKey.IndexType := KEY;
|
||||
TblKey.IndexType := TTableKey.KEY;
|
||||
TblKey.OldIndexType := TblKey.IndexType;
|
||||
TblKey.Added := True;
|
||||
FKeys.Add(TblKey);
|
||||
@@ -1576,7 +1576,7 @@ begin
|
||||
end;
|
||||
if not ColExists then begin
|
||||
NewCol := Column.Name;
|
||||
if (TblKey.IndexType <> FKEY) and (Column.DataType.Index in [dtTinyText, dtText, dtMediumText, dtLongText, dtTinyBlob, dtBlob, dtMediumBlob, dtLongBlob]) then
|
||||
if (TblKey.IndexType <> TTableKey.FULLTEXT) and (Column.DataType.Index in [dtTinyText, dtText, dtMediumText, dtLongText, dtTinyBlob, dtBlob, dtMediumBlob, dtLongBlob]) then
|
||||
PartLength := '100';
|
||||
break;
|
||||
end;
|
||||
@@ -1672,7 +1672,7 @@ begin
|
||||
0: begin
|
||||
TblKey := FKeys[Node.Index];
|
||||
case Column of
|
||||
0: if TblKey.IndexType = PKEY then
|
||||
0: if TblKey.IndexType = TTableKey.PRIMARY then
|
||||
CellText := TblKey.IndexType + ' KEY' // Fixed name "PRIMARY KEY", cannot be changed
|
||||
else
|
||||
CellText := TblKey.Name;
|
||||
@@ -1766,7 +1766,7 @@ begin
|
||||
Allowed := False;
|
||||
if VT.GetNodeLevel(Node) = 0 then begin
|
||||
// Disallow renaming primary key
|
||||
if (Column <> 0) or (VT.Text[Node, 1] <> PKEY) then
|
||||
if (Column <> 0) or (VT.Text[Node, 1] <> TTableKey.PRIMARY) then
|
||||
Allowed := True
|
||||
end else case Column of
|
||||
0: Allowed := True;
|
||||
@@ -1800,7 +1800,7 @@ begin
|
||||
// Index type pulldown
|
||||
EnumEditor := TEnumEditorLink.Create(VT, True);
|
||||
EnumEditor.ValueList := TStringList.Create;
|
||||
EnumEditor.ValueList.CommaText := PKEY +','+ KEY +','+ UKEY +','+ FKEY +','+ SKEY;
|
||||
EnumEditor.ValueList.CommaText := TTableKey.PRIMARY +','+ TTableKey.KEY +','+ TTableKey.UNIQUE +','+ TTableKey.FULLTEXT +','+ TTableKey.SPATIAL;
|
||||
EditLink := EnumEditor;
|
||||
end else if (Level = 0) and (Column = 2) then begin
|
||||
// Algorithm pulldown
|
||||
@@ -1839,8 +1839,8 @@ begin
|
||||
0: TblKey.Name := NewText;
|
||||
1: begin
|
||||
TblKey.IndexType := NewText;
|
||||
if NewText = PKEY then
|
||||
TblKey.Name := PKEY;
|
||||
if NewText = TTableKey.PRIMARY then
|
||||
TblKey.Name := TTableKey.PRIMARY;
|
||||
end;
|
||||
2: TblKey.Algorithm := NewText;
|
||||
end;
|
||||
@@ -1968,7 +1968,7 @@ begin
|
||||
|
||||
TblKey.Columns.Insert(ColPos, ColName);
|
||||
PartLength := '';
|
||||
if (TblKey.IndexType <> FKEY) and (Col.DataType.Index in [dtTinyText, dtText, dtMediumText, dtLongText, dtTinyBlob, dtBlob, dtMediumBlob, dtLongBlob]) then
|
||||
if (TblKey.IndexType <> TTableKey.FULLTEXT) and (Col.DataType.Index in [dtTinyText, dtText, dtMediumText, dtLongText, dtTinyBlob, dtBlob, dtMediumBlob, dtLongBlob]) then
|
||||
PartLength := '100';
|
||||
TblKey.Subparts.Insert(ColPos, PartLength);
|
||||
IndexNode.States := IndexNode.States + [vsHasChildren, vsExpanded];
|
||||
@@ -2096,9 +2096,9 @@ begin
|
||||
// Auto create submenu items for "Add to index" ...
|
||||
PrimaryKeyExists := False;
|
||||
for i:=0 to FKeys.Count-1 do begin
|
||||
if FKeys[i].IndexType = PKEY then begin
|
||||
if FKeys[i].IndexType = TTableKey.PRIMARY then begin
|
||||
PrimaryKeyExists := True;
|
||||
IndexName := PKEY;
|
||||
IndexName := TTableKey.PRIMARY;
|
||||
end else
|
||||
IndexName := FKeys[i].Name + ' ('+FKeys[i].IndexType+')';
|
||||
Item := AddItem(menuAddToIndex, IndexName, FKeys[i].ImageIndex);
|
||||
@@ -2118,12 +2118,12 @@ begin
|
||||
menuAddToIndex.Enabled := menuAddToIndex.Count > 0;
|
||||
|
||||
// ... and for item "Create index"
|
||||
Item := AddItem(menuCreateIndex, PKEY, ICONINDEX_PRIMARYKEY);
|
||||
Item := AddItem(menuCreateIndex, TTableKey.PRIMARY, ICONINDEX_PRIMARYKEY);
|
||||
Item.Enabled := not PrimaryKeyExists;
|
||||
AddItem(menuCreateIndex, KEY, ICONINDEX_INDEXKEY);
|
||||
AddItem(menuCreateIndex, UKEY, ICONINDEX_UNIQUEKEY);
|
||||
AddItem(menuCreateIndex, FKEY, ICONINDEX_FULLTEXTKEY);
|
||||
AddItem(menuCreateIndex, SKEY, ICONINDEX_SPATIALKEY);
|
||||
AddItem(menuCreateIndex, TTableKey.KEY, ICONINDEX_INDEXKEY);
|
||||
AddItem(menuCreateIndex, TTableKey.UNIQUE, ICONINDEX_UNIQUEKEY);
|
||||
AddItem(menuCreateIndex, TTableKey.FULLTEXT, ICONINDEX_FULLTEXTKEY);
|
||||
AddItem(menuCreateIndex, TTableKey.SPATIAL, ICONINDEX_SPATIALKEY);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user