Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 bench/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fn bench(c: &mut Criterion) {
cornucopia::container::setup(false).unwrap();
let client = &mut cornucopia_conn().unwrap();

cornucopia::load_schema(client, vec!["../codegen_test/schema.sql".into()]).unwrap();
cornucopia::load_schema(client, &["../codegen_test/schema.sql"]).unwrap();
c.bench_function("codegen_sync", |b| {
b.iter(|| {
cornucopia::generate_live(
Expand Down
2 changes: 1 addition & 1 deletion bench/usage/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ fn bench(c: &mut Criterion) {
let conn =
&mut PgConnection::establish("postgresql://postgres:postgres@127.0.0.1:5435/postgres")
.unwrap();
cornucopia::load_schema(client, vec!["usage/cornucopia_benches/schema.sql".into()]).unwrap();
cornucopia::load_schema(client, &["usage/cornucopia_benches/schema.sql"]).unwrap();
{
let mut group = c.benchmark_group("bench_trivial_query");
for size in QUERY_SIZE {
Expand Down
14 changes: 8 additions & 6 deletions cornucopia/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::PathBuf;

use clap::{Parser, Subcommand};

use crate::{conn, container, error::Error, generate_live, generate_managed, CodegenSettings};
Expand All @@ -11,10 +13,10 @@ struct Args {
podman: bool,
/// Folder containing the queries
#[clap(short, long, default_value = "queries/")]
queries_path: String,
queries_path: PathBuf,
/// Destination folder for generated modules
#[clap(short, long, default_value = "src/cornucopia.rs")]
destination: String,
destination: PathBuf,
#[clap(subcommand)]
action: Action,
/// Generate synchronous rust code. Async otherwise.
Expand All @@ -35,7 +37,7 @@ enum Action {
/// Generate your modules against schema files
Schema {
/// SQL files containing the database schema
schema_files: Vec<String>,
schema_files: Vec<PathBuf>,
},
}

Expand Down Expand Up @@ -66,9 +68,9 @@ pub fn run() -> Result<(), Error> {
Action::Schema { schema_files } => {
// Run the generate command. If the command is unsuccessful, cleanup Cornucopia's container
if let Err(e) = generate_managed(
&queries_path,
schema_files,
Some(&destination),
queries_path,
&schema_files,
Some(destination),
podman,
CodegenSettings {
is_async: !sync,
Expand Down
4 changes: 3 additions & 1 deletion cornucopia/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::PathBuf;

use miette::{Diagnostic, GraphicalReportHandler, GraphicalTheme};
use thiserror::Error as ThisError;

Expand Down Expand Up @@ -39,6 +41,6 @@ impl Error {
#[derive(Debug, ThisError, Diagnostic)]
#[error("Could not write your queries to destination file `{file_path}`: ({err})")]
pub struct WriteOutputError {
pub(crate) file_path: String,
pub(crate) file_path: PathBuf,
pub(crate) err: std::io::Error,
}
28 changes: 15 additions & 13 deletions cornucopia/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub mod conn;
/// High-level interfaces to work with Cornucopia's container manager.
pub mod container;

use std::path::Path;

use postgres::Client;

use codegen::generate as generate_internal;
Expand All @@ -39,14 +41,14 @@ pub struct CodegenSettings {
/// using a live database managed by you. If some `destination` is given,
/// the generated code will be written at that path. Code generation settings are
/// set using the `settings` parameter.
pub fn generate_live(
pub fn generate_live<P: AsRef<Path>>(
client: &mut Client,
queries_path: &str,
destination: Option<&str>,
queries_path: P,
destination: Option<P>,
settings: CodegenSettings,
) -> Result<String, Error> {
// Read
let modules = read_query_modules(queries_path)?
let modules = read_query_modules(queries_path.as_ref())?
.into_iter()
.map(parse_query_module)
.collect::<Result<_, parser::error::Error>>()?;
Expand All @@ -55,7 +57,7 @@ pub fn generate_live(
let generated_code = generate_internal(prepared_modules, settings);
// Write
if let Some(d) = destination {
write_generated_code(d, &generated_code)?;
write_generated_code(d.as_ref(), &generated_code)?;
};

Ok(generated_code)
Expand All @@ -68,15 +70,15 @@ pub fn generate_live(
///
/// By default, the container manager is Docker, but Podman can be used by setting the
/// `podman` parameter to `true`.
pub fn generate_managed(
queries_path: &str,
schema_files: Vec<String>,
destination: Option<&str>,
pub fn generate_managed<P: AsRef<Path>>(
queries_path: P,
schema_files: &[P],
destination: Option<P>,
podman: bool,
settings: CodegenSettings,
) -> Result<String, Error> {
// Read
let modules = read_query_modules(queries_path)?
let modules = read_query_modules(queries_path.as_ref())?
.into_iter()
.map(parse_query_module)
.collect::<Result<_, parser::error::Error>>()?;
Expand All @@ -88,17 +90,17 @@ pub fn generate_managed(
container::cleanup(podman)?;

if let Some(destination) = destination {
write_generated_code(destination, &generated_code)?;
write_generated_code(destination.as_ref(), &generated_code)?;
};

Ok(generated_code)
}

fn write_generated_code(destination: &str, generated_code: &str) -> Result<(), Error> {
fn write_generated_code(destination: &Path, generated_code: &str) -> Result<(), Error> {
Ok(
std::fs::write(destination, generated_code).map_err(|err| WriteOutputError {
err,
file_path: String::from(destination),
file_path: destination.to_owned(),
})?,
)
}
11 changes: 7 additions & 4 deletions cornucopia/src/load_schema.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::Path;

use miette::NamedSource;
use postgres::Client;

Expand All @@ -8,15 +10,16 @@ use self::error::Error;
/// Loads PostgreSQL schemas into a database.
///
/// Takes a list of file paths as parameter and loads them in their given order.
pub fn load_schema(client: &mut Client, paths: Vec<String>) -> Result<(), Error> {
pub fn load_schema<P: AsRef<Path>>(client: &mut Client, paths: &[P]) -> Result<(), Error> {
for path in paths {
let sql = std::fs::read_to_string(&path).map_err(|err| Error::Io {
path: path.clone(),
let path = path.as_ref();
let sql = std::fs::read_to_string(path).map_err(|err| Error::Io {
path: path.to_string_lossy().to_string(),
err,
})?;
client.batch_execute(&sql).map_err(|err| {
let msg = format!("{:#}", err);
let src = NamedSource::new(path, sql);
let src = NamedSource::new(path.to_string_lossy(), sql);
if let Some((position, msg, help)) = db_err(&err) {
Error::Postgres {
msg,
Expand Down
2 changes: 1 addition & 1 deletion cornucopia/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ pub(crate) fn parse_query_module(info: ModuleInfo) -> Result<Module, Error> {
})
}
Err(e) => Err(Error {
src: info.into(),
src: (&info).into(),
err_span: e[0].span().into(),
help: e[0].to_string().replace('\n', "\\n"),
}),
Expand Down
25 changes: 16 additions & 9 deletions cornucopia/src/read_queries.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,40 @@
use std::{
path::{Path, PathBuf},
sync::Arc,
};

use miette::NamedSource;

use self::error::Error;

#[derive(Debug, Clone)]
pub(crate) struct ModuleInfo {
pub(crate) path: String,
pub(crate) path: PathBuf,
pub(crate) name: String,
pub(crate) content: String,
pub(crate) content: Arc<String>,
}

impl From<ModuleInfo> for NamedSource {
fn from(m: ModuleInfo) -> Self {
Self::new(m.path, m.content)
Self::new(m.path.to_string_lossy(), m.content)
}
}

impl From<&ModuleInfo> for NamedSource {
fn from(m: &ModuleInfo) -> Self {
Self::new(&m.path, m.content.clone())
Self::new(&m.path.to_string_lossy(), m.content.clone())
}
}

/// Reads queries in the directory. Only .sql files are considered.
///
/// # Error
/// Returns an error if `dir_path` does not point to a valid directory or if a query file cannot be parsed.
pub(crate) fn read_query_modules(dir_path: &str) -> Result<Vec<ModuleInfo>, Error> {
pub(crate) fn read_query_modules(dir_path: &Path) -> Result<Vec<ModuleInfo>, Error> {
let mut modules_info = Vec::new();
for entry_result in std::fs::read_dir(dir_path).map_err(|err| Error {
err,
path: String::from(dir_path),
path: dir_path.to_owned(),
})? {
// Directory entry
let entry = entry_result.map_err(|err| Error {
Expand Down Expand Up @@ -57,9 +62,9 @@ pub(crate) fn read_query_modules(dir_path: &str) -> Result<Vec<ModuleInfo>, Erro
})?;

modules_info.push(ModuleInfo {
path: String::from(path_buf.to_string_lossy()),
path: path_buf,
name: module_name,
content: file_contents,
content: Arc::new(file_contents),
});
}
}
Expand All @@ -69,13 +74,15 @@ pub(crate) fn read_query_modules(dir_path: &str) -> Result<Vec<ModuleInfo>, Erro
}

pub(crate) mod error {
use std::path::PathBuf;

use miette::Diagnostic;
use thiserror::Error as ThisError;

#[derive(Debug, ThisError, Diagnostic)]
#[error("[{path}] : {err:#}")]
pub struct Error {
pub(crate) err: std::io::Error,
pub(crate) path: String,
pub(crate) path: PathBuf,
}
}
2 changes: 1 addition & 1 deletion examples/auto_build/_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn main() -> Result<(), Error> {
println!("cargo:rerun-if-changed={schema_file}");
cornucopia::generate_managed(
queries_path,
vec![schema_file.into()],
&[schema_file],
Some(destination),
false,
settings,
Expand Down
4 changes: 2 additions & 2 deletions integration/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ fn run_errors_test(

// Run codegen
let result: Result<(), cornucopia::Error> = (|| {
cornucopia::load_schema(client, vec!["schema.sql".into()])?;
cornucopia::load_schema(client, &["schema.sql"])?;
cornucopia::generate_live(
client,
"queries",
Expand Down Expand Up @@ -222,7 +222,7 @@ fn run_codegen_test(

// Load schema
reset_db(client)?;
cornucopia::load_schema(client, vec![schema_path.to_string()])?;
cornucopia::load_schema(client, &[schema_path])?;

// If `--apply`, then the code will be regenerated.
// Otherwise, it is only checked.
Expand Down