public FileUpdateResult PutFile(string filename, long?totalSize, RavenJObject metadata, bool tombstone = false) { var filesByEtag = storage.Files.GetIndex(Tables.Files.Indices.ByEtag); var keyString = CreateKey(filename); var keySlice = (Slice)keyString; ushort version; var existingFile = LoadJson(storage.Files, keySlice, writeBatch.Value, out version); var newEtag = uuidGenerator.CreateSequentialUuid(); metadata.Remove(RavenConstants.MetadataEtagField); var file = new RavenJObject { { "name", filename }, { "total_size", totalSize }, { "uploaded_size", 0 }, { "etag", newEtag.ToByteArray() }, { "metadata", metadata } }; storage.Files.Add(writeBatch.Value, keySlice, file, version); if (existingFile != null) { filesByEtag.Delete(writeBatch.Value, CreateKey(Etag.Parse(existingFile.Value <byte[]>("etag")))); } filesByEtag.Add(writeBatch.Value, (Slice)CreateKey(newEtag), keyString); if (tombstone == false) { var fileCount = storage.Files.GetIndex(Tables.Files.Indices.Count); fileCount.Add(writeBatch.Value, keySlice, keyString); } return(new FileUpdateResult() { Etag = newEtag }); }
public FileUpdateResult PutFile(string filename, long?totalSize, RavenJObject metadata, bool tombstone = false) { FileUpdateResult result; using (var update = new Update(session, Files, JET_prep.Insert)) { Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["name"], filename, Encoding.Unicode); if (totalSize != null) { Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["total_size"], BitConverter.GetBytes(totalSize.Value)); } Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["uploaded_size"], BitConverter.GetBytes(0)); metadata.Remove(Constants.MetadataEtagField); var newEtag = uuidGenerator.CreateSequentialUuid(); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["etag"], newEtag.TransformToValueForEsentSorting()); Api.SetColumn(session, Files, tableColumnsCache.FilesColumns["metadata"], ToQueryString(metadata), Encoding.Unicode); update.Save(); result = new FileUpdateResult { PrevEtag = null, Etag = newEtag }; } if (!tombstone) { if (Api.TryMoveFirst(session, Details) == false) { throw new InvalidOperationException("Could not find system metadata row"); } Api.EscrowUpdate(session, Details, tableColumnsCache.DetailsColumns["file_count"], 1); } return(result); }
public void FaultyOverflowPagesHandling_CannotModifyReadOnlyPages(int initialNumberOfDocs, int numberOfModifications, int seed) { const string documents = "documents"; const string keyByEtag = "documents_key_by_etag"; const string metadata = "documents_metadata"; var inMemoryKeysByEtag = new Dictionary <Guid, string>(); var inMemoryKeys = new HashSet <string>(); var r = new Random(seed); var uuidGenerator = new UuidGenerator(); using (var tx = Env.WriteTransaction()) { var docsTree = tx.CreateTree(documents); var metadataTree = tx.CreateTree(metadata); var indexTree = tx.CreateTree(keyByEtag); for (int i = 0; i < initialNumberOfDocs; i++) { var etag = uuidGenerator.CreateSequentialUuid(); var docKey = get_id(etag, r); put_doc(r, etag, inMemoryKeysByEtag, inMemoryKeys, docKey, docsTree, metadataTree, indexTree); } tx.Commit(); } for (int i = 0; i < numberOfModifications; i++) { using (var tx = Env.WriteTransaction()) { var docsTree = tx.ReadTree(documents); var metadataTree = tx.ReadTree(metadata); var indexTree = tx.ReadTree(keyByEtag); if (r.Next(3) == 0) { // insert new var etag = uuidGenerator.CreateSequentialUuid(); var docKey = get_id(etag, r); put_doc(r, etag, inMemoryKeysByEtag, inMemoryKeys, docKey, docsTree, metadataTree, indexTree); } else { // update existing var docCount = inMemoryKeysByEtag.Values.Count; var docKeyToUpdate = inMemoryKeysByEtag.Values.Skip(r.Next(0, docCount - 1)).First(); var etag = uuidGenerator.CreateSequentialUuid(); put_doc(r, etag, inMemoryKeysByEtag, inMemoryKeys, docKeyToUpdate, docsTree, metadataTree, indexTree); } tx.Commit(); } } using (var tx = Env.ReadTransaction()) { var docsTree = tx.ReadTree(documents); var metadataTree = tx.ReadTree(metadata); var keyByEtagTree = tx.ReadTree(keyByEtag); var count = 0; using (var iterator = keyByEtagTree.Iterate(false)) { iterator.Seek(Slices.BeforeAllKeys); do { var etag = Guid.Parse(iterator.CurrentKey.ToString()); var reader = iterator.CreateReaderForCurrent(); var key = reader.ReadString(reader.Length); var inMemoryKey = inMemoryKeysByEtag[etag]; Assert.Equal(inMemoryKey, key); var docReadResult = docsTree.Read(key); Assert.NotNull(docReadResult); var metadataReader = metadataTree.Read(key).Reader; Assert.NotNull(metadataReader); var etagFromMetadata = new byte[16]; metadataReader.Read(etagFromMetadata, 0, 16); var readEtag = new Guid(etagFromMetadata); Assert.Equal(etag, readEtag); count++; }while (iterator.MoveNext()); } Assert.Equal(inMemoryKeysByEtag.Count, count); } }
public void FaultyOverflowPagesHandling_CannotModifyReadOnlyPages(int initialNumberOfDocs, int numberOfModifications, int seed) { const string documents = "documents"; const string keyByEtag = "documents_key_by_etag"; const string metadata = "documents_metadata"; var inMemoryKeysByEtag = new Dictionary <Guid, string>(); var inMemoryKeys = new HashSet <string>(); var r = new Random(seed); var uuidGenerator = new UuidGenerator(); using (var tx = Env.NewTransaction(TransactionFlags.ReadWrite)) { var docsTree = Env.CreateTree(tx, documents); var metadataTree = Env.CreateTree(tx, metadata); var indexTree = Env.CreateTree(tx, keyByEtag); for (int i = 0; i < initialNumberOfDocs; i++) { var etag = uuidGenerator.CreateSequentialUuid(); var docKey = get_id(etag, r); put_doc(r, etag, inMemoryKeysByEtag, inMemoryKeys, docKey, docsTree, metadataTree, indexTree); } tx.Commit(); } for (int i = 0; i < numberOfModifications; i++) { using (var tx = Env.NewTransaction(TransactionFlags.ReadWrite)) { var docsTree = tx.ReadTree(documents); var metadataTree = tx.ReadTree(metadata); var indexTree = tx.ReadTree(keyByEtag); if (r.Next(3) == 0) { // insert new var etag = uuidGenerator.CreateSequentialUuid(); var docKey = get_id(etag, r); put_doc(r, etag, inMemoryKeysByEtag, inMemoryKeys, docKey, docsTree, metadataTree, indexTree); } else { // update existing var docCount = inMemoryKeysByEtag.Values.Count; var docKeyToUpdate = inMemoryKeysByEtag.Values.Skip(r.Next(0, docCount - 1)).First(); var etag = uuidGenerator.CreateSequentialUuid(); put_doc(r, etag, inMemoryKeysByEtag, inMemoryKeys, docKeyToUpdate, docsTree, metadataTree, indexTree); } tx.Commit(); } } using (var tx = Env.NewTransaction(TransactionFlags.Read)) { var docsTree = tx.ReadTree(documents); var metadataTree = tx.ReadTree(metadata); var reader = new SnapshotReader(tx); var count = 0; using (var iterator = reader.Iterate(keyByEtag)) { iterator.Seek(Slice.BeforeAllKeys); do { var etag = Guid.Parse(iterator.CurrentKey.ToString()); string key; using (var currentDataStream = iterator.CreateReaderForCurrent().AsStream()) { var keyBytes = currentDataStream.ReadData(); key = Encoding.UTF8.GetString(keyBytes); } var inMemoryKey = inMemoryKeysByEtag[etag]; Assert.Equal(inMemoryKey, key); var docReadResult = docsTree.Read(key); Assert.NotNull(docReadResult); var metadataReader = metadataTree.Read(key).Reader; Assert.NotNull(metadataReader); var etagFromMetadata = new byte[16]; metadataReader.Read(etagFromMetadata, 0, 16); var readEtag = new Guid(etagFromMetadata); if (etag != readEtag) { string existingDocKey; if (inMemoryKeysByEtag.TryGetValue(readEtag, out existingDocKey)) { Console.WriteLine("Etag " + readEtag + " belongs to " + existingDocKey + " document"); } else { Console.WriteLine("There is no document with etag " + readEtag); } } Assert.Equal(etag, readEtag); count++; }while (iterator.MoveNext()); } Assert.Equal(inMemoryKeysByEtag.Count, count); } }
public void FaultyOverflowPagesHandling_CannotModifyReadOnlyPages(int initialNumberOfDocs, int numberOfModifications, int seed) { const string documents = "documents"; const string keyByEtag = "documents_key_by_etag"; const string metadata = "documents_metadata"; var inMemoryKeysByEtag = new Dictionary<Guid, string>(); var inMemoryKeys = new HashSet<string>(); var r = new Random(seed); var uuidGenerator = new UuidGenerator(); using (var tx = Env.NewTransaction(TransactionFlags.ReadWrite)) { var docsTree = Env.CreateTree(tx, documents); var metadataTree = Env.CreateTree(tx, metadata); var indexTree = Env.CreateTree(tx, keyByEtag); for (int i = 0; i < initialNumberOfDocs; i++) { var etag = uuidGenerator.CreateSequentialUuid(); var docKey = get_id(etag, r); put_doc(r, etag, inMemoryKeysByEtag, inMemoryKeys, docKey, docsTree, metadataTree, indexTree); } tx.Commit(); } for (int i = 0; i < numberOfModifications; i++) { using (var tx = Env.NewTransaction(TransactionFlags.ReadWrite)) { var docsTree = tx.ReadTree(documents); var metadataTree = tx.ReadTree(metadata); var indexTree = tx.ReadTree(keyByEtag); if (r.Next(3) == 0) { // insert new var etag = uuidGenerator.CreateSequentialUuid(); var docKey = get_id(etag, r); put_doc(r, etag, inMemoryKeysByEtag, inMemoryKeys, docKey, docsTree, metadataTree, indexTree); } else { // update existing var docCount = inMemoryKeysByEtag.Values.Count; var docKeyToUpdate = inMemoryKeysByEtag.Values.Skip(r.Next(0, docCount - 1)).First(); var etag = uuidGenerator.CreateSequentialUuid(); put_doc(r, etag, inMemoryKeysByEtag, inMemoryKeys, docKeyToUpdate, docsTree, metadataTree, indexTree); } tx.Commit(); } } using (var tx = Env.NewTransaction(TransactionFlags.Read)) { var docsTree = tx.ReadTree(documents); var metadataTree = tx.ReadTree(metadata); var reader = new SnapshotReader(tx); var count = 0; using (var iterator = reader.Iterate(keyByEtag)) { iterator.Seek(Slice.BeforeAllKeys); do { var etag = Guid.Parse(iterator.CurrentKey.ToString()); string key; using (var currentDataStream = iterator.CreateReaderForCurrent().AsStream()) { var keyBytes = currentDataStream.ReadData(); key = Encoding.UTF8.GetString(keyBytes); } var inMemoryKey = inMemoryKeysByEtag[etag]; Assert.Equal(inMemoryKey, key); var docReadResult = docsTree.Read(key); Assert.NotNull(docReadResult); var metadataReader = metadataTree.Read(key).Reader; Assert.NotNull(metadataReader); var etagFromMetadata = new byte[16]; metadataReader.Read(etagFromMetadata, 0, 16); var readEtag = new Guid(etagFromMetadata); if (etag != readEtag) { string existingDocKey; if (inMemoryKeysByEtag.TryGetValue(readEtag, out existingDocKey)) { Console.WriteLine("Etag " + readEtag + " belongs to " + existingDocKey + " document"); } else { Console.WriteLine("There is no document with etag " + readEtag); } } Assert.Equal(etag, readEtag); count++; } while (iterator.MoveNext()); } Assert.Equal(inMemoryKeysByEtag.Count, count); } }