-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
105 lines (84 loc) · 3.33 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using System;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Threading;
using Wivuu.AzCosmosCopy;
var root = new RootCommand
{
new Option<string?>(
new [] { "-s", "--source" }, "Source connection string (required)"
),
new Option<string?>(
new [] { "--sd", "--source-database" }, "Source database name (required)"
),
new Option<string?>(
new [] { "-d", "--destination" }, "Destination connection string"
),
new Option<string?>(
new [] { "--dd", "--destination-database" }, "Destination database name"
),
new Option<int?>(
new [] { "--pc", "--parallel-containers" }, "Parallel container copies"
),
new Option<int?>(
new [] { "--pd", "--parallel-documents" }, "Parallel document copies"
),
new Option(new [] { "-b", "--bulk" }, "Use bulk executor (serverless not supported)"),
new Option<int?>(
new [] { "--dbscale" }, "Destination database scale (serverless not supported)"
),
new Option<int?>(
new [] { "--dcscale" }, "Destination container scale (serverless not supported)"
),
};
// Add validators
root.AddValidator(result => result.Children.Contains("-s") ? default : "--source is required");
root.AddValidator(result => result.Children.Contains("--sd") ? default : "--source-database is required");
root.AddValidator(result =>
!result.Children.Contains("-d") && !result.Children.Contains("--dd")
? "--destination must be specified if --destination-database is not" : default
);
root.Description = "Copy Cosmos database from source to destination";
using var cancellation = new CancellationTokenSource();
// Handle command
root.Handler = CommandHandler.Create(
async (Args args) =>
{
if (args.Destination is null && args.DestinationDatabase == args.SourceDatabase)
throw new System.Exception("--destination cannot be copied to --source with the same --destination-database name");
var copyOptions = new DbCopierOptions(
args.Source,
string.IsNullOrWhiteSpace(args.Destination) ? args.Source : args.Destination,
args.SourceDatabase,
args.DestinationDatabase ?? args.SourceDatabase
)
{
MaxContainerParallel = args.ParallelContainers,
MaxDocCopyParallel = args.ParallelDocuments,
UseBulk = args.Bulk,
DestinationContainerThroughput = args.DcScale,
DestinationDbThroughput = args.DbScale,
};
var activity = DbCopier.CopyAsync(copyOptions, cancellation.Token);
var result = await DbCopier.RenderCopyDetailsAsync(activity);
return result ? 0 : 1;
});
// Handle cancel
Console.CancelKeyPress += new ConsoleCancelEventHandler((sender, e) =>
{
e.Cancel = true;
cancellation.Cancel();
});
await root.InvokeAsync(args);
class Args
{
public string Source { get; init; } = default!;
public string SourceDatabase { get; init; } = default!;
public string? Destination { get; init; }
public string? DestinationDatabase { get; init; }
public int ParallelContainers { get; set; } = 10;
public int ParallelDocuments { get; set; } = 100;
public bool Bulk { get; set; }
public int? DbScale { get; set; }
public int? DcScale { get; set; }
}