LCOV - code coverage report
Current view: top level - libs/postgres_ffi/wal_craft/src/bin - wal_craft.rs (source / functions) Coverage Total Hit
Test: e402c46de0a007db6b48dddbde450ddbb92e6ceb.info Lines: 47.9 % 121 58
Test Date: 2024-06-25 10:31:23 Functions: 40.0 % 5 2

            Line data    Source code
       1              : use anyhow::*;
       2              : use clap::{value_parser, Arg, ArgMatches, Command};
       3              : use postgres::Client;
       4              : use std::{path::PathBuf, str::FromStr};
       5              : use wal_craft::*;
       6              : 
       7            0 : fn main() -> Result<()> {
       8            0 :     env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("wal_craft=info"))
       9            0 :         .init();
      10            0 :     let arg_matches = cli().get_matches();
      11            0 : 
      12            0 :     let wal_craft = |arg_matches: &ArgMatches, client: &mut Client| {
      13            0 :         let intermediate_lsns = match arg_matches
      14            0 :             .get_one::<String>("type")
      15            0 :             .map(|s| s.as_str())
      16            0 :             .context("'type' is required")?
      17              :         {
      18            0 :             Simple::NAME => Simple::craft(client)?,
      19            0 :             LastWalRecordXlogSwitch::NAME => LastWalRecordXlogSwitch::craft(client)?,
      20            0 :             LastWalRecordXlogSwitchEndsOnPageBoundary::NAME => {
      21            0 :                 LastWalRecordXlogSwitchEndsOnPageBoundary::craft(client)?
      22              :             }
      23            0 :             WalRecordCrossingSegmentFollowedBySmallOne::NAME => {
      24            0 :                 WalRecordCrossingSegmentFollowedBySmallOne::craft(client)?
      25              :             }
      26            0 :             LastWalRecordCrossingSegment::NAME => LastWalRecordCrossingSegment::craft(client)?,
      27            0 :             a => panic!("Unknown --type argument: {a}"),
      28              :         };
      29            0 :         let end_of_wal_lsn = client.pg_current_wal_insert_lsn()?;
      30            0 :         for lsn in intermediate_lsns {
      31            0 :             println!("intermediate_lsn = {lsn}");
      32            0 :         }
      33            0 :         println!("end_of_wal = {end_of_wal_lsn}");
      34            0 :         Ok(())
      35            0 :     };
      36              : 
      37            0 :     match arg_matches.subcommand() {
      38            0 :         None => panic!("No subcommand provided"),
      39            0 :         Some(("print-postgres-config", _)) => {
      40            0 :             for cfg in REQUIRED_POSTGRES_CONFIG.iter() {
      41            0 :                 println!("{cfg}");
      42            0 :             }
      43            0 :             Ok(())
      44              :         }
      45              : 
      46            0 :         Some(("with-initdb", arg_matches)) => {
      47            0 :             let cfg = Conf {
      48            0 :                 pg_version: *arg_matches
      49            0 :                     .get_one::<u32>("pg-version")
      50            0 :                     .context("'pg-version' is required")?,
      51            0 :                 pg_distrib_dir: arg_matches
      52            0 :                     .get_one::<PathBuf>("pg-distrib-dir")
      53            0 :                     .context("'pg-distrib-dir' is required")?
      54            0 :                     .to_owned(),
      55            0 :                 datadir: arg_matches
      56            0 :                     .get_one::<PathBuf>("datadir")
      57            0 :                     .context("'datadir' is required")?
      58            0 :                     .to_owned(),
      59            0 :             };
      60            0 :             cfg.initdb()?;
      61            0 :             let srv = cfg.start_server()?;
      62            0 :             wal_craft(arg_matches, &mut srv.connect_with_timeout()?)?;
      63            0 :             srv.kill();
      64            0 :             Ok(())
      65              :         }
      66            0 :         Some(("in-existing", arg_matches)) => wal_craft(
      67            0 :             arg_matches,
      68            0 :             &mut postgres::Config::from_str(
      69            0 :                 arg_matches
      70            0 :                     .get_one::<String>("connection")
      71            0 :                     .context("'connection' is required")?,
      72              :             )
      73            0 :             .context(
      74            0 :                 "'connection' argument value could not be parsed as a postgres connection string",
      75            0 :             )?
      76            0 :             .connect(postgres::NoTls)?,
      77              :         ),
      78            0 :         Some(_) => panic!("Unknown subcommand"),
      79              :     }
      80            0 : }
      81              : 
      82            2 : fn cli() -> Command {
      83            2 :     let type_arg = &Arg::new("type")
      84            2 :         .help("Type of WAL to craft")
      85            2 :         .value_parser([
      86            2 :             Simple::NAME,
      87            2 :             LastWalRecordXlogSwitch::NAME,
      88            2 :             LastWalRecordXlogSwitchEndsOnPageBoundary::NAME,
      89            2 :             WalRecordCrossingSegmentFollowedBySmallOne::NAME,
      90            2 :             LastWalRecordCrossingSegment::NAME,
      91            2 :         ])
      92            2 :         .required(true);
      93            2 : 
      94            2 :     Command::new("Postgres WAL crafter")
      95            2 :         .about("Crafts Postgres databases with specific WAL properties")
      96            2 :         .subcommand(
      97            2 :             Command::new("print-postgres-config")
      98            2 :                 .about("Print the configuration required for PostgreSQL server before running this script")
      99            2 :         )
     100            2 :         .subcommand(
     101            2 :             Command::new("with-initdb")
     102            2 :                 .about("Craft WAL in a new data directory first initialized with initdb")
     103            2 :                 .arg(type_arg)
     104            2 :                 .arg(
     105            2 :                     Arg::new("datadir")
     106            2 :                         .help("Data directory for the Postgres server")
     107            2 :                         .value_parser(value_parser!(PathBuf))
     108            2 :                         .required(true)
     109            2 :                 )
     110            2 :                 .arg(
     111            2 :                     Arg::new("pg-distrib-dir")
     112            2 :                         .long("pg-distrib-dir")
     113            2 :                         .value_parser(value_parser!(PathBuf))
     114            2 :                         .help("Directory with Postgres distributions (bin and lib directories, e.g. pg_install containing subpath `v14/bin/postgresql`)")
     115            2 :                         .default_value("/usr/local")
     116            2 :                 )
     117            2 :                 .arg(
     118            2 :                     Arg::new("pg-version")
     119            2 :                     .long("pg-version")
     120            2 :                     .help("Postgres version to use for the initial tenant")
     121            2 :                     .value_parser(value_parser!(u32))
     122            2 :                     .required(true)
     123            2 : 
     124            2 :                 )
     125            2 :         )
     126            2 :         .subcommand(
     127            2 :             Command::new("in-existing")
     128            2 :                 .about("Craft WAL at an existing recently created Postgres database. Note that server may append new WAL entries on shutdown.")
     129            2 :                 .arg(type_arg)
     130            2 :                 .arg(
     131            2 :                     Arg::new("connection")
     132            2 :                         .help("Connection string to the Postgres database to populate")
     133            2 :                         .required(true)
     134            2 :                 )
     135            2 :         )
     136            2 : }
     137              : 
     138              : #[test]
     139            2 : fn verify_cli() {
     140            2 :     cli().debug_assert();
     141            2 : }
        

Generated by: LCOV version 2.1-beta