Let ParseRoutineStructure() cache values from IS.ROUTINES into TDBObject members. Fixes issue #3108.

This commit is contained in:
Ansgar Becker
2013-02-21 11:19:44 +00:00
parent 53c9553c5b
commit fc015e61bd
3 changed files with 42 additions and 41 deletions

View File

@ -27,9 +27,14 @@ type
function GetCreateCode: String; function GetCreateCode: String;
procedure SetCreateCode(Value: String); procedure SetCreateCode(Value: String);
public public
// Table options:
Name, Database, Column, Engine, Comment, RowFormat, CreateOptions, Collation: String; Name, Database, Column, Engine, Comment, RowFormat, CreateOptions, Collation: String;
Created, Updated, LastChecked: TDateTime; Created, Updated, LastChecked: TDateTime;
Rows, Size, Version, AvgRowLen, MaxDataLen, IndexLen, DataLen, DataFree, AutoInc, CheckSum: Int64; Rows, Size, Version, AvgRowLen, MaxDataLen, IndexLen, DataLen, DataFree, AutoInc, CheckSum: Int64;
// Routine options:
Body, Definer, Returns, DataAccess, Security: String;
Deterministic: Boolean;
NodeType, GroupType: TListNodeType; NodeType, GroupType: TListNodeType;
constructor Create(OwnerConnection: TDBConnection); constructor Create(OwnerConnection: TDBConnection);
procedure Assign(Source: TPersistent); override; procedure Assign(Source: TPersistent); override;
@ -332,8 +337,7 @@ type
procedure ParseTableStructure(CreateTable: String; Columns: TTableColumnList; Keys: TTableKeyList; ForeignKeys: TForeignKeyList); procedure ParseTableStructure(CreateTable: String; Columns: TTableColumnList; Keys: TTableKeyList; ForeignKeys: TForeignKeyList);
procedure ParseViewStructure(CreateCode, ViewName: String; Columns: TTableColumnList; procedure ParseViewStructure(CreateCode, ViewName: String; Columns: TTableColumnList;
var Algorithm, Definer, SQLSecurity, CheckOption, SelectCode: String); var Algorithm, Definer, SQLSecurity, CheckOption, SelectCode: String);
procedure ParseRoutineStructure(Obj: TDBObject; Parameters: TRoutineParamList; procedure ParseRoutineStructure(Obj: TDBObject; Parameters: TRoutineParamList);
var Deterministic: Boolean; var Definer, Returns, DataAccess, Security, Comment, Body: String);
function GetDatatypeByName(Datatype: String): TDBDatatype; function GetDatatypeByName(Datatype: String): TDBDatatype;
function ApplyLimitClause(QueryType, QueryBody: String; Limit, Offset: Cardinal): String; function ApplyLimitClause(QueryType, QueryBody: String; Limit, Offset: Cardinal): String;
property Parameters: TConnectionParameters read FParameters write FParameters; property Parameters: TConnectionParameters read FParameters write FParameters;
@ -3422,8 +3426,7 @@ begin
end; end;
procedure TDBConnection.ParseRoutineStructure(Obj: TDBObject; Parameters: TRoutineParamList; procedure TDBConnection.ParseRoutineStructure(Obj: TDBObject; Parameters: TRoutineParamList);
var Deterministic: Boolean; var Definer, Returns, DataAccess, Security, Comment, Body: String);
var var
CreateCode, Params: String; CreateCode, Params: String;
ParenthesesCount: Integer; ParenthesesCount: Integer;
@ -3469,6 +3472,7 @@ begin
end; end;
rx.Free; rx.Free;
if Obj.Body = '' then begin
// Get everything else from information_schema. // Get everything else from information_schema.
// See http://www.heidisql.com/forum.php?t=12075 // See http://www.heidisql.com/forum.php?t=12075
// See issue #3114 // See issue #3114
@ -3480,13 +3484,14 @@ begin
' AND '+QuoteIdent('ROUTINE_NAME')+'='+EscapeString(Obj.Name)+ ' AND '+QuoteIdent('ROUTINE_NAME')+'='+EscapeString(Obj.Name)+
' AND '+QuoteIdent('ROUTINE_TYPE')+'='+EscapeString(UpperCase(Obj.ObjType)) ' AND '+QuoteIdent('ROUTINE_TYPE')+'='+EscapeString(UpperCase(Obj.ObjType))
); );
Body := FromIS.Col('ROUTINE_DEFINITION'); Obj.Body := FromIS.Col('ROUTINE_DEFINITION');
Definer := FromIS.Col('DEFINER'); Obj.Definer := FromIS.Col('DEFINER');
Returns := FromIS.Col('DTD_IDENTIFIER'); Obj.Returns := FromIS.Col('DTD_IDENTIFIER');
Deterministic := FromIS.Col('IS_DETERMINISTIC') = 'YES'; Obj.Deterministic := FromIS.Col('IS_DETERMINISTIC') = 'YES';
DataAccess := FromIS.Col('SQL_DATA_ACCESS'); Obj.DataAccess := FromIS.Col('SQL_DATA_ACCESS');
Security := FromIS.Col('SECURITY_TYPE'); Obj.Security := FromIS.Col('SECURITY_TYPE');
Comment := FromIS.Col('ROUTINE_COMMENT'); Obj.Comment := FromIS.Col('ROUTINE_COMMENT');
end;
end; end;

View File

@ -3279,9 +3279,8 @@ end;
procedure TMainForm.actRunRoutinesExecute(Sender: TObject); procedure TMainForm.actRunRoutinesExecute(Sender: TObject);
var var
Tab: TQueryTab; Tab: TQueryTab;
Query, ParamValues, ParamValue, DummyStr: String; Query, ParamValues, ParamValue: String;
Params: TStringList; Params: TStringList;
DummyBool: Boolean;
pObj: PDBObject; pObj: PDBObject;
Obj: TDBObject; Obj: TDBObject;
Objects: TDBObjectList; Objects: TDBObjectList;
@ -3318,7 +3317,7 @@ begin
Query := 'EXEC '; Query := 'EXEC ';
end; end;
Parameters := TRoutineParamList.Create; Parameters := TRoutineParamList.Create;
Obj.Connection.ParseRoutineStructure(Obj, Parameters, DummyBool, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr); Obj.Connection.ParseRoutineStructure(Obj, Parameters);
Query := Query + Obj.QuotedName; Query := Query + Obj.QuotedName;
Params := TStringList.Create; Params := TStringList.Create;
for Param in Parameters do begin for Param in Parameters do begin
@ -5058,11 +5057,10 @@ var
LeftText, Identifier: String; LeftText, Identifier: String;
rx: TRegExpr; rx: TRegExpr;
i: Integer; i: Integer;
DummyBool: Boolean;
DbObjects: TDBObjectList; DbObjects: TDBObjectList;
DbObj: TDbObject; DbObj: TDbObject;
Params: TRoutineParamList; Params: TRoutineParamList;
ItemText, DummyStr: String; ItemText: String;
Prop: TSynCompletionProposal; Prop: TSynCompletionProposal;
begin begin
// Display hint on function and procedure parameters // Display hint on function and procedure parameters
@ -5092,7 +5090,7 @@ begin
for DbObj in DbObjects do begin for DbObj in DbObjects do begin
if (CompareText(DbObj.Name, Identifier)=0) and (DbObj.NodeType in [lntFunction, lntProcedure]) then begin if (CompareText(DbObj.Name, Identifier)=0) and (DbObj.NodeType in [lntFunction, lntProcedure]) then begin
Params := TRoutineParamList.Create(True); Params := TRoutineParamList.Create(True);
DbObj.Connection.ParseRoutineStructure(DbObj, Params, DummyBool, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr); DbObj.Connection.ParseRoutineStructure(DbObj, Params);
ItemText := ''; ItemText := '';
for i:=0 to Params.Count-1 do for i:=0 to Params.Count-1 do
ItemText := ItemText + '"' + Params[i].Name + ': ' + Params[i].Datatype + '", '; ItemText := ItemText + '"' + Params[i].Name + ': ' + Params[i].Datatype + '", ';

View File

@ -132,8 +132,6 @@ end;
procedure TfrmRoutineEditor.Init(Obj: TDBObject); procedure TfrmRoutineEditor.Init(Obj: TDBObject);
var var
Definer, Returns, DataAccess, Security, Comment, Body: String;
Deterministic: Boolean;
i: Integer; i: Integer;
begin begin
inherited; inherited;
@ -162,19 +160,19 @@ begin
lntProcedure: comboType.ItemIndex := 0; lntProcedure: comboType.ItemIndex := 0;
lntFunction: comboType.ItemIndex := 1; lntFunction: comboType.ItemIndex := 1;
end; end;
DBObject.Connection.ParseRoutineStructure(Obj, Parameters, Deterministic, Definer, Returns, DataAccess, Security, Comment, Body); DBObject.Connection.ParseRoutineStructure(Obj, Parameters);
comboReturns.Text := Returns; comboReturns.Text := Obj.Returns;
chkDeterministic.Checked := Deterministic; chkDeterministic.Checked := Obj.Deterministic;
if DataAccess <> '' then if Obj.DataAccess <> '' then
comboDataAccess.ItemIndex := comboDataAccess.Items.IndexOf(DataAccess); comboDataAccess.ItemIndex := comboDataAccess.Items.IndexOf(Obj.DataAccess);
if Security <> '' then if Obj.Security <> '' then
comboSecurity.ItemIndex := comboSecurity.Items.IndexOf(Security); comboSecurity.ItemIndex := comboSecurity.Items.IndexOf(Obj.Security);
editComment.Text := Comment; editComment.Text := Obj.Comment;
comboDefiner.Text := Definer; comboDefiner.Text := Obj.Definer;
// The whole CREATE CODE may be empty if the user is not allowed to view code in SHOW CREATE FUNCTION // The whole CREATE CODE may be empty if the user is not allowed to view code in SHOW CREATE FUNCTION
// => Disable the whole editor in this case. // => Disable the whole editor in this case.
SynMemoBody.Text := Body; SynMemoBody.Text := Obj.Body;
lblDisabledWhy.Visible := Body = ''; lblDisabledWhy.Visible := Obj.Body = '';
PageControlMain.Enabled := not lblDisabledWhy.Visible; PageControlMain.Enabled := not lblDisabledWhy.Visible;
SynMemoBody.Enabled := PageControlMain.Enabled; SynMemoBody.Enabled := PageControlMain.Enabled;
end else begin end else begin