internal ParamOptionalChainer(Chainer prev, ParameterArgument defaultArgument) : base(prev) { if (defaultArgument.IsNullReference()) { defaultArgument = Designer.Null; } TryTakeException(defaultArgument.Exception); TryThrow(); ParamChainer paramObj = prev.GetPrev <ParamChainer>(); paramObj.Param.IsOptional = true; paramObj.Param.Default = defaultArgument; if (defaultArgument.CheckType(paramObj.Param, defaultArgument.Value, out chainException)) { paramObj.Param.Default.BuildArgument(GetRoot(), paramObj.Param.Name); TryThrow(paramObj.Param.Default.Exception); } else { chainException.Extra = "Argument is a default value of the parameter."; TryThrow(); } }
// ctor for non-mapped stored procedure internal PassChainer(IStoredProc prev, ParameterArgument[] arguments) : this((Chainer)prev) { var root = GetRoot(); if (arguments == null) { arguments = new ParameterArgument[] { null }; } Array.ForEach(arguments, argument => { if (argument == null) { argument = Designer.Null; } TryThrow(argument.Exception); // infer data type from value var param = Variable.InferParam(root, argument, out chainException); TryThrow(); root.TryAddParamOrThrow(param, true); }); Executable = new Executable((Compilable)prev, arguments); }
internal static void AppendTestValue(StringBuilder builder, ParameterArgument argument) { // table-valued test argument if (argument.TestValue is View) { return; } // scalar test argument (is always a string) string value = (string)argument.TestValue; if (value.EqualsCS(Text.Null, false)) { builder.Append(Text.Null); } else { // if CLR type is not given => original value has been passed as d.Null if (argument.ArgType == null) { if (argument.DT.IsDefined()) { builder.Append(value); } else { builder.Append(Mapping.BuildUnchecked(argument.Value)); } } else { builder.Append(value); } } }
// infer param from param argument internal static Variable InferParam(Designer root, ParameterArgument argument, out QueryTalkException exception, string name = null) { exception = null; Variable param; long variableIndex = 0; if (argument.DT.IsDataType()) { param = new Variable(argument.DataType); } else { if (argument.DT.IsTable()) { var view = (View)argument.Original; if (view.UserDefinedType == null) { exception = new QueryTalkException("Variable.InferParam", QueryTalkExceptionType.MissingDataViewUdt, null); return(null); } var udt = view.UserDefinedType; variableIndex = Designer.GetVariableGuid(); // important! param = new Variable(variableIndex, name, argument.DT, udt, IdentifierType.Param); } else { var dataType = DbInferenceBaseType; if (!argument.IsUndefined() && argument.ArgType != null) { // special handling of a variable passed by .Output if (argument.IsArgumentOutput) { dataType = DT.VarcharMax.ToDataType(); } // other data type else { dataType = Mapping.ClrMapping[argument.ArgType].DefaultDataType; } } param = new Variable(dataType, name); argument.DataType = dataType; } } if (name == null) { if (variableIndex == 0) { variableIndex = root.GetVariableIndex(); // cannot be mistaken with guid method } param.SetNameByOrdinal(variableIndex); } param.IsOutput = argument.IsArgumentOutput; return(param); }
private static int ReadOutputDataOnFound(IDataReader reader, Connectable connectable) { Value[] values = Common.DefaultReturnValue; // double check if (!reader.Read()) { return(0); } try { int count = reader.FieldCount; values = new Value[count]; var outputArguments = ParameterArgument.GetOutputArguments(connectable.Executable.Arguments); for (int i = 0; i < count; ++i) { Value outputData = new Value(reader.GetValue(i)); values[i] = outputData; // output values: if (i >= 1) { outputArguments[i - 1].SetOutput(outputData.Original); } } connectable.OutputArguments = outputArguments; int returnValue = 0; if (values[0] != null) { int retval; if (int.TryParse(values[0].ToString(), out retval)) { returnValue = retval; } else { ThrowQueryTalkReservedNameException(); } } connectable.ReturnValue = returnValue; return(returnValue); } catch (QueryTalkException) { throw; } catch (System.Exception ex) { throw ClrException(ex, "ReadOutputDataOnFound", connectable, null); } }
/// <summary> /// Specifies a list of arguments which are to be passed to the stored procedure. The parameter values have to be passed in the order of parameters as declared in the stored procedure. /// </summary> /// <param name="arguments">Are the arguments to pass.</param> protected PassChainer Pass(params ParameterArgument[] arguments) { if (arguments == null) { arguments = new ParameterArgument[] { Designer.Null }; } BuildProc(arguments); return(new PassChainer(this)); }
internal Column[] ProcessValueArrayInliner(BuildContext buildContext, BuildArgs buildArgs, Column[] values) { if (values.Length == 1 && values[0].Original is System.String) { var name = (System.String)values[0].Original; Variable variable = buildContext.ParamRoot.TryGetVariable(name, out chainException); if (variable.IsInliner()) { // inliner type check if (variable.DT != DT.InColumn) { buildContext.TryTakeException(variable.DT.InvalidInlinerException(GetType().Name, variable.Name, new[] { DT.InColumn })); return(null); } string arg2 = variable.Name; if (buildArgs.Executable != null) { ParameterArgument inlinerArgument = buildArgs.Executable.GetInlinerArgument(variable.Name); if (inlinerArgument.Value != null) { if (inlinerArgument.Value is System.String[]) { var args = new List <Column>(); foreach (var column in (System.String[])inlinerArgument.Value) { args.Add(column); } return(args.ToArray()); } else if (inlinerArgument.Value is Column[]) { return((Column[])inlinerArgument.Value); } } else { buildContext.TryTakeException(new QueryTalkException(this, QueryTalkExceptionType.InlinerArgumentNull, String.Format("{0} = null", arg2))); return(null); } } } } return(null); }
internal static string GetParamDeclaration(ParameterArgument argument, bool check, bool outer) { var dt = argument.DT; var dbt = argument.DataType; if (dt.IsNameType()) { var sql = Text.GenerateSql(500) .Append(argument.NameTypeSql); if (!outer && dt == DT.Udtt) { sql.S().Append(Text.Readonly); } return(sql.ToString()); } if (dbt != null) { if (dbt.Precision != 0) { if (check) { CriticalCheckArgumentSize(argument); } return(String.Format("{0}({1},{2})", Mapping.SqlMapping[dt].Sql, dbt.Precision, dbt.Scale)); } else if (dbt.Length != 0) { if (check) { CriticalCheckArgumentSize(argument); } return(String.Format("{0}({1})", Mapping.SqlMapping[dt].Sql, dbt.Length)); } // if precision/size is not declared, infer it from the value else { return(Mapping.SqlMapping[dt].SqlByValue(argument.Value)); } } else { return(Mapping.SqlMapping[dt].SqlByValue(argument.Value)); } }
private ParameterArgument GetInlinerArgument(string inlinerName, Executable executable) { ParameterArgument argument = executable.GetArgumentByName(inlinerName); if (argument.IsPassedVariable) { if (executable.InlineCaller != null) { return(GetInlinerArgument(argument.Value.ToString(), executable.InlineCaller)); } return(argument); } else { return(argument); } }
private void AddArgument(string paramName, ParameterArgument argument) { if (chainException != null) { return; } if (argument == null) { argument = new ParameterArgument(Designer.Null); } // check if argument has already been passed if (CheckArgumentByName(paramName)) { Throw(QueryTalkExceptionType.ParamArgumentAlreadyPassed, String.Format("param = {0}{1} argument = {2}", paramName, Environment.NewLine, argument.Value.ToReport()), Text.Method.Pass); } argument.BuildArgument(_rootCompilable, paramName); TryThrow(argument.Exception); if (argument.IsArgumentOutput) { if (!_rootCompilable.ExplicitParams .Where(p => p.Name.EqualsCS(paramName) && p.IsOutput) .Any()) { Throw(QueryTalkExceptionType.NonOutputParam, String.Format("param = {0}{1} argument = {2}", paramName, Environment.NewLine, argument.Value.ToReport()), Text.Method.Pass); } } _arguments.Add(argument); }
internal static void CriticalCheckArgumentSize(ParameterArgument argument) { if (!Mapping.SqlMapping[argument.DT].CheckSize( argument.Value, argument.DataType.Length, argument.DataType.Precision, argument.DataType.Scale)) { throw new QueryTalkException("CriticalCheckArgumentSize", QueryTalkExceptionType.InvalidArgumentSize, String.Format("param = {0}{1} " + "parameter length = {2}{3} " + "parameter precision = {4}{5} " + "parameter scale = {6}{7} " + "argument = {8}{9} " + "argument db type = {10}", argument.ParamName, Environment.NewLine, argument.DataType.Length, Environment.NewLine, argument.DataType.Precision, Environment.NewLine, argument.DataType.Scale, Environment.NewLine, argument.Value.ToReport(), Environment.NewLine, Mapping.SqlMapping[argument.DT].SqlByValue(argument.Value)), Text.Method.Pass); } }
// ctor for SQL batch internal PassChainer(IStoredProc prev, ParameterArgument[] arguments, List <string> batchParameters) : this((Chainer)prev) { var root = GetRoot(); // check arguments-params count int argumentsCount = arguments == null ? 0 : arguments.Count(); int parametersCount = batchParameters.Count; if (argumentsCount != parametersCount) { ThrowArgumentCountMismatch(parametersCount, argumentsCount); } if (arguments == null) { arguments = new ParameterArgument[] { null }; } int i = 0; Array.ForEach(arguments, argument => { if (argument == null) { argument = Designer.Null; } TryThrow(argument.Exception); // infer data type from value var param = Variable.InferParam(root, argument, out chainException, batchParameters[i++]); TryThrow(); root.TryAddParamOrThrow(param, true); }); Executable = new Executable((Compilable)prev, arguments); }
internal PassChainer(Chainer prev, ParameterArgument[] arguments) : this(prev) { Compilable compilable = (Compilable)prev; var root = GetRoot(); if (arguments == null) { arguments = new ParameterArgument[] { Designer.Null }; } // check arguments-params count match int argumentsCount = arguments.Count(); int explicitParamsCount = root.ExplicitParams.Count; if (!root.ParamCountCheck(argumentsCount)) { ThrowArgumentCountMismatch(explicitParamsCount, argumentsCount); } // check each argument int i = 0; Array.ForEach(arguments, argument => { if (argument != null && argument.Exception != null) { if (argument.Exception.Arguments == null && i < root.ExplicitParams.Count) { argument.Exception.Arguments = String.Format("param = {0}", root.ExplicitParams[i].Name); } TryThrow(argument.Exception); } ++i; }); Executable = new Executable(compilable, arguments); }
private static string GetParamDisplayValue(ParameterArgument argument) { if (argument.DT.IsDataType()) { if (argument.DT == DT.Datetime2) { return(Filter.TrimSingleQuotes(Mapping.BuildUnchecked((DateTime)argument.Value))); } else { return(Filter.TrimSingleQuotes(Mapping.BuildUnchecked(argument.Value))); } } else if (argument.DT.IsNameType() || argument.DT.IsTable()) { if (argument.IsBulk) { return(Wall.Text.NotAvailable); } else if (argument.DT.IsTable()) { return(Wall.Text.ThreeDots); } else { return(argument.Value.ToString()); } } else if (argument.DT.IsInlinerOrConcatenator()) { return(argument.Value.ToString()); } else { return(Wall.Text.NotAvailable); } }
// inliner: procedure, snippet, stored procedure private ExecChainer( Chainer prev, Variable inliner, string returnValueToVariable, params ParameterArgument[] arguments) : base(prev) { Build = (buildContext, buildArgs) => { ParameterArgument inlinerArgument = buildArgs.Executable.GetInlinerArgument(inliner.Name); if (inlinerArgument.Value == null) { buildContext.TryTakeException(new QueryTalkException(this, QueryTalkExceptionType.InlinerArgumentNull, String.Format("{0} = null", inliner.Name))); return(null); } if (inliner.DT == DT.InProcedure) { if (inlinerArgument.DT != DT.InProcedure) { buildContext.TryTakeException(inliner.DT.InvalidInlinerException(GetType().Name, inliner.Name, _procInliners)); return(null); } PassChainer cpass; if (inlinerArgument.ArgType == typeof(PassChainer)) { cpass = (PassChainer)inlinerArgument.Original; } // inliner variable else { var proc = (Procedure)inlinerArgument.Original; cpass = new PassChainer(proc, arguments); } BodyMethod(cpass, returnValueToVariable); return(BuildExecProc(buildContext, buildArgs)); } else if (inliner.DT == DT.InStoredProcedure) { if (inlinerArgument.DT != DT.InStoredProcedure) { buildContext.TryTakeException(inliner.DT.InvalidInlinerException(GetType().Name, inliner.Name, _sprocInliners)); return(null); } PassChainer cpass; if (inlinerArgument.ArgType == typeof(PassChainer)) { cpass = (PassChainer)inlinerArgument.Original; } else if (inlinerArgument.ArgType == typeof(ExecArgument)) { cpass = PassChainer.Create(new InternalRoot(), (ExecArgument)inlinerArgument.Original); } // inliner variable else { var execArgument = ((string)inlinerArgument.Original).Pass(arguments); cpass = PassChainer.Create(new InternalRoot(), execArgument); } BodyMethod(cpass, returnValueToVariable); return(BuildExecProc(buildContext, buildArgs)); } else { if (inlinerArgument.DT != DT.InSql) { buildContext.TryTakeException(inliner.DT.InvalidInlinerException(GetType().Name, inliner.Name, _sqlInliners)); return(null); } PassChainer cpass; if (inlinerArgument.ArgType == typeof(ExecArgument)) { cpass = PassChainer.Create(new InternalRoot(), (ExecArgument)inlinerArgument.Original); } // inliner variable else { var execArgument = ((string)inlinerArgument.Original).Pass(arguments); cpass = PassChainer.Create(new InternalRoot(), execArgument); } BodyMethod(cpass, null); return(BuildExecProc(buildContext, buildArgs)); } }; }
internal CollateChainer(System.String identifier, string collation) : base(null) { CheckNullAndThrow(Arg(() => identifier, identifier)); CheckNullAndThrow(Arg(() => collation, collation)); Build = (buildContext, buildArgs) => { string sql; Variable variable = buildContext.TryGetVariable(identifier, out chainException); if (variable.IsInliner()) { if (!_inliners.Contains(variable.DT)) { buildContext.TryTakeException(variable.DT.InvalidInlinerException(GetType().Name, variable.Name, _inliners)); return(null); } var arg2 = variable.Name; if (buildArgs.Executable != null) { ParameterArgument inlinerArgument = buildArgs.Executable.GetInlinerArgument(variable.Name); if (inlinerArgument.Value != null) { if (inlinerArgument.Value is System.String) { _columnName = (System.String)inlinerArgument.Value; return(Filter.DelimitColumnMultiPart((string)inlinerArgument.Value, out chainException)); } else { _columnName = ((Column)inlinerArgument.Value).ColumnName; return(((Column)inlinerArgument.Value).Build(buildContext, buildArgs)); } } else { buildContext.TryTakeException(new QueryTalkException(this, QueryTalkExceptionType.InlinerArgumentNull, String.Format("{0} = null", arg2))); return(null); } } return(arg2); } else { Column argument = new Column(identifier); if (argument.ProcessVariable(buildContext, buildArgs, out sql, variable)) { return(sql); } } // not a variable: _columnName = identifier; sql = Text.GenerateSql(100) .Append(Filter.DelimitMultiPartOrParam(identifier, IdentifierType.ColumnOrParam, out chainException)).S() .Append(Text.Collate).S() .Append(collation) .ToString(); buildContext.TryTakeException(chainException); return(sql); }; }
private static int ReadOutputData(IDataReader reader, Connectable connectable) { object output; int returnValue = 0; try { bool found = false; do { while (reader.Read()) { if (reader.GetName(0) == Text.Reserved.ReturnValueColumnName) { found = true; break; // last datasource table always exists } } } while (!found && reader.NextResult()); if (found) { int count = reader.FieldCount; var outputArguments = ParameterArgument.GetOutputArguments(connectable.Executable.Arguments); for (int i = 0; i < count; ++i) { if (reader.IsDBNull(i)) { output = null; } else { output = reader.GetValue(i); } // output values: if (i >= 1) { outputArguments[i - 1].SetOutput(output); } // return value: else { if (output != null && output.GetType() == typeof(System.Int32)) { int.TryParse(output.ToString(), out returnValue); connectable.ReturnValue = returnValue; } } } connectable.OutputArguments = outputArguments; } return(returnValue); } catch (System.Exception ex) { throw ClrException(ex, "ReaderOutputData", connectable, null); } }
// build the most outer SQL wrapper internal string BuildOutputWrapper(string execSql) { var root = Executable.Compilable.GetRoot(); var outputArguments = ParameterArgument.GetOutputArguments(Executable.Arguments); var sql = Text.GenerateSql(1000).Append(Text.Free.QueryTalkCode); // after: drop temp tables var sqlAfter = Text.GenerateSql(100); sqlAfter.Append(DropTempTables()); if (root.IsEmbeddedTryCatch) { sqlAfter .NewLine(Text.EndTry) .NewLine(Text.BeginCatch) .NewLine(Text.Free.RaiserrorS) .NewLine(Text.EndCatch).Terminate(); } sql.Append(Text.Declare).S().Append(Text.Reserved.ReturnValueOuterParam) .Append(Text._As_).Append(Text.Free.EnclosedInt).Terminate().S() .Append(Text.Set).S().Append(Text.Reserved.ReturnValueOuterParam).Append(Text._Equal_) .Append(Text.Zero).Terminate(); // TRY outer wrapper if (root.IsEmbeddedTryCatch) { sql.NewLine(Text.BeginTry); } // output arguments string outputValues = String.Empty; foreach (var argument in outputArguments) { // param in outer wrapper that holds the outer reference string paramOuterName = String.Format("{0}{1}{2}", argument.ParamName, Text.Underscore, Text.Output); // before sql.NewLine(Text.Declare).S() .Append(paramOuterName).Append(Text._As_) .Append(Executable.GetParamDeclaration(argument, false, true)) .Terminate().S() .Append(Text.Set).S().Append(paramOuterName).Append(Text._Equal_); if (argument.TestValue != null) { Testing.AppendTestValue(sql, argument); } else { sql.Append(Mapping.BuildUnchecked(argument.Value)); } sql.TerminateSingle(); // after: return output values outputValues = Text.GenerateSql(100) .NewLineIndent(Text.Comma) .Append(paramOuterName) .Append(Text._As_) .Append(Filter.Delimit(paramOuterName)) .ToString(); } // append last sql code: return value + output values sqlAfter .NewLine(Text.Select).S() .Append(Text.Free.ReturnValue) .Append(Text._As_) .Append(Text.Reserved.ReturnValueColumnName) .Append(outputValues); TryThrow(Text.Method.Pass); sql.NewLine(execSql) .Append(sqlAfter.ToString()) .TerminateSingle(); return(sql.ToString()); }
private void ShowTableValuedGrid(string param, int rowIndex) { try { if (_params[param].Processing == Processing.Running) { ShowTableParamStop(param, rowIndex, Processing.Idle); return; } // get argument, it must exist ParameterArgument argument = _connectable.Executable.Arguments .Where(arg => arg.ParamName == param) .Select(arg => arg) .FirstOrDefault(); TabPage tab = FindTab(argument.ParamName); if (tab == null) { tab = new TabPage(); tab.ThreadSafeInvoke(new Action(() => tab.Text = argument.ParamName)); _tabControl.ThreadSafeInvoke(new Action(() => _tabControl.TabPages.Add(tab))); var grid = new DataGridView(); var isReadOnly = (argument.DT == DT.TableVariable); SetGridAppearance(grid, !isReadOnly); grid.ThreadSafeInvoke(new Action(() => { // lock grid in case of table variables (modified data does not affect the query) if (isReadOnly) { grid.ReadOnly = true; grid.AllowUserToAddRows = false; } grid.DataError += OnDataError; })); if (_params[param].Processing != 0) { return; } ShowTableParamStop(param, rowIndex, Processing.Running); _params[param].Async = ((View)argument.Original) .ConnectByInternal(_connectable.Client, _connectable.ConnectionString) .GoAsync <DataTable>(ret => { if (ret.AsyncStatus == AsyncStatus.Completed) { // show data grid.ThreadSafeInvoke(new Action(() => grid.DataSource = ret.ToDataTable())); tab.ThreadSafeInvoke(new Action(() => tab.Controls.Add(grid))); ShowTableParamStop(param, rowIndex, Processing.Completed); // set rowCount ShowRowCount(ret.RowCount); tab.Tag = ret.RowCount; } else { ShowException(ret.Exception); ShowTableParamStop(param, rowIndex, 0); } }); } _tabControl.ThreadSafeInvoke(new Action(() => _tabControl.SelectedTab = tab)); } catch (System.Exception ex) { ShowException(ex); ShowTableParamStop(param, rowIndex, 0); } }
internal InjectChainer(Chainer prev, string sqlOrInliner) : base(prev) { var root = GetRoot(); var inliner = root.TryGetVariable(sqlOrInliner, out chainException, Variable.SearchType.Inliner); chainException = null; // reset exception if (inliner == null) { Build = (buildContext, buildArgs) => { return(Text.GenerateSql(200) .NewLine(sqlOrInliner) .TerminateSingle() .ToString()); }; } // inliner else { Build = (buildContext, buildArgs) => { ParameterArgument inlinerArgument = buildArgs.Executable.GetInlinerArgument(inliner.Name); if (inlinerArgument == null) { return(null); } if (inliner.DT == DT.InSql) { if (inlinerArgument.DT != DT.InSql) { TryThrow(inliner.DT.InvalidInlinerException(GetType().Name, inliner.Name, _sqlInliners)); } string sql2 = inliner.Name; if (buildArgs.Executable != null) { sql2 = (string)inlinerArgument.Value; } return(Text.GenerateSql(500) .NewLine(sql2) .TerminateSingle() .ToString()); } else if (inliner.DT == DT.InSnippet) { if (inlinerArgument.DT != DT.InSnippet) { buildContext.TryTakeException(inliner.DT.InvalidInlinerException(GetType().Name, inliner.Name, _snippetInliners)); return(null); } string sql = inliner.Name; if (buildArgs.Executable != null) { var snippet = (Snippet)inlinerArgument.Value; if (snippet != null) { TryTake(snippet); buildContext.ParamRoot = GetRoot(); sql = snippet.Build(buildContext, buildArgs); } else { sql = null; // it is allowed that snippet is not passed } } return(sql); } else { chainException = inliner.DT.InvalidInlinerException(GetType().Name, inliner.Name, _inliners); chainException.ObjectName = root.Name; chainException.Method = Text.Method.Exec; throw chainException; } }; } }
internal void ClearParameterizedValue() { _parameterizedValue = null; }
internal void SetParameterizedValue(ParameterArgument value) { _parameterizedValue = value; }
internal ColumnAsChainer(string column, string alias) : base(alias) { _columnName = alias; if (!CheckNull(Arg(() => column, column))) { return; } if (chainException != null) { return; } Build = (buildContext, buildArgs) => { QueryTalkException exception; Variable variable = buildContext.TryGetVariable(column, out exception); string inlinerSql = null; string columnSql = null; if (variable.IsInliner()) { inlinerSql = variable.Name; if (variable.DT != DT.InColumn) { buildContext.TryTakeException(variable.DT.InvalidInlinerException(GetType().Name, inlinerSql, _inliners)); return(null); } if (buildArgs.Executable != null) { ParameterArgument argument = buildArgs.Executable.GetInlinerArgument(inlinerSql); if (argument.Value != null) { if (argument.Value is System.String) { inlinerSql = Filter.DelimitColumnMultiPart((string)argument.Value, out chainException); } else { inlinerSql = ((Column)argument.Value).Build(buildContext, buildArgs); } } else { buildContext.TryTakeException(new QueryTalkException(this, QueryTalkExceptionType.InlinerArgumentNull, String.Format("{0} = null", inlinerSql))); return(null); } } } else { columnSql = Variable.ProcessVariable(column, buildContext, buildArgs, out chainException); TryThrow(); if (columnSql == null) { if (buildContext.IsCurrentStringAsValue) { columnSql = buildContext.BuildString(column); } else { columnSql = Filter.DelimitMultiPartOrParam(column, IdentifierType.ColumnOrParam, out chainException); } } } var sql = Text.GenerateSql(100) .Append(inlinerSql ?? columnSql).S() .Append(Text.As).S() .Append(Filter.Delimit(Name)) .ToString(); buildContext.TryTakeException(chainException); return(sql); }; }