/// <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); }
/// <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); }