public async Task Execute(params string[] args) { var stopWatch = Stopwatch.StartNew(); string target; if (!ArgsHelper.GetTargetEnvironmentFromArgs(args, out target, true)) { return; } string queryArg = args.Length >= 2 ? args[1] : null; if (string.IsNullOrWhiteSpace(queryArg)) { Console.Out.WriteLine(this.queryArgumentMissingError); return; } Console.Out.WriteLine(this.queryingInfo, queryArg, target); var targetTable = new EnvironmentClient(target).GetTable("events"); var exists = await targetTable.ExistsAsync(); if (!exists) { Console.Out.WriteLine("Event store does not exist, exiting."); return; } var query = new TableQuery <EventEntity>().Where(this.query(queryArg)); TableQuerySegment <EventEntity> querySegment = null; var foundEntities = new List <EventEntity>(); while (querySegment == null || querySegment.ContinuationToken != null) { querySegment = await targetTable.ExecuteQuerySegmentedAsync( query, querySegment != null?querySegment.ContinuationToken : null); foundEntities.AddRange(querySegment); } foreach (var e in foundEntities) { Console.Out.WriteLine( "PartitionKey: {0}\r\n" + "RowKey: {1}\r\n" + "DataType: {2}\r\n" + "EventTimeStamp: {3}\r\n" + "{4}\r\n", e.PartitionKey, e.RowKey, e.DataType, e.EventTimestamp, e.Data); } Console.Out.WriteLine("Search complete, found {0:n0} events in {1:n1} seconds.", foundEntities.Count, stopWatch.Elapsed.TotalSeconds); return; }
public async Task Execute(params string[] args) { var stopWatch = Stopwatch.StartNew(); var parsedArguments = TableCopyArguments.Parse(args); if (!parsedArguments.Valid) { Console.WriteLine("Must give source and target, both in a form environmentName:TableName."); return; } Console.Out.WriteLine("Copying {0} from {1} to {2} at {3}.", parsedArguments.Source.TableName, parsedArguments.Source.Environment, parsedArguments.Target.TableName, parsedArguments.Target.Environment); var sourceTable = new EnvironmentClient(parsedArguments.Source.Environment).GetTable(parsedArguments.Source.TableName); var targetTable = new EnvironmentClient(parsedArguments.Target.Environment).GetTable(parsedArguments.Target.TableName); if (!await sourceTable.ExistsAsync()) { Console.Out.WriteLine("Source table does not exist, exiting."); return; } await targetTable.CreateIfNotExistsAsync(); var allQuery = new TableQuery <DynamicTableEntity>(); TableQuerySegment <DynamicTableEntity> querySegment = null; var sourceEntities = new List <DynamicTableEntity>(); while (querySegment == null || querySegment.ContinuationToken != null) { querySegment = await sourceTable.ExecuteQuerySegmentedAsync( allQuery, querySegment != null?querySegment.ContinuationToken : null); sourceEntities.AddRange(querySegment); } var batches = new List <TableBatchOperation>(); var groupedByPartitionKey = sourceEntities.GroupBy( p => p.PartitionKey, e => e, (key, list) => new KeyValuePair <string, IEnumerable <DynamicTableEntity> >(key, list)); foreach (var g in groupedByPartitionKey) { const int BatchSize = 100; int i = 1; // If batch size is more than 100, chunk it as it is the max sixe for azure storage batch operation foreach (var chunk in g.Value.Chunk(BatchSize)) { Console.Out.WriteLine(g.Key + " - Batch " + i); var batch = new TableBatchOperation(); foreach (var entity in chunk) { batch.Insert(entity); } batches.Add(batch); i++; } } Console.Out.WriteLine("This might take a while..."); var waits = batches.Select(targetTable.ExecuteBatchAsync).Cast <Task>().ToArray(); Task.WaitAll(waits, TimeSpan.FromHours(1)); Console.Out.WriteLine("\r\nCopying successful, copied {0:n0} rows in {1:n1} seconds.", sourceEntities.Count, stopWatch.Elapsed.TotalSeconds); return; }