Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Branches: REPL backslash commands for branches #1284

Merged
merged 9 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/branch/current.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crossterm::style::Stylize;
use crate::branch::context::Context;
use crate::branch::option::Current;
use crate::connect::Connection;


pub async fn main(
options: &Current,
Expand Down
41 changes: 27 additions & 14 deletions src/branch/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::future::Future;
use crate::branch::context::Context;
use crate::branch::option::{BranchCommand, Command};
use crate::branch::{create, current, drop, list, merge, rebase, rename, switch, wipe};
Expand All @@ -10,31 +11,43 @@ use edgedb_tokio::get_project_dir;
pub async fn branch_main(options: &Options, cmd: &BranchCommand) -> anyhow::Result<()> {
let context = create_context().await?;

run_branch_command(&cmd.subcommand, options, &context, None).await
}

pub async fn run_branch_command(cmd: &Command, options: &Options, context: &Context, connection: Option<&mut Connection>) -> anyhow::Result<()> {
let mut connector: Connector = options.create_connector().await?;

// match commands that don't require a connection to run, then match the ones that do with a connection.
match &cmd.subcommand {
match &cmd {
Command::Switch(switch) => switch::main(switch, &context, &mut connector).await,
Command::Wipe(wipe) => wipe::main(wipe, &context, &mut connector).await,
Command::Current(current) => current::main(current, &context).await,
command => {
let mut connection = connector.connect().await?;
verify_server_can_use_branches(&mut connection).await?;

match command {
Command::Create(create) => create::main(create, &context, &mut connection).await,
Command::Drop(drop) => drop::main(drop, &context, &mut connection).await,
Command::List(list) => list::main(list, &context, &mut connection).await,
Command::Rename(rename) => rename::main(rename, &context, &mut connection, &options).await,
Command::Rebase(rebase) => rebase::main(rebase, &context, &mut connection, &options).await,
Command::Merge(merge) => merge::main(merge, &context, &mut connection, &options).await,
unhandled => anyhow::bail!("unimplemented branch command '{:?}'", unhandled)
match connection {
Some(conn) => run_branch_command1(command, conn, context, options).await,
None => {
let mut conn = connector.connect().await?;
run_branch_command1(command, &mut conn, context, options).await
}
}
}
}
}

async fn create_context() -> anyhow::Result<Context> {
async fn run_branch_command1(command: &Command, connection: &mut Connection, context: &Context, options: &Options) -> anyhow::Result<()> {
verify_server_can_use_branches(connection).await?;

match command {
Command::Create(create) => create::main(create, &context, connection).await,
Command::Drop(drop) => drop::main(drop, &context, connection).await,
Command::List(list) => list::main(list, &context, connection).await,
Command::Rename(rename) => rename::main(rename, &context, connection, &options).await,
Command::Rebase(rebase) => rebase::main(rebase, &context, connection, &options).await,
Command::Merge(merge) => merge::main(merge, &context, connection, &options).await,
unhandled => anyhow::bail!("unimplemented branch command '{:?}'", unhandled)
}
}

pub async fn create_context() -> anyhow::Result<Context> {
let project_dir = get_project_dir(None, true).await?;
Context::new(project_dir.as_ref()).await
}
Expand Down
2 changes: 1 addition & 1 deletion src/branch/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod context;
pub mod context;
mod create;
mod drop;
mod list;
Expand Down
13 changes: 13 additions & 0 deletions src/branch/option.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use crate::commands;
use crate::commands::parser::BranchingCmd;

#[derive(clap::Args, Debug, Clone)]
pub struct BranchCommand {
#[command(subcommand)]
Expand All @@ -17,6 +20,16 @@ pub enum Command {
Current(Current)
}

impl From<&BranchingCmd> for Command {
fn from(cmd: &BranchingCmd) -> Self {
match cmd {
BranchingCmd::Create(args) => Command::Create(args.clone()),
BranchingCmd::Drop(args) => Command::Drop(args.clone()),
BranchingCmd::Wipe(args) => Command::Wipe(args.clone()),
}
}
}

/// Creates a new branch and switches to it.
#[derive(clap::Args, Debug, Clone)]
pub struct Create {
Expand Down
11 changes: 6 additions & 5 deletions src/commands/backslash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Introspection

\d [-v] NAME Describe schema object
\ds Describe whole schema (alias: \describe schema)
\l List databases (alias: \list databases)
\l List databases/branches (alias: \list branches)
\ls [-sc] [PATTERN] List scalar types (alias: \list scalars)
\lt [-sc] [PATTERN] List object types (alias: \list types)
\lr [-c] [PATTERN] List roles (alias: \list roles)
Expand All @@ -63,7 +63,7 @@ Editing
Defaults to vi (Notepad in Windows).

Connection
\c, \connect [DBNAME] Connect to database DBNAME
\c, \connect [DBNAME] Connect to database/branch DBNAME

Settings
\set [OPTION [VALUE]] Show/change settings. Type \set to list
Expand Down Expand Up @@ -306,7 +306,7 @@ impl CommandCache {
let mut aliases = BTreeMap::new();
aliases.insert("d", &["describe", "object"][..]);
aliases.insert("ds", &["describe", "schema"]);
aliases.insert("l", &["list", "databases"]);
aliases.insert("l", &["list", "branches"]);
aliases.insert("ls", &["list", "scalars"]);
aliases.insert("lt", &["list", "types"]);
aliases.insert("lr", &["list", "roles"]);
Expand All @@ -322,6 +322,7 @@ impl CommandCache {
aliases.insert("quit", &["exit"]);
aliases.insert("?", &["help"]);
aliases.insert("h", &["help"]);
aliases.insert("branch", &["branching"]);
let mut setting_cmd = None;
let commands: BTreeMap<_,_> = clap.get_subcommands_mut()
.map(|cmd| {
Expand Down Expand Up @@ -547,7 +548,7 @@ fn list_settings(prompt: &mut repl::State) {
table.printstd();
}

pub async fn execute(cmd: &BackslashCmd, prompt: &mut repl::State)
pub async fn execute(cmd: &BackslashCmd, prompt: &mut repl::State, cli_opts: &crate::options::Options)
-> Result<ExecuteResult, anyhow::Error>
{
use crate::commands::parser::BackslashCmd::*;
Expand All @@ -569,7 +570,7 @@ pub async fn execute(cmd: &BackslashCmd, prompt: &mut repl::State)
prompt.soft_reconnect().await?;
let cli = prompt.connection.as_mut()
.expect("connection established");
execute::common(cli, cmd, &options).await?;
execute::common(cli, cmd, &options, cli_opts).await?;
Ok(Skip)
}
Set(SetCommand {setting: None}) => {
Expand Down
10 changes: 10 additions & 0 deletions src/commands/branching.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::branch;
use crate::commands::parser::BranchingCmd;
use crate::connect::Connection;
use crate::options::Options;

pub async fn main(connection: &mut Connection, cmd: &BranchingCmd, options: &Options) -> anyhow::Result<()> {
let context = branch::main::create_context().await?;

branch::main::run_branch_command(&cmd.into(), options, &context, Some(connection)).await
}
2 changes: 1 addition & 1 deletion src/commands/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async fn common_cmd(_options: &Options, cmdopt: commands::Options, cmd: &Common)
{
let mut conn = cmdopt.conn_params.connect().await?;
commands::execute::common(
&mut conn, cmd, &cmdopt
&mut conn, cmd, &cmdopt, _options
).await?;
Ok(())
}
Expand Down
12 changes: 9 additions & 3 deletions src/commands/execute.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use crate::connect::Connection;
use edgedb_tokio::server_params::PostgresAddress;

use crate::analyze;
use crate::{analyze, options};
use crate::commands::parser::{Common, DatabaseCmd, ListCmd, DescribeCmd};
use crate::commands::{self, Options};
use crate::commands::{self, branching, Options};
use crate::migrations::options::{MigrationCmd};
use crate::migrations;
use crate::print;


pub async fn common(cli: &mut Connection, cmd: &Common, options: &Options)
pub async fn common(cli: &mut Connection, cmd: &Common, options: &Options, cli_opts: &options::Options)
-> Result<(), anyhow::Error>
quinchs marked this conversation as resolved.
Show resolved Hide resolved
{
use Common::*;
Expand All @@ -29,6 +29,9 @@ pub async fn common(cli: &mut Connection, cmd: &Common, options: &Options)
}
ListCmd::Databases => {
commands::list_databases(cli, &options).await?;
},
ListCmd::Branches => {
commands::list_branches(cli, &options).await?;
}
ListCmd::Scalars(c) => {
commands::list_scalar_types(cli, &options,
Expand Down Expand Up @@ -91,6 +94,9 @@ pub async fn common(cli: &mut Connection, cmd: &Common, options: &Options)
DatabaseCmd::Wipe(w) => {
commands::database::wipe(cli, w, &options).await?;
}
},
Branching(branching) => {
branching::main(cli, &branching.subcommand, &cli_opts).await?
}
Migrate(params) => {
migrations::migrate(cli, &options, params).await?;
Expand Down
27 changes: 27 additions & 0 deletions src/commands/list_branches.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::commands::list_databases::get_databases;
use crate::commands::{list, list_databases, Options};
use crate::connect::Connection;
use crate::print;

pub async fn get_branches(cli: &mut Connection) -> anyhow::Result<Vec<String>> {
get_databases(cli).await
}

pub async fn list_branches(cli: &mut Connection, options: &Options)
-> Result<(), anyhow::Error>
{
let version = cli.get_version().await?;

if version.specific().major <= 4 {
print::warn(format!("Branches are not supported in EdgeDB {}, printing list of databases instead", version));
return list_databases(cli, options).await;
}

list_branches0(cli, options).await
}

pub async fn list_branches0(cli: &mut Connection, options: &Options) -> Result<(), anyhow::Error> {
let databases = get_branches(cli).await?;
list::print(databases, "List of branches", options).await?;
Ok(())
}
10 changes: 10 additions & 0 deletions src/commands/list_databases.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::commands::Options;
use crate::commands::list;
use crate::commands::list_branches::{list_branches0};
use crate::connect::Connection;
use crate::print;


pub async fn get_databases(cli: &mut Connection) -> anyhow::Result<Vec<String>>
Expand All @@ -15,6 +17,14 @@ pub async fn get_databases(cli: &mut Connection) -> anyhow::Result<Vec<String>>
pub async fn list_databases(cli: &mut Connection, options: &Options)
-> Result<(), anyhow::Error>
{
let version = cli.get_version().await?;


if version.specific().major >= 5 {
print::warn(format!("Databases are not supported in EdgeDB {}, printing list of branches instead", version));
return list_branches0(cli, options).await;
}

let databases = get_databases(cli).await?;
list::print(databases, "List of databases", options).await?;
Ok(())
Expand Down
3 changes: 3 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub mod cli;
pub mod options;
pub mod parser;
mod ui;
mod list_branches;
mod branching;

pub use self::configure::configure;
pub use self::dump::{dump, dump_all};
Expand All @@ -32,6 +34,7 @@ pub use self::describe_schema::describe_schema;
pub use self::list_aliases::list_aliases;
pub use self::list_casts::list_casts;
pub use self::list_databases::list_databases;
pub use self::list_branches::list_branches;
pub use self::list_indexes::list_indexes;
pub use self::list_modules::list_modules;
pub use self::list_object_types::list_object_types;
Expand Down
27 changes: 26 additions & 1 deletion src/commands/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub enum Common {

/// Database commands
Database(Database),
Branching(Branching),
/// Describe database schema or object
Describe(Describe),

Expand Down Expand Up @@ -96,8 +97,10 @@ pub enum ListCmd {
Aliases(ListAliases),
/// Display list of casts defined in the schema
Casts(ListCasts),
/// Display list of databases for an EdgeDB instance
/// On EdgeDB < 5.x: Display list of databases for an EdgeDB instance
Databases,
/// On EdgeDB >= 5.x: Display list of branches for an EdgeDB instance
Branches,
/// Display list of indexes defined in the schema
Indexes(ListIndexes),
/// Display list of modules defined in the schema
Expand All @@ -110,6 +113,28 @@ pub enum ListCmd {
Types(ListTypes),
}

#[derive(clap::Args, Clone, Debug)]
#[command(version = "help_expand")]
#[command(disable_version_flag=true)]
pub struct Branching {
#[command(flatten)]
pub conn: ConnectionOptions,

#[command(subcommand)]
pub subcommand: BranchingCmd,
}

#[derive(clap::Subcommand, Clone, Debug)]
pub enum BranchingCmd {
/// Create a new branch
Create(crate::branch::option::Create),
/// Delete a branch along with its data
Drop(crate::branch::option::Drop),
/// Delete a branches data and reset its schema while
/// preserving the branch itself (its cfg::DatabaseConfig)
/// and existing migration scripts
Wipe(crate::branch::option::Wipe),
}

#[derive(clap::Args, Clone, Debug)]
#[command(version = "help_expand")]
Expand Down
6 changes: 3 additions & 3 deletions src/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ fn check_json_limit(json: &serde_json::Value, path: &str, limit: usize) -> bool
return true;
}

async fn execute_backslash(mut state: &mut repl::State, text: &str)
async fn execute_backslash(mut state: &mut repl::State, text: &str, options: &Options)
-> anyhow::Result<()>
{
use backslash::ExecuteResult::*;
Expand All @@ -236,7 +236,7 @@ async fn execute_backslash(mut state: &mut repl::State, text: &str)
return Ok(());
}
};
let res = backslash::execute(&cmd.command, &mut state).await;
let res = backslash::execute(&cmd.command, &mut state, options).await;
match res {
Ok(Skip) => {},
Ok(Quit) => {
Expand Down Expand Up @@ -543,7 +543,7 @@ async fn _interactive_main(options: &Options, state: &mut repl::State)
let result = match item {
ToDoItem::Backslash(text) => {
tokio::select!(
res = execute_backslash(state, text) => res,
res = execute_backslash(state, text, options) => res,
res = ctrlc.wait_result() => res,
)
}
Expand Down
Loading
Loading