diff --git a/README.md b/README.md index 3b299de1..4392a079 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ cargo install dsync * `--model-path`: (optional) set a custom model import path, default `crate::models::` * `--schema-path`: (optional) set a custom schema import path, default `crate::schema::` * `--no-serde`: (optional) if set, does not output any serde related code +* `--no-crud`: (optional) Do not generate the CRUD functions for generated models * note: the CLI has fail-safes to prevent accidental file overwriting ```sh diff --git a/src/bin/main.rs b/src/bin/main.rs index 0e3c7b67..04809f99 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -72,6 +72,11 @@ struct Args { help = "Optional; Disable generating serde implementations" )] no_serde: bool, + #[structopt( + long = "no-crud", + help = "Optional; Do not generate the CRUD functions for generated models" + )] + no_crud: bool, } fn main() { @@ -89,7 +94,7 @@ fn main() { ); } else { eprintln!("{}", backtrace); - } + } } #[cfg(not(feature = "backtrace"))] { @@ -120,6 +125,10 @@ fn actual_main() -> dsync::Result<()> { default_table_options = default_table_options.disable_serde(); } + if args.no_crud { + default_table_options = default_table_options.disable_fns(); + } + dsync::generate_files( args.input, args.output, diff --git a/src/code.rs b/src/code.rs index 1b33f7e3..6d972c57 100644 --- a/src/code.rs +++ b/src/code.rs @@ -481,25 +481,42 @@ fn build_imports(table: &ParsedTableMacro, config: &GenerationConfig) -> String "" }; + let fns_imports = if table_options.get_fns() { + "\nuse diesel::QueryResult;" + } else { + "" + }; + + let connection_type_alias = if table_options.get_fns() { + format!( + "\ntype Connection = {connection_type};", + connection_type = config.connection_type, + ) + } else { + "".to_string() + }; + format!( indoc! {" use crate::diesel::*; - use {schema_path}; - use diesel::QueryResult; + use {schema_path};{fns_imports} {serde_imports}{async_imports} {belongs_imports} - - type Connection = {connection_type}; + {connection_type_alias} "}, - connection_type = config.connection_type, belongs_imports = belongs_imports, async_imports = async_imports, schema_path = schema_path, - serde_imports = serde_imports + serde_imports = serde_imports, + fns_imports = fns_imports, + connection_type_alias = connection_type_alias, ) + .trim_end() + .to_string() } pub fn generate_for_table(table: ParsedTableMacro, config: &GenerationConfig) -> String { + let table_options = config.table(&table.name.to_string()); // first, we generate struct code let read_struct = Struct::new(StructType::Read, &table, config); let update_struct = Struct::new(StructType::Update, &table, config); @@ -512,8 +529,12 @@ pub fn generate_for_table(table: ParsedTableMacro, config: &GenerationConfig) -> structs.push('\n'); structs.push_str(update_struct.code()); - let functions = build_table_fns(&table, config, create_struct, update_struct); + let functions = if table_options.get_fns() { + build_table_fns(&table, config, create_struct, update_struct) + } else { + "".to_string() + }; let imports = build_imports(&table, config); - format!("{FILE_SIGNATURE}\n\n{imports}\n{structs}\n{functions}") + format!("{FILE_SIGNATURE}\n\n{imports}\n\n{structs}\n{functions}") } diff --git a/src/lib.rs b/src/lib.rs index d12f22c4..c1bda207 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ mod code; +pub mod error; mod file; mod parser; -pub mod error; use error::IOErrorToError; pub use error::{Error, Result}; @@ -27,6 +27,9 @@ pub struct TableOptions<'a> { /// Generates serde::Serialize and serde::Deserialize derive implementations use_serde: bool, + + /// Generates the CRUD functions for generated models + fns: bool, } impl<'a> TableOptions<'a> { @@ -48,6 +51,10 @@ impl<'a> TableOptions<'a> { self.use_serde } + pub fn get_fns(&self) -> bool { + self.fns + } + pub fn get_autogenerated_columns(&self) -> &[&'_ str] { self.autogenerated_columns.as_deref().unwrap_or_default() } @@ -82,6 +89,10 @@ impl<'a> TableOptions<'a> { } } + pub fn disable_fns(self) -> Self { + Self { fns: false, ..self } + } + pub fn autogenerated_columns(self, cols: Vec<&'a str>) -> Self { Self { autogenerated_columns: Some(cols.clone()), @@ -103,6 +114,7 @@ impl<'a> TableOptions<'a> { .or_else(|| other.autogenerated_columns.clone()), use_serde: self.use_serde || other.use_serde, + fns: self.fns || other.fns, } } } @@ -117,6 +129,7 @@ impl<'a> Default for TableOptions<'a> { #[cfg(feature = "async")] use_async: Default::default(), use_serde: true, + fns: true, } } } @@ -200,8 +213,7 @@ pub fn generate_files( } // pass 2: delete code for removed tables - for item in std::fs::read_dir(&output_dir).attach_path_err(&output_dir)? - { + for item in std::fs::read_dir(&output_dir).attach_path_err(&output_dir)? { let item = item.attach_path_err(&output_dir)?; // check if item is a directory diff --git a/test/simple_table_no_crud/models/mod.rs b/test/simple_table_no_crud/models/mod.rs new file mode 100644 index 00000000..015a6a2b --- /dev/null +++ b/test/simple_table_no_crud/models/mod.rs @@ -0,0 +1 @@ +pub mod todos; diff --git a/test/simple_table_no_crud/models/todos/generated.rs b/test/simple_table_no_crud/models/todos/generated.rs new file mode 100644 index 00000000..c5dca1ac --- /dev/null +++ b/test/simple_table_no_crud/models/todos/generated.rs @@ -0,0 +1,35 @@ +/* This file is generated and managed by dsync */ + +use crate::diesel::*; +use crate::schema::*; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize, Clone, Queryable, Insertable, AsChangeset, Selectable)] +#[diesel(table_name=todos, primary_key(id))] +pub struct Todo { + pub id: i32, + pub unsigned: u32, + pub text: String, + pub completed: bool, + pub created_at: chrono::DateTime, + pub updated_at: chrono::DateTime, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Queryable, Insertable, AsChangeset)] +#[diesel(table_name=todos)] +pub struct CreateTodo { + pub unsigned: u32, + pub text: String, + pub completed: bool, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Queryable, Insertable, AsChangeset)] +#[diesel(table_name=todos)] +pub struct UpdateTodo { + pub unsigned: Option, + pub text: Option, + pub completed: Option, + pub created_at: Option>, + pub updated_at: Option>, +} + diff --git a/test/simple_table_no_crud/models/todos/mod.rs b/test/simple_table_no_crud/models/todos/mod.rs new file mode 100644 index 00000000..a5bb9b90 --- /dev/null +++ b/test/simple_table_no_crud/models/todos/mod.rs @@ -0,0 +1,2 @@ +pub use generated::*; +pub mod generated; diff --git a/test/simple_table_no_crud/schema.rs b/test/simple_table_no_crud/schema.rs new file mode 100644 index 00000000..37cf5cec --- /dev/null +++ b/test/simple_table_no_crud/schema.rs @@ -0,0 +1,10 @@ +diesel::table! { + todos (id) { + id -> Int4, + unsigned -> Unsigned, + text -> Text, + completed -> Bool, + created_at -> Timestamptz, + updated_at -> Timestamptz, + } +} diff --git a/test/simple_table_no_crud/test.sh b/test/simple_table_no_crud/test.sh new file mode 100755 index 00000000..cdfdf0e7 --- /dev/null +++ b/test/simple_table_no_crud/test.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +cd $SCRIPT_DIR + +cargo run -- -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --no-crud