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
106
107
108
109
110
111
112
113
114
115
116
117
use std::ffi::OsString;
use std::path::PathBuf;
use clap::{Args, Parser, Subcommand};
/// Work with ephemeral PostgreSQL clusters.
#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
pub struct Cli {
#[clap(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
/// Start a psql shell, creating and starting the cluster as necessary.
#[clap(display_order = 1)]
Shell {
#[clap(flatten)]
cluster: ClusterArgs,
#[clap(flatten)]
database: DatabaseArgs,
#[clap(flatten)]
lifecycle: LifecycleArgs,
},
/// Execute an arbitrary command, creating and starting the cluster as
/// necessary.
#[clap(display_order = 2)]
Exec {
#[clap(flatten)]
cluster: ClusterArgs,
#[clap(flatten)]
database: DatabaseArgs,
#[clap(flatten)]
lifecycle: LifecycleArgs,
/// The executable to invoke. By default it will start a shell.
#[clap(env = "SHELL", value_name = "COMMAND")]
command: OsString,
/// Arguments to pass to the executable.
#[clap(value_name = "ARGUMENTS")]
args: Vec<OsString>,
},
/// List discovered PostgreSQL runtimes.
///
/// The runtime shown on the line beginning with `=>` is the default, i.e.
/// the runtime that will be used when creating a new cluster.
#[clap(display_order = 3)]
Runtimes,
}
#[derive(Args)]
pub struct ClusterArgs {
/// The directory in which to place, or find, the cluster.
#[clap(
short = 'D',
long = "datadir",
env = "PGDATA",
value_name = "PGDATA",
default_value = "cluster",
display_order = 1
)]
pub dir: PathBuf,
/// Run the cluster in a "safer" or "faster" mode.
///
/// DANGER! Choosing "faster-but-less-safe" makes the cluster faster but it
/// can lead to unrecoverable data corruption in the event of a power
/// failure or system crash.
///
/// The mode is STICKY. Running with a mode reconfigures the cluster, and it
/// will continue to run in that mode. To find out which mode the cluster is
/// configured for, open a `psql` shell (e.g. `postgresfixture shell`) and
/// run `SHOW fsync; SHOW full_page_writes; SHOW synchronous_commit;`.
#[clap(long = "mode", display_order = 4)]
pub mode: Option<Mode>,
}
#[derive(Args)]
pub struct DatabaseArgs {
/// The database to connect to.
#[clap(
short = 'd',
long = "database",
env = "PGDATABASE",
value_name = "PGDATABASE",
default_value = "postgres",
display_order = 2
)]
pub name: String,
}
#[derive(Args)]
pub struct LifecycleArgs {
/// Destroy the cluster after use. WARNING: This will DELETE THE DATA
/// DIRECTORY. The default is to NOT destroy the cluster.
#[clap(long = "destroy", display_order = 100)]
pub destroy: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
pub enum Mode {
/// Resets fsync, full_page_writes, and synchronous_commit to defaults.
#[value(name = "slower-but-safer", alias = "safe")]
Slow,
/// Disable fsync, full_page_writes, and synchronous_commit. DANGER!
#[value(name = "faster-but-less-safe", alias = "fast")]
Fast,
}