Exemple #1
0
        public bool Update(UpdateStep step)
        {
            // When the revision are enabled and we delete a document we stored it with a 'RevisionDelete' flag. This flag was used to find the deleted revisions.
            // Now we store the resolved conflicts as revisions, so it could be, that a deleted revision will contain flags such as 'Conflicted' or 'Resolved'.

            // This change require use to change the index definition and the logic of how we find the deleted revisions.
            // So we say that if the revision is deleted it will be stored with the 'DeletedEtag' to the etag value,
            // otherwise (if the revision is a document) it will be stored with 'DeletedEtag' set to 0.

            step.DocumentsStorage.RevisionsStorage = new RevisionsStorage(step.DocumentsStorage.DocumentDatabase, step.WriteTx);

            using (step.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                step.WriteTx.DeleteTree("RevisionsFlagsAndEtag"); // remove the old index
                step.WriteTx.CreateTree(DeleteRevisionEtagSlice);
                foreach (var collection in step.DocumentsStorage.RevisionsStorage.GetCollections(step.ReadTx))
                {
                    var collectionName = new CollectionName(collection);
                    var tableName      = collectionName.GetTableName(CollectionTableType.Revisions);
                    var readTable      = step.ReadTx.OpenTable(RevisionsSchema, tableName);
                    if (readTable == null)
                    {
                        continue;
                    }

                    var writeTable = step.DocumentsStorage.RevisionsStorage.EnsureRevisionTableCreated(step.WriteTx, collectionName);
                    foreach (var read in readTable.SeekForwardFrom(RevisionsSchema.FixedSizeIndexes[CollectionRevisionsEtagsSlice], 0, 0))
                    {
                        using (TableValueReaderUtil.CloneTableValueReader(context, read))
                            using (writeTable.Allocate(out TableValueBuilder write))
                            {
                                var flags = TableValueToFlags((int)Columns.Flags, ref read.Reader);
                                write.Add(read.Reader.Read((int)Columns.ChangeVector, out int size), size);
                                write.Add(read.Reader.Read((int)Columns.LowerId, out size), size);
                                write.Add(read.Reader.Read((int)Columns.RecordSeparator, out size), size);
                                write.Add(read.Reader.Read((int)Columns.Etag, out size), size);
                                write.Add(read.Reader.Read((int)Columns.Id, out size), size);
                                write.Add(read.Reader.Read((int)Columns.Document, out size), size);
                                write.Add((int)flags);
                                if ((flags & DocumentFlags.DeleteRevision) == DocumentFlags.DeleteRevision)
                                {
                                    write.Add(read.Reader.Read((int)Columns.Etag, out size), size); // set the DeletedEtag
                                }
                                else
                                {
                                    write.Add(NotDeletedRevisionMarker);
                                }
                                write.Add(read.Reader.Read((int)Columns.LastModified, out size), size);
                                write.Add(read.Reader.Read((int)Columns.TransactionMarker, out size), size);
                                writeTable.Set(write, true);
                            }
                    }
                }
            }
            return(true);
        }
Exemple #2
0
        public bool Update(UpdateStep step)
        {
            step.DocumentsStorage.RevisionsStorage = new RevisionsStorage(step.DocumentsStorage.DocumentDatabase, step.WriteTx);

            // update revisions
            using (step.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                foreach (var collection in step.DocumentsStorage.RevisionsStorage.GetCollections(step.ReadTx))
                {
                    var collectionName = new CollectionName(collection);
                    var tableName      = collectionName.GetTableName(CollectionTableType.Revisions);
                    var readTable      = step.ReadTx.OpenTable(RevisionsSchema, tableName);
                    if (readTable == null)
                    {
                        continue;
                    }

                    var writeTable = step.DocumentsStorage.RevisionsStorage.EnsureRevisionTableCreated(step.WriteTx, collectionName);
                    foreach (var read in readTable.SeekForwardFrom(RevisionsSchema.FixedSizeIndexes[CollectionRevisionsEtagsSlice], 0, 0))
                    {
                        using (TableValueReaderUtil.CloneTableValueReader(context, read))
                            using (writeTable.Allocate(out TableValueBuilder write))
                            {
                                var flags        = TableValueToFlags((int)Columns.Flags, ref read.Reader);
                                var lastModified = TableValueToDateTime((int)Columns.LastModified, ref read.Reader);

                                write.Add(read.Reader.Read((int)Columns.ChangeVector, out int size), size);
                                write.Add(read.Reader.Read((int)Columns.LowerId, out size), size);
                                write.Add(read.Reader.Read((int)Columns.RecordSeparator, out size), size);
                                write.Add(read.Reader.Read((int)Columns.Etag, out size), size);
                                write.Add(read.Reader.Read((int)Columns.Id, out size), size);
                                write.Add(read.Reader.Read((int)Columns.Document, out size), size);
                                write.Add((int)flags);
                                write.Add(read.Reader.Read((int)Columns.DeletedEtag, out size), size);
                                write.Add(lastModified.Ticks);
                                write.Add(read.Reader.Read((int)Columns.TransactionMarker, out size), size);
                                if ((flags & DocumentFlags.Resolved) == DocumentFlags.Resolved)
                                {
                                    write.Add((int)DocumentFlags.Resolved);
                                }
                                else
                                {
                                    write.Add(0);
                                }
                                write.Add(Bits.SwapBytes(lastModified.Ticks));
                                writeTable.Set(write, true);
                            }
                    }
                }
            }

            return(true);
        }
Exemple #3
0
        public bool Update(UpdateStep step)
        {
            // Update collections
            using (step.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var readTable = step.ReadTx.OpenTable(CollectionsSchema, CollectionsSlice);
                if (readTable != null)
                {
                    var writeTable = step.WriteTx.OpenTable(CollectionsSchema, CollectionsSlice);
                    foreach (var read in readTable.SeekByPrimaryKey(Slices.BeforeAllKeys, 0))
                    {
                        using (TableValueReaderUtil.CloneTableValueReader(context, read))
                        {
                            var collection = TableValueToString(context, (int)CollectionsTable.Name, ref read.Reader);
                            using (DocumentIdWorker.GetStringPreserveCase(context, collection, out Slice collectionSlice))
                                using (writeTable.Allocate(out TableValueBuilder write))
                                {
                                    write.Add(collectionSlice);
                                    var pk = read.Reader.Read((int)CollectionsTable.Name, out int size);
                                    using (Slice.External(context.Allocator, pk, size, out var pkSlice))
                                    {
                                        writeTable.DeleteByKey(pkSlice);
                                    }
                                    writeTable.Insert(write);
                                }
                        }
                    }
                }
            }

            // Update tombstones's collection value
            using (step.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                foreach (var collection in step.DocumentsStorage.GetTombstoneCollections(step.ReadTx))
                {
                    string tableName;
                    if (collection == AttachmentsTombstones ||
                        collection == RevisionsTombstones)
                    {
                        tableName = collection;
                    }
                    else
                    {
                        var collectionName = new CollectionName(collection);
                        tableName = collectionName.GetTableName(CollectionTableType.Tombstones);
                    }

                    var readTable = step.ReadTx.OpenTable(TombstonesSchema, tableName);
                    if (readTable == null)
                    {
                        continue;
                    }

                    var writeTable = step.WriteTx.OpenTable(TombstonesSchema, tableName);
                    // We seek by an index instead the PK because
                    // we weed to ensure that we aren't accessing an IsGlobal key
                    foreach (var read in readTable.SeekForwardFrom(TombstonesSchema.FixedSizeIndexes[CollectionEtagsSlice], 0, 0))
                    {
                        // We copy the memory of the read so AssertNoReferenceToOldData won't throw.
                        // This is done instead of moving AssertNoReferenceToOldData to assert later
                        // after we allocate the new write memory.
                        using (TableValueReaderUtil.CloneTableValueReader(context, read))
                        {
                            var type          = *(Tombstone.TombstoneType *)read.Reader.Read((int)TombstoneTable.Type, out _);
                            var oldCollection = TableValueToString(context, (int)TombstoneTable.Collection, ref read.Reader);
                            using (DocumentIdWorker.GetStringPreserveCase(context, oldCollection, out Slice collectionSlice))
                                using (writeTable.Allocate(out TableValueBuilder write))
                                {
                                    write.Add(read.Reader.Read((int)TombstoneTable.LowerId, out int size), size);
                                    write.Add(read.Reader.Read((int)TombstoneTable.Etag, out size), size);
                                    write.Add(read.Reader.Read((int)TombstoneTable.DeletedEtag, out size), size);
                                    write.Add(read.Reader.Read((int)TombstoneTable.TransactionMarker, out size), size);
                                    write.Add(read.Reader.Read((int)TombstoneTable.Type, out size), size);
                                    if (type == Tombstone.TombstoneType.Attachment)
                                    {
                                        write.Add(read.Reader.Read((int)TombstoneTable.Collection, out size), size);
                                    }
                                    else
                                    {
                                        write.Add(collectionSlice);
                                    }
                                    write.Add(read.Reader.Read((int)TombstoneTable.Flags, out size), size);
                                    write.Add(read.Reader.Read((int)TombstoneTable.ChangeVector, out size), size);
                                    write.Add(read.Reader.Read((int)TombstoneTable.LastModified, out size), size);
                                    writeTable.Set(write);
                                }
                        }
                    }
                }
            }

            // Update conflicts' collection value
            using (step.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                var readTable = step.ReadTx.OpenTable(ConflictsSchema, ConflictsSlice);
                if (readTable != null)
                {
                    var writeTable = step.WriteTx.OpenTable(ConflictsSchema, ConflictsSlice);
                    foreach (var read in readTable.SeekByPrimaryKey(Slices.BeforeAllKeys, 0))
                    {
                        using (TableValueReaderUtil.CloneTableValueReader(context, read))
                        {
                            var oldCollection = TableValueToString(context, (int)ConflictsTable.Collection, ref read.Reader);
                            using (DocumentIdWorker.GetStringPreserveCase(context, oldCollection, out Slice collectionSlice))
                                using (writeTable.Allocate(out TableValueBuilder write))
                                {
                                    write.Add(read.Reader.Read((int)ConflictsTable.LowerId, out int size), size);
                                    write.Add(read.Reader.Read((int)ConflictsTable.RecordSeparator, out size), size);
                                    write.Add(read.Reader.Read((int)ConflictsTable.ChangeVector, out size), size);
                                    write.Add(read.Reader.Read((int)ConflictsTable.Id, out size), size);
                                    write.Add(read.Reader.Read((int)ConflictsTable.Data, out size), size);
                                    write.Add(read.Reader.Read((int)ConflictsTable.Etag, out size), size);
                                    write.Add(collectionSlice);
                                    write.Add(read.Reader.Read((int)ConflictsTable.LastModified, out size), size);
                                    write.Add(read.Reader.Read((int)ConflictsTable.Flags, out size), size);
                                    writeTable.Set(write);
                                }
                        }
                    }
                }
            }

            return(true);
        }