Ejemplo n.º 1
0
        /// <summary>
        /// Loads the schema for the specified database and returns a new <see cref="GlobalState"/> with the database added or updated.
        /// </summary>
        private async Task <GlobalState> AddOrUpdateDatabaseAsync(GlobalState globals, string databaseName, string clusterName, bool asDefault, bool throwOnError, CancellationToken cancellation)
        {
            var db = await LoadDatabaseAsync(databaseName, clusterName, throwOnError, cancellation).ConfigureAwait(false);

            if (db == null)
            {
                return(globals);
            }

            var clusterHost = GetClusterHost(clusterName);

            var cluster = globals.GetCluster(clusterHost);

            if (cluster == null)
            {
                cluster = new ClusterSymbol(clusterHost, new[] { db }, isOpen: true);
                globals = globals.WithClusterList(globals.Clusters.Concat(new[] { cluster }).ToArray());
            }
            else
            {
                cluster = cluster.AddOrUpdateDatabase(db);
                globals = globals.WithClusterList(globals.Clusters.Select(c => c.Name == cluster.Name ? cluster : c).ToArray());
            }

            if (asDefault)
            {
                globals = globals.WithCluster(cluster).WithDatabase(db);
            }

            return(globals);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Loads and adds the <see cref="DatabaseSymbol"/> for any database explicity referenced in the query but not already present in the <see cref="GlobalState"/>.
        /// </summary>
        private async Task <GlobalState> AddReferencedDatabasesAsync(GlobalState globals, CodeService service, CancellationToken cancellationToken = default)
        {
            // find all explicit cluster (xxx) references
            var clusterRefs = service.GetClusterReferences(cancellationToken);

            foreach (ClusterReference clusterRef in clusterRefs)
            {
                // don't bother with cluster names that we've already shown to not exist
                if (_ignoreClusterNames.Contains(clusterRef.Cluster))
                {
                    continue;
                }

                var cluster = globals.GetCluster(clusterRef.Cluster);
                if (cluster == null || cluster.IsOpen)
                {
                    // check to see if this is an actual cluster and get all database names
                    var databaseNames = await GetDatabaseNamesAsync(clusterRef.Cluster).ConfigureAwait(false);

                    if (databaseNames != null)
                    {
                        // initially populate with empty 'open' databases. These will get updated to full schema if referenced
                        var databases = databaseNames.Select(db => new DatabaseSymbol(db, null, isOpen: true)).ToArray();
                        cluster = new ClusterSymbol(clusterRef.Cluster, databases);
                        globals = globals.WithClusterList(globals.Clusters.Concat(new[] { cluster }).ToArray());
                    }
                }
                else
                {
                    // we already have all the schema for this cluster
                    _ignoreClusterNames.Add(clusterRef.Cluster);
                }
            }

            // examine all explicit database(xxx) references
            var dbRefs = service.GetDatabaseReferences(cancellationToken);

            foreach (DatabaseReference dbRef in dbRefs)
            {
                // get implicit or explicit named cluster
                var cluster = string.IsNullOrEmpty(dbRef.Cluster) ? globals.Cluster : globals.GetCluster(dbRef.Cluster);

                if (cluster != null)
                {
                    // look for existing database of this name
                    var db = cluster.Databases.FirstOrDefault(m => m.Name == dbRef.Database);

                    // is this one of those not-yet-populated databases?
                    if (db == null || (db != null && db.Members.Count == 0 && db.IsOpen))
                    {
                        var newGlobals = await AddOrUpdateDatabaseAsync(globals, dbRef.Database, cluster.Name, asDefault : false, throwOnError : false, cancellationToken).ConfigureAwait(false);

                        globals = newGlobals != null ? newGlobals : globals;
                    }
                }
            }

            return(globals);
        }