示例#1
0
        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();
            }
        }
示例#2
0
        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));
        }