/// <summary> /// Gets the <see cref="ClusterSymbol"/> that contains the <see cref="DatabaseSymbol"/>. /// </summary> public ClusterSymbol GetCluster(DatabaseSymbol database) { if (database == null) { return(null); } if (this.reverseClusterMap == null) { var map = new Dictionary <Symbol, ClusterSymbol>(); foreach (var cluster in this.Clusters) { foreach (var member in cluster.Members) { map[member] = cluster; } } Interlocked.CompareExchange(ref this.reverseClusterMap, map, null); } this.reverseClusterMap.TryGetValue(database, out var result); return(result); }
private GlobalState( IReadOnlyList <ClusterSymbol> clusters, ClusterSymbol cluster, DatabaseSymbol database, IReadOnlyList <FunctionSymbol> functions, Dictionary <string, FunctionSymbol> functionMap, IReadOnlyList <FunctionSymbol> aggregates, Dictionary <string, FunctionSymbol> aggregateMap, IReadOnlyList <FunctionSymbol> plugins, Dictionary <string, FunctionSymbol> pluginMap, IReadOnlyList <OperatorSymbol> operators, Dictionary <OperatorKind, OperatorSymbol> operatorMap, IReadOnlyList <CommandSymbol> commands, Dictionary <string, CommandSymbol> commandMap, Dictionary <string, IReadOnlyList <CommandSymbol> > commandListMap, IReadOnlyList <ParameterSymbol> parameters, IReadOnlyList <OptionSymbol> options) { this.Clusters = clusters; this.Cluster = cluster ?? new ClusterSymbol("", databases: null, isOpen: true); this.Database = database ?? new DatabaseSymbol("", members: null, isOpen: true); this.Functions = functions; this.Aggregates = aggregates; this.PlugIns = plugins; this.Operators = operators; this.Commands = commands; this.commandMap = commandMap; this.commandListMap = commandListMap; this.Parameters = parameters.ToReadOnly(); this.Options = options; }
/// <summary> /// Constructs a new <see cref="GlobalState"/> with the specified default database. /// </summary> public GlobalState WithDatabase(DatabaseSymbol database) { database = database ?? DatabaseSymbol.Unknown; if (this.Database == database) { return(this); } else if (database == DatabaseSymbol.Unknown || this.Cluster.Databases.Contains(database)) { // same cluster, just change database return(With(database: database)); } else { // check if it is a database of some other known cluster var knownCluster = GetCluster(database); if (knownCluster != null) { // changing the current database changes the current cluster too return(With(cluster: knownCluster, database: database)); } else { // the database must be part of a known cluster, so add a cluster for it to be part of var cluster = new ClusterSymbol(database.Name + ":cluster", database); return(WithCluster(cluster).WithDatabase(database)); } } }
private GlobalState( IReadOnlyList <ClusterSymbol> clusters, ClusterSymbol cluster, DatabaseSymbol database, IReadOnlyList <FunctionSymbol> functions, Dictionary <string, FunctionSymbol> functionMap, IReadOnlyList <FunctionSymbol> aggregates, Dictionary <string, FunctionSymbol> aggregateMap, IReadOnlyList <FunctionSymbol> plugins, Dictionary <string, FunctionSymbol> pluginMap, IReadOnlyList <OperatorSymbol> operators, Dictionary <OperatorKind, OperatorSymbol> operatorMap, IReadOnlyList <CommandSymbol> commands, Dictionary <string, CommandSymbol> commandMap, Dictionary <string, IReadOnlyList <CommandSymbol> > commandListMap, IReadOnlyList <ParameterSymbol> parameters, IReadOnlyList <OptionSymbol> options) { this.Clusters = clusters ?? EmptyReadOnlyList <ClusterSymbol> .Instance; this.Cluster = cluster ?? ClusterSymbol.Unknown; this.Database = database ?? DatabaseSymbol.Unknown; this.Functions = functions ?? EmptyReadOnlyList <FunctionSymbol> .Instance; this.Aggregates = aggregates ?? EmptyReadOnlyList <FunctionSymbol> .Instance; this.PlugIns = plugins ?? EmptyReadOnlyList <FunctionSymbol> .Instance; this.Operators = operators ?? EmptyReadOnlyList <OperatorSymbol> .Instance; this.Commands = commands ?? EmptyReadOnlyList <CommandSymbol> .Instance; this.commandMap = commandMap; this.commandListMap = commandListMap; this.Parameters = parameters ?? EmptyReadOnlyList <ParameterSymbol> .Instance; this.Options = options ?? EmptyReadOnlyList <OptionSymbol> .Instance; }
/// <summary> /// Constructs a new <see cref="GlobalState"/> instance. /// </summary> private GlobalState( IReadOnlyList <ClusterSymbol> clusters, ClusterSymbol cluster, DatabaseSymbol database, IReadOnlyList <FunctionSymbol> functions, IReadOnlyList <FunctionSymbol> aggregates, IReadOnlyList <FunctionSymbol> plugins, IReadOnlyList <OperatorSymbol> operators, IReadOnlyList <CommandSymbol> commands, IReadOnlyList <ParameterSymbol> parameters, IReadOnlyList <OptionSymbol> options, KustoCache cache, Dictionary <Symbol, ClusterSymbol> reverseClusterMap, Dictionary <Symbol, DatabaseSymbol> reverseDatabaseMap, Dictionary <Symbol, TableSymbol> reverseTableMap, Dictionary <string, FunctionSymbol> functionsMap, Dictionary <string, FunctionSymbol> aggregatesMap, Dictionary <string, FunctionSymbol> pluginMap, Dictionary <OperatorKind, OperatorSymbol> operatorMap, Dictionary <string, CommandSymbol> commandMap, Dictionary <string, OptionSymbol> optionMap) { this.Clusters = clusters ?? EmptyReadOnlyList <ClusterSymbol> .Instance; this.Cluster = cluster ?? ClusterSymbol.Unknown; this.Database = database ?? DatabaseSymbol.Unknown; this.Functions = functions ?? EmptyReadOnlyList <FunctionSymbol> .Instance; this.Aggregates = aggregates ?? EmptyReadOnlyList <FunctionSymbol> .Instance; this.PlugIns = plugins ?? EmptyReadOnlyList <FunctionSymbol> .Instance; this.Operators = operators ?? EmptyReadOnlyList <OperatorSymbol> .Instance; this.Commands = commands ?? EmptyReadOnlyList <CommandSymbol> .Instance; this.Parameters = parameters ?? EmptyReadOnlyList <ParameterSymbol> .Instance; this.Options = options ?? EmptyReadOnlyList <OptionSymbol> .Instance; this.Cache = cache != null?cache.WithGlobals(this) : null; this.reverseClusterMap = reverseClusterMap; this.reverseDatabaseMap = reverseDatabaseMap; this.reverseTableMap = reverseTableMap; this.functionsMap = functionsMap; this.aggregatesMap = aggregatesMap; this.pluginMap = pluginMap; this.operatorMap = operatorMap; this.commandMap = commandMap; this.optionMap = optionMap; }
/// <summary> /// Constructs a new <see cref="GlobalState"/> with the specified default database. /// </summary> public GlobalState WithDatabase(DatabaseSymbol database) { if (this.Cluster != null && this.Cluster.Databases.Contains(database)) { // same cluster, just change database return(With(database: database)); } else { var existingCluster = GetCluster(database); if (existingCluster != null) { // changing the current database changes the current cluster too return(With(cluster: existingCluster, database: database)); } else { // no existing cluster for this database, so make a new one var cluster = new ClusterSymbol(database.Name + ":cluster", database); return(WithCluster(cluster).With(database: database)); } } }
/// <summary> /// Loads the schema for the specified database into a <see cref="DatabaseSymbol"/>. /// </summary> public async Task <DatabaseSymbol> LoadDatabaseAsync(string databaseName, string clusterName = null, bool throwOnError = false, CancellationToken cancellationToken = default) { var connection = GetClusterConnection(clusterName); var tables = await LoadTablesAsync(connection, databaseName, throwOnError, cancellationToken).ConfigureAwait(false); var externalTables = await LoadExternalTablesAsync(connection, databaseName, throwOnError, cancellationToken).ConfigureAwait(false); var materializedViews = await LoadMaterializedViewsAsync(connection, databaseName, throwOnError, cancellationToken).ConfigureAwait(false); var functions = await LoadFunctionsAsync(connection, databaseName, throwOnError, cancellationToken).ConfigureAwait(false); var members = new List <Symbol>(); members.AddRange(tables); members.AddRange(externalTables); members.AddRange(materializedViews); members.AddRange(functions); var databaseSymbol = new DatabaseSymbol(databaseName, members); return(databaseSymbol); }
/// <summary> /// Create tools for the shape toolbox and sort them into custom categories /// </summary> private void CreateTools() { toolSetPresenter.ToolSetController.Clear(); toolSetPresenter.ToolSetController.AddTool(new SelectionTool(), true); string category = "Database Entities"; DatabaseSymbol databaseShape = (DatabaseSymbol)project.ShapeTypes["Database"].CreateInstance(); databaseShape.Width = 120; databaseShape.Height = 120; databaseShape.FillStyle = project.Design.FillStyles.Yellow; databaseShape.CharacterStyle = project.Design.CharacterStyles.Heading3; databaseShape.Text = "Database"; CreateTemplateAndTool("Database", category, databaseShape); EntitySymbol tableShape = (EntitySymbol)project.ShapeTypes["Entity"].CreateInstance(); tableShape.Width = 100; tableShape.Height = 160; tableShape.FillStyle = project.Design.FillStyles.Red; tableShape.CharacterStyle = project.Design.CharacterStyles.Heading3; tableShape.ParagraphStyle = project.Design.ParagraphStyles.Title; tableShape.ColumnCharacterStyle = project.Design.CharacterStyles.Caption; tableShape.ColumnParagraphStyle = project.Design.ParagraphStyles.Label; CreateTemplateAndTool("Entity", category, tableShape); RectangularLine line; ShapeType relationShapeType = project.ShapeTypes["RectangularLine"]; line = (RectangularLine)relationShapeType.CreateInstance(); line.LineStyle = project.Design.LineStyles.Thick; CreateTemplateAndTool("Relationship", category, line); line = (RectangularLine)relationShapeType.CreateInstance(); line.LineStyle = project.Design.LineStyles.Thick; line.EndCapStyle = project.Design.CapStyles.ClosedArrow; CreateTemplateAndTool("1:n Relationship", category, line); line = (RectangularLine)relationShapeType.CreateInstance(); line.LineStyle = project.Design.LineStyles.Thick; line.StartCapStyle = project.Design.CapStyles.ClosedArrow; line.EndCapStyle = project.Design.CapStyles.ClosedArrow; CreateTemplateAndTool("n:m Relationship", category, line); CloudSymbol cloudShape = (CloudSymbol)project.ShapeTypes["Cloud"].CreateInstance(); cloudShape.FillStyle = project.Design.FillStyles.Blue; cloudShape.CharacterStyle = project.Design.CharacterStyles.Heading1; cloudShape.Width = 300; cloudShape.Height = 160; cloudShape.Text = "WAN / LAN"; CreateTemplateAndTool("Cloud", category, cloudShape); category = "Description"; Text text = (Text)project.ShapeTypes["Text"].CreateInstance(); text.CharacterStyle = project.Design.CharacterStyles.Normal; text.Width = 100; CreateTemplateAndTool("Text", category, text); AnnotationSymbol annotationShape = (AnnotationSymbol)project.ShapeTypes["Annotation"].CreateInstance(); annotationShape.FillStyle = project.Design.FillStyles.White; annotationShape.CharacterStyle = project.Design.CharacterStyles.Caption; annotationShape.ParagraphStyle = project.Design.ParagraphStyles.Text; annotationShape.Width = 120; annotationShape.Height = 120; CreateTemplateAndTool("Annotation", category, annotationShape); category = "Miscellaneous"; RoundedBox roundedRectangle = (RoundedBox)project.ShapeTypes["RoundedBox"].CreateInstance(); roundedRectangle.FillStyle = project.Design.FillStyles.Green; roundedRectangle.Width = 120; roundedRectangle.Height = 80; CreateTemplateAndTool("Box", category, roundedRectangle); Ellipse ellipse = (Ellipse)project.ShapeTypes["Ellipse"].CreateInstance(); ellipse.FillStyle = project.Design.FillStyles.Yellow; ellipse.Width = 120; ellipse.Height = 80; CreateTemplateAndTool("Ellipse", category, ellipse); Picture picture = (Picture)project.ShapeTypes["Picture"].CreateInstance(); picture.FillStyle = project.Design.FillStyles.Transparent; picture.Width = 120; picture.Height = 120; CreateTemplateAndTool("Picture", category, picture); ShapeType arcShapeType = project.ShapeTypes["CircularArc"]; CircularArc arc; arc = (CircularArc)arcShapeType.CreateInstance(); arc.LineStyle = project.Design.LineStyles.Thick; CreateTemplateAndTool("Arc", category, arc); arc = (CircularArc)arcShapeType.CreateInstance(); arc.LineStyle = project.Design.LineStyles.Thick; arc.EndCapStyle = project.Design.CapStyles.ClosedArrow; CreateTemplateAndTool("Bowed Arrow", category, arc); arc = (CircularArc)arcShapeType.CreateInstance(); arc.LineStyle = project.Design.LineStyles.Thick; arc.StartCapStyle = project.Design.CapStyles.ClosedArrow; arc.EndCapStyle = project.Design.CapStyles.ClosedArrow; CreateTemplateAndTool("Bowed Double Arrow", category, arc); }
private void GetDatabaseReferences(SyntaxNode root, SyntaxNode location, ClusterSymbol defaultCluster, DatabaseSymbol defaultDatabase, List <DatabaseReference> refs, CancellationToken cancellationToken) { root.WalkElements(element => { cancellationToken.ThrowIfCancellationRequested(); if (element is FunctionCallExpression fc && fc.ReferencedSymbol is FunctionSymbol fs) { if (fs == Functions.Database) { var dbref = GetDatabaseReference(fc, location, defaultCluster); if (dbref != null) { refs.Add(dbref); } } else if (fs.Signatures[0].HasDatabaseCall) { var expansion = fc.GetExpansion(); if (expansion != null) { var db = defaultDatabase; var cluster = defaultCluster; db = this.globals.GetDatabase(fs) ?? defaultDatabase; cluster = this.globals.GetCluster(db) ?? defaultCluster; GetDatabaseReferences(expansion, location ?? fc.Name, cluster, db, refs, cancellationToken); } } } }); }