/// <summary>
        /// Add a new collection. Check if name the not exists. Create only in transaction page - will update header only in commit
        /// </summary>
        private void Add(string name, ref CollectionPage collectionPage)
        {
            if (Encoding.UTF8.GetByteCount(name) > _header.GetAvaiableCollectionSpace())
            {
                throw LiteException.InvalidCollectionName(name, "There is no space in header for more collections");
            }
            if (!name.IsWord())
            {
                throw LiteException.InvalidCollectionName(name, "Use only [a-Z$_]");
            }
            if (name.StartsWith("$"))
            {
                throw LiteException.InvalidCollectionName(name, "Collection can't starts with `$` (reserved for system collections)");
            }

            // create new collection page
            collectionPage = _snapshot.NewPage <CollectionPage>();
            var pageID = collectionPage.PageID;

            // insert collection name/pageID in header only in commit operation
            _transPages.Commit += (h) => h.InsertCollection(name, pageID);

            // create first index (_id pk) (must pass collectionPage because snapshot contains null in CollectionPage prop)
            var indexer = new IndexService(_snapshot);

            indexer.CreateIndex("_id", "$._id", true);
        }
Beispiel #2
0
        /// <summary>
        /// Rename a collection (do not support transactions)
        /// </summary>
        public bool RenameCollection(string collection, string newName)
        {
            if (collection.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException(nameof(collection));
            }
            if (newName.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException(nameof(newName));
            }

            // rename collection is possible only in exclusive transaction for this
            if (_locker.IsInTransaction)
            {
                throw LiteException.AlreadyExistsTransaction();
            }

            // check for collection name
            if (collection.Equals(newName, StringComparison.OrdinalIgnoreCase))
            {
                throw LiteException.InvalidCollectionName(newName, "New name must be different from current name");
            }

            // checks if newName are compatible
            CollectionService.CheckName(newName, _header);

            // rename collection is possible only in exclusive transaction for this
            if (_locker.IsInTransaction)
            {
                throw LiteException.AlreadyExistsTransaction();
            }

            return(this.AutoTransaction(transaction =>
            {
                var currentSnapshot = transaction.CreateSnapshot(LockMode.Write, collection, false);
                var newSnapshot = transaction.CreateSnapshot(LockMode.Write, newName, false);

                if (currentSnapshot.CollectionPage == null)
                {
                    return false;
                }

                // checks if do not already exists this collection name
                if (_header.GetCollectionPageID(newName) != uint.MaxValue)
                {
                    throw LiteException.AlreadyExistsCollectionName(newName);
                }

                // rename collection and set page as dirty (there is no need to set IsDirty in HeaderPage)
                transaction.Pages.Commit += (h) =>
                {
                    h.RenameCollection(collection, newName);
                };

                return true;
            }));
        }
Beispiel #3
0
 /// <summary>
 /// Check collection name if is valid (and fit on header)
 /// Throw correct message error if not valid name or not fit on header page
 /// </summary>
 public static void CheckName(string name, HeaderPage header)
 {
     if (Encoding.UTF8.GetByteCount(name) > header.GetAvaiableCollectionSpace())
     {
         throw LiteException.InvalidCollectionName(name, "There is no space in header this collection name");
     }
     if (!name.IsWord())
     {
         throw LiteException.InvalidCollectionName(name, "Use only [a-Z$_]");
     }
     if (name.StartsWith("$"))
     {
         throw LiteException.InvalidCollectionName(name, "Collection can't starts with `$` (reserved for system collections)");
     }
 }