private static void Migrate(StorageEnvironment env, string tableName, Action <string> output, Action <Slice, RavenJObject> modifyRecord) { long entriesCount; using (var tx = env.NewTransaction(TransactionFlags.ReadWrite)) { entriesCount = tx.ReadTree(tableName).State.EntriesCount; } if (entriesCount == 0) { output(string.Format("No records to migrate in '{0}' table.", tableName)); return; } output(string.Format("Starting to migrate '{0}' table to. Records to process: {1}", tableName, entriesCount)); using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { env.DeleteTree(txw, "Temp_" + tableName); txw.Commit(); } using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { env.CreateTree(txw, "Temp_" + tableName); txw.Commit(); } var migrated = 0L; var keyToSeek = Slice.BeforeAllKeys; do { using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { var destTree = txw.ReadTree("Temp_" + tableName); var srcTree = txw.ReadTree(tableName); var iterator = srcTree.Iterate(); if (iterator.Seek(keyToSeek) == false) { break; } var itemsInBatch = 0; do { keyToSeek = iterator.CurrentKey; if (itemsInBatch != 0 && itemsInBatch % 100 == 0) { break; } using (var stream = iterator.CreateReaderForCurrent().AsStream()) { var value = stream.ToJObject(); modifyRecord(iterator.CurrentKey, value); using (var streamValue = new MemoryStream()) { value.WriteTo(streamValue); streamValue.Position = 0; destTree.Add(iterator.CurrentKey, streamValue); } migrated++; itemsInBatch++; } } while (iterator.MoveNext()); txw.Commit(); output(string.Format("{0} of {1} entries processed.", migrated, entriesCount)); } } while (migrated < entriesCount); using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { env.DeleteTree(txw, tableName); env.RenameTree(txw, "Temp_" + tableName, tableName); txw.Commit(); } }
public void MigrateToStructures <T>(StorageEnvironment env, TableOfStructures <T> table, Action <string> output, Action <RavenJObject, Structure <T> > copyToStructure) { long entriesCount; using (var tx = env.NewTransaction(TransactionFlags.ReadWrite)) { entriesCount = tx.ReadTree(table.TableName).State.EntriesCount; } if (entriesCount == 0) { output(string.Format("No records to migrate in '{0}' table.", table.TableName)); return; } output(string.Format("Starting to migrate '{0}' table to use structures. Records to process: {1}", table.TableName, entriesCount)); var migratedEntries = 0L; var keyToSeek = Slice.BeforeAllKeys; // delete Temp_TabelName if exists using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { env.DeleteTree(txw, "Temp_" + table.TableName); txw.Commit(); } using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { env.CreateTree(txw, "Temp_" + table.TableName); txw.Commit(); } do { using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { var destTree = txw.ReadTree("Temp_" + table.TableName); var srcTree = txw.ReadTree(table.TableName); var iterator = srcTree.Iterate(); if (iterator.Seek(keyToSeek) == false) { break; } var writtenStructsSize = 0; do { keyToSeek = iterator.CurrentKey; if (writtenStructsSize > 8 * 1024 * 1024) // 8 MB { break; } var readerForCurrent = iterator.CreateReaderForCurrent(); using (var stream = readerForCurrent.AsStream()) { var currentDataSize = iterator.GetCurrentDataSize(); try { RavenJObject jsonValue = stream.ToJObject(); var structValue = new Structure <T>(table.Schema); copyToStructure(jsonValue, structValue); destTree.WriteStruct(iterator.CurrentKey, structValue); writtenStructsSize += structValue.GetSize(); } catch (Exception) { // already converted this, probably, just move as is int used; var readBytes = readerForCurrent.ReadBytes(currentDataSize, out used); destTree.Add(iterator.CurrentKey, readBytes); writtenStructsSize += currentDataSize; } migratedEntries++; } } while (iterator.MoveNext()); txw.Commit(); output(string.Format("{0} of {1} records processed.", migratedEntries, entriesCount)); } } while (migratedEntries < entriesCount); using (var txw = env.NewTransaction(TransactionFlags.ReadWrite)) { env.DeleteTree(txw, table.TableName); env.RenameTree(txw, "Temp_" + table.TableName, table.TableName); txw.Commit(); } output(string.Format("All records of '{0}' table have been migrated to structures.", table.TableName)); }