/// <summary>Opens a named partition, and change the root subspace of the database to the corresponding prefix</summary> internal static async Task SwitchToNamedPartitionAsync([NotNull] FdbDatabase db, [NotNull, ItemNotNull] string[] path, bool readOnly, CancellationToken ct) { Contract.Requires(db != null && path != null); ct.ThrowIfCancellationRequested(); if (path.Length == 0) { throw new ArgumentException("The path to the named partition cannot be empty", nameof(path)); } if (Logging.On) { Logging.Verbose(typeof(Fdb.Directory), "OpenNamedPartitionAsync", $"Opened root layer of database {db.Name} using cluster file '{db.Cluster.Path}'"); } // look up in the root layer for the named partition var descriptor = await db.Directory.CreateOrOpenAsync(path, layer : FdbDirectoryPartition.LayerId, ct : ct).ConfigureAwait(false); if (Logging.On) { Logging.Verbose(typeof(Fdb.Directory), "OpenNamedPartitionAsync", $"Found named partition '{descriptor.FullName}' at prefix {descriptor}"); } // we have to chroot the database to the new prefix, and create a new DirectoryLayer with a new '/' var rootSpace = descriptor.Copy(); //note: create a copy of the key //TODO: find a nicer way to do that! db.ChangeRoot(rootSpace, FdbDirectoryLayer.Create(rootSpace, path), readOnly); if (Logging.On) { Logging.Info(typeof(Fdb.Directory), "OpenNamedPartitionAsync", $"Opened partition {descriptor.FullName} at {db.GlobalSpace}, using directory layer at {db.Directory.DirectoryLayer.NodeSubspace}"); } }
public static async Task <IFdbDatabase> OpenNamedPartitionAsync(string clusterFile, string dbName, [NotNull] IEnumerable <string> path, bool readOnly, CancellationToken ct) { if (path == null) { throw new ArgumentNullException(nameof(path)); } var partitionPath = path.ToList(); if (partitionPath.Count == 0) { throw new ArgumentException("The path to the named partition cannot be empty", nameof(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 = KeySubspace.Empty; try { db = await Fdb.OpenInternalAsync(clusterFile, dbName, rootSpace, readOnly : false, ct : ct).ConfigureAwait(false); var rootLayer = FdbDirectoryLayer.Create(rootSpace); if (Logging.On) { Logging.Verbose(typeof(Fdb.Directory), "OpenNamedPartitionAsync", $"Opened root layer of database {db.Name} using cluster file '{db.Cluster.Path}'"); } // look up in the root layer for the named partition var descriptor = await rootLayer.CreateOrOpenAsync(db, partitionPath, layer : FdbDirectoryPartition.LayerId, ct : ct).ConfigureAwait(false); if (Logging.On) { Logging.Verbose(typeof(Fdb.Directory), "OpenNamedPartitionAsync", $"Found named partition '{descriptor.FullName}' at prefix {descriptor}"); } // we have to chroot the database to the new prefix, and create a new DirectoryLayer with a new '/' rootSpace = descriptor.Copy(); //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", $"Opened partition {descriptor.FullName} at {db.GlobalSpace}, using directory layer at {db.Directory.DirectoryLayer.NodeSubspace}"); } return(db); } catch (Exception e) { db?.Dispose(); if (Logging.On) { Logging.Exception(typeof(Fdb.Directory), "OpenNamedPartitionAsync", e); } throw; } }