(config: Config, args: &ArgMatches)
| 179 | } |
| 180 | |
| 181 | pub async fn exec(config: Config, args: &ArgMatches) -> Result<(), anyhow::Error> { |
| 182 | eprintln!("{UNSTABLE_WARNING}\n"); |
| 183 | let interactive = args.get_one::<bool>("interactive").unwrap_or(&false); |
| 184 | let no_config = args.get_flag("no_config"); |
| 185 | let raw_parts: Vec<String> = args |
| 186 | .get_many::<String>("sql_parts") |
| 187 | .map(|vals| vals.cloned().collect()) |
| 188 | .unwrap_or_default(); |
| 189 | let config_targets = load_config_db_targets(no_config)?; |
| 190 | |
| 191 | if *interactive { |
| 192 | if raw_parts.len() > 1 { |
| 193 | anyhow::bail!( |
| 194 | "Too many positional arguments for interactive mode.\nUsage: spacetime sql [database] --interactive [--no-config]" |
| 195 | ); |
| 196 | } |
| 197 | let resolved = resolve_database_arg( |
| 198 | raw_parts.first().map(|s| s.as_str()), |
| 199 | config_targets.as_deref(), |
| 200 | "spacetime sql [database] --interactive [--no-config]", |
| 201 | )?; |
| 202 | let con = parse_req(config, args, &resolved.database, resolved.server.as_deref()).await?; |
| 203 | |
| 204 | crate::repl::exec(con).await?; |
| 205 | } else { |
| 206 | let resolved = resolve_optional_database_parts( |
| 207 | &raw_parts, |
| 208 | config_targets.as_deref(), |
| 209 | "query", |
| 210 | "spacetime sql [database] <query> [--no-config]", |
| 211 | ) |
| 212 | .or_else(|e| { |
| 213 | // `sql` expects exactly 1 query arg, so if we have 2+ positional args the first |
| 214 | // must be a database name. If it didn't match any config target, treat it as an |
| 215 | // ad-hoc database outside the project (auto-fallthrough). |
| 216 | if raw_parts.len() >= 2 { |
| 217 | Ok(ResolvedDbArgs { |
| 218 | database: raw_parts[0].clone(), |
| 219 | server: None, |
| 220 | remaining_args: raw_parts[1..].to_vec(), |
| 221 | }) |
| 222 | } else if raw_parts.len() == 1 && raw_parts[0].contains(' ') { |
| 223 | // The single arg contains spaces, so it's almost certainly a SQL query, |
| 224 | // not a database name. Give a clearer error than "missing <query>". |
| 225 | let targets = config_targets.as_deref().unwrap_or_default(); |
| 226 | let known: Vec<&str> = targets.iter().map(|t| t.database.as_str()).collect(); |
| 227 | Err(anyhow::anyhow!( |
| 228 | "Multiple databases found in config: {}. Please specify which database to query:\n \ |
| 229 | spacetime sql <database> \"{}\"", |
| 230 | known.join(", "), |
| 231 | raw_parts[0] |
| 232 | )) |
| 233 | } else { |
| 234 | Err(e) |
| 235 | } |
| 236 | })?; |
| 237 | let query = resolved.remaining_args.join(" "); |
| 238 | let confirmed = args.get_one::<bool>("confirmed").copied(); |
no test coverage detected
searching dependent graphs…