mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
Export whole CREATE VIEW code, not only the VIEW body. Fixes issue #2625.
This commit is contained in:
@ -119,7 +119,7 @@ begin
|
||||
FForeignKeys.Clear;
|
||||
case FDBObj.NodeType of
|
||||
lntTable: FDBObj.Connection.ParseTableStructure(FDBObj.CreateCode, FColumns, FKeys, FForeignKeys);
|
||||
lntView: FDBObj.Connection.ParseViewStructure(FDBObj.CreateCode, FDBObj.Name, FColumns, Dummy, Dummy, Dummy, Dummy);
|
||||
lntView: FDBObj.Connection.ParseViewStructure(FDBObj.CreateCode, FDBObj.Name, FColumns, Dummy, Dummy, Dummy, Dummy, Dummy);
|
||||
else raise Exception.Create('Neither table nor view: '+FDBObj.Name);
|
||||
end;
|
||||
|
||||
|
@ -18,7 +18,6 @@ type
|
||||
TDBObject = class(TPersistent)
|
||||
private
|
||||
FCreateCode: String;
|
||||
FViewSelectCode: String;
|
||||
FCreateCodeFetched: Boolean;
|
||||
FConnection: TDBConnection;
|
||||
function GetObjType: String;
|
||||
@ -39,7 +38,6 @@ type
|
||||
property ObjType: String read GetObjType;
|
||||
property ImageIndex: Integer read GetImageIndex;
|
||||
property CreateCode: String read GetCreateCode write SetCreateCode;
|
||||
property ViewSelectCode: String read FViewSelectCode;
|
||||
property Connection: TDBConnection read FConnection;
|
||||
end;
|
||||
PDBObject = ^TDBObject;
|
||||
@ -302,7 +300,8 @@ type
|
||||
procedure ClearDbObjects(db: String);
|
||||
procedure ClearAllDbObjects;
|
||||
procedure ParseTableStructure(CreateTable: String; Columns: TTableColumnList; Keys: TTableKeyList; ForeignKeys: TForeignKeyList);
|
||||
procedure ParseViewStructure(CreateCode, ViewName: String; Columns: TTableColumnList; var Algorithm, Definer, CheckOption, SelectCode: String);
|
||||
procedure ParseViewStructure(CreateCode, ViewName: String; Columns: TTableColumnList;
|
||||
var Algorithm, Definer, SQLSecurity, CheckOption, SelectCode: String);
|
||||
procedure ParseRoutineStructure(CreateCode: String; Parameters: TRoutineParamList;
|
||||
var Deterministic: Boolean; var Definer, Returns, DataAccess, Security, Comment, Body: String);
|
||||
function GetDatatypeByName(Datatype: String): TDBDatatype;
|
||||
@ -2938,7 +2937,8 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TDBConnection.ParseViewStructure(CreateCode, ViewName: String; Columns: TTableColumnList; var Algorithm, Definer, CheckOption, SelectCode: String);
|
||||
procedure TDBConnection.ParseViewStructure(CreateCode, ViewName: String; Columns: TTableColumnList;
|
||||
var Algorithm, Definer, SQLSecurity, CheckOption, SelectCode: String);
|
||||
var
|
||||
rx: TRegExpr;
|
||||
Col: TTableColumn;
|
||||
@ -3800,7 +3800,7 @@ begin
|
||||
lntTable:
|
||||
Connection.ParseTableStructure(CreateCode, FColumns, FKeys, FForeignKeys);
|
||||
lntView:
|
||||
Connection.ParseViewStructure(CreateCode, TableName, FColumns, Dummy, Dummy, Dummy, Dummy);
|
||||
Connection.ParseViewStructure(CreateCode, TableName, FColumns, Dummy, Dummy, Dummy, Dummy, Dummy);
|
||||
end;
|
||||
FreeAndNil(FUpdateData);
|
||||
FUpdateData := TUpdateData.Create(True);
|
||||
@ -4379,7 +4379,6 @@ begin
|
||||
Size := s.Size;
|
||||
FCreateCode := s.FCreateCode;
|
||||
FCreateCodeFetched := s.FCreateCodeFetched;
|
||||
FViewSelectCode := s.FViewSelectCode;
|
||||
end else
|
||||
inherited;
|
||||
end;
|
||||
@ -4437,19 +4436,33 @@ end;
|
||||
function TDBObject.GetCreateCode: String;
|
||||
var
|
||||
rx: TRegExpr;
|
||||
ViewName, Algorithm, CheckOption, SelectCode, Definer, SQLSecurity: String;
|
||||
AlternativeSelectCode: String;
|
||||
begin
|
||||
if not FCreateCodeFetched then try
|
||||
FCreateCode := Connection.GetCreateCode(Database, Name, NodeType);
|
||||
if NodeType = lntView then begin
|
||||
FViewSelectCode := Connection.GetVar('SELECT LOAD_FILE(CONCAT(IFNULL(@@GLOBAL.datadir, CONCAT(@@GLOBAL.basedir, '+Connection.EscapeString('data/')+')), '+Connection.EscapeString(Database+'/'+Name+'.frm')+'))');
|
||||
// Try to fetch original VIEW code from .frm file
|
||||
AlternativeSelectCode := Connection.GetVar('SELECT LOAD_FILE(CONCAT(IFNULL(@@GLOBAL.datadir, CONCAT(@@GLOBAL.basedir, '+Connection.EscapeString('data/')+')), '+Connection.EscapeString(Database+'/'+Name+'.frm')+'))');
|
||||
rx := TRegExpr.Create;
|
||||
rx.ModifierI := True;
|
||||
rx.ModifierG := False;
|
||||
rx.Expression := '\nsource\=(.+)\n\w+\=';
|
||||
if rx.Exec(FViewSelectCode) then
|
||||
FViewSelectCode := Connection.UnescapeString(rx.Match[1])
|
||||
else
|
||||
FViewSelectCode := '';
|
||||
if rx.Exec(AlternativeSelectCode) then begin
|
||||
// Put pieces of CREATE VIEW together
|
||||
Connection.ParseViewStructure(FCreateCode, ViewName, nil,
|
||||
Algorithm, Definer, SQLSecurity, CheckOption, SelectCode);
|
||||
AlternativeSelectCode := Connection.UnescapeString(rx.Match[1]);
|
||||
FCreateCode := 'CREATE ';
|
||||
if Algorithm <> '' then
|
||||
FCreateCode := FCreateCode + 'ALGORITHM='+Uppercase(Algorithm)+' ';
|
||||
if Definer <> '' then
|
||||
FCreateCode := FCreateCode + 'DEFINER='+Connection.QuoteIdent(Definer, True, '@')+' ';
|
||||
FCreateCode := FCreateCode + 'VIEW '+QuotedName+' AS '+AlternativeSelectCode+' ';
|
||||
if CheckOption <> '' then
|
||||
FCreateCode := FCreateCode + 'WITH '+Uppercase(CheckOption)+' CHECK OPTION';
|
||||
end;
|
||||
rx.Free;
|
||||
end;
|
||||
except
|
||||
end;
|
||||
|
@ -256,7 +256,7 @@ begin
|
||||
if (Obj.Database=comboDatabase.Text) and (Obj.Name=comboTable.Text) then begin
|
||||
case Obj.NodeType of
|
||||
lntTable: Obj.Connection.ParseTableStructure(Obj.CreateCode, Columns, nil, nil);
|
||||
lntView: Obj.Connection.ParseViewStructure(Obj.CreateCode, Obj.Name, Columns, DummyStr, DummyStr, DummyStr, DummyStr);
|
||||
lntView: Obj.Connection.ParseViewStructure(Obj.CreateCode, Obj.Name, Columns, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -4746,7 +4746,7 @@ var
|
||||
lntTable:
|
||||
Conn.ParseTableStructure(Obj.CreateCode, Columns, nil, nil);
|
||||
lntView:
|
||||
Conn.ParseViewStructure(Obj.CreateCode, Obj.Name, Columns, Dummy, Dummy, Dummy, Dummy);
|
||||
Conn.ParseViewStructure(Obj.CreateCode, Obj.Name, Columns, Dummy, Dummy, Dummy, Dummy, Dummy);
|
||||
end;
|
||||
for Col in Columns do begin
|
||||
Proposal.InsertList.Add(Col.Name);
|
||||
@ -6885,7 +6885,7 @@ begin
|
||||
lntTable:
|
||||
FActiveDbObj.Connection.ParseTableStructure(FActiveDbObj.CreateCode, SelectedTableColumns, SelectedTableKeys, SelectedTableForeignKeys);
|
||||
lntView:
|
||||
FActiveDbObj.Connection.ParseViewStructure(FActiveDbObj.CreateCode, FActiveDbObj.Name, SelectedTableColumns, DummyStr, DummyStr, DummyStr, DummyStr);
|
||||
FActiveDbObj.Connection.ParseViewStructure(FActiveDbObj.CreateCode, FActiveDbObj.Name, SelectedTableColumns, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr);
|
||||
end;
|
||||
except on E:EDatabaseError do
|
||||
ErrorDialog(E.Message);
|
||||
|
@ -644,7 +644,7 @@ begin
|
||||
Columns := TTableColumnList.Create(True);
|
||||
case DBObj.NodeType of
|
||||
lntTable: DBObj.Connection.ParseTableStructure(DBObj.CreateCode, Columns, nil, nil);
|
||||
lntView: DBObj.Connection.ParseViewStructure(DBObj.CreateCode, DBObj.Name, Columns, Dummy, Dummy, Dummy, Dummy);
|
||||
lntView: DBObj.Connection.ParseViewStructure(DBObj.CreateCode, DBObj.Name, Columns, Dummy, Dummy, Dummy, Dummy, Dummy);
|
||||
else AddNotes(DBObj.Database, DBObj.Name, STRSKIPPED+'a '+LowerCase(DBObj.ObjType)+' does not contain rows.', '');
|
||||
end;
|
||||
if Columns.Count > 0 then begin
|
||||
@ -1216,7 +1216,7 @@ begin
|
||||
if not FSecondExportPass then begin
|
||||
// Create temporary VIEW replacement
|
||||
ColumnList := TTableColumnList.Create(True);
|
||||
DBObj.Connection.ParseViewStructure(DBObj.CreateCode, DBObj.Name, ColumnList, Dummy, Dummy, Dummy, Dummy);
|
||||
DBObj.Connection.ParseViewStructure(DBObj.CreateCode, DBObj.Name, ColumnList, Dummy, Dummy, Dummy, Dummy, Dummy);
|
||||
Struc := '-- Creating temporary table to overcome VIEW dependency errors'+CRLF+
|
||||
'CREATE TABLE ';
|
||||
if ToDb then
|
||||
@ -1235,8 +1235,6 @@ begin
|
||||
Struc := Struc + Quoter.QuoteIdent(DBObj.Name);
|
||||
Output(Struc, True, True, True, True, True);
|
||||
Struc := DBObj.CreateCode;
|
||||
if DBObj.ViewSelectCode <> '' then
|
||||
Struc := DBObj.ViewSelectCode;
|
||||
if ToDb then
|
||||
Insert(Quoter.QuoteIdent(FinalDbName)+'.', Struc, Pos('VIEW', Struc) + 5 );
|
||||
end;
|
||||
|
@ -61,7 +61,7 @@ end;
|
||||
}
|
||||
procedure TfrmView.Init(Obj: TDBObject);
|
||||
var
|
||||
Algorithm, CheckOption, SelectCode, Definer: String;
|
||||
Algorithm, CheckOption, SelectCode, Definer, SQLSecurity: String;
|
||||
begin
|
||||
inherited;
|
||||
lblDisabledWhy.Font.Color := clRed;
|
||||
@ -71,16 +71,13 @@ begin
|
||||
if Obj.Name <> '' then begin
|
||||
// Edit mode
|
||||
editName.Text := Obj.Name;
|
||||
Obj.Connection.ParseViewStructure(Obj.CreateCode, Obj.Name, nil, Algorithm, Definer, CheckOption, SelectCode);
|
||||
Obj.Connection.ParseViewStructure(Obj.CreateCode, Obj.Name, nil, Algorithm, Definer, SQLSecurity, CheckOption, SelectCode);
|
||||
comboDefiner.Text := Definer;
|
||||
rgAlgorithm.ItemIndex := rgAlgorithm.Items.IndexOf(Algorithm);
|
||||
rgCheck.ItemIndex := rgCheck.Items.IndexOf(CheckOption);
|
||||
if rgCheck.ItemIndex = -1 then
|
||||
rgCheck.ItemIndex := 0;
|
||||
if Obj.ViewSelectCode <> '' then
|
||||
SynMemoSelect.Text := Obj.ViewSelectCode
|
||||
else
|
||||
SynMemoSelect.Text := SelectCode;
|
||||
SynMemoSelect.Text := SelectCode;
|
||||
// User may not be allowed to run SHOW CREATE VIEW, in which case we have an empty CreateCode.
|
||||
// Disable editor in this case.
|
||||
lblDisabledWhy.Visible := SelectCode = '';
|
||||
|
Reference in New Issue
Block a user