protected override sealed void Analyze(IAnalyzerContext context) { foreach (IDocument document in context.Inputs) { AnalyzeData(document, context); } }
protected override async ValueTask <IQsiAnalysisResult> OnExecute(IAnalyzerContext context) { var identifierSet = new HashSet <QsiIdentifier>(IdentifierComparer); QsiQualifiedIdentifier tableIdentifier = null; QsiTableNode node = (context.Tree as QsiDerivedTableNode); bool isCountFunction = false; while (node is QsiDerivedTableNode tableNode) { IEnumerable <QsiQualifiedIdentifier> columns = tableNode .Columns.Value .FindAscendants <QsiDeclaredColumnNode>() .Select(c => c.Name); var hasCountFunction = tableNode .Columns.Value .FindAscendants <QsiDerivedColumnNode>() .Any(c => c.Expression.Value is QsiInvokeExpressionNode invokeExpressionNode && invokeExpressionNode.Member.Value.Identifier[^ 1].Value.EqualsIgnoreCase("COUNT")); if (hasCountFunction) { isCountFunction = true; } foreach (var column in columns) { identifierSet.Add(column[^ 1]);
protected override async ValueTask <IQsiAnalysisResult> OnExecute(IAnalyzerContext context) { switch (context.Tree) { case IQsiPrepareActionNode prepareActionNode: return(await ExecutePrepareAction(context, prepareActionNode)); case IQsiDropPrepareActionNode dropPrepareAction: return(await ExecuteDropPrepareAction(context, dropPrepareAction)); case IQsiExecutePrepareActionNode executeAction: return(await ExecuteExecutePrepareAction(context, executeAction)); case IQsiDataInsertActionNode dataInsertAction: return(await ExecuteDataInsertAction(context, dataInsertAction)); case IQsiDataDeleteActionNode dataDeleteAction: return(await ExecuteDataDeleteAction(context, dataDeleteAction)); case IQsiDataUpdateActionNode dataUpdateAction: return(await ExecuteDataUpdateAction(context, dataUpdateAction)); case IQsiChangeSearchPathActionNode searchPathAction: return(await ExecuteSearchPathAction(context, searchPathAction)); default: throw TreeHelper.NotSupportedTree(context.Tree); } }
public TableCompileContext(IAnalyzerContext context) : base(context) { _directives = new List <QsiTableStructure>(); Directives = _directives; SourceTables = new List <QsiTableStructure>(); }
protected override sealed void Analyze(IAnalyzerContext context) { foreach (IDocument document in context.Inputs.FilterSources("community/speakers/*.md")) { AnalyzeSpeakerData(document, context); } }
protected override sealed void Analyze(ImmutableArray <IDocument> documents, IAnalyzerContext context) { foreach (IDocument document in documents.FilterSources("community/speakers/*.md")) { AnalyzeSpeakerData(document, context); } }
protected override async ValueTask <IQsiAnalysisResult> OnExecute(IAnalyzerContext context) { if (context.Tree is CqlDerivedTableNode { IsJson : true } cqlTableNode) { using var scope = new TableCompileContext(context); var table = await BuildTableStructure(scope, cqlTableNode); var jsonTable = new QsiTableStructure { Identifier = table.Identifier, Type = table.Type, IsSystem = table.IsSystem }; jsonTable.References.AddRange(table.References); var jsonColumn = jsonTable.NewColumn(); jsonColumn.Name = new QsiIdentifier("[json]", false); jsonColumn.References.AddRange(table.Columns); return(new CqlJsonTableAnalysisResult(jsonTable)); } return(await base.OnExecute(context)); }
protected virtual ValueTask <IQsiAnalysisResult> ExecuteExecutePrepareAction(IAnalyzerContext context, IQsiExecutePrepareActionNode action) { var definition = context.Engine.RepositoryProvider.LookupDefinition(action.Identifier, QsiTableType.Prepared) ?? throw new QsiException(QsiError.UnableResolveDefinition, action.Identifier); return(context.Engine.Execute(definition)); }
public AttributeAnalyzer(IAnalyzerContext context) : base(context) { analyze = KeySeek; start = -1; quote = char.MinValue; mode = Mode.Invalid; attributes = new Dictionary<string, string>(); }
protected override void AnalyzeSpeakerData(IDocument document, IAnalyzerContext context) { string pronouns = document.GetString(SiteKeys.Pronouns); if (!pronouns.IsNullOrEmpty() && (pronouns.Count(x => x == '/') != 1 || pronouns.Any(x => x != '/' && (!char.IsLetter(x) || !char.IsLower(x))))) { context.AddAnalyzerResult(document, $"Preferred gender pronouns should be of the form [subject]/[object] in lowercase (I.e. \"they/them\")"); } }
public TextAnalyzer(IAnalyzerContext context, int position) : base(context) { if (position < 0) { throw new ArgumentOutOfRangeException("position"); } this.startPosition = position; }
protected override void AnalyzeSpeakerData(IDocument document, IAnalyzerContext context) { foreach (string linkKey in SpeakerLinkAttribute.GetAll().Keys) { if (document.ContainsKey(linkKey) && !Uri.TryCreate(document.GetString(linkKey), UriKind.Absolute, out _)) { context.Add(document, $"{linkKey} link {document.GetString(linkKey)} is invalid"); } } }
protected ValueTask <IQsiAnalysisResult> ExecuteAlterUserAction(IAnalyzerContext context, SqlServerAlterUserActionNode alterUserActionNode) { var action = new SqlServerAlterUserAction { TargetUser = alterUserActionNode.TargetUser, NewUserName = alterUserActionNode.NewUserName, DefaultSchema = alterUserActionNode.DefaultSchema }; return(new ValueTask <IQsiAnalysisResult>(action)); }
protected virtual QsiDataValue ResolveColumnValue(IAnalyzerContext context, IQsiExpressionNode expression) { if (expression is IQsiLiteralExpressionNode literal) { return(new QsiDataValue(literal.Value, literal.Type)); } var value = context.Engine.TreeDeparser.Deparse(expression, context.Script); return(new QsiDataValue(value, QsiDataType.Raw)); }
protected virtual ValueTask <IQsiAnalysisResult> ExecuteDropPrepareAction(IAnalyzerContext context, IQsiDropPrepareActionNode action) { var refAction = new QsiReferenceAction { Type = QsiReferenceType.Prepared, Operation = QsiReferenceOperation.Delete, IsolationLevel = QsiReferenceIsolationLevel.Session, Target = action.Identifier }; return(refAction.ToResult().AsValueTask()); }
public HtmlTextParser(string html) { if (string.IsNullOrEmpty(html)) { throw new ArgumentNullException("html"); } context = new AnalyzerContext(html, this); index = 0; eof = context.EOF; analyzer = context.GetTextAnalyzer(index); }
protected override async ValueTask <IQsiAnalysisResult> OnExecute(IAnalyzerContext context) { if (!(context.Tree is IQsiTableNode tableNode)) { throw new InvalidOperationException(); } using var scope = new TableCompileContext(context); var table = await BuildTableStructure(scope, tableNode); return(new QsiTableAnalysisResult(table)); }
protected override async ValueTask <IQsiAnalysisResult[]> OnExecute(IAnalyzerContext context) { switch (context.Tree) { case SqlServerMergeActionNode mergeActionNode: return(await ExecuteMergeAction(context, mergeActionNode)); case SqlServerAlterUserActionNode alterUserActionNode: return(new[] { await ExecuteAlterUserAction(context, alterUserActionNode) }); } return(await base.OnExecute(context)); }
protected bool Match(IAnalyzerContext context, QsiTableStructure table, QsiQualifiedIdentifier identifier) { if (!table.HasIdentifier) { return(false); } // * case - Explicit access // ┌──────────────────────────────────────────────────────────┐ // │ SELECT sakila.actor.column FROM sakila.actor │ // │ ▔▔▔▔▔▔^▔▔▔▔▔ == ▔▔▔▔▔▔^▔▔▔▔▔ │ // │ └-> identifier(2) └-> table.Identifier(2) │ // └──────────────────────────────────────────────────────────┘ if (Match(table.Identifier, identifier)) { return(true); } // * case - 2 Level implicit access // ┌──────────────────────────────────────────────────────────┐ // │ SELECT actor.column FROM sakila.actor │ // │ ▔▔▔▔▔ < ▔▔▔▔▔^▔▔▔▔▔ │ // │ └-> identifier(1) └-> table.Identifier(2) │ // └──────────────────────────────────────────────────────────┘ // * case - 3 Level implicit access // ┌──────────────────────────────────────────────────────────┐ // │ SELECT sakila.actor.column FROM db.sakila.actor │ // │ ▔▔▔▔▔▔^▔▔▔▔▔ < ▔▔^▔▔▔▔▔▔^▔▔▔▔▔ │ // │ └-> identifier(2) └-> table.Identifier(3) │ // └──────────────────────────────────────────────────────────┘ if (context.Options.UseExplicitRelationAccess) { return(false); } if (!QsiUtility.IsReferenceType(table.Type)) { return(false); } if (table.Identifier.Level <= identifier.Level) { return(false); } QsiIdentifier[] partialIdentifiers = table.Identifier[^ identifier.Level..];
protected override void AnalyzeSpeakerData(IDocument document, IAnalyzerContext context) { IReadOnlyList <string> languages = document.GetList <string>(SiteKeys.Language); if (languages?.Count > 0) { foreach (string language in languages) { if (!char.IsUpper(language[0])) { context.AddAnalyzerResult(document, $"Please capitalize speaker language: {language}"); } } } }
protected override void AnalyzeSpeakerData(IDocument document, IAnalyzerContext context) { IReadOnlyList <string> topics = document.GetList <string>(SiteKeys.Topics); if (topics == null || topics.Count == 0) { // No topics, but that's okay (if we ever want to enforce at least one topic, add an analyzer result here) return; } string[] nonApprovedTopics = topics.Where(x => !Topics.Contains(x)).ToArray(); if (nonApprovedTopics.Length > 0) { context.AddAnalyzerResult(document, $"Document contains non-approved topic(s): {string.Join(", ", nonApprovedTopics)}"); } }
protected override void Analyze(IAnalyzerContext context) { IDirectory dataDirectory = context.FileSystem.GetRootDirectory("data"); foreach (IFile dataFile in dataDirectory.GetFiles(System.IO.SearchOption.AllDirectories)) { if (!dataFile.Path.Extension.Equals(".yml")) { context.AddAnalyzerResult(null, $"File {dataDirectory.Parent.Path.GetRelativePath(dataFile.Path.FullPath)} should have a .yml extension"); } if (dataFile.Path.FileName.FullPath.ToLower() != dataFile.Path.FileName || dataFile.Path.FileNameWithoutExtension.FullPath.Any(c => !char.IsLetterOrDigit(c) && c != '-')) { context.AddAnalyzerResult(null, $"File {dataDirectory.Parent.Path.GetRelativePath(dataFile.Path.FullPath)} should only contain lowercase letters, digits, and dashes"); } } }
protected override void AnalyzeSpeakerData(IDocument document, IAnalyzerContext context) { foreach (KeyValuePair <string, SpeakerLinkAttribute> linkAttribute in SpeakerLinkAttribute.GetAll()) { if (document.ContainsKey(linkAttribute.Key)) { if (!Uri.TryCreate(document.GetString(linkAttribute.Key), UriKind.Absolute, out Uri uri)) { context.AddAnalyzerResult(document, $"{linkAttribute.Key} link {document.GetString(linkAttribute.Key)} is invalid"); } else if (linkAttribute.Value.EnforceHttps && uri.Scheme != Uri.UriSchemeHttps) { context.AddAnalyzerResult(document, $"{linkAttribute.Key} link should be HTTPS and was not"); } } } }
private IEnumerable <ColumnPlan> CompileColumnPlan(IAnalyzerContext context, QsiTableStructure table, IQsiColumnsDeclarationNode columns) { if (columns.Columns.All(c => c is IQsiAllColumnNode)) { return(table.Columns.Select(c => new ColumnPlan(c.Name))); } var plans = new Dictionary <QsiIdentifier, ColumnPlan>(IdentifierComparer); foreach (var column in columns) { QsiIdentifier identifier; ISelector[] selectors = null; switch (column) { case IQsiDeclaredColumnNode declaredColumn: { identifier = declaredColumn.Name[^ 1];
protected virtual ValueTask <IQsiAnalysisResult> ExecutePrepareAction(IAnalyzerContext context, IQsiPrepareActionNode action) { string query; switch (action.Query) { case IQsiLiteralExpressionNode { Type: QsiDataType.String } literal: query = literal.Value?.ToString(); break; case IQsiVariableExpressionNode variableAccess: var variable = context.Engine.RepositoryProvider.LookupVariable(variableAccess.Identifier) ?? throw new QsiException(QsiError.UnknownVariable, variableAccess.Identifier); if (variable.Type != QsiDataType.String) { throw new InvalidOperationException(); } query = variable.Value.ToString(); break; default: throw new InvalidOperationException(); } var scriptType = context.Engine.ScriptParser.GetSuitableType(query); var refAction = new QsiReferenceAction { Type = QsiReferenceType.Prepared, Operation = QsiReferenceOperation.Create, IsolationLevel = QsiReferenceIsolationLevel.Session, Target = action.Identifier, Definition = new QsiScript(query, scriptType) }; return(refAction.ToResult().AsValueTask()); }
protected async ValueTask <IQsiAnalysisResult[]> ExecuteMergeAction(IAnalyzerContext context, SqlServerMergeActionNode mergeActionNode) { var results = new List <IQsiAnalysisResult>(); foreach (var actionNode in mergeActionNode.ActionNodes) { IQsiAnalysisResult[] result; switch (actionNode) { case QsiDataInsertActionNode insertActionNode: { result = await ExecuteDataInsertAction(context, insertActionNode); break; } case QsiDataDeleteActionNode deleteActionNode: { result = await ExecuteDataDeleteAction(context, deleteActionNode); break; } case QsiDataUpdateActionNode updateActionNode: { result = await ExecuteDataUpdateAction(context, updateActionNode); break; } default: throw TreeHelper.NotSupportedTree(actionNode); } results.AddRange(result); } return(results.ToArray()); }
internal void CloseNonNestedParents(int htmlStart, string tag, IAnalyzerContext context, ref HtmlNode parent) { if (parent == null) { return; } if (string.IsNullOrEmpty(tag) || string.IsNullOrEmpty(parent.Tag)) { return; } List<string> parentTags; if (nonNestedTags.TryGetValue(tag.Trim().ToLower(), out parentTags)) { if (parentTags.Contains(parent.Tag.Trim().ToLower())) { parent.SetBoundary(htmlStart, htmlStart); context.PreviousNode = parent; parent = parent.GetParent(); } } }
protected override async ValueTask <IQsiAnalysisResult> ExecuteDataDeleteAction(IAnalyzerContext context, IQsiDataDeleteActionNode action) { var tableAnalyzer = context.Engine.GetAnalyzer <QsiTableAnalyzer>(); using var tableContext = new TableCompileContext(context); var table = (await tableAnalyzer.BuildTableStructure(tableContext, action.Target)).References[0]; var tempTable = CreateTemporaryTable(table.Identifier); var commonTableNode = ReassembleCommonTableNode(action.Target); var dataTable = await GetDataTableByCommonTableNode(context, commonTableNode); var deleteRows = new QsiDataRowCollection(1); foreach (var row in dataTable.Rows) { var targetRow = deleteRows.NewRow(); targetRow.Items[0] = row.Items[0]; } var dataAction = new QsiDataAction { Table = tempTable, DeleteRows = deleteRows.ToNullIfEmpty() }; return((new[] { dataAction }).ToResult()); }
protected AnalyzerContextWrapper(IAnalyzerContext context) { _context = context; }
protected HtmlAnalyzer(IAnalyzerContext context) { if (context == null) { throw new ArgumentNullException("context"); } this.context = context; }
public TextAnalyzer(IAnalyzerContext context, int position, HtmlNode parent) : this(context, position) { this.parent = parent; }
public CommentAnalyzer(IAnalyzerContext context) : base(context) { onTagExecuted = false; }
public CloseTagAnalyzer(IAnalyzerContext context) : base(context) { tagStart = -1; }
protected abstract ValueTask <IQsiAnalysisResult> OnExecute(IAnalyzerContext context);
protected abstract void AnalyzeSpeakerData(IDocument document, IAnalyzerContext context);
protected override async ValueTask <IQsiAnalysisResult> ExecuteDataUpdateAction(IAnalyzerContext context, IQsiDataUpdateActionNode action) { var tableAnalyzer = context.Engine.GetAnalyzer <QsiTableAnalyzer>(); using var tableContext = new TableCompileContext(context); var table = (await tableAnalyzer.BuildTableStructure(tableContext, action.Target)).References[0]; var tempTable = CreateTemporaryTable(table.Identifier); var commonTableNode = ReassembleCommonTableNode(action.Target); var dataTable = await GetDataTableByCommonTableNode(context, commonTableNode); var updateBeforeRows = new QsiDataRowCollection(1); var updateAfterRows = new QsiDataRowCollection(1); (object[], QsiExpressionNode, bool)[] setValues = action.SetValues
public TableDataInsertContext(IAnalyzerContext context, QsiTableStructure table) : base(context, table) { }
public OpenTagAnalyzer(IAnalyzerContext context) : base(context) { tagStart = -1; }
protected TableDataContext(IAnalyzerContext context, QsiTableStructure table) : base(context) { Table = table; }