/// <summary>Change the current global namespace.</summary> /// <remarks>Do NOT call this, unless you know exactly what you are doing !</remarks> internal void ChangeRoot(FdbSubspace subspace, IFdbDirectory directory, bool readOnly) { subspace = subspace ?? FdbSubspace.Empty; lock (this) //TODO: don't use this for locking { m_readOnly = readOnly; m_globalSpace = subspace; m_globalSpaceCopy = subspace.Copy(); m_directory = directory == null ? null : new FdbDatabasePartition(this, directory); } }
public static async Task <IFdbDatabase> OpenNamedPartitionAsync(string clusterFile, string dbName, [NotNull] IEnumerable <string> path, bool readOnly, CancellationToken cancellationToken) { if (path == null) { throw new ArgumentNullException("path"); } var partitionPath = path.ToList(); if (partitionPath.Count == 0) { throw new ArgumentException("The path to the named partition cannot be empty", "path"); } // looks at the global partition table for the specified named partition // By convention, all named databases will be under the "/Databases" folder FdbDatabase db = null; var rootSpace = FdbSubspace.Empty; try { db = await Fdb.OpenInternalAsync(clusterFile, dbName, rootSpace, readOnly : false, cancellationToken : cancellationToken).ConfigureAwait(false); var rootLayer = FdbDirectoryLayer.Create(rootSpace); if (Logging.On) { Logging.Verbose(typeof(Fdb.Directory), "OpenNamedPartitionAsync", String.Format("Opened root layer of database {0} using cluster file '{1}'", db.Name, db.Cluster.Path)); } // look up in the root layer for the named partition var descriptor = await rootLayer.CreateOrOpenAsync(db, partitionPath, layer : FdbDirectoryPartition.LayerId, cancellationToken : cancellationToken).ConfigureAwait(false); if (Logging.On) { Logging.Verbose(typeof(Fdb.Directory), "OpenNamedPartitionAsync", String.Format("Found named partition '{0}' at prefix {1}", descriptor.FullName, descriptor)); } // we have to chroot the database to the new prefix, and create a new DirectoryLayer with a new '/' rootSpace = FdbSubspace.Copy(descriptor); //note: create a copy of the key //TODO: find a nicer way to do that! db.ChangeRoot(rootSpace, FdbDirectoryLayer.Create(rootSpace, partitionPath), readOnly); if (Logging.On) { Logging.Info(typeof(Fdb.Directory), "OpenNamedPartitionAsync", String.Format("Opened partition {0} at {1}, using directory layer at {2}", descriptor.FullName, db.GlobalSpace, db.Directory.DirectoryLayer.NodeSubspace)); } return(db); } catch (Exception e) { if (db != null) { db.Dispose(); } if (Logging.On) { Logging.Exception(typeof(Fdb.Directory), "OpenNamedPartitionAsync", e); } throw; } }