/// <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}");
                }
            }
Пример #2
0
            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;
                }
            }