/// <summary> /// Executes this directive, if applicable. /// </summary> /// <param name="context">DB Context.</param> /// <param name="text">SQL statement text</param> /// <param name="directive">Source information.</param> /// <param name="initState">Initialization state.</param> /// <returns><c>true</c> if this processor can execute the current statement, otherwise <c>false</c></returns> /// <exception cref="UnrecognizedStatementException">If this directive's <c>callback</c> returns <c>false</c></exception> public bool TryExecute(CompositeProcessorContext context, string text, ScriptDirective directive, object initState) { if (directive.Name != DirectiveName) { return(false); } var statementName = ((InitializedState)initState).StatementName; if (!callback(statementName, text)) { throw new UnrecognizedStatementException(statementName, directive); } return(true); }
/// <summary> /// Executes this directive against the given context, if applicable. /// </summary> /// <param name="context">DB context</param> /// <param name="text">SQL statement text</param> /// <param name="directive">Source information</param> /// <param name="initState">Initialization state</param> /// <returns><see langword="true"/> if this processor is able to execute the given directive, otherwise <see langword="false" /></returns> public bool TryExecute(CompositeProcessorContext context, string text, ScriptDirective directive, object initState) { if (directive.Name != DirectiveName && directive.Name != NegatedDirectiveName) { return(false); } var initData = (InitializedState)initState; if (Eval(initData.PropertyName, initData.PropertyValue, initData.Negated)) { var command = context.NewCommand(); command.CommandText = text; command.ExecuteNonQuery(); } return(true); }
/// <summary> /// Constructs an <see cref="UnrecognizedDirectiveException"/> with the given <see cref="ScriptDirective"/>. /// </summary> /// <param name="directive">The unrecognized script directive.</param> public UnrecognizedDirectiveException(ScriptDirective directive) : base($"Unrecognized directive: {directive}") { Directive = directive; }
/// <summary> /// Construct a new <see cref="InvalidDirectiveException"/> with the given error <c>message</c>, and the offending /// <see cref="ScriptDirective"/>. /// </summary> /// <param name="message">Message explaining why the direcitve or its configuration is invalid.</param> /// <param name="directive">The invalid directive.</param> public InvalidDirectiveException(string message, ScriptDirective directive) : base($"{message} ({directive.FileName}: {directive.LineNumber})") { Error = message; Directive = directive; }
/// <summary> /// N/A /// </summary> /// <param name="context"></param> /// <param name="directive"></param> /// <param name="initState"></param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> public DirectiveInitialization SetupDirective(CompositeProcessorContext context, ScriptDirective directive, object initState) { throw new NotImplementedException(); }
/// <summary> /// Initializes this directive. /// </summary> /// <param name="context">DB context.</param> /// <param name="directive">Directive to test.</param> /// <returns><c>null</c> if not applicable, otherwise this directive's initialization state</returns> /// <exception cref="InvalidDirectiveException">If the number of argments provided to this directive is not exactly <c>1</c></exception> public DirectiveInitialization InitDirective(CompositeProcessorContext context, ScriptDirective directive) { if (directive.Name != DirectiveName) { return(null); } if (directive.Arguments.Count != 1) { throw new InvalidDirectiveException("Callback directive must have exactly 1 argument.", directive); } return(new DirectiveInitialization(new InitializedState(directive.Arguments[0]))); }
internal UnrecognizedStatementException(string statementName, ScriptDirective directive) : base($"Unrecognized statement name: {statementName}; Directive: {directive}") { StatementName = statementName; Directive = directive; }
/// <summary> /// Initializes this directive as configured in the source script. /// </summary> /// <param name="context">DB context</param> /// <param name="directive">Source information</param> /// <returns>Initialization state if this processor can handle the given directive, otherwise <see langword="null" /></returns> /// <exception cref="InvalidDirectiveException">If the provided argument count is less than 1 or greater than 2</exception> public DirectiveInitialization InitDirective(CompositeProcessorContext context, ScriptDirective directive) { bool negated; switch (directive.Name) { case DirectiveName: negated = false; break; case NegatedDirectiveName: negated = true; break; default: return(null); } if (directive.Name != directive.Name) { return(null); } if (directive.Arguments.Count < 1) { throw new InvalidDirectiveException($"{directive.Name} must have at least 1 argument (property name).", directive); } if (directive.Arguments.Count > 2) { throw new InvalidDirectiveException($"{directive.Name} can have at most 2 arguments.", directive); } var propertyName = directive.Arguments[0]; var value = directive.Arguments.Count > 1 ? directive.Arguments[1] : null; return(new DirectiveInitialization(new InitializedState(propertyName, value, negated))); }
/// <summary> /// Evaluates the given <see cref="ScriptDirective"/>. /// </summary> /// <remarks> /// <para>If the given <c>directive</c> matches the <c>directiveName</c> or <c>negatedDirectiveName</c> given in the constructor, /// the directive will be evaluated.</para> /// /// <para>Properties replace directives have between 2 and 4 arguments:</para> /// <list type="number"> /// <item> /// <term><c>propertyName</c></term> /// <description>Property name.</description> /// </item> /// <item> /// <term><c>replaceValue</c> OR <c>propertyValue</c></term> /// <description>If argument count is two, value to replace in statement text if <c>propertyName</c> is defined. /// Otherwise, the value to evaluate <c>propertyName</c> against to determine replacement.</description> /// </item> /// <item> /// <term><c>replaceValue</c></term> /// <description>Value to replace in statement text if <c>propertyName</c> equals <c>propertyValue</c>, following /// the semantics described in <see cref="PropertiesEvaluator.Eval"/>.</description> /// </item> /// <item> /// <term><c>elseValue</c></term> /// <description>Value to replace in statement text if the evaluation fails. Default is the empty string.</description> /// </item> /// </list> /// </remarks> /// <param name="context">Not used.</param> /// <param name="directive"><see cref="ScriptDirective"/> to process.</param> /// <returns>Appropriate <see cref="DirectiveInitialization"/> if <c>directive</c> is supported, otherwise <see langword="null" />.</returns> public DirectiveInitialization InitDirective(CompositeProcessorContext context, ScriptDirective directive) { bool negated; if (directive.Name == directiveName) { negated = false; } else if (directive.Name == negatedDirectiveName) { negated = true; } else { return(null); } if (directive.Arguments.Count < 2) { throw new InvalidDirectiveException($"{directiveName} must have at least 2 arguments (property name, replace value).", directive); } if (directive.Arguments.Count > 4) { throw new InvalidDirectiveException($"{directiveName} can have at most 4 arguments.", directive); } var propertyName = directive.Arguments[0]; var propertyValue = directive.Arguments.Count > 2 ? directive.Arguments[1] : null; var replaceValue = directive.Arguments[directive.Arguments.Count > 2 ? 2 : 1]; var elseValue = directive.Arguments.Count > 3 ? directive.Arguments[3] : null; if (deferRuntime) { return(new DirectiveInitialization(new InitializedState(propertyName, replaceValue, propertyValue, elseValue, negated), DirectiveInitializationAction.DeferSetup)); } if (Eval(propertyName, propertyValue, negated)) { return(new DirectiveInitialization(action: DirectiveInitializationAction.ReplaceText | DirectiveInitializationAction.NoStore, replacementText: replaceValue)); } else { if (elseValue is not null) { return(new DirectiveInitialization(action: DirectiveInitializationAction.ReplaceText | DirectiveInitializationAction.NoStore, replacementText: elseValue)); } else { return(new DirectiveInitialization(action: DirectiveInitializationAction.NoStore)); } } }
/// <summary> /// Always returns <see langword="false"/> (does nothing). All necessary operations are performed in <see cref="InitDirective"/> /// and <see cref="SetupDirective" />, if applicable. /// </summary> /// <param name="context"></param> /// <param name="text"></param> /// <param name="directive"></param> /// <param name="initState"></param> /// <returns><see langword="false"/></returns> public bool TryExecute(CompositeProcessorContext context, string text, ScriptDirective directive, object initState) { return(false); }
/// <summary> /// Performs property <see cref="PropertiesEvaluator.Eval">evaluation</see> if <c>deferRuntime</c> was specified in the constructor. /// </summary> /// <param name="context">Not used.</param> /// <param name="directive"><see cref="ScriptDirective"/> to process.</param> /// <param name="initState">Processed directive argument information from <see cref="InitDirective"/>.</param> /// <returns></returns> public DirectiveInitialization SetupDirective(CompositeProcessorContext context, ScriptDirective directive, object initState) { if (!deferRuntime) { throw new NotImplementedException(); } var initData = (InitializedState)initState; if (Eval(initData.PropertyName, initData.PropertyValue, initData.Negated)) { return(new DirectiveInitialization(action: DirectiveInitializationAction.ReplaceText, replacementText: initData.ReplaceValue)); } else { if (initData.ElseValue is not null) { return(new DirectiveInitialization(action: DirectiveInitializationAction.ReplaceText, replacementText: initData.ElseValue)); } else { return(new DirectiveInitialization()); } } }