├── .gitignore ├── test ├── postgres_array_column │ ├── models │ │ ├── mod.rs │ │ └── user │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── test.sh │ └── schema.rs ├── simple_table_pg │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── lib.rs │ ├── test.sh │ ├── Cargo.toml │ └── schema.rs ├── advanced_queries │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── lib.rs │ ├── Cargo.toml │ ├── schema.rs │ └── test.sh ├── autogenerated_all │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── cleanup_generated_content │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── README.md │ ├── schema2.rs │ ├── schema1.rs │ └── test.sh ├── manual_primary_keys │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── multiple_primary_keys │ ├── models │ │ ├── mod.rs │ │ └── users │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── no_default_features │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── test.sh │ └── schema.rs ├── simple_table_async │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── simple_table_mysql │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── lib.rs │ ├── test.sh │ ├── Cargo.toml │ └── schema.rs ├── simple_table_no_crud │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── simple_table_sqlite │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── lib.rs │ ├── test.sh │ ├── Cargo.toml │ └── schema.rs ├── use_statements │ ├── models │ │ ├── mod.rs │ │ └── fang_tasks │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── test.sh │ └── schema.rs ├── autogenerated_attributes │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── create_update_bytes_cow │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── create_update_bytes_slice │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── create_update_str_cow │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── create_update_str_str │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── simple_table_no_serde │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── autogenerated_primary_keys │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── custom_model_path │ ├── models │ │ ├── mod.rs │ │ ├── table_a │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ └── table_b │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── schema.rs │ └── test.sh ├── simple_table_custom_schema_path │ ├── models │ │ ├── mod.rs │ │ └── todos │ │ │ ├── mod.rs │ │ │ └── generated.rs │ ├── data │ │ └── schema.rs │ └── test.sh ├── single_model_file │ ├── models │ │ ├── mod.rs │ │ ├── table1.rs │ │ └── table2.rs │ ├── lib.rs │ ├── schema.rs │ ├── Cargo.toml │ └── test.sh ├── readonly │ ├── models │ │ ├── normal │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ ├── prefix_table │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ ├── table_suffix │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ ├── prefix_table_suffix │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ └── mod.rs │ ├── test.sh │ └── schema.rs ├── custom_model_and_schema_path │ ├── data │ │ ├── mod.rs │ │ ├── models │ │ │ ├── mod.rs │ │ │ ├── table_a │ │ │ │ ├── mod.rs │ │ │ │ └── generated.rs │ │ │ └── table_b │ │ │ │ ├── mod.rs │ │ │ │ └── generated.rs │ │ └── schema.rs │ ├── lib.rs │ ├── Cargo.toml │ └── test.sh ├── once_common_structs │ ├── models │ │ ├── mod.rs │ │ ├── table1 │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ ├── table2 │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ └── common.rs │ ├── schema.rs │ └── test.sh ├── once_connection_type │ ├── models │ │ ├── table1 │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ ├── table2 │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ ├── mod.rs │ │ └── common.rs │ ├── schema.rs │ └── test.sh ├── once_common_structs_once_connection_type │ ├── models │ │ ├── table1 │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ ├── table2 │ │ │ ├── mod.rs │ │ │ └── generated.rs │ │ ├── mod.rs │ │ └── common.rs │ ├── schema.rs │ └── test.sh ├── once_common_structs_once_connection_type_single_file │ ├── models │ │ ├── mod.rs │ │ ├── common.rs │ │ ├── table1.rs │ │ └── table2.rs │ ├── schema.rs │ └── test.sh ├── test_compile.sh ├── Cargo.toml ├── test_all.sh └── test_generate.sh ├── clippy.sh ├── fmt.sh ├── .editorconfig ├── COPYRIGHT ├── LICENSE-MIT ├── Cargo.toml ├── CHANGELOG.md ├── .releaserc.js ├── .github └── workflows │ └── CI.yml ├── src ├── file.rs ├── error.rs └── lib.rs ├── README.md └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | target 3 | .vscode/ 4 | -------------------------------------------------------------------------------- /test/postgres_array_column/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod user; -------------------------------------------------------------------------------- /test/simple_table_pg/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/advanced_queries/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/autogenerated_all/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/cleanup_generated_content/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; -------------------------------------------------------------------------------- /test/manual_primary_keys/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/multiple_primary_keys/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod users; -------------------------------------------------------------------------------- /test/no_default_features/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/simple_table_async/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/simple_table_mysql/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/simple_table_no_crud/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/simple_table_sqlite/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/use_statements/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fang_tasks; 2 | -------------------------------------------------------------------------------- /test/autogenerated_attributes/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/create_update_bytes_cow/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/create_update_bytes_slice/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/create_update_str_cow/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/create_update_str_str/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/simple_table_no_serde/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/autogenerated_primary_keys/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/custom_model_path/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod table_a; 2 | pub mod table_b; -------------------------------------------------------------------------------- /test/simple_table_custom_schema_path/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod todos; 2 | -------------------------------------------------------------------------------- /test/single_model_file/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod table1; 2 | pub mod table2; 3 | -------------------------------------------------------------------------------- /test/readonly/models/normal/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/data/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod models; 2 | pub mod schema; 3 | -------------------------------------------------------------------------------- /test/advanced_queries/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/autogenerated_all/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/custom_model_path/models/table_a/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/custom_model_path/models/table_b/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/manual_primary_keys/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/no_default_features/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/readonly/models/prefix_table/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/readonly/models/table_suffix/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/simple_table_async/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/simple_table_mysql/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/simple_table_pg/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/simple_table_sqlite/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/use_statements/models/fang_tasks/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/autogenerated_attributes/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/create_update_bytes_cow/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/create_update_str_cow/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/create_update_str_str/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/data/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod table_a; 2 | pub mod table_b; 3 | -------------------------------------------------------------------------------- /test/multiple_primary_keys/models/users/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/once_common_structs/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod common; 2 | pub mod table1; 3 | pub mod table2; 4 | -------------------------------------------------------------------------------- /test/once_common_structs/models/table1/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/once_common_structs/models/table2/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/once_connection_type/models/table1/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/once_connection_type/models/table2/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/postgres_array_column/models/user/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/readonly/models/prefix_table_suffix/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/simple_table_no_crud/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/simple_table_no_serde/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/autogenerated_primary_keys/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/cleanup_generated_content/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/create_update_bytes_slice/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /test/once_connection_type/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod common; 2 | pub mod table1; 3 | pub mod table2; 4 | -------------------------------------------------------------------------------- /test/simple_table_custom_schema_path/models/todos/mod.rs: -------------------------------------------------------------------------------- 1 | pub use generated::*; 2 | pub mod generated; 3 | -------------------------------------------------------------------------------- /clippy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # this file is an shorthand for the command below 4 | cargo clippy --all "$@" 5 | -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/data/models/table_a/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/data/models/table_b/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/manual_primary_keys/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type/models/table1/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type/models/table2/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod generated; 2 | pub use generated::*; 3 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod common; 2 | pub mod table1; 3 | pub mod table2; 4 | -------------------------------------------------------------------------------- /test/advanced_queries/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod models; 2 | pub mod schema; 3 | 4 | pub mod diesel { 5 | pub use diesel::*; 6 | } 7 | -------------------------------------------------------------------------------- /test/simple_table_pg/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod models; 2 | pub mod schema; 3 | 4 | pub mod diesel { 5 | pub use diesel::*; 6 | } 7 | -------------------------------------------------------------------------------- /test/single_model_file/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod models; 2 | pub mod schema; 3 | 4 | pub mod diesel { 5 | pub use diesel::*; 6 | } 7 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type_single_file/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod common; 2 | pub mod table1; 3 | pub mod table2; 4 | -------------------------------------------------------------------------------- /test/simple_table_mysql/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod models; 2 | pub mod schema; 3 | 4 | pub mod diesel { 5 | pub use diesel::*; 6 | } 7 | -------------------------------------------------------------------------------- /test/simple_table_sqlite/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod models; 2 | pub mod schema; 3 | 4 | pub mod diesel { 5 | pub use diesel::*; 6 | } 7 | -------------------------------------------------------------------------------- /fmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # this file is an shorthand for the command below, to not forget the nightly 4 | cargo +nightly fmt --all "$@" 5 | -------------------------------------------------------------------------------- /test/readonly/models/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod normal; 2 | 3 | 4 | 5 | pub mod prefix_table; 6 | pub mod table_suffix; 7 | pub mod prefix_table_suffix; -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_snake_case)] 2 | pub mod data; 3 | 4 | pub mod diesel { 5 | pub use diesel::*; 6 | } 7 | -------------------------------------------------------------------------------- /test/autogenerated_all/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | created_at -> Timestamp, 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/autogenerated_primary_keys/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | text -> Text, 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/autogenerated_attributes/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | created_at -> Timestamp, 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/create_update_bytes_cow/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (data) { 3 | data -> Binary, 4 | data_nullable -> Nullable, 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/create_update_bytes_slice/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (data) { 3 | data -> Binary, 4 | data_nullable -> Nullable, 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/multiple_primary_keys/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | users (name, address) { 3 | name -> Text, 4 | address -> Text, 5 | secret -> Text, 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/cleanup_generated_content/README.md: -------------------------------------------------------------------------------- 1 | This test ensures that generated content is removed for tables that are removed. 2 | 3 | Tables can be removed in development or after a migration, for example. -------------------------------------------------------------------------------- /test/once_connection_type/models/common.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 4 | -------------------------------------------------------------------------------- /test/once_common_structs/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | table1 (id) { 3 | id -> Int4, 4 | } 5 | } 6 | 7 | diesel::table! { 8 | table2 (id) { 9 | id -> Int4, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/once_connection_type/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | table1 (id) { 3 | id -> Int4, 4 | } 5 | } 6 | 7 | diesel::table! { 8 | table2 (id) { 9 | id -> Int4, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/single_model_file/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | table1 (id) { 3 | id -> Int4, 4 | } 5 | } 6 | 7 | diesel::table! { 8 | table2 (id) { 9 | id -> Int4, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 4 8 | 9 | [*.{yml, yaml}] 10 | indent_style = space 11 | indent_size = 2 12 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | table1 (id) { 3 | id -> Int4, 4 | } 5 | } 6 | 7 | diesel::table! { 8 | table2 (id) { 9 | id -> Int4, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type_single_file/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | table1 (id) { 3 | id -> Int4, 4 | } 5 | } 6 | 7 | diesel::table! { 8 | table2 (id) { 9 | id -> Int4, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/cleanup_generated_content/schema2.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | text -> Text, 5 | completed -> Bool, 6 | created_at -> Timestamptz, 7 | updated_at -> Timestamptz, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/create_update_str_cow/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (text) { 3 | text -> Text, 4 | text_nullable -> Nullable, 5 | #[max_length = 255] 6 | varchar -> Varchar, 7 | varchar_nullable -> Nullable, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/create_update_str_str/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (text) { 3 | text -> Text, 4 | text_nullable -> Nullable, 5 | #[max_length = 255] 6 | varchar -> Varchar, 7 | varchar_nullable -> Nullable, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/simple_table_async/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | unsigned -> Unsigned, 5 | text -> Text, 6 | completed -> Bool, 7 | created_at -> Timestamptz, 8 | updated_at -> Timestamptz, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/simple_table_no_crud/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | unsigned -> Unsigned, 5 | text -> Text, 6 | completed -> Bool, 7 | created_at -> Timestamptz, 8 | updated_at -> Timestamptz, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/simple_table_no_serde/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | unsigned -> Unsigned, 5 | text -> Text, 6 | completed -> Bool, 7 | created_at -> Timestamptz, 8 | updated_at -> Timestamptz, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/custom_model_path/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | tableA (_id) { 3 | _id -> Integer, 4 | } 5 | } 6 | 7 | diesel::table! { 8 | tableB (_id) { 9 | _id -> Integer, 10 | link -> Integer, 11 | } 12 | } 13 | 14 | diesel::joinable!(tableB -> tableA (link)); 15 | -------------------------------------------------------------------------------- /test/simple_table_custom_schema_path/data/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | unsigned -> Unsigned, 5 | text -> Text, 6 | completed -> Bool, 7 | created_at -> Timestamptz, 8 | updated_at -> Timestamptz, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/data/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | tableA (_id) { 3 | _id -> Integer, 4 | } 5 | } 6 | 7 | diesel::table! { 8 | tableB (_id) { 9 | _id -> Integer, 10 | link -> Integer, 11 | } 12 | } 13 | 14 | diesel::joinable!(tableB -> tableA (link)); 15 | -------------------------------------------------------------------------------- /test/use_statements/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -c "diesel::r2d2::PooledConnection>" -------------------------------------------------------------------------------- /test/manual_primary_keys/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -c "diesel::r2d2::PooledConnection>" -------------------------------------------------------------------------------- /test/multiple_primary_keys/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -c "diesel::r2d2::PooledConnection>" -------------------------------------------------------------------------------- /test/autogenerated_all/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -c "diesel::r2d2::PooledConnection>" -------------------------------------------------------------------------------- /test/autogenerated_attributes/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g created_at -c "diesel::r2d2::PooledConnection>" -------------------------------------------------------------------------------- /test/autogenerated_primary_keys/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -c "diesel::r2d2::PooledConnection>" 9 | -------------------------------------------------------------------------------- /test/simple_table_pg/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" 9 | -------------------------------------------------------------------------------- /test/single_model_file/Cargo.toml: -------------------------------------------------------------------------------- 1 | [lib] 2 | path = "lib.rs" 3 | 4 | [package] 5 | name = "single_model_file" 6 | version = "0.1.0" 7 | edition = "2021" 8 | 9 | [dependencies] 10 | diesel = { version = "*", default-features = false, features = [ 11 | "postgres", 12 | "chrono", 13 | ] } 14 | chrono.workspace = true 15 | serde.workspace = true 16 | -------------------------------------------------------------------------------- /test/postgres_array_column/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" 9 | -------------------------------------------------------------------------------- /test/test_compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is to compile all compile-able tests to see if they are correct 4 | 5 | # fail on non-0 exit codes, which makes it more obvious if a test has failed 6 | set -e 7 | 8 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 9 | 10 | cd $SCRIPT_DIR 11 | 12 | cargo build --all 13 | -------------------------------------------------------------------------------- /test/simple_table_sqlite/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" 9 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright 2022 Haris Khan 2 | 3 | Licensed under the Apache License, Version 2.0 or the MIT license 5 | , at your 6 | option. All files in the project carrying such notice may not be 7 | copied, modified, or distributed except according to those terms. -------------------------------------------------------------------------------- /test/simple_table_no_crud/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --no-crud 9 | -------------------------------------------------------------------------------- /test/simple_table_no_serde/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --no-serde 9 | -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/Cargo.toml: -------------------------------------------------------------------------------- 1 | [lib] 2 | path = "lib.rs" 3 | 4 | [package] 5 | name = "custom_model_and_schema_path" 6 | version = "0.1.0" 7 | edition = "2021" 8 | 9 | [dependencies] 10 | diesel = { version = "*", default-features = false, features = [ 11 | "postgres", 12 | "chrono", 13 | ] } 14 | chrono.workspace = true 15 | serde.workspace = true 16 | -------------------------------------------------------------------------------- /test/no_default_features/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --no-default-features --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" 9 | -------------------------------------------------------------------------------- /test/simple_table_async/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --features async --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel_async::pooled_connection::deadpool::Object" --async 9 | -------------------------------------------------------------------------------- /test/simple_table_mysql/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --no-crud 9 | -------------------------------------------------------------------------------- /test/single_model_file/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --single-model-file 9 | -------------------------------------------------------------------------------- /test/once_common_structs/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --once-common-structs 9 | -------------------------------------------------------------------------------- /test/once_connection_type/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --once-connection-type 9 | -------------------------------------------------------------------------------- /test/advanced_queries/Cargo.toml: -------------------------------------------------------------------------------- 1 | [lib] 2 | path = "lib.rs" 3 | 4 | [package] 5 | name = "advanced_queries" 6 | version = "0.1.0" 7 | edition = "2021" 8 | 9 | [dependencies] 10 | diesel = { version = "*", default-features = false, features = [ 11 | "postgres", 12 | "r2d2", 13 | "chrono", 14 | ] } 15 | r2d2.workspace = true 16 | chrono.workspace = true 17 | serde.workspace = true 18 | -------------------------------------------------------------------------------- /test/create_update_str_cow/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --create-str=cow --update-str=cow 9 | -------------------------------------------------------------------------------- /test/create_update_str_str/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --create-str=str --update-str=str 9 | -------------------------------------------------------------------------------- /test/custom_model_path/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --model-path "crate::data::models::" 9 | -------------------------------------------------------------------------------- /test/simple_table_pg/Cargo.toml: -------------------------------------------------------------------------------- 1 | [lib] 2 | path = "lib.rs" 3 | 4 | [package] 5 | name = "simple_table_pg" 6 | version = "0.1.0" 7 | edition = "2021" 8 | 9 | [dependencies] 10 | diesel = { version = "*", default-features = false, features = [ 11 | "postgres", 12 | "r2d2", 13 | "chrono", 14 | ] } 15 | r2d2.workspace = true 16 | chrono.workspace = true 17 | serde.workspace = true 18 | -------------------------------------------------------------------------------- /test/create_update_bytes_cow/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --create-bytes=cow --update-bytes=cow 9 | -------------------------------------------------------------------------------- /test/readonly/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --readonly-prefix prefix --readonly-suffix Suffix 9 | -------------------------------------------------------------------------------- /test/simple_table_mysql/Cargo.toml: -------------------------------------------------------------------------------- 1 | [lib] 2 | path = "lib.rs" 3 | 4 | [package] 5 | name = "simple_table_mysql" 6 | version = "0.1.0" 7 | edition = "2021" 8 | 9 | [dependencies] 10 | diesel = { version = "*", default-features = false, features = [ 11 | "mysql", 12 | "r2d2", 13 | "chrono", 14 | ] } 15 | r2d2.workspace = true 16 | chrono.workspace = true 17 | serde.workspace = true 18 | -------------------------------------------------------------------------------- /test/simple_table_pg/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | text -> Text, 5 | completed -> Bool, 6 | #[sql_name = "type"] 7 | #[max_length = 255] 8 | type_ -> Varchar, 9 | smallint -> Int2, 10 | bigint -> Int8, 11 | created_at -> Timestamptz, 12 | updated_at -> Timestamp, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/advanced_queries/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | text -> Text, 5 | completed -> Bool, 6 | #[sql_name = "type"] 7 | #[max_length = 255] 8 | type_ -> Varchar, 9 | smallint -> Int2, 10 | bigint -> Int8, 11 | created_at -> Timestamptz, 12 | updated_at -> Timestamp, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/cleanup_generated_content/schema1.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | text -> Text, 5 | completed -> Bool, 6 | created_at -> Timestamptz, 7 | updated_at -> Timestamptz, 8 | } 9 | 10 | books (id) { 11 | id -> Int4, 12 | title -> Text, 13 | year -> Int4, 14 | read -> Bool, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/create_update_bytes_slice/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --create-bytes=slice --update-bytes=slice 9 | -------------------------------------------------------------------------------- /test/advanced_queries/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run -F advanced-queries --manifest-path ../../Cargo.toml -- \ 8 | --diesel-backend diesel::pg::Pg -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" 9 | -------------------------------------------------------------------------------- /test/simple_table_custom_schema_path/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i data/schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --schema-path "crate::data::schema::" 9 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --once-common-structs --once-connection-type 9 | -------------------------------------------------------------------------------- /test/simple_table_sqlite/Cargo.toml: -------------------------------------------------------------------------------- 1 | [lib] 2 | path = "lib.rs" 3 | 4 | [package] 5 | name = "simple_table_sqlite" 6 | version = "0.1.0" 7 | edition = "2021" 8 | 9 | [dependencies] 10 | diesel = { version = "*", default-features = false, features = [ 11 | "sqlite", 12 | "r2d2", 13 | "chrono", 14 | "returning_clauses_for_sqlite_3_35", 15 | ] } 16 | r2d2.workspace = true 17 | chrono.workspace = true 18 | serde.workspace = true 19 | -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i data/schema.rs -o data/models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --schema-path "crate::data::schema::" --model-path "crate::data::models::" 9 | -------------------------------------------------------------------------------- /test/no_default_features/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | unsigned -> Unsigned, 5 | unsigned_nullable -> Nullable>, 6 | text -> Text, 7 | completed -> Bool, 8 | #[sql_name = "type"] 9 | #[max_length = 255] 10 | type_ -> Varchar, 11 | created_at -> Timestamptz, 12 | updated_at -> Timestamptz, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type_single_file/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema.rs -o models -g id -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" --once-common-structs --once-connection-type --single-model-file 9 | -------------------------------------------------------------------------------- /test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | # only some tests are currently compile-able 3 | members = [ 4 | "simple_table_pg", 5 | "simple_table_mysql", 6 | "simple_table_sqlite", 7 | "custom_model_and_schema_path", 8 | "single_model_file", 9 | "advanced_queries", 10 | ] 11 | resolver = "2" 12 | 13 | [workspace.dependencies] 14 | chrono = { version = "*", features = ["serde"] } 15 | serde = { version = "*", features = ["derive"] } 16 | r2d2 = "*" 17 | -------------------------------------------------------------------------------- /test/test_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is to run "dsync" generation on all test-cases 4 | 5 | # fail on non-0 exit codes, which makes it more obvious if a test has failed 6 | set -e 7 | 8 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 9 | 10 | cd $SCRIPT_DIR 11 | 12 | echo "Testing Generation" 13 | ./test_generate.sh 14 | 15 | # extra separator 16 | echo "" 17 | 18 | echo "Testing Compilation" 19 | ./test_compile.sh 20 | -------------------------------------------------------------------------------- /test/test_generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # fail on non-0 exit codes, which makes it more obvious if a test has failed 4 | set -e 5 | 6 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 7 | 8 | cd $SCRIPT_DIR 9 | 10 | for D in *; do 11 | # ignore the test's "target" directory 12 | if [ -d "${D}" ] && [ "${D}" != "target" ]; then 13 | echo "Testing $D" 14 | ${D}/test.sh 15 | # output separator 16 | echo "" 17 | fi 18 | done 19 | -------------------------------------------------------------------------------- /test/simple_table_mysql/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | unsigned -> Unsigned, 5 | unsigned_nullable -> Nullable>, 6 | text -> Text, 7 | completed -> Bool, 8 | #[sql_name = "type"] 9 | #[max_length = 255] 10 | type_ -> Varchar, 11 | smallint -> Int2, 12 | bigint -> Int8, 13 | created_at -> Timestamp, 14 | updated_at -> Timestamp, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/simple_table_sqlite/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | todos (id) { 3 | id -> Int4, 4 | // unsigned -> Unsigned, 5 | // unsigned_nullable -> Nullable>, 6 | text -> Text, 7 | completed -> Bool, 8 | #[sql_name = "type"] 9 | #[max_length = 255] 10 | type_ -> Varchar, 11 | smallint -> Int2, 12 | bigint -> Int8, 13 | created_at -> Timestamp, 14 | updated_at -> Timestamp, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/postgres_array_column/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | /* 3 | CREATE TABLE user ( 4 | id SERIAL PRIMARY KEY, 5 | phone_numbers TEXT[], 6 | optional_array_column TEXT[] NOT NULL 7 | ); 8 | */ 9 | 10 | user (id) { 11 | id -> Int4, 12 | // note: diesel will always generate a Array> 13 | phone_numbers -> Array>, 14 | optional_array_column -> Nullable>>, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/readonly/schema.rs: -------------------------------------------------------------------------------- 1 | diesel::table! { 2 | normal (id) { 3 | id -> Int4, 4 | testprop -> Int4, 5 | } 6 | } 7 | 8 | diesel::table! { 9 | prefixTable (id) { 10 | id -> Int4, 11 | testprop -> Int4, 12 | } 13 | } 14 | 15 | diesel::table! { 16 | tableSuffix (id) { 17 | id -> Int4, 18 | testprop -> Int4, 19 | } 20 | } 21 | 22 | diesel::table! { 23 | prefixTableSuffix (id) { 24 | id -> Int4, 25 | testprop -> Int4, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/cleanup_generated_content/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 4 | 5 | cd $SCRIPT_DIR 6 | 7 | cargo run --manifest-path ../../Cargo.toml -- \ 8 | -i schema1.rs -o models -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" 9 | cargo run --manifest-path ../../Cargo.toml -- \ 10 | -i schema2.rs -o models -g created_at -g updated_at -c "diesel::r2d2::PooledConnection>" -------------------------------------------------------------------------------- /test/once_common_structs/models/common.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | /// Result of a `.paginate` function 3 | #[derive(Debug, serde::Serialize)] 4 | pub struct PaginationResult { 5 | /// Resulting items that are from the current page 6 | pub items: Vec, 7 | /// The count of total items there are 8 | pub total_items: i64, 9 | /// Current page, 0-based index 10 | pub page: i64, 11 | /// Size of a page 12 | pub page_size: i64, 13 | /// Number of total possible pages, given the `page_size` and `total_items` 14 | pub num_pages: i64, 15 | } 16 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type/models/common.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | /// Result of a `.paginate` function 3 | #[derive(Debug, serde::Serialize)] 4 | pub struct PaginationResult { 5 | /// Resulting items that are from the current page 6 | pub items: Vec, 7 | /// The count of total items there are 8 | pub total_items: i64, 9 | /// Current page, 0-based index 10 | pub page: i64, 11 | /// Size of a page 12 | pub page_size: i64, 13 | /// Number of total possible pages, given the `page_size` and `total_items` 14 | pub num_pages: i64, 15 | } 16 | 17 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 18 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type_single_file/models/common.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | /// Result of a `.paginate` function 3 | #[derive(Debug, serde::Serialize)] 4 | pub struct PaginationResult { 5 | /// Resulting items that are from the current page 6 | pub items: Vec, 7 | /// The count of total items there are 8 | pub total_items: i64, 9 | /// Current page, 0-based index 10 | pub page: i64, 11 | /// Size of a page 12 | pub page_size: i64, 13 | /// Number of total possible pages, given the `page_size` and `total_items` 14 | pub num_pages: i64, 15 | } 16 | 17 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 18 | -------------------------------------------------------------------------------- /test/use_statements/schema.rs: -------------------------------------------------------------------------------- 1 | // @generated automatically by Diesel CLI. 2 | 3 | pub mod sql_types { 4 | #[derive(diesel::sql_types::SqlType)] 5 | #[diesel(postgres_type(name = "fang_task_state"))] 6 | pub struct FangTaskState; 7 | } 8 | 9 | diesel::table! { 10 | use diesel::sql_types::*; 11 | use super::sql_types::FangTaskState; 12 | 13 | fang_tasks (id) { 14 | id -> Uuid, 15 | metadata -> Jsonb, 16 | error_message -> Nullable, 17 | state -> FangTaskState, 18 | task_type -> Varchar, 19 | uniq_hash -> Nullable, 20 | retries -> Int4, 21 | scheduled_at -> Timestamptz, 22 | created_at -> Timestamptz, 23 | updated_at -> Timestamptz, 24 | } 25 | } 26 | 27 | diesel::allow_tables_to_appear_in_same_query!( 28 | fang_tasks, 29 | ); 30 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Haris Khan 4 | 5 | Permission is hereby granted, free of charge, to any 6 | person obtaining a copy of this software and associated 7 | documentation files (the "Software"), to deal in the 8 | Software without restriction, including without 9 | limitation the rights to use, copy, modify, merge, 10 | publish, distribute, sublicense, and/or sell copies of 11 | the Software, and to permit persons to whom the Software 12 | is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice 16 | shall be included in all copies or substantial portions 17 | of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 20 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 21 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 22 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 23 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 26 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type/models/table1/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | use crate::models::common::*; 7 | 8 | /// Struct representing a row in table `table1` 9 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 10 | #[diesel(table_name=table1, primary_key(id))] 11 | pub struct Table1 { 12 | /// Field representing column `id` 13 | pub id: i32, 14 | } 15 | 16 | impl Table1 { 17 | /// Insert a new row into `table1` with all default values 18 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 19 | use crate::schema::table1::dsl::*; 20 | 21 | diesel::insert_into(table1).default_values().get_result::(db) 22 | } 23 | 24 | /// Get a row from `table1`, identified by the primary key 25 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 26 | use crate::schema::table1::dsl::*; 27 | 28 | table1.filter(id.eq(param_id)).first::(db) 29 | } 30 | 31 | /// Delete a row in `table1`, identified by the primary key 32 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 33 | use crate::schema::table1::dsl::*; 34 | 35 | diesel::delete(table1.filter(id.eq(param_id))).execute(db) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type/models/table2/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | use crate::models::common::*; 7 | 8 | /// Struct representing a row in table `table2` 9 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 10 | #[diesel(table_name=table2, primary_key(id))] 11 | pub struct Table2 { 12 | /// Field representing column `id` 13 | pub id: i32, 14 | } 15 | 16 | impl Table2 { 17 | /// Insert a new row into `table2` with all default values 18 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 19 | use crate::schema::table2::dsl::*; 20 | 21 | diesel::insert_into(table2).default_values().get_result::(db) 22 | } 23 | 24 | /// Get a row from `table2`, identified by the primary key 25 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 26 | use crate::schema::table2::dsl::*; 27 | 28 | table2.filter(id.eq(param_id)).first::(db) 29 | } 30 | 31 | /// Delete a row in `table2`, identified by the primary key 32 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 33 | use crate::schema::table2::dsl::*; 34 | 35 | diesel::delete(table2.filter(id.eq(param_id))).execute(db) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type_single_file/models/table1.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | use crate::models::common::*; 7 | 8 | /// Struct representing a row in table `table1` 9 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 10 | #[diesel(table_name=table1, primary_key(id))] 11 | pub struct Table1 { 12 | /// Field representing column `id` 13 | pub id: i32, 14 | } 15 | 16 | impl Table1 { 17 | /// Insert a new row into `table1` with all default values 18 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 19 | use crate::schema::table1::dsl::*; 20 | 21 | diesel::insert_into(table1).default_values().get_result::(db) 22 | } 23 | 24 | /// Get a row from `table1`, identified by the primary key 25 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 26 | use crate::schema::table1::dsl::*; 27 | 28 | table1.filter(id.eq(param_id)).first::(db) 29 | } 30 | 31 | /// Delete a row in `table1`, identified by the primary key 32 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 33 | use crate::schema::table1::dsl::*; 34 | 35 | diesel::delete(table1.filter(id.eq(param_id))).execute(db) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/once_common_structs_once_connection_type_single_file/models/table2.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | use crate::models::common::*; 7 | 8 | /// Struct representing a row in table `table2` 9 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 10 | #[diesel(table_name=table2, primary_key(id))] 11 | pub struct Table2 { 12 | /// Field representing column `id` 13 | pub id: i32, 14 | } 15 | 16 | impl Table2 { 17 | /// Insert a new row into `table2` with all default values 18 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 19 | use crate::schema::table2::dsl::*; 20 | 21 | diesel::insert_into(table2).default_values().get_result::(db) 22 | } 23 | 24 | /// Get a row from `table2`, identified by the primary key 25 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 26 | use crate::schema::table2::dsl::*; 27 | 28 | table2.filter(id.eq(param_id)).first::(db) 29 | } 30 | 31 | /// Delete a row in `table2`, identified by the primary key 32 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 33 | use crate::schema::table2::dsl::*; 34 | 35 | diesel::delete(table2.filter(id.eq(param_id))).execute(db) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dsync" 3 | description = "Generate rust structs & query functions from diesel schema files." 4 | version = "0.1.0" 5 | readme = "README.md" 6 | repository = "https://github.com/Wulf/dsync" 7 | license = "MIT OR Apache-2.0" 8 | keywords = ["diesel", "crud", "database", "codegen", "generation"] 9 | categories = [ 10 | "command-line-utilities", 11 | "development-tools", 12 | "development-tools::ffi", 13 | "web-programming", 14 | ] 15 | authors = [ 16 | "Haris <4259838+Wulf@users.noreply.github.com>", 17 | "hasezoey ", 18 | ] 19 | edition = "2021" 20 | rust-version = "1.70" 21 | 22 | [features] 23 | default = ["tsync", "backtrace", "derive-queryablebyname"] 24 | # enable support for tsync (https://github.com/Wulf/tsync) 25 | tsync = [] 26 | # enable support for diesel_async (https://github.com/weiznich/diesel_async) 27 | async = [] 28 | # enable support for backtraces on errors 29 | backtrace = [] 30 | # enable derive "QueryableByName" 31 | derive-queryablebyname = [] 32 | # enable *experimental* queries 33 | advanced-queries = [] 34 | 35 | [dependencies] 36 | clap = { version = "4.4", features = ["derive", "wrap_help"] } 37 | clap_complete = "4.4" 38 | syn = { version = "2", features = ["extra-traits", "full"] } 39 | proc-macro2 = "1" 40 | indoc = "2.0.4" 41 | heck = "0.4" # same case converter diesel uses 42 | thiserror = "1.0" 43 | 44 | [lib] 45 | path = "src/lib.rs" 46 | 47 | [[bin]] 48 | name = "dsync" 49 | test = false 50 | path = "src/bin/main.rs" 51 | -------------------------------------------------------------------------------- /test/once_common_structs/models/table1/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | use crate::models::common::*; 7 | 8 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 9 | 10 | /// Struct representing a row in table `table1` 11 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 12 | #[diesel(table_name=table1, primary_key(id))] 13 | pub struct Table1 { 14 | /// Field representing column `id` 15 | pub id: i32, 16 | } 17 | 18 | impl Table1 { 19 | /// Insert a new row into `table1` with all default values 20 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 21 | use crate::schema::table1::dsl::*; 22 | 23 | diesel::insert_into(table1).default_values().get_result::(db) 24 | } 25 | 26 | /// Get a row from `table1`, identified by the primary key 27 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 28 | use crate::schema::table1::dsl::*; 29 | 30 | table1.filter(id.eq(param_id)).first::(db) 31 | } 32 | 33 | /// Delete a row in `table1`, identified by the primary key 34 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 35 | use crate::schema::table1::dsl::*; 36 | 37 | diesel::delete(table1.filter(id.eq(param_id))).execute(db) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/once_common_structs/models/table2/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | use crate::models::common::*; 7 | 8 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 9 | 10 | /// Struct representing a row in table `table2` 11 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 12 | #[diesel(table_name=table2, primary_key(id))] 13 | pub struct Table2 { 14 | /// Field representing column `id` 15 | pub id: i32, 16 | } 17 | 18 | impl Table2 { 19 | /// Insert a new row into `table2` with all default values 20 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 21 | use crate::schema::table2::dsl::*; 22 | 23 | diesel::insert_into(table2).default_values().get_result::(db) 24 | } 25 | 26 | /// Get a row from `table2`, identified by the primary key 27 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 28 | use crate::schema::table2::dsl::*; 29 | 30 | table2.filter(id.eq(param_id)).first::(db) 31 | } 32 | 33 | /// Delete a row in `table2`, identified by the primary key 34 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 35 | use crate::schema::table2::dsl::*; 36 | 37 | diesel::delete(table2.filter(id.eq(param_id))).execute(db) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/readonly/models/prefix_table/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `prefixTable` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=prefixTable, primary_key(id))] 12 | pub struct PrefixTable { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `testprop` 16 | pub testprop: i32, 17 | } 18 | 19 | /// Result of a `.paginate` function 20 | #[derive(Debug, serde::Serialize)] 21 | pub struct PaginationResult { 22 | /// Resulting items that are from the current page 23 | pub items: Vec, 24 | /// The count of total items there are 25 | pub total_items: i64, 26 | /// Current page, 0-based index 27 | pub page: i64, 28 | /// Size of a page 29 | pub page_size: i64, 30 | /// Number of total possible pages, given the `page_size` and `total_items` 31 | pub num_pages: i64, 32 | } 33 | 34 | impl PrefixTable { 35 | /// Get a row from `prefixTable`, identified by the primary key 36 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 37 | use crate::schema::prefixTable::dsl::*; 38 | 39 | prefixTable.filter(id.eq(param_id)).first::(db) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/readonly/models/table_suffix/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `tableSuffix` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=tableSuffix, primary_key(id))] 12 | pub struct TableSuffix { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `testprop` 16 | pub testprop: i32, 17 | } 18 | 19 | /// Result of a `.paginate` function 20 | #[derive(Debug, serde::Serialize)] 21 | pub struct PaginationResult { 22 | /// Resulting items that are from the current page 23 | pub items: Vec, 24 | /// The count of total items there are 25 | pub total_items: i64, 26 | /// Current page, 0-based index 27 | pub page: i64, 28 | /// Size of a page 29 | pub page_size: i64, 30 | /// Number of total possible pages, given the `page_size` and `total_items` 31 | pub num_pages: i64, 32 | } 33 | 34 | impl TableSuffix { 35 | /// Get a row from `tableSuffix`, identified by the primary key 36 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 37 | use crate::schema::tableSuffix::dsl::*; 38 | 39 | tableSuffix.filter(id.eq(param_id)).first::(db) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/readonly/models/prefix_table_suffix/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `prefixTableSuffix` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=prefixTableSuffix, primary_key(id))] 12 | pub struct PrefixTableSuffix { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `testprop` 16 | pub testprop: i32, 17 | } 18 | 19 | /// Result of a `.paginate` function 20 | #[derive(Debug, serde::Serialize)] 21 | pub struct PaginationResult { 22 | /// Resulting items that are from the current page 23 | pub items: Vec, 24 | /// The count of total items there are 25 | pub total_items: i64, 26 | /// Current page, 0-based index 27 | pub page: i64, 28 | /// Size of a page 29 | pub page_size: i64, 30 | /// Number of total possible pages, given the `page_size` and `total_items` 31 | pub num_pages: i64, 32 | } 33 | 34 | impl PrefixTableSuffix { 35 | /// Get a row from `prefixTableSuffix`, identified by the primary key 36 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 37 | use crate::schema::prefixTableSuffix::dsl::*; 38 | 39 | prefixTableSuffix.filter(id.eq(param_id)).first::(db) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/once_connection_type/models/table1/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | use crate::models::common::*; 7 | 8 | /// Struct representing a row in table `table1` 9 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 10 | #[diesel(table_name=table1, primary_key(id))] 11 | pub struct Table1 { 12 | /// Field representing column `id` 13 | pub id: i32, 14 | } 15 | 16 | /// Result of a `.paginate` function 17 | #[derive(Debug, serde::Serialize)] 18 | pub struct PaginationResult { 19 | /// Resulting items that are from the current page 20 | pub items: Vec, 21 | /// The count of total items there are 22 | pub total_items: i64, 23 | /// Current page, 0-based index 24 | pub page: i64, 25 | /// Size of a page 26 | pub page_size: i64, 27 | /// Number of total possible pages, given the `page_size` and `total_items` 28 | pub num_pages: i64, 29 | } 30 | 31 | impl Table1 { 32 | /// Insert a new row into `table1` with all default values 33 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 34 | use crate::schema::table1::dsl::*; 35 | 36 | diesel::insert_into(table1).default_values().get_result::(db) 37 | } 38 | 39 | /// Get a row from `table1`, identified by the primary key 40 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 41 | use crate::schema::table1::dsl::*; 42 | 43 | table1.filter(id.eq(param_id)).first::(db) 44 | } 45 | 46 | /// Delete a row in `table1`, identified by the primary key 47 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 48 | use crate::schema::table1::dsl::*; 49 | 50 | diesel::delete(table1.filter(id.eq(param_id))).execute(db) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/once_connection_type/models/table2/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | use crate::models::common::*; 7 | 8 | /// Struct representing a row in table `table2` 9 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 10 | #[diesel(table_name=table2, primary_key(id))] 11 | pub struct Table2 { 12 | /// Field representing column `id` 13 | pub id: i32, 14 | } 15 | 16 | /// Result of a `.paginate` function 17 | #[derive(Debug, serde::Serialize)] 18 | pub struct PaginationResult { 19 | /// Resulting items that are from the current page 20 | pub items: Vec, 21 | /// The count of total items there are 22 | pub total_items: i64, 23 | /// Current page, 0-based index 24 | pub page: i64, 25 | /// Size of a page 26 | pub page_size: i64, 27 | /// Number of total possible pages, given the `page_size` and `total_items` 28 | pub num_pages: i64, 29 | } 30 | 31 | impl Table2 { 32 | /// Insert a new row into `table2` with all default values 33 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 34 | use crate::schema::table2::dsl::*; 35 | 36 | diesel::insert_into(table2).default_values().get_result::(db) 37 | } 38 | 39 | /// Get a row from `table2`, identified by the primary key 40 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 41 | use crate::schema::table2::dsl::*; 42 | 43 | table2.filter(id.eq(param_id)).first::(db) 44 | } 45 | 46 | /// Delete a row in `table2`, identified by the primary key 47 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 48 | use crate::schema::table2::dsl::*; 49 | 50 | diesel::delete(table2.filter(id.eq(param_id))).execute(db) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/single_model_file/models/table1.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `table1` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=table1, primary_key(id))] 12 | pub struct Table1 { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | } 16 | 17 | /// Result of a `.paginate` function 18 | #[derive(Debug, serde::Serialize)] 19 | pub struct PaginationResult { 20 | /// Resulting items that are from the current page 21 | pub items: Vec, 22 | /// The count of total items there are 23 | pub total_items: i64, 24 | /// Current page, 0-based index 25 | pub page: i64, 26 | /// Size of a page 27 | pub page_size: i64, 28 | /// Number of total possible pages, given the `page_size` and `total_items` 29 | pub num_pages: i64, 30 | } 31 | 32 | impl Table1 { 33 | /// Insert a new row into `table1` with all default values 34 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 35 | use crate::schema::table1::dsl::*; 36 | 37 | diesel::insert_into(table1).default_values().get_result::(db) 38 | } 39 | 40 | /// Get a row from `table1`, identified by the primary key 41 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 42 | use crate::schema::table1::dsl::*; 43 | 44 | table1.filter(id.eq(param_id)).first::(db) 45 | } 46 | 47 | /// Delete a row in `table1`, identified by the primary key 48 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 49 | use crate::schema::table1::dsl::*; 50 | 51 | diesel::delete(table1.filter(id.eq(param_id))).execute(db) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/single_model_file/models/table2.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `table2` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=table2, primary_key(id))] 12 | pub struct Table2 { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | } 16 | 17 | /// Result of a `.paginate` function 18 | #[derive(Debug, serde::Serialize)] 19 | pub struct PaginationResult { 20 | /// Resulting items that are from the current page 21 | pub items: Vec, 22 | /// The count of total items there are 23 | pub total_items: i64, 24 | /// Current page, 0-based index 25 | pub page: i64, 26 | /// Size of a page 27 | pub page_size: i64, 28 | /// Number of total possible pages, given the `page_size` and `total_items` 29 | pub num_pages: i64, 30 | } 31 | 32 | impl Table2 { 33 | /// Insert a new row into `table2` with all default values 34 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 35 | use crate::schema::table2::dsl::*; 36 | 37 | diesel::insert_into(table2).default_values().get_result::(db) 38 | } 39 | 40 | /// Get a row from `table2`, identified by the primary key 41 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 42 | use crate::schema::table2::dsl::*; 43 | 44 | table2.filter(id.eq(param_id)).first::(db) 45 | } 46 | 47 | /// Delete a row in `table2`, identified by the primary key 48 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 49 | use crate::schema::table2::dsl::*; 50 | 51 | diesel::delete(table2.filter(id.eq(param_id))).execute(db) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/simple_table_no_crud/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | /// Struct representing a row in table `todos` 8 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 9 | #[diesel(table_name=todos, primary_key(id))] 10 | pub struct Todos { 11 | /// Field representing column `id` 12 | pub id: i32, 13 | /// Field representing column `unsigned` 14 | pub unsigned: u32, 15 | /// Field representing column `text` 16 | pub text: String, 17 | /// Field representing column `completed` 18 | pub completed: bool, 19 | /// Field representing column `created_at` 20 | pub created_at: chrono::DateTime, 21 | /// Field representing column `updated_at` 22 | pub updated_at: chrono::DateTime, 23 | } 24 | 25 | /// Create Struct for a row in table `todos` for [`Todos`] 26 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 27 | #[diesel(table_name=todos)] 28 | pub struct CreateTodos { 29 | /// Field representing column `unsigned` 30 | pub unsigned: u32, 31 | /// Field representing column `text` 32 | pub text: String, 33 | /// Field representing column `completed` 34 | pub completed: bool, 35 | } 36 | 37 | /// Update Struct for a row in table `todos` for [`Todos`] 38 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 39 | #[diesel(table_name=todos)] 40 | pub struct UpdateTodos { 41 | /// Field representing column `unsigned` 42 | pub unsigned: Option, 43 | /// Field representing column `text` 44 | pub text: Option, 45 | /// Field representing column `completed` 46 | pub completed: Option, 47 | /// Field representing column `created_at` 48 | pub created_at: Option>, 49 | /// Field representing column `updated_at` 50 | pub updated_at: Option>, 51 | } 52 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## next 4 | 5 | - set MSRV to `1.70` 6 | 7 | ## 0.1.0 8 | 9 | - replace `structopt` with `clap` 10 | - replace dependency `Inflector` with `heck` 11 | - add dependency `thiserror` 12 | - remove dependency `anyhow` 13 | - add subcommand to generate shell completions 14 | - function `generate_files` now takes in `&Path`s instead of `PathBuf`s 15 | - remove `to_singular` name generations 16 | - add option `--create-str` to set `Create*` structs string & byte types 17 | - add option `--update-str` to set `Update*` structs string & byte type 18 | - add option `--single-model-file` to only generate a single file instead of a directory with `mod.rs` and `generated.rs` 19 | - add option `--readonly-prefix` and `--readonly-suffix` to treat a matching name as a readonly struct 20 | - add option `--no-crud` to not generate any `impl` blocks 21 | - derive generation has been refactored and now only necessary derives are added to a given struct 22 | - reduce amount of empty-newlines 23 | - add `dsync::Error`(and `dsync::error` module) 24 | - replace most `panic!`, `.expect` and some `.unwrap` with `Result`s 25 | - fix nullable unsigned integers not resulting in `Option` 26 | - derive `Default` for all `Update*` structs 27 | - use `@generated` file signature to exclude the files from formatting 28 | - rename `type Connection =` to `type ConnectionType =` to lessen naming conflicts 29 | - add many doc-comments to fields and functions 30 | - list changes to files (unchanged, modified, deleted) 31 | - generate doc-comments for generated structs, fields and functions 32 | - add derive `QueryableByName` to read-structs 33 | - add derive `PartialEq` to update-structs 34 | - add new experimental filters (behind the `advanced-queries` feature flag) 35 | - move function `paginate` behind `advanced-queries` feature flag 36 | - split `GenerationConfig` into required and optional parts (`GenerationConfigOpts`) (fixes #92) 37 | - added compile tests to actually verify all options compiling 38 | 39 | ## 0.0.17 (yanked) 40 | 41 | - used for testing publishing CI 42 | 43 | ## 0.0.16 44 | 45 | - add option `schema-path` and `model-path` to specify custom paths for diesel schemas input and model output 46 | 47 | ## 0.0.15 48 | 49 | - add option `--no-serde` to disable serde derives 50 | 51 | ## 0.0.14 52 | 53 | - fixes for diesel `2.1.0` 54 | -------------------------------------------------------------------------------- /test/manual_primary_keys/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | } 16 | 17 | /// Create Struct for a row in table `todos` for [`Todos`] 18 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 19 | #[diesel(table_name=todos)] 20 | pub struct CreateTodos { 21 | /// Field representing column `id` 22 | pub id: i32, 23 | } 24 | 25 | /// Result of a `.paginate` function 26 | #[derive(Debug, serde::Serialize)] 27 | pub struct PaginationResult { 28 | /// Resulting items that are from the current page 29 | pub items: Vec, 30 | /// The count of total items there are 31 | pub total_items: i64, 32 | /// Current page, 0-based index 33 | pub page: i64, 34 | /// Size of a page 35 | pub page_size: i64, 36 | /// Number of total possible pages, given the `page_size` and `total_items` 37 | pub num_pages: i64, 38 | } 39 | 40 | impl Todos { 41 | /// Insert a new row into `todos` with a given [`CreateTodos`] 42 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 43 | use crate::schema::todos::dsl::*; 44 | 45 | diesel::insert_into(todos).values(item).get_result::(db) 46 | } 47 | 48 | /// Get a row from `todos`, identified by the primary key 49 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 50 | use crate::schema::todos::dsl::*; 51 | 52 | todos.filter(id.eq(param_id)).first::(db) 53 | } 54 | 55 | /// Delete a row in `todos`, identified by the primary key 56 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 57 | use crate::schema::todos::dsl::*; 58 | 59 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /test/custom_model_path/models/table_a/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `tableA` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=tableA, primary_key(_id))] 12 | pub struct TableA { 13 | /// Field representing column `_id` 14 | pub _id: i32, 15 | } 16 | 17 | /// Create Struct for a row in table `tableA` for [`TableA`] 18 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 19 | #[diesel(table_name=tableA)] 20 | pub struct CreateTableA { 21 | /// Field representing column `_id` 22 | pub _id: i32, 23 | } 24 | 25 | /// Result of a `.paginate` function 26 | #[derive(Debug, serde::Serialize)] 27 | pub struct PaginationResult { 28 | /// Resulting items that are from the current page 29 | pub items: Vec, 30 | /// The count of total items there are 31 | pub total_items: i64, 32 | /// Current page, 0-based index 33 | pub page: i64, 34 | /// Size of a page 35 | pub page_size: i64, 36 | /// Number of total possible pages, given the `page_size` and `total_items` 37 | pub num_pages: i64, 38 | } 39 | 40 | impl TableA { 41 | /// Insert a new row into `tableA` with a given [`CreateTableA`] 42 | pub fn create(db: &mut ConnectionType, item: &CreateTableA) -> diesel::QueryResult { 43 | use crate::schema::tableA::dsl::*; 44 | 45 | diesel::insert_into(tableA).values(item).get_result::(db) 46 | } 47 | 48 | /// Get a row from `tableA`, identified by the primary key 49 | pub fn read(db: &mut ConnectionType, param__id: i32) -> diesel::QueryResult { 50 | use crate::schema::tableA::dsl::*; 51 | 52 | tableA.filter(_id.eq(param__id)).first::(db) 53 | } 54 | 55 | /// Delete a row in `tableA`, identified by the primary key 56 | pub fn delete(db: &mut ConnectionType, param__id: i32) -> diesel::QueryResult { 57 | use crate::schema::tableA::dsl::*; 58 | 59 | diesel::delete(tableA.filter(_id.eq(param__id))).execute(db) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/data/models/table_a/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::data::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `tableA` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=tableA, primary_key(_id))] 12 | pub struct TableA { 13 | /// Field representing column `_id` 14 | pub _id: i32, 15 | } 16 | 17 | /// Create Struct for a row in table `tableA` for [`TableA`] 18 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 19 | #[diesel(table_name=tableA)] 20 | pub struct CreateTableA { 21 | /// Field representing column `_id` 22 | pub _id: i32, 23 | } 24 | 25 | /// Result of a `.paginate` function 26 | #[derive(Debug, serde::Serialize)] 27 | pub struct PaginationResult { 28 | /// Resulting items that are from the current page 29 | pub items: Vec, 30 | /// The count of total items there are 31 | pub total_items: i64, 32 | /// Current page, 0-based index 33 | pub page: i64, 34 | /// Size of a page 35 | pub page_size: i64, 36 | /// Number of total possible pages, given the `page_size` and `total_items` 37 | pub num_pages: i64, 38 | } 39 | 40 | impl TableA { 41 | /// Insert a new row into `tableA` with a given [`CreateTableA`] 42 | pub fn create(db: &mut ConnectionType, item: &CreateTableA) -> diesel::QueryResult { 43 | use crate::data::schema::tableA::dsl::*; 44 | 45 | diesel::insert_into(tableA).values(item).get_result::(db) 46 | } 47 | 48 | /// Get a row from `tableA`, identified by the primary key 49 | pub fn read(db: &mut ConnectionType, param__id: i32) -> diesel::QueryResult { 50 | use crate::data::schema::tableA::dsl::*; 51 | 52 | tableA.filter(_id.eq(param__id)).first::(db) 53 | } 54 | 55 | /// Delete a row in `tableA`, identified by the primary key 56 | pub fn delete(db: &mut ConnectionType, param__id: i32) -> diesel::QueryResult { 57 | use crate::data::schema::tableA::dsl::*; 58 | 59 | diesel::delete(tableA.filter(_id.eq(param__id))).execute(db) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /.releaserc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | [ 4 | '@semantic-release/commit-analyzer', 5 | { 6 | preset: 'angular', 7 | releaseRules: [ 8 | { breaking: true, release: 'major' }, 9 | { type: 'feat', release: 'minor' }, 10 | { type: 'fix', release: 'patch' }, 11 | { type: 'docs', release: false }, 12 | { type: 'style', release: false }, 13 | { type: 'refactor', release: 'patch' }, 14 | { type: 'perf', release: 'patch' }, 15 | { type: 'test', release: false }, 16 | { type: 'chore', release: false }, 17 | { type: 'deps', release: 'minor' }, 18 | { type: 'devdeps', release: false }, 19 | { type: 'revert', release: 'patch' }, 20 | // don't trigger another release on release commit 21 | { type: 'release', release: false } 22 | ], 23 | parserOpts: { 24 | noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES'] 25 | } 26 | } 27 | ], 28 | [ 29 | '@semantic-release/release-notes-generator', 30 | { 31 | preset: 'conventionalcommits', 32 | presetConfig: { 33 | types: [ 34 | { type: 'feat', section: 'Features' }, 35 | { type: 'fix', section: 'Fixes' }, 36 | { type: 'docs', hidden: true }, 37 | { type: 'style', section: 'Style' }, 38 | { type: 'refactor', section: 'Refactor' }, 39 | { type: 'perf', section: 'Performance' }, 40 | { type: 'test', hidden: true }, 41 | { type: 'chore', hidden: true }, 42 | { type: 'deps', section: 'Dependencies' }, 43 | { type: 'devdeps', section: 'Dev-Dependencies' }, 44 | { type: 'revert', section: 'Reverts' }, 45 | { type: 'release', hidden: true } 46 | ] 47 | } 48 | } 49 | ], 50 | '@semantic-release/changelog', 51 | '@semantic-release-cargo/semantic-release-cargo', 52 | [ 53 | '@semantic-release/git', { 54 | assets: ['Cargo.toml', 'Cargo.loc', 'CHANGELOG.md'], 55 | message: 'release: v${nextRelease.version}' 56 | } 57 | ], 58 | '@semantic-release/github' 59 | ], 60 | branches: [ 61 | 'main', 62 | ] 63 | }; 64 | -------------------------------------------------------------------------------- /test/autogenerated_all/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `created_at` 16 | pub created_at: chrono::NaiveDateTime, 17 | } 18 | 19 | /// Update Struct for a row in table `todos` for [`Todos`] 20 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 21 | #[diesel(table_name=todos)] 22 | pub struct UpdateTodos { 23 | /// Field representing column `created_at` 24 | pub created_at: Option, 25 | } 26 | 27 | /// Result of a `.paginate` function 28 | #[derive(Debug, serde::Serialize)] 29 | pub struct PaginationResult { 30 | /// Resulting items that are from the current page 31 | pub items: Vec, 32 | /// The count of total items there are 33 | pub total_items: i64, 34 | /// Current page, 0-based index 35 | pub page: i64, 36 | /// Size of a page 37 | pub page_size: i64, 38 | /// Number of total possible pages, given the `page_size` and `total_items` 39 | pub num_pages: i64, 40 | } 41 | 42 | impl Todos { 43 | /// Insert a new row into `todos` with all default values 44 | pub fn create(db: &mut ConnectionType) -> diesel::QueryResult { 45 | use crate::schema::todos::dsl::*; 46 | 47 | diesel::insert_into(todos).default_values().get_result::(db) 48 | } 49 | 50 | /// Get a row from `todos`, identified by the primary key 51 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 52 | use crate::schema::todos::dsl::*; 53 | 54 | todos.filter(id.eq(param_id)).first::(db) 55 | } 56 | 57 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 58 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 59 | use crate::schema::todos::dsl::*; 60 | 61 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 62 | } 63 | 64 | /// Delete a row in `todos`, identified by the primary key 65 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 66 | use crate::schema::todos::dsl::*; 67 | 68 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /test/simple_table_mysql/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | /// Struct representing a row in table `todos` 8 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 9 | #[diesel(table_name=todos, primary_key(id))] 10 | pub struct Todos { 11 | /// Field representing column `id` 12 | pub id: i32, 13 | /// Field representing column `unsigned` 14 | pub unsigned: u32, 15 | /// Field representing column `unsigned_nullable` 16 | pub unsigned_nullable: Option, 17 | /// Field representing column `text` 18 | pub text: String, 19 | /// Field representing column `completed` 20 | pub completed: bool, 21 | /// Field representing column `type` 22 | pub type_: String, 23 | /// Field representing column `smallint` 24 | pub smallint: i16, 25 | /// Field representing column `bigint` 26 | pub bigint: i64, 27 | /// Field representing column `created_at` 28 | pub created_at: chrono::NaiveDateTime, 29 | /// Field representing column `updated_at` 30 | pub updated_at: chrono::NaiveDateTime, 31 | } 32 | 33 | /// Create Struct for a row in table `todos` for [`Todos`] 34 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 35 | #[diesel(table_name=todos)] 36 | pub struct CreateTodos { 37 | /// Field representing column `unsigned` 38 | pub unsigned: u32, 39 | /// Field representing column `unsigned_nullable` 40 | pub unsigned_nullable: Option, 41 | /// Field representing column `text` 42 | pub text: String, 43 | /// Field representing column `completed` 44 | pub completed: bool, 45 | /// Field representing column `type` 46 | pub type_: String, 47 | /// Field representing column `smallint` 48 | pub smallint: i16, 49 | /// Field representing column `bigint` 50 | pub bigint: i64, 51 | } 52 | 53 | /// Update Struct for a row in table `todos` for [`Todos`] 54 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 55 | #[diesel(table_name=todos)] 56 | pub struct UpdateTodos { 57 | /// Field representing column `unsigned` 58 | pub unsigned: Option, 59 | /// Field representing column `unsigned_nullable` 60 | pub unsigned_nullable: Option>, 61 | /// Field representing column `text` 62 | pub text: Option, 63 | /// Field representing column `completed` 64 | pub completed: Option, 65 | /// Field representing column `type` 66 | pub type_: Option, 67 | /// Field representing column `smallint` 68 | pub smallint: Option, 69 | /// Field representing column `bigint` 70 | pub bigint: Option, 71 | /// Field representing column `created_at` 72 | pub created_at: Option, 73 | /// Field representing column `updated_at` 74 | pub updated_at: Option, 75 | } 76 | -------------------------------------------------------------------------------- /test/autogenerated_primary_keys/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `text` 16 | pub text: String, 17 | } 18 | 19 | /// Create Struct for a row in table `todos` for [`Todos`] 20 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 21 | #[diesel(table_name=todos)] 22 | pub struct CreateTodos { 23 | /// Field representing column `text` 24 | pub text: String, 25 | } 26 | 27 | /// Update Struct for a row in table `todos` for [`Todos`] 28 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 29 | #[diesel(table_name=todos)] 30 | pub struct UpdateTodos { 31 | /// Field representing column `text` 32 | pub text: Option, 33 | } 34 | 35 | /// Result of a `.paginate` function 36 | #[derive(Debug, serde::Serialize)] 37 | pub struct PaginationResult { 38 | /// Resulting items that are from the current page 39 | pub items: Vec, 40 | /// The count of total items there are 41 | pub total_items: i64, 42 | /// Current page, 0-based index 43 | pub page: i64, 44 | /// Size of a page 45 | pub page_size: i64, 46 | /// Number of total possible pages, given the `page_size` and `total_items` 47 | pub num_pages: i64, 48 | } 49 | 50 | impl Todos { 51 | /// Insert a new row into `todos` with a given [`CreateTodos`] 52 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 53 | use crate::schema::todos::dsl::*; 54 | 55 | diesel::insert_into(todos).values(item).get_result::(db) 56 | } 57 | 58 | /// Get a row from `todos`, identified by the primary key 59 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 60 | use crate::schema::todos::dsl::*; 61 | 62 | todos.filter(id.eq(param_id)).first::(db) 63 | } 64 | 65 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 66 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 67 | use crate::schema::todos::dsl::*; 68 | 69 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 70 | } 71 | 72 | /// Delete a row in `todos`, identified by the primary key 73 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 74 | use crate::schema::todos::dsl::*; 75 | 76 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /test/readonly/models/normal/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `normal` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=normal, primary_key(id))] 12 | pub struct Normal { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `testprop` 16 | pub testprop: i32, 17 | } 18 | 19 | /// Create Struct for a row in table `normal` for [`Normal`] 20 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 21 | #[diesel(table_name=normal)] 22 | pub struct CreateNormal { 23 | /// Field representing column `testprop` 24 | pub testprop: i32, 25 | } 26 | 27 | /// Update Struct for a row in table `normal` for [`Normal`] 28 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 29 | #[diesel(table_name=normal)] 30 | pub struct UpdateNormal { 31 | /// Field representing column `testprop` 32 | pub testprop: Option, 33 | } 34 | 35 | /// Result of a `.paginate` function 36 | #[derive(Debug, serde::Serialize)] 37 | pub struct PaginationResult { 38 | /// Resulting items that are from the current page 39 | pub items: Vec, 40 | /// The count of total items there are 41 | pub total_items: i64, 42 | /// Current page, 0-based index 43 | pub page: i64, 44 | /// Size of a page 45 | pub page_size: i64, 46 | /// Number of total possible pages, given the `page_size` and `total_items` 47 | pub num_pages: i64, 48 | } 49 | 50 | impl Normal { 51 | /// Insert a new row into `normal` with a given [`CreateNormal`] 52 | pub fn create(db: &mut ConnectionType, item: &CreateNormal) -> diesel::QueryResult { 53 | use crate::schema::normal::dsl::*; 54 | 55 | diesel::insert_into(normal).values(item).get_result::(db) 56 | } 57 | 58 | /// Get a row from `normal`, identified by the primary key 59 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 60 | use crate::schema::normal::dsl::*; 61 | 62 | normal.filter(id.eq(param_id)).first::(db) 63 | } 64 | 65 | /// Update a row in `normal`, identified by the primary key with [`UpdateNormal`] 66 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateNormal) -> diesel::QueryResult { 67 | use crate::schema::normal::dsl::*; 68 | 69 | diesel::update(normal.filter(id.eq(param_id))).set(item).get_result(db) 70 | } 71 | 72 | /// Delete a row in `normal`, identified by the primary key 73 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 74 | use crate::schema::normal::dsl::*; 75 | 76 | diesel::delete(normal.filter(id.eq(param_id))).execute(db) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /test/autogenerated_attributes/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `created_at` 16 | pub created_at: chrono::NaiveDateTime, 17 | } 18 | 19 | /// Create Struct for a row in table `todos` for [`Todos`] 20 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 21 | #[diesel(table_name=todos)] 22 | pub struct CreateTodos { 23 | /// Field representing column `id` 24 | pub id: i32, 25 | } 26 | 27 | /// Update Struct for a row in table `todos` for [`Todos`] 28 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 29 | #[diesel(table_name=todos)] 30 | pub struct UpdateTodos { 31 | /// Field representing column `created_at` 32 | pub created_at: Option, 33 | } 34 | 35 | /// Result of a `.paginate` function 36 | #[derive(Debug, serde::Serialize)] 37 | pub struct PaginationResult { 38 | /// Resulting items that are from the current page 39 | pub items: Vec, 40 | /// The count of total items there are 41 | pub total_items: i64, 42 | /// Current page, 0-based index 43 | pub page: i64, 44 | /// Size of a page 45 | pub page_size: i64, 46 | /// Number of total possible pages, given the `page_size` and `total_items` 47 | pub num_pages: i64, 48 | } 49 | 50 | impl Todos { 51 | /// Insert a new row into `todos` with a given [`CreateTodos`] 52 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 53 | use crate::schema::todos::dsl::*; 54 | 55 | diesel::insert_into(todos).values(item).get_result::(db) 56 | } 57 | 58 | /// Get a row from `todos`, identified by the primary key 59 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 60 | use crate::schema::todos::dsl::*; 61 | 62 | todos.filter(id.eq(param_id)).first::(db) 63 | } 64 | 65 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 66 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 67 | use crate::schema::todos::dsl::*; 68 | 69 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 70 | } 71 | 72 | /// Delete a row in `todos`, identified by the primary key 73 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 74 | use crate::schema::todos::dsl::*; 75 | 76 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /test/custom_model_path/models/table_b/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::data::models::table_a::TableA; 6 | use crate::schema::*; 7 | 8 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 9 | 10 | /// Struct representing a row in table `tableB` 11 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Associations, diesel::Identifiable)] 12 | #[diesel(table_name=tableB, primary_key(_id), belongs_to(TableA, foreign_key=link))] 13 | pub struct TableB { 14 | /// Field representing column `_id` 15 | pub _id: i32, 16 | /// Field representing column `link` 17 | pub link: i32, 18 | } 19 | 20 | /// Create Struct for a row in table `tableB` for [`TableB`] 21 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 22 | #[diesel(table_name=tableB)] 23 | pub struct CreateTableB { 24 | /// Field representing column `_id` 25 | pub _id: i32, 26 | /// Field representing column `link` 27 | pub link: i32, 28 | } 29 | 30 | /// Update Struct for a row in table `tableB` for [`TableB`] 31 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 32 | #[diesel(table_name=tableB)] 33 | pub struct UpdateTableB { 34 | /// Field representing column `link` 35 | pub link: Option, 36 | } 37 | 38 | /// Result of a `.paginate` function 39 | #[derive(Debug, serde::Serialize)] 40 | pub struct PaginationResult { 41 | /// Resulting items that are from the current page 42 | pub items: Vec, 43 | /// The count of total items there are 44 | pub total_items: i64, 45 | /// Current page, 0-based index 46 | pub page: i64, 47 | /// Size of a page 48 | pub page_size: i64, 49 | /// Number of total possible pages, given the `page_size` and `total_items` 50 | pub num_pages: i64, 51 | } 52 | 53 | impl TableB { 54 | /// Insert a new row into `tableB` with a given [`CreateTableB`] 55 | pub fn create(db: &mut ConnectionType, item: &CreateTableB) -> diesel::QueryResult { 56 | use crate::schema::tableB::dsl::*; 57 | 58 | diesel::insert_into(tableB).values(item).get_result::(db) 59 | } 60 | 61 | /// Get a row from `tableB`, identified by the primary key 62 | pub fn read(db: &mut ConnectionType, param__id: i32) -> diesel::QueryResult { 63 | use crate::schema::tableB::dsl::*; 64 | 65 | tableB.filter(_id.eq(param__id)).first::(db) 66 | } 67 | 68 | /// Update a row in `tableB`, identified by the primary key with [`UpdateTableB`] 69 | pub fn update(db: &mut ConnectionType, param__id: i32, item: &UpdateTableB) -> diesel::QueryResult { 70 | use crate::schema::tableB::dsl::*; 71 | 72 | diesel::update(tableB.filter(_id.eq(param__id))).set(item).get_result(db) 73 | } 74 | 75 | /// Delete a row in `tableB`, identified by the primary key 76 | pub fn delete(db: &mut ConnectionType, param__id: i32) -> diesel::QueryResult { 77 | use crate::schema::tableB::dsl::*; 78 | 79 | diesel::delete(tableB.filter(_id.eq(param__id))).execute(db) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /test/create_update_bytes_slice/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(data))] 12 | pub struct Todos { 13 | /// Field representing column `data` 14 | pub data: Vec, 15 | /// Field representing column `data_nullable` 16 | pub data_nullable: Option>, 17 | } 18 | 19 | /// Create Struct for a row in table `todos` for [`Todos`] 20 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 21 | #[diesel(table_name=todos)] 22 | pub struct CreateTodos<'a> { 23 | /// Field representing column `data` 24 | pub data: &'a [u8], 25 | /// Field representing column `data_nullable` 26 | pub data_nullable: Option<&'a [u8]>, 27 | } 28 | 29 | /// Update Struct for a row in table `todos` for [`Todos`] 30 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 31 | #[diesel(table_name=todos)] 32 | pub struct UpdateTodos<'a> { 33 | /// Field representing column `data_nullable` 34 | pub data_nullable: Option>, 35 | } 36 | 37 | /// Result of a `.paginate` function 38 | #[derive(Debug, serde::Serialize)] 39 | pub struct PaginationResult { 40 | /// Resulting items that are from the current page 41 | pub items: Vec, 42 | /// The count of total items there are 43 | pub total_items: i64, 44 | /// Current page, 0-based index 45 | pub page: i64, 46 | /// Size of a page 47 | pub page_size: i64, 48 | /// Number of total possible pages, given the `page_size` and `total_items` 49 | pub num_pages: i64, 50 | } 51 | 52 | impl Todos { 53 | /// Insert a new row into `todos` with a given [`CreateTodos`] 54 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 55 | use crate::schema::todos::dsl::*; 56 | 57 | diesel::insert_into(todos).values(item).get_result::(db) 58 | } 59 | 60 | /// Get a row from `todos`, identified by the primary key 61 | pub fn read(db: &mut ConnectionType, param_data: Vec) -> diesel::QueryResult { 62 | use crate::schema::todos::dsl::*; 63 | 64 | todos.filter(data.eq(param_data)).first::(db) 65 | } 66 | 67 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 68 | pub fn update(db: &mut ConnectionType, param_data: Vec, item: &UpdateTodos) -> diesel::QueryResult { 69 | use crate::schema::todos::dsl::*; 70 | 71 | diesel::update(todos.filter(data.eq(param_data))).set(item).get_result(db) 72 | } 73 | 74 | /// Delete a row in `todos`, identified by the primary key 75 | pub fn delete(db: &mut ConnectionType, param_data: Vec) -> diesel::QueryResult { 76 | use crate::schema::todos::dsl::*; 77 | 78 | diesel::delete(todos.filter(data.eq(param_data))).execute(db) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /test/create_update_bytes_cow/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(data))] 12 | pub struct Todos { 13 | /// Field representing column `data` 14 | pub data: Vec, 15 | /// Field representing column `data_nullable` 16 | pub data_nullable: Option>, 17 | } 18 | 19 | /// Create Struct for a row in table `todos` for [`Todos`] 20 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 21 | #[diesel(table_name=todos)] 22 | pub struct CreateTodos<'a> { 23 | /// Field representing column `data` 24 | pub data: Cow<'a, [u8]>, 25 | /// Field representing column `data_nullable` 26 | pub data_nullable: Option>, 27 | } 28 | 29 | /// Update Struct for a row in table `todos` for [`Todos`] 30 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 31 | #[diesel(table_name=todos)] 32 | pub struct UpdateTodos<'a> { 33 | /// Field representing column `data_nullable` 34 | pub data_nullable: Option>>, 35 | } 36 | 37 | /// Result of a `.paginate` function 38 | #[derive(Debug, serde::Serialize)] 39 | pub struct PaginationResult { 40 | /// Resulting items that are from the current page 41 | pub items: Vec, 42 | /// The count of total items there are 43 | pub total_items: i64, 44 | /// Current page, 0-based index 45 | pub page: i64, 46 | /// Size of a page 47 | pub page_size: i64, 48 | /// Number of total possible pages, given the `page_size` and `total_items` 49 | pub num_pages: i64, 50 | } 51 | 52 | impl Todos { 53 | /// Insert a new row into `todos` with a given [`CreateTodos`] 54 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 55 | use crate::schema::todos::dsl::*; 56 | 57 | diesel::insert_into(todos).values(item).get_result::(db) 58 | } 59 | 60 | /// Get a row from `todos`, identified by the primary key 61 | pub fn read(db: &mut ConnectionType, param_data: Vec) -> diesel::QueryResult { 62 | use crate::schema::todos::dsl::*; 63 | 64 | todos.filter(data.eq(param_data)).first::(db) 65 | } 66 | 67 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 68 | pub fn update(db: &mut ConnectionType, param_data: Vec, item: &UpdateTodos) -> diesel::QueryResult { 69 | use crate::schema::todos::dsl::*; 70 | 71 | diesel::update(todos.filter(data.eq(param_data))).set(item).get_result(db) 72 | } 73 | 74 | /// Delete a row in `todos`, identified by the primary key 75 | pub fn delete(db: &mut ConnectionType, param_data: Vec) -> diesel::QueryResult { 76 | use crate::schema::todos::dsl::*; 77 | 78 | diesel::delete(todos.filter(data.eq(param_data))).execute(db) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /test/custom_model_and_schema_path/data/models/table_b/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::data::models::table_a::TableA; 6 | use crate::data::schema::*; 7 | 8 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 9 | 10 | /// Struct representing a row in table `tableB` 11 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Associations, diesel::Identifiable)] 12 | #[diesel(table_name=tableB, primary_key(_id), belongs_to(TableA, foreign_key=link))] 13 | pub struct TableB { 14 | /// Field representing column `_id` 15 | pub _id: i32, 16 | /// Field representing column `link` 17 | pub link: i32, 18 | } 19 | 20 | /// Create Struct for a row in table `tableB` for [`TableB`] 21 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 22 | #[diesel(table_name=tableB)] 23 | pub struct CreateTableB { 24 | /// Field representing column `_id` 25 | pub _id: i32, 26 | /// Field representing column `link` 27 | pub link: i32, 28 | } 29 | 30 | /// Update Struct for a row in table `tableB` for [`TableB`] 31 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 32 | #[diesel(table_name=tableB)] 33 | pub struct UpdateTableB { 34 | /// Field representing column `link` 35 | pub link: Option, 36 | } 37 | 38 | /// Result of a `.paginate` function 39 | #[derive(Debug, serde::Serialize)] 40 | pub struct PaginationResult { 41 | /// Resulting items that are from the current page 42 | pub items: Vec, 43 | /// The count of total items there are 44 | pub total_items: i64, 45 | /// Current page, 0-based index 46 | pub page: i64, 47 | /// Size of a page 48 | pub page_size: i64, 49 | /// Number of total possible pages, given the `page_size` and `total_items` 50 | pub num_pages: i64, 51 | } 52 | 53 | impl TableB { 54 | /// Insert a new row into `tableB` with a given [`CreateTableB`] 55 | pub fn create(db: &mut ConnectionType, item: &CreateTableB) -> diesel::QueryResult { 56 | use crate::data::schema::tableB::dsl::*; 57 | 58 | diesel::insert_into(tableB).values(item).get_result::(db) 59 | } 60 | 61 | /// Get a row from `tableB`, identified by the primary key 62 | pub fn read(db: &mut ConnectionType, param__id: i32) -> diesel::QueryResult { 63 | use crate::data::schema::tableB::dsl::*; 64 | 65 | tableB.filter(_id.eq(param__id)).first::(db) 66 | } 67 | 68 | /// Update a row in `tableB`, identified by the primary key with [`UpdateTableB`] 69 | pub fn update(db: &mut ConnectionType, param__id: i32, item: &UpdateTableB) -> diesel::QueryResult { 70 | use crate::data::schema::tableB::dsl::*; 71 | 72 | diesel::update(tableB.filter(_id.eq(param__id))).set(item).get_result(db) 73 | } 74 | 75 | /// Delete a row in `tableB`, identified by the primary key 76 | pub fn delete(db: &mut ConnectionType, param__id: i32) -> diesel::QueryResult { 77 | use crate::data::schema::tableB::dsl::*; 78 | 79 | diesel::delete(tableB.filter(_id.eq(param__id))).execute(db) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | pull_request: 5 | workflow_dispatch: 6 | 7 | env: 8 | CARGO_TERM_COLOR: always 9 | 10 | concurrency: 11 | group: CI-${{ github.ref }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | build: 16 | name: cargo build & test 17 | strategy: 18 | matrix: 19 | os: [ubuntu-latest] 20 | rust: [stable, "1.70"] 21 | runs-on: ${{ matrix.os }} 22 | steps: 23 | - uses: actions/checkout@v4 24 | - uses: rui314/setup-mold@v1 25 | - uses: dtolnay/rust-toolchain@stable 26 | with: 27 | toolchain: ${{ matrix.rust }} 28 | - uses: Swatinem/rust-cache@v2 29 | with: 30 | shared-key: "build" 31 | - run: cargo build --all-targets 32 | - run: cargo test 33 | 34 | clippy: 35 | name: cargo clippy 36 | needs: [build] 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: actions/checkout@v4 40 | - uses: rui314/setup-mold@v1 41 | - uses: dtolnay/rust-toolchain@stable 42 | with: 43 | components: clippy 44 | - uses: Swatinem/rust-cache@v2 45 | with: 46 | shared-key: "build" 47 | - run: cargo clippy --all 48 | 49 | test-script: 50 | name: test-scripts 51 | needs: [build] 52 | runs-on: ubuntu-latest 53 | steps: 54 | - uses: actions/checkout@v4 55 | - uses: rui314/setup-mold@v1 56 | - uses: dtolnay/rust-toolchain@stable 57 | - uses: Swatinem/rust-cache@v2 58 | with: 59 | shared-key: "build" 60 | - run: bash test/test_all.sh 61 | - run: git diff --exit-code --stat || exit 1 62 | 63 | # Things that don't need a cache 64 | fmt: 65 | name: cargo fmt 66 | runs-on: ubuntu-latest 67 | steps: 68 | - uses: actions/checkout@v4 69 | - uses: dtolnay/rust-toolchain@stable 70 | with: 71 | toolchain: nightly 72 | components: rustfmt 73 | - run: cargo fmt --all -- --check 74 | 75 | release: 76 | runs-on: ubuntu-latest 77 | name: release 78 | needs: [build, clippy, test-script, fmt] 79 | if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' 80 | permissions: 81 | contents: write # for actions/checkout to fetch code and for semantic-release to push commits, release releases and tags 82 | issues: write # for semantic-release to comment on and close issues 83 | pull-requests: write # for semantic-release to comment on and close pull requests 84 | steps: 85 | - uses: actions/checkout@v4 86 | - uses: dtolnay/rust-toolchain@stable 87 | - name: Semantic Release 88 | uses: cycjimmy/semantic-release-action@61680d0e9b02ff86f5648ade99e01be17f0260a4 # v4 89 | with: 90 | dry_run: true 91 | extra_plugins: | 92 | @semantic-release/git 93 | @semantic-release/changelog 94 | @semantic-release/commit-analyzer 95 | @semantic-release/release-notes-generator 96 | @semantic-release/github 97 | @semantic-release-cargo/semantic-release-cargo 98 | @commitlint/config-conventional 99 | env: 100 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 101 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 102 | -------------------------------------------------------------------------------- /test/postgres_array_column/models/user/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `user` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=user, primary_key(id))] 12 | pub struct User { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `phone_numbers` 16 | pub phone_numbers: Vec>, 17 | /// Field representing column `optional_array_column` 18 | pub optional_array_column: Option>>, 19 | } 20 | 21 | /// Create Struct for a row in table `user` for [`User`] 22 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 23 | #[diesel(table_name=user)] 24 | pub struct CreateUser { 25 | /// Field representing column `phone_numbers` 26 | pub phone_numbers: Vec>, 27 | /// Field representing column `optional_array_column` 28 | pub optional_array_column: Option>>, 29 | } 30 | 31 | /// Update Struct for a row in table `user` for [`User`] 32 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 33 | #[diesel(table_name=user)] 34 | pub struct UpdateUser { 35 | /// Field representing column `phone_numbers` 36 | pub phone_numbers: Option>>, 37 | /// Field representing column `optional_array_column` 38 | pub optional_array_column: Option>>>, 39 | } 40 | 41 | /// Result of a `.paginate` function 42 | #[derive(Debug, serde::Serialize)] 43 | pub struct PaginationResult { 44 | /// Resulting items that are from the current page 45 | pub items: Vec, 46 | /// The count of total items there are 47 | pub total_items: i64, 48 | /// Current page, 0-based index 49 | pub page: i64, 50 | /// Size of a page 51 | pub page_size: i64, 52 | /// Number of total possible pages, given the `page_size` and `total_items` 53 | pub num_pages: i64, 54 | } 55 | 56 | impl User { 57 | /// Insert a new row into `user` with a given [`CreateUser`] 58 | pub fn create(db: &mut ConnectionType, item: &CreateUser) -> diesel::QueryResult { 59 | use crate::schema::user::dsl::*; 60 | 61 | diesel::insert_into(user).values(item).get_result::(db) 62 | } 63 | 64 | /// Get a row from `user`, identified by the primary key 65 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 66 | use crate::schema::user::dsl::*; 67 | 68 | user.filter(id.eq(param_id)).first::(db) 69 | } 70 | 71 | /// Update a row in `user`, identified by the primary key with [`UpdateUser`] 72 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateUser) -> diesel::QueryResult { 73 | use crate::schema::user::dsl::*; 74 | 75 | diesel::update(user.filter(id.eq(param_id))).set(item).get_result(db) 76 | } 77 | 78 | /// Delete a row in `user`, identified by the primary key 79 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 80 | use crate::schema::user::dsl::*; 81 | 82 | diesel::delete(user.filter(id.eq(param_id))).execute(db) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /test/multiple_primary_keys/models/users/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `users` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=users, primary_key(name,address))] 12 | pub struct Users { 13 | /// Field representing column `name` 14 | pub name: String, 15 | /// Field representing column `address` 16 | pub address: String, 17 | /// Field representing column `secret` 18 | pub secret: String, 19 | } 20 | 21 | /// Create Struct for a row in table `users` for [`Users`] 22 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 23 | #[diesel(table_name=users)] 24 | pub struct CreateUsers { 25 | /// Field representing column `name` 26 | pub name: String, 27 | /// Field representing column `address` 28 | pub address: String, 29 | /// Field representing column `secret` 30 | pub secret: String, 31 | } 32 | 33 | /// Update Struct for a row in table `users` for [`Users`] 34 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 35 | #[diesel(table_name=users)] 36 | pub struct UpdateUsers { 37 | /// Field representing column `secret` 38 | pub secret: Option, 39 | } 40 | 41 | /// Result of a `.paginate` function 42 | #[derive(Debug, serde::Serialize)] 43 | pub struct PaginationResult { 44 | /// Resulting items that are from the current page 45 | pub items: Vec, 46 | /// The count of total items there are 47 | pub total_items: i64, 48 | /// Current page, 0-based index 49 | pub page: i64, 50 | /// Size of a page 51 | pub page_size: i64, 52 | /// Number of total possible pages, given the `page_size` and `total_items` 53 | pub num_pages: i64, 54 | } 55 | 56 | impl Users { 57 | /// Insert a new row into `users` with a given [`CreateUsers`] 58 | pub fn create(db: &mut ConnectionType, item: &CreateUsers) -> diesel::QueryResult { 59 | use crate::schema::users::dsl::*; 60 | 61 | diesel::insert_into(users).values(item).get_result::(db) 62 | } 63 | 64 | /// Get a row from `users`, identified by the primary keys 65 | pub fn read(db: &mut ConnectionType, param_name: String, param_address: String) -> diesel::QueryResult { 66 | use crate::schema::users::dsl::*; 67 | 68 | users.filter(name.eq(param_name)).filter(address.eq(param_address)).first::(db) 69 | } 70 | 71 | /// Update a row in `users`, identified by the primary keys with [`UpdateUsers`] 72 | pub fn update(db: &mut ConnectionType, param_name: String, param_address: String, item: &UpdateUsers) -> diesel::QueryResult { 73 | use crate::schema::users::dsl::*; 74 | 75 | diesel::update(users.filter(name.eq(param_name)).filter(address.eq(param_address))).set(item).get_result(db) 76 | } 77 | 78 | /// Delete a row in `users`, identified by the primary keys 79 | pub fn delete(db: &mut ConnectionType, param_name: String, param_address: String) -> diesel::QueryResult { 80 | use crate::schema::users::dsl::*; 81 | 82 | diesel::delete(users.filter(name.eq(param_name)).filter(address.eq(param_address))).execute(db) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /test/cleanup_generated_content/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `text` 16 | pub text: String, 17 | /// Field representing column `completed` 18 | pub completed: bool, 19 | /// Field representing column `created_at` 20 | pub created_at: chrono::DateTime, 21 | /// Field representing column `updated_at` 22 | pub updated_at: chrono::DateTime, 23 | } 24 | 25 | /// Create Struct for a row in table `todos` for [`Todos`] 26 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 27 | #[diesel(table_name=todos)] 28 | pub struct CreateTodos { 29 | /// Field representing column `id` 30 | pub id: i32, 31 | /// Field representing column `text` 32 | pub text: String, 33 | /// Field representing column `completed` 34 | pub completed: bool, 35 | } 36 | 37 | /// Update Struct for a row in table `todos` for [`Todos`] 38 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 39 | #[diesel(table_name=todos)] 40 | pub struct UpdateTodos { 41 | /// Field representing column `text` 42 | pub text: Option, 43 | /// Field representing column `completed` 44 | pub completed: Option, 45 | /// Field representing column `created_at` 46 | pub created_at: Option>, 47 | /// Field representing column `updated_at` 48 | pub updated_at: Option>, 49 | } 50 | 51 | /// Result of a `.paginate` function 52 | #[derive(Debug, serde::Serialize)] 53 | pub struct PaginationResult { 54 | /// Resulting items that are from the current page 55 | pub items: Vec, 56 | /// The count of total items there are 57 | pub total_items: i64, 58 | /// Current page, 0-based index 59 | pub page: i64, 60 | /// Size of a page 61 | pub page_size: i64, 62 | /// Number of total possible pages, given the `page_size` and `total_items` 63 | pub num_pages: i64, 64 | } 65 | 66 | impl Todos { 67 | /// Insert a new row into `todos` with a given [`CreateTodos`] 68 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 69 | use crate::schema::todos::dsl::*; 70 | 71 | diesel::insert_into(todos).values(item).get_result::(db) 72 | } 73 | 74 | /// Get a row from `todos`, identified by the primary key 75 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 76 | use crate::schema::todos::dsl::*; 77 | 78 | todos.filter(id.eq(param_id)).first::(db) 79 | } 80 | 81 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 82 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 83 | use crate::schema::todos::dsl::*; 84 | 85 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 86 | } 87 | 88 | /// Delete a row in `todos`, identified by the primary key 89 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 90 | use crate::schema::todos::dsl::*; 91 | 92 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /test/create_update_str_str/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(text))] 12 | pub struct Todos { 13 | /// Field representing column `text` 14 | pub text: String, 15 | /// Field representing column `text_nullable` 16 | pub text_nullable: Option, 17 | /// Field representing column `varchar` 18 | pub varchar: String, 19 | /// Field representing column `varchar_nullable` 20 | pub varchar_nullable: Option, 21 | } 22 | 23 | /// Create Struct for a row in table `todos` for [`Todos`] 24 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 25 | #[diesel(table_name=todos)] 26 | pub struct CreateTodos<'a> { 27 | /// Field representing column `text` 28 | pub text: &'a str, 29 | /// Field representing column `text_nullable` 30 | pub text_nullable: Option<&'a str>, 31 | /// Field representing column `varchar` 32 | pub varchar: &'a str, 33 | /// Field representing column `varchar_nullable` 34 | pub varchar_nullable: Option<&'a str>, 35 | } 36 | 37 | /// Update Struct for a row in table `todos` for [`Todos`] 38 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 39 | #[diesel(table_name=todos)] 40 | pub struct UpdateTodos<'a> { 41 | /// Field representing column `text_nullable` 42 | pub text_nullable: Option>, 43 | /// Field representing column `varchar` 44 | pub varchar: Option<&'a str>, 45 | /// Field representing column `varchar_nullable` 46 | pub varchar_nullable: Option>, 47 | } 48 | 49 | /// Result of a `.paginate` function 50 | #[derive(Debug, serde::Serialize)] 51 | pub struct PaginationResult { 52 | /// Resulting items that are from the current page 53 | pub items: Vec, 54 | /// The count of total items there are 55 | pub total_items: i64, 56 | /// Current page, 0-based index 57 | pub page: i64, 58 | /// Size of a page 59 | pub page_size: i64, 60 | /// Number of total possible pages, given the `page_size` and `total_items` 61 | pub num_pages: i64, 62 | } 63 | 64 | impl Todos { 65 | /// Insert a new row into `todos` with a given [`CreateTodos`] 66 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 67 | use crate::schema::todos::dsl::*; 68 | 69 | diesel::insert_into(todos).values(item).get_result::(db) 70 | } 71 | 72 | /// Get a row from `todos`, identified by the primary key 73 | pub fn read(db: &mut ConnectionType, param_text: String) -> diesel::QueryResult { 74 | use crate::schema::todos::dsl::*; 75 | 76 | todos.filter(text.eq(param_text)).first::(db) 77 | } 78 | 79 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 80 | pub fn update(db: &mut ConnectionType, param_text: String, item: &UpdateTodos) -> diesel::QueryResult { 81 | use crate::schema::todos::dsl::*; 82 | 83 | diesel::update(todos.filter(text.eq(param_text))).set(item).get_result(db) 84 | } 85 | 86 | /// Delete a row in `todos`, identified by the primary key 87 | pub fn delete(db: &mut ConnectionType, param_text: String) -> diesel::QueryResult { 88 | use crate::schema::todos::dsl::*; 89 | 90 | diesel::delete(todos.filter(text.eq(param_text))).execute(db) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /test/create_update_str_cow/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(text))] 12 | pub struct Todos { 13 | /// Field representing column `text` 14 | pub text: String, 15 | /// Field representing column `text_nullable` 16 | pub text_nullable: Option, 17 | /// Field representing column `varchar` 18 | pub varchar: String, 19 | /// Field representing column `varchar_nullable` 20 | pub varchar_nullable: Option, 21 | } 22 | 23 | /// Create Struct for a row in table `todos` for [`Todos`] 24 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 25 | #[diesel(table_name=todos)] 26 | pub struct CreateTodos<'a> { 27 | /// Field representing column `text` 28 | pub text: Cow<'a, str>, 29 | /// Field representing column `text_nullable` 30 | pub text_nullable: Option>, 31 | /// Field representing column `varchar` 32 | pub varchar: Cow<'a, str>, 33 | /// Field representing column `varchar_nullable` 34 | pub varchar_nullable: Option>, 35 | } 36 | 37 | /// Update Struct for a row in table `todos` for [`Todos`] 38 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 39 | #[diesel(table_name=todos)] 40 | pub struct UpdateTodos<'a> { 41 | /// Field representing column `text_nullable` 42 | pub text_nullable: Option>>, 43 | /// Field representing column `varchar` 44 | pub varchar: Option>, 45 | /// Field representing column `varchar_nullable` 46 | pub varchar_nullable: Option>>, 47 | } 48 | 49 | /// Result of a `.paginate` function 50 | #[derive(Debug, serde::Serialize)] 51 | pub struct PaginationResult { 52 | /// Resulting items that are from the current page 53 | pub items: Vec, 54 | /// The count of total items there are 55 | pub total_items: i64, 56 | /// Current page, 0-based index 57 | pub page: i64, 58 | /// Size of a page 59 | pub page_size: i64, 60 | /// Number of total possible pages, given the `page_size` and `total_items` 61 | pub num_pages: i64, 62 | } 63 | 64 | impl Todos { 65 | /// Insert a new row into `todos` with a given [`CreateTodos`] 66 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 67 | use crate::schema::todos::dsl::*; 68 | 69 | diesel::insert_into(todos).values(item).get_result::(db) 70 | } 71 | 72 | /// Get a row from `todos`, identified by the primary key 73 | pub fn read(db: &mut ConnectionType, param_text: String) -> diesel::QueryResult { 74 | use crate::schema::todos::dsl::*; 75 | 76 | todos.filter(text.eq(param_text)).first::(db) 77 | } 78 | 79 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 80 | pub fn update(db: &mut ConnectionType, param_text: String, item: &UpdateTodos) -> diesel::QueryResult { 81 | use crate::schema::todos::dsl::*; 82 | 83 | diesel::update(todos.filter(text.eq(param_text))).set(item).get_result(db) 84 | } 85 | 86 | /// Delete a row in `todos`, identified by the primary key 87 | pub fn delete(db: &mut ConnectionType, param_text: String) -> diesel::QueryResult { 88 | use crate::schema::todos::dsl::*; 89 | 90 | diesel::delete(todos.filter(text.eq(param_text))).execute(db) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /test/simple_table_no_serde/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `unsigned` 16 | pub unsigned: u32, 17 | /// Field representing column `text` 18 | pub text: String, 19 | /// Field representing column `completed` 20 | pub completed: bool, 21 | /// Field representing column `created_at` 22 | pub created_at: chrono::DateTime, 23 | /// Field representing column `updated_at` 24 | pub updated_at: chrono::DateTime, 25 | } 26 | 27 | /// Create Struct for a row in table `todos` for [`Todos`] 28 | #[derive(Debug, Clone, diesel::Insertable)] 29 | #[diesel(table_name=todos)] 30 | pub struct CreateTodos { 31 | /// Field representing column `unsigned` 32 | pub unsigned: u32, 33 | /// Field representing column `text` 34 | pub text: String, 35 | /// Field representing column `completed` 36 | pub completed: bool, 37 | } 38 | 39 | /// Update Struct for a row in table `todos` for [`Todos`] 40 | #[derive(Debug, Clone, diesel::AsChangeset, PartialEq, Default)] 41 | #[diesel(table_name=todos)] 42 | pub struct UpdateTodos { 43 | /// Field representing column `unsigned` 44 | pub unsigned: Option, 45 | /// Field representing column `text` 46 | pub text: Option, 47 | /// Field representing column `completed` 48 | pub completed: Option, 49 | /// Field representing column `created_at` 50 | pub created_at: Option>, 51 | /// Field representing column `updated_at` 52 | pub updated_at: Option>, 53 | } 54 | 55 | /// Result of a `.paginate` function 56 | #[derive(Debug, )] 57 | pub struct PaginationResult { 58 | /// Resulting items that are from the current page 59 | pub items: Vec, 60 | /// The count of total items there are 61 | pub total_items: i64, 62 | /// Current page, 0-based index 63 | pub page: i64, 64 | /// Size of a page 65 | pub page_size: i64, 66 | /// Number of total possible pages, given the `page_size` and `total_items` 67 | pub num_pages: i64, 68 | } 69 | 70 | impl Todos { 71 | /// Insert a new row into `todos` with a given [`CreateTodos`] 72 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 73 | use crate::schema::todos::dsl::*; 74 | 75 | diesel::insert_into(todos).values(item).get_result::(db) 76 | } 77 | 78 | /// Get a row from `todos`, identified by the primary key 79 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 80 | use crate::schema::todos::dsl::*; 81 | 82 | todos.filter(id.eq(param_id)).first::(db) 83 | } 84 | 85 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 86 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 87 | use crate::schema::todos::dsl::*; 88 | 89 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 90 | } 91 | 92 | /// Delete a row in `todos`, identified by the primary key 93 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 94 | use crate::schema::todos::dsl::*; 95 | 96 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /test/simple_table_custom_schema_path/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::data::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `unsigned` 16 | pub unsigned: u32, 17 | /// Field representing column `text` 18 | pub text: String, 19 | /// Field representing column `completed` 20 | pub completed: bool, 21 | /// Field representing column `created_at` 22 | pub created_at: chrono::DateTime, 23 | /// Field representing column `updated_at` 24 | pub updated_at: chrono::DateTime, 25 | } 26 | 27 | /// Create Struct for a row in table `todos` for [`Todos`] 28 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 29 | #[diesel(table_name=todos)] 30 | pub struct CreateTodos { 31 | /// Field representing column `unsigned` 32 | pub unsigned: u32, 33 | /// Field representing column `text` 34 | pub text: String, 35 | /// Field representing column `completed` 36 | pub completed: bool, 37 | } 38 | 39 | /// Update Struct for a row in table `todos` for [`Todos`] 40 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 41 | #[diesel(table_name=todos)] 42 | pub struct UpdateTodos { 43 | /// Field representing column `unsigned` 44 | pub unsigned: Option, 45 | /// Field representing column `text` 46 | pub text: Option, 47 | /// Field representing column `completed` 48 | pub completed: Option, 49 | /// Field representing column `created_at` 50 | pub created_at: Option>, 51 | /// Field representing column `updated_at` 52 | pub updated_at: Option>, 53 | } 54 | 55 | /// Result of a `.paginate` function 56 | #[derive(Debug, serde::Serialize)] 57 | pub struct PaginationResult { 58 | /// Resulting items that are from the current page 59 | pub items: Vec, 60 | /// The count of total items there are 61 | pub total_items: i64, 62 | /// Current page, 0-based index 63 | pub page: i64, 64 | /// Size of a page 65 | pub page_size: i64, 66 | /// Number of total possible pages, given the `page_size` and `total_items` 67 | pub num_pages: i64, 68 | } 69 | 70 | impl Todos { 71 | /// Insert a new row into `todos` with a given [`CreateTodos`] 72 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 73 | use crate::data::schema::todos::dsl::*; 74 | 75 | diesel::insert_into(todos).values(item).get_result::(db) 76 | } 77 | 78 | /// Get a row from `todos`, identified by the primary key 79 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 80 | use crate::data::schema::todos::dsl::*; 81 | 82 | todos.filter(id.eq(param_id)).first::(db) 83 | } 84 | 85 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 86 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 87 | use crate::data::schema::todos::dsl::*; 88 | 89 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 90 | } 91 | 92 | /// Delete a row in `todos`, identified by the primary key 93 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 94 | use crate::data::schema::todos::dsl::*; 95 | 96 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /test/simple_table_async/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use diesel_async::RunQueryDsl; 6 | use crate::schema::*; 7 | 8 | pub type ConnectionType = diesel_async::pooled_connection::deadpool::Object; 9 | 10 | /// Struct representing a row in table `todos` 11 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 12 | #[diesel(table_name=todos, primary_key(id))] 13 | pub struct Todos { 14 | /// Field representing column `id` 15 | pub id: i32, 16 | /// Field representing column `unsigned` 17 | pub unsigned: u32, 18 | /// Field representing column `text` 19 | pub text: String, 20 | /// Field representing column `completed` 21 | pub completed: bool, 22 | /// Field representing column `created_at` 23 | pub created_at: chrono::DateTime, 24 | /// Field representing column `updated_at` 25 | pub updated_at: chrono::DateTime, 26 | } 27 | 28 | /// Create Struct for a row in table `todos` for [`Todos`] 29 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 30 | #[diesel(table_name=todos)] 31 | pub struct CreateTodos { 32 | /// Field representing column `unsigned` 33 | pub unsigned: u32, 34 | /// Field representing column `text` 35 | pub text: String, 36 | /// Field representing column `completed` 37 | pub completed: bool, 38 | } 39 | 40 | /// Update Struct for a row in table `todos` for [`Todos`] 41 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 42 | #[diesel(table_name=todos)] 43 | pub struct UpdateTodos { 44 | /// Field representing column `unsigned` 45 | pub unsigned: Option, 46 | /// Field representing column `text` 47 | pub text: Option, 48 | /// Field representing column `completed` 49 | pub completed: Option, 50 | /// Field representing column `created_at` 51 | pub created_at: Option>, 52 | /// Field representing column `updated_at` 53 | pub updated_at: Option>, 54 | } 55 | 56 | /// Result of a `.paginate` function 57 | #[derive(Debug, serde::Serialize)] 58 | pub struct PaginationResult { 59 | /// Resulting items that are from the current page 60 | pub items: Vec, 61 | /// The count of total items there are 62 | pub total_items: i64, 63 | /// Current page, 0-based index 64 | pub page: i64, 65 | /// Size of a page 66 | pub page_size: i64, 67 | /// Number of total possible pages, given the `page_size` and `total_items` 68 | pub num_pages: i64, 69 | } 70 | 71 | impl Todos { 72 | /// Insert a new row into `todos` with a given [`CreateTodos`] 73 | pub async fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 74 | use crate::schema::todos::dsl::*; 75 | 76 | diesel::insert_into(todos).values(item).get_result::(db).await 77 | } 78 | 79 | /// Get a row from `todos`, identified by the primary key 80 | pub async fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 81 | use crate::schema::todos::dsl::*; 82 | 83 | todos.filter(id.eq(param_id)).first::(db).await 84 | } 85 | 86 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 87 | pub async fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 88 | use crate::schema::todos::dsl::*; 89 | 90 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db).await 91 | } 92 | 93 | /// Delete a row in `todos`, identified by the primary key 94 | pub async fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 95 | use crate::schema::todos::dsl::*; 96 | 97 | diesel::delete(todos.filter(id.eq(param_id))).execute(db).await 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /test/simple_table_sqlite/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `text` 16 | pub text: String, 17 | /// Field representing column `completed` 18 | pub completed: bool, 19 | /// Field representing column `type` 20 | pub type_: String, 21 | /// Field representing column `smallint` 22 | pub smallint: i16, 23 | /// Field representing column `bigint` 24 | pub bigint: i64, 25 | /// Field representing column `created_at` 26 | pub created_at: chrono::NaiveDateTime, 27 | /// Field representing column `updated_at` 28 | pub updated_at: chrono::NaiveDateTime, 29 | } 30 | 31 | /// Create Struct for a row in table `todos` for [`Todos`] 32 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 33 | #[diesel(table_name=todos)] 34 | pub struct CreateTodos { 35 | /// Field representing column `text` 36 | pub text: String, 37 | /// Field representing column `completed` 38 | pub completed: bool, 39 | /// Field representing column `type` 40 | pub type_: String, 41 | /// Field representing column `smallint` 42 | pub smallint: i16, 43 | /// Field representing column `bigint` 44 | pub bigint: i64, 45 | } 46 | 47 | /// Update Struct for a row in table `todos` for [`Todos`] 48 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 49 | #[diesel(table_name=todos)] 50 | pub struct UpdateTodos { 51 | /// Field representing column `text` 52 | pub text: Option, 53 | /// Field representing column `completed` 54 | pub completed: Option, 55 | /// Field representing column `type` 56 | pub type_: Option, 57 | /// Field representing column `smallint` 58 | pub smallint: Option, 59 | /// Field representing column `bigint` 60 | pub bigint: Option, 61 | /// Field representing column `created_at` 62 | pub created_at: Option, 63 | /// Field representing column `updated_at` 64 | pub updated_at: Option, 65 | } 66 | 67 | /// Result of a `.paginate` function 68 | #[derive(Debug, serde::Serialize)] 69 | pub struct PaginationResult { 70 | /// Resulting items that are from the current page 71 | pub items: Vec, 72 | /// The count of total items there are 73 | pub total_items: i64, 74 | /// Current page, 0-based index 75 | pub page: i64, 76 | /// Size of a page 77 | pub page_size: i64, 78 | /// Number of total possible pages, given the `page_size` and `total_items` 79 | pub num_pages: i64, 80 | } 81 | 82 | impl Todos { 83 | /// Insert a new row into `todos` with a given [`CreateTodos`] 84 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 85 | use crate::schema::todos::dsl::*; 86 | 87 | diesel::insert_into(todos).values(item).get_result::(db) 88 | } 89 | 90 | /// Get a row from `todos`, identified by the primary key 91 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 92 | use crate::schema::todos::dsl::*; 93 | 94 | todos.filter(id.eq(param_id)).first::(db) 95 | } 96 | 97 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 98 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 99 | use crate::schema::todos::dsl::*; 100 | 101 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 102 | } 103 | 104 | /// Delete a row in `todos`, identified by the primary key 105 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 106 | use crate::schema::todos::dsl::*; 107 | 108 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /test/simple_table_pg/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `text` 16 | pub text: String, 17 | /// Field representing column `completed` 18 | pub completed: bool, 19 | /// Field representing column `type` 20 | pub type_: String, 21 | /// Field representing column `smallint` 22 | pub smallint: i16, 23 | /// Field representing column `bigint` 24 | pub bigint: i64, 25 | /// Field representing column `created_at` 26 | pub created_at: chrono::DateTime, 27 | /// Field representing column `updated_at` 28 | pub updated_at: chrono::NaiveDateTime, 29 | } 30 | 31 | /// Create Struct for a row in table `todos` for [`Todos`] 32 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 33 | #[diesel(table_name=todos)] 34 | pub struct CreateTodos { 35 | /// Field representing column `text` 36 | pub text: String, 37 | /// Field representing column `completed` 38 | pub completed: bool, 39 | /// Field representing column `type` 40 | pub type_: String, 41 | /// Field representing column `smallint` 42 | pub smallint: i16, 43 | /// Field representing column `bigint` 44 | pub bigint: i64, 45 | } 46 | 47 | /// Update Struct for a row in table `todos` for [`Todos`] 48 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 49 | #[diesel(table_name=todos)] 50 | pub struct UpdateTodos { 51 | /// Field representing column `text` 52 | pub text: Option, 53 | /// Field representing column `completed` 54 | pub completed: Option, 55 | /// Field representing column `type` 56 | pub type_: Option, 57 | /// Field representing column `smallint` 58 | pub smallint: Option, 59 | /// Field representing column `bigint` 60 | pub bigint: Option, 61 | /// Field representing column `created_at` 62 | pub created_at: Option>, 63 | /// Field representing column `updated_at` 64 | pub updated_at: Option, 65 | } 66 | 67 | /// Result of a `.paginate` function 68 | #[derive(Debug, serde::Serialize)] 69 | pub struct PaginationResult { 70 | /// Resulting items that are from the current page 71 | pub items: Vec, 72 | /// The count of total items there are 73 | pub total_items: i64, 74 | /// Current page, 0-based index 75 | pub page: i64, 76 | /// Size of a page 77 | pub page_size: i64, 78 | /// Number of total possible pages, given the `page_size` and `total_items` 79 | pub num_pages: i64, 80 | } 81 | 82 | impl Todos { 83 | /// Insert a new row into `todos` with a given [`CreateTodos`] 84 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 85 | use crate::schema::todos::dsl::*; 86 | 87 | diesel::insert_into(todos).values(item).get_result::(db) 88 | } 89 | 90 | /// Get a row from `todos`, identified by the primary key 91 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 92 | use crate::schema::todos::dsl::*; 93 | 94 | todos.filter(id.eq(param_id)).first::(db) 95 | } 96 | 97 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 98 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 99 | use crate::schema::todos::dsl::*; 100 | 101 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 102 | } 103 | 104 | /// Delete a row in `todos`, identified by the primary key 105 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 106 | use crate::schema::todos::dsl::*; 107 | 108 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /test/no_default_features/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `unsigned` 16 | pub unsigned: u32, 17 | /// Field representing column `unsigned_nullable` 18 | pub unsigned_nullable: Option, 19 | /// Field representing column `text` 20 | pub text: String, 21 | /// Field representing column `completed` 22 | pub completed: bool, 23 | /// Field representing column `type` 24 | pub type_: String, 25 | /// Field representing column `created_at` 26 | pub created_at: chrono::DateTime, 27 | /// Field representing column `updated_at` 28 | pub updated_at: chrono::DateTime, 29 | } 30 | 31 | /// Create Struct for a row in table `todos` for [`Todos`] 32 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 33 | #[diesel(table_name=todos)] 34 | pub struct CreateTodos { 35 | /// Field representing column `unsigned` 36 | pub unsigned: u32, 37 | /// Field representing column `unsigned_nullable` 38 | pub unsigned_nullable: Option, 39 | /// Field representing column `text` 40 | pub text: String, 41 | /// Field representing column `completed` 42 | pub completed: bool, 43 | /// Field representing column `type` 44 | pub type_: String, 45 | } 46 | 47 | /// Update Struct for a row in table `todos` for [`Todos`] 48 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 49 | #[diesel(table_name=todos)] 50 | pub struct UpdateTodos { 51 | /// Field representing column `unsigned` 52 | pub unsigned: Option, 53 | /// Field representing column `unsigned_nullable` 54 | pub unsigned_nullable: Option>, 55 | /// Field representing column `text` 56 | pub text: Option, 57 | /// Field representing column `completed` 58 | pub completed: Option, 59 | /// Field representing column `type` 60 | pub type_: Option, 61 | /// Field representing column `created_at` 62 | pub created_at: Option>, 63 | /// Field representing column `updated_at` 64 | pub updated_at: Option>, 65 | } 66 | 67 | /// Result of a `.paginate` function 68 | #[derive(Debug, serde::Serialize)] 69 | pub struct PaginationResult { 70 | /// Resulting items that are from the current page 71 | pub items: Vec, 72 | /// The count of total items there are 73 | pub total_items: i64, 74 | /// Current page, 0-based index 75 | pub page: i64, 76 | /// Size of a page 77 | pub page_size: i64, 78 | /// Number of total possible pages, given the `page_size` and `total_items` 79 | pub num_pages: i64, 80 | } 81 | 82 | impl Todos { 83 | /// Insert a new row into `todos` with a given [`CreateTodos`] 84 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 85 | use crate::schema::todos::dsl::*; 86 | 87 | diesel::insert_into(todos).values(item).get_result::(db) 88 | } 89 | 90 | /// Get a row from `todos`, identified by the primary key 91 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 92 | use crate::schema::todos::dsl::*; 93 | 94 | todos.filter(id.eq(param_id)).first::(db) 95 | } 96 | 97 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 98 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 99 | use crate::schema::todos::dsl::*; 100 | 101 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 102 | } 103 | 104 | /// Delete a row in `todos`, identified by the primary key 105 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 106 | use crate::schema::todos::dsl::*; 107 | 108 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/file.rs: -------------------------------------------------------------------------------- 1 | use crate::{Error, IOErrorToError, Result}; 2 | use std::path::PathBuf; 3 | 4 | pub struct MarkedFile { 5 | /// File contents that were read / need to be written 6 | file_contents: String, 7 | /// Path of the read / to write file 8 | pub path: PathBuf, 9 | modified: bool, 10 | } 11 | 12 | impl MarkedFile { 13 | /// Tries to open the file at `path` 14 | /// 15 | /// If the file does not exist, a empty file is created 16 | pub fn new(path: PathBuf) -> Result { 17 | let file_contents = if !path.exists() { 18 | "".to_string() 19 | } else { 20 | std::fs::read_to_string(&path).attach_path_err(&path)? 21 | }; 22 | Ok(MarkedFile { 23 | path, 24 | file_contents, 25 | modified: false, 26 | }) 27 | } 28 | 29 | pub fn get_file_contents(&self) -> &str { 30 | &self.file_contents 31 | } 32 | 33 | pub fn is_modified(&self) -> bool { 34 | self.modified 35 | } 36 | 37 | pub fn has_use_stmt(&self, use_name: &str) -> bool { 38 | self.file_contents.contains(&format!("pub use {use_name};")) 39 | } 40 | 41 | pub fn has_mod_stmt(&self, mod_name: &str) -> bool { 42 | self.file_contents.contains(&format!("pub mod {mod_name};")) 43 | } 44 | 45 | pub fn change_file_contents(&mut self, new_content: String) { 46 | if !self.modified && self.file_contents != new_content { 47 | self.modified = true; 48 | } 49 | 50 | self.file_contents = new_content; 51 | } 52 | 53 | pub fn add_use_stmt(&mut self, use_name: &str) { 54 | self.file_contents = self.file_contents.trim().to_string(); 55 | if !self.file_contents.is_empty() { 56 | self.file_contents.push('\n'); 57 | } 58 | self.file_contents 59 | .push_str(&format!("pub use {use_name};\n")); 60 | self.modified = true; 61 | } 62 | 63 | pub fn add_mod_stmt(&mut self, mod_name: &str) { 64 | self.file_contents = self.file_contents.trim().to_string(); 65 | if !self.file_contents.is_empty() { 66 | self.file_contents.push('\n'); 67 | } 68 | self.file_contents 69 | .push_str(&format!("pub mod {mod_name};\n")); 70 | self.modified = true; 71 | } 72 | 73 | pub fn remove_use_stmt(&mut self, mod_name: &str) { 74 | let content_to_remove = &format!("pub use {mod_name};"); 75 | if self.file_contents.contains(content_to_remove) { 76 | self.file_contents = self 77 | .file_contents 78 | .replace(content_to_remove, "") 79 | .trim() 80 | .to_string(); 81 | self.modified = true; 82 | } 83 | } 84 | 85 | pub fn remove_mod_stmt(&mut self, mod_name: &str) { 86 | let content_to_remove = &format!("pub mod {mod_name};"); 87 | if self.file_contents.contains(content_to_remove) { 88 | self.file_contents = self 89 | .file_contents 90 | .replace(content_to_remove, "") 91 | .trim() 92 | .to_string(); 93 | self.modified = true; 94 | } 95 | } 96 | 97 | pub fn ensure_use_stmt(&mut self, use_name: &str) { 98 | if !self.has_use_stmt(use_name) { 99 | self.add_use_stmt(use_name) 100 | } 101 | } 102 | 103 | pub fn ensure_mod_stmt(&mut self, mod_name: &str) { 104 | if !self.has_mod_stmt(mod_name) { 105 | self.add_mod_stmt(mod_name) 106 | } 107 | } 108 | 109 | pub fn has_file_signature(&self) -> bool { 110 | // the reason we consider filelength=0 as having a file signature is because 111 | // the whole purpose of file signatures is to prevent writing to files which aren't generated 112 | // and if a file's length is 0, then it's safe to write to this file! 113 | // :) 114 | self.file_contents.is_empty() 115 | || self 116 | .file_contents 117 | .starts_with(crate::parser::FILE_SIGNATURE) 118 | } 119 | 120 | /// Ensure that the file, has the dsync file signature 121 | /// to prevent accidental overwriting of non-dsync files 122 | /// 123 | /// Returns a [Err] if the file does not have a signature 124 | pub fn ensure_file_signature(&self) -> Result<()> { 125 | if !self.has_file_signature() { 126 | return Err(Error::no_file_signature(format!("Expected file '{path:#?}' to have file signature ('{sig}') -- you might be accidentally overwriting files that weren't generated!", path=self.path, sig=crate::parser::FILE_SIGNATURE))); 127 | } 128 | 129 | Ok(()) 130 | } 131 | 132 | pub fn write(&self) -> Result<()> { 133 | std::fs::write(&self.path, &self.file_contents).attach_path_err(&self.path) 134 | } 135 | 136 | pub fn delete(self) -> Result { 137 | std::fs::remove_file(&self.path).attach_path_err(&self.path)?; 138 | 139 | Ok(self.path) 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /test/use_statements/models/fang_tasks/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `fang_tasks` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=fang_tasks, primary_key(id))] 12 | pub struct FangTasks { 13 | /// Field representing column `id` 14 | pub id: uuid::Uuid, 15 | /// Field representing column `metadata` 16 | pub metadata: serde_json::Value, 17 | /// Field representing column `error_message` 18 | pub error_message: Option, 19 | /// Field representing column `state` 20 | pub state: crate::schema::sql_types::FangTaskState, 21 | /// Field representing column `task_type` 22 | pub task_type: String, 23 | /// Field representing column `uniq_hash` 24 | pub uniq_hash: Option, 25 | /// Field representing column `retries` 26 | pub retries: i32, 27 | /// Field representing column `scheduled_at` 28 | pub scheduled_at: chrono::DateTime, 29 | /// Field representing column `created_at` 30 | pub created_at: chrono::DateTime, 31 | /// Field representing column `updated_at` 32 | pub updated_at: chrono::DateTime, 33 | } 34 | 35 | /// Create Struct for a row in table `fang_tasks` for [`FangTasks`] 36 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 37 | #[diesel(table_name=fang_tasks)] 38 | pub struct CreateFangTasks { 39 | /// Field representing column `id` 40 | pub id: uuid::Uuid, 41 | /// Field representing column `metadata` 42 | pub metadata: serde_json::Value, 43 | /// Field representing column `error_message` 44 | pub error_message: Option, 45 | /// Field representing column `state` 46 | pub state: crate::schema::sql_types::FangTaskState, 47 | /// Field representing column `task_type` 48 | pub task_type: String, 49 | /// Field representing column `uniq_hash` 50 | pub uniq_hash: Option, 51 | /// Field representing column `retries` 52 | pub retries: i32, 53 | /// Field representing column `scheduled_at` 54 | pub scheduled_at: chrono::DateTime, 55 | /// Field representing column `created_at` 56 | pub created_at: chrono::DateTime, 57 | /// Field representing column `updated_at` 58 | pub updated_at: chrono::DateTime, 59 | } 60 | 61 | /// Update Struct for a row in table `fang_tasks` for [`FangTasks`] 62 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 63 | #[diesel(table_name=fang_tasks)] 64 | pub struct UpdateFangTasks { 65 | /// Field representing column `metadata` 66 | pub metadata: Option, 67 | /// Field representing column `error_message` 68 | pub error_message: Option>, 69 | /// Field representing column `state` 70 | pub state: Option, 71 | /// Field representing column `task_type` 72 | pub task_type: Option, 73 | /// Field representing column `uniq_hash` 74 | pub uniq_hash: Option>, 75 | /// Field representing column `retries` 76 | pub retries: Option, 77 | /// Field representing column `scheduled_at` 78 | pub scheduled_at: Option>, 79 | /// Field representing column `created_at` 80 | pub created_at: Option>, 81 | /// Field representing column `updated_at` 82 | pub updated_at: Option>, 83 | } 84 | 85 | /// Result of a `.paginate` function 86 | #[derive(Debug, serde::Serialize)] 87 | pub struct PaginationResult { 88 | /// Resulting items that are from the current page 89 | pub items: Vec, 90 | /// The count of total items there are 91 | pub total_items: i64, 92 | /// Current page, 0-based index 93 | pub page: i64, 94 | /// Size of a page 95 | pub page_size: i64, 96 | /// Number of total possible pages, given the `page_size` and `total_items` 97 | pub num_pages: i64, 98 | } 99 | 100 | impl FangTasks { 101 | /// Insert a new row into `fang_tasks` with a given [`CreateFangTasks`] 102 | pub fn create(db: &mut ConnectionType, item: &CreateFangTasks) -> diesel::QueryResult { 103 | use crate::schema::fang_tasks::dsl::*; 104 | 105 | diesel::insert_into(fang_tasks).values(item).get_result::(db) 106 | } 107 | 108 | /// Get a row from `fang_tasks`, identified by the primary key 109 | pub fn read(db: &mut ConnectionType, param_id: uuid::Uuid) -> diesel::QueryResult { 110 | use crate::schema::fang_tasks::dsl::*; 111 | 112 | fang_tasks.filter(id.eq(param_id)).first::(db) 113 | } 114 | 115 | /// Update a row in `fang_tasks`, identified by the primary key with [`UpdateFangTasks`] 116 | pub fn update(db: &mut ConnectionType, param_id: uuid::Uuid, item: &UpdateFangTasks) -> diesel::QueryResult { 117 | use crate::schema::fang_tasks::dsl::*; 118 | 119 | diesel::update(fang_tasks.filter(id.eq(param_id))).set(item).get_result(db) 120 | } 121 | 122 | /// Delete a row in `fang_tasks`, identified by the primary key 123 | pub fn delete(db: &mut ConnectionType, param_id: uuid::Uuid) -> diesel::QueryResult { 124 | use crate::schema::fang_tasks::dsl::*; 125 | 126 | diesel::delete(fang_tasks.filter(id.eq(param_id))).execute(db) 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | // TODO: change backtrace implementation to be by thiserror, if possible once features become stable 2 | // error_generic_member_access https://github.com/rust-lang/rust/issues/99301 3 | // provide_any https://github.com/rust-lang/rust/issues/96024 4 | 5 | #[cfg(feature = "backtrace")] 6 | use std::backtrace::Backtrace; 7 | use std::{io::Error as ioError, path::Path}; 8 | 9 | pub type Result = std::result::Result; 10 | 11 | /// Macro to not repeat having to do multiple implementations of a [ErrorEnum] variant with the same string type 12 | macro_rules! fn_string { 13 | ($fn_name:ident, $fortype:expr) => { 14 | #[doc = concat!("Create a new [Self] as [", stringify!($fortype), "]")] 15 | pub fn $fn_name(msg: M) -> Self 16 | where 17 | M: Into, 18 | { 19 | return Self::new($fortype(msg.into())); 20 | } 21 | }; 22 | } 23 | 24 | /// Error type for libytdlr, contains a backtrace, wrapper around [ErrorEnum] 25 | #[derive(Debug)] 26 | pub struct Error { 27 | /// The actual error 28 | source: ErrorEnum, 29 | #[cfg(feature = "backtrace")] 30 | /// The backtrace for the error 31 | backtrace: Backtrace, 32 | } 33 | 34 | impl Error { 35 | /// Construct a new [Error] instance based on [ErrorEnum] 36 | pub fn new(source: ErrorEnum) -> Self { 37 | Self { 38 | source, 39 | #[cfg(feature = "backtrace")] 40 | backtrace: Backtrace::capture(), 41 | } 42 | } 43 | 44 | #[cfg(feature = "backtrace")] 45 | /// Get the backtrace that is stored 46 | pub fn backtrace(&self) -> &Backtrace { 47 | &self.backtrace 48 | } 49 | 50 | fn_string!(other, ErrorEnum::Other); 51 | fn_string!( 52 | unsupported_schema_format, 53 | ErrorEnum::UnsupportedSchemaFormat 54 | ); 55 | fn_string!(unsupported_type, ErrorEnum::UnsupportedType); 56 | fn_string!(no_file_signature, ErrorEnum::NoFileSignature); 57 | 58 | /// Create a custom [ioError] with this [Error] wrapped around with a [Path] attached 59 | pub fn custom_ioerror_path(kind: std::io::ErrorKind, msg: M, path: P) -> Self 60 | where 61 | M: Into, 62 | P: AsRef, 63 | { 64 | Self::new(ErrorEnum::IoError( 65 | ioError::new(kind, msg.into()), 66 | format_path(path.as_ref().to_string_lossy().to_string()), 67 | )) 68 | } 69 | 70 | pub fn not_a_directory(msg: M, path: P) -> Self 71 | where 72 | M: Into, 73 | P: AsRef, 74 | { 75 | Self::new(ErrorEnum::NotADirectory( 76 | msg.into(), 77 | path.as_ref().to_string_lossy().to_string(), 78 | )) 79 | } 80 | } 81 | 82 | impl std::fmt::Display for Error { 83 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 84 | self.source.fmt(f) 85 | } 86 | } 87 | 88 | impl std::error::Error for Error { 89 | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 90 | self.source.source() 91 | } 92 | } 93 | 94 | // implement all From<> variants that ErrorEnum also implements 95 | impl From for Error 96 | where 97 | T: Into, 98 | { 99 | fn from(value: T) -> Self { 100 | Self::new(value.into()) 101 | } 102 | } 103 | 104 | /// Error type for "yt-downloader-rust", implements all Error types that could happen in this lib 105 | #[derive(thiserror::Error, Debug)] 106 | pub enum ErrorEnum { 107 | /// Wrapper Variant for [`std::io::Error`] 108 | /// Argument 1 (String) is up to the implementation to set, commonly the path 109 | #[error("IoError: {0}; {1}")] 110 | IoError(std::io::Error, String), 111 | /// Variant for when a directory path was expected but did not exist yet or was not a directory 112 | /// TODO: replace with io::ErrorKind::NotADirectory once stable 113 | #[error("NotADirectory: {0}; Path: \"{1}\"")] 114 | NotADirectory(String, String), 115 | /// Variant for unsupported diesel schema formats 116 | #[error("UnsupportedSchemaFormat: {0}")] 117 | UnsupportedSchemaFormat(String), 118 | /// Variant for unsupported sql types 119 | #[error("UnsupportedType: {0}")] 120 | UnsupportedType(String), 121 | /// Variant for when "has_file_signature" is `false` 122 | #[error("NoFileSignature: {0}")] 123 | NoFileSignature(String), 124 | 125 | /// Invalid generation config 126 | #[error("InvalidGenerationConfig: {0}")] 127 | InvalidGenerationConfig(String), 128 | 129 | /// Variant for Other messages 130 | #[error("Other: {0}")] 131 | Other(String), 132 | } 133 | 134 | /// Helper function to keep consistent formatting 135 | #[inline] 136 | fn format_path(msg: String) -> String { 137 | format!("Path \"{}\"", msg) 138 | } 139 | 140 | /// Trait to map [std::io::Error] into [Error] 141 | pub trait IOErrorToError { 142 | /// Map a [std::io::Error] to [Error] with a [std::path::Path] attached 143 | fn attach_path_err>(self, path: P) -> Result; 144 | 145 | /// Map a [std::io::Error] to [Error] with a [std::path::Path] and message attached 146 | fn attach_path_msg, M: AsRef>(self, path: P, msg: M) -> Result; 147 | } 148 | 149 | impl IOErrorToError for std::result::Result { 150 | fn attach_path_err>(self, path: P) -> Result { 151 | match self { 152 | Ok(v) => Ok(v), 153 | Err(e) => Err(crate::Error::new(ErrorEnum::IoError( 154 | e, 155 | format_path(path.as_ref().to_string_lossy().to_string()), 156 | ))), 157 | } 158 | } 159 | 160 | fn attach_path_msg, M: AsRef>(self, path: P, msg: M) -> Result { 161 | match self { 162 | Ok(v) => Ok(v), 163 | Err(e) => Err(crate::Error::new(ErrorEnum::IoError( 164 | e, 165 | format!( 166 | "{msg} {path}", 167 | msg = msg.as_ref(), 168 | path = format_path(path.as_ref().to_string_lossy().to_string()) 169 | ), 170 | ))), 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /test/advanced_queries/models/todos/generated.rs: -------------------------------------------------------------------------------- 1 | /* @generated and managed by dsync */ 2 | 3 | #[allow(unused)] 4 | use crate::diesel::*; 5 | use crate::schema::*; 6 | 7 | pub type ConnectionType = diesel::r2d2::PooledConnection>; 8 | 9 | /// Struct representing a row in table `todos` 10 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Queryable, diesel::Selectable, diesel::QueryableByName, diesel::Identifiable)] 11 | #[diesel(table_name=todos, primary_key(id))] 12 | pub struct Todos { 13 | /// Field representing column `id` 14 | pub id: i32, 15 | /// Field representing column `text` 16 | pub text: String, 17 | /// Field representing column `completed` 18 | pub completed: bool, 19 | /// Field representing column `type` 20 | pub type_: String, 21 | /// Field representing column `smallint` 22 | pub smallint: i16, 23 | /// Field representing column `bigint` 24 | pub bigint: i64, 25 | /// Field representing column `created_at` 26 | pub created_at: chrono::DateTime, 27 | /// Field representing column `updated_at` 28 | pub updated_at: chrono::NaiveDateTime, 29 | } 30 | 31 | /// Create Struct for a row in table `todos` for [`Todos`] 32 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::Insertable)] 33 | #[diesel(table_name=todos)] 34 | pub struct CreateTodos { 35 | /// Field representing column `text` 36 | pub text: String, 37 | /// Field representing column `completed` 38 | pub completed: bool, 39 | /// Field representing column `type` 40 | pub type_: String, 41 | /// Field representing column `smallint` 42 | pub smallint: i16, 43 | /// Field representing column `bigint` 44 | pub bigint: i64, 45 | } 46 | 47 | /// Update Struct for a row in table `todos` for [`Todos`] 48 | #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, diesel::AsChangeset, PartialEq, Default)] 49 | #[diesel(table_name=todos)] 50 | pub struct UpdateTodos { 51 | /// Field representing column `text` 52 | pub text: Option, 53 | /// Field representing column `completed` 54 | pub completed: Option, 55 | /// Field representing column `type` 56 | pub type_: Option, 57 | /// Field representing column `smallint` 58 | pub smallint: Option, 59 | /// Field representing column `bigint` 60 | pub bigint: Option, 61 | /// Field representing column `created_at` 62 | pub created_at: Option>, 63 | /// Field representing column `updated_at` 64 | pub updated_at: Option, 65 | } 66 | 67 | /// Result of a `.paginate` function 68 | #[derive(Debug, serde::Serialize)] 69 | pub struct PaginationResult { 70 | /// Resulting items that are from the current page 71 | pub items: Vec, 72 | /// The count of total items there are 73 | pub total_items: i64, 74 | /// Current page, 0-based index 75 | pub page: i64, 76 | /// Size of a page 77 | pub page_size: i64, 78 | /// Number of total possible pages, given the `page_size` and `total_items` 79 | pub num_pages: i64, 80 | } 81 | 82 | impl Todos { 83 | /// Insert a new row into `todos` with a given [`CreateTodos`] 84 | pub fn create(db: &mut ConnectionType, item: &CreateTodos) -> diesel::QueryResult { 85 | use crate::schema::todos::dsl::*; 86 | 87 | diesel::insert_into(todos).values(item).get_result::(db) 88 | } 89 | 90 | /// Get a row from `todos`, identified by the primary key 91 | pub fn read(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 92 | use crate::schema::todos::dsl::*; 93 | 94 | todos.filter(id.eq(param_id)).first::(db) 95 | } 96 | 97 | /// Paginates through the table where page is a 0-based index (i.e. page 0 is the first page) 98 | pub fn paginate(db: &mut ConnectionType, page: i64, page_size: i64, filter: TodosFilter) -> diesel::QueryResult> { 99 | let page = page.max(0); 100 | let page_size = page_size.max(1); 101 | let total_items = Self::filter(filter.clone()).count().get_result(db)?; 102 | let items = Self::filter(filter).limit(page_size).offset(page * page_size).load::(db)?; 103 | 104 | Ok(PaginationResult { 105 | items, 106 | total_items, 107 | page, 108 | page_size, 109 | /* ceiling division of integers */ 110 | num_pages: total_items / page_size + i64::from(total_items % page_size != 0) 111 | }) 112 | } 113 | 114 | /// A utility function to help build custom search queries 115 | /// 116 | /// Example: 117 | /// 118 | /// ``` 119 | /// // create a filter for completed todos 120 | /// let query = Todo::filter(TodoFilter { 121 | /// completed: Some(true), 122 | /// ..Default::default() 123 | /// }); 124 | /// 125 | /// // delete completed todos 126 | /// diesel::delete(query).execute(db)?; 127 | /// ``` 128 | pub fn filter<'a>( 129 | filter: TodosFilter, 130 | ) -> crate::schema::todos::BoxedQuery<'a, diesel::pg::Pg> { 131 | let mut query = crate::schema::todos::table.into_boxed(); 132 | 133 | if let Some(filter_id) = filter.id { 134 | query = query.filter(crate::schema::todos::id.eq(filter_id)); 135 | } 136 | if let Some(filter_text) = filter.text { 137 | query = query.filter(crate::schema::todos::text.eq(filter_text)); 138 | } 139 | if let Some(filter_completed) = filter.completed { 140 | query = query.filter(crate::schema::todos::completed.eq(filter_completed)); 141 | } 142 | if let Some(filter_type_) = filter.type_ { 143 | query = query.filter(crate::schema::todos::type_.eq(filter_type_)); 144 | } 145 | if let Some(filter_smallint) = filter.smallint { 146 | query = query.filter(crate::schema::todos::smallint.eq(filter_smallint)); 147 | } 148 | if let Some(filter_bigint) = filter.bigint { 149 | query = query.filter(crate::schema::todos::bigint.eq(filter_bigint)); 150 | } 151 | if let Some(filter_created_at) = filter.created_at { 152 | query = query.filter(crate::schema::todos::created_at.eq(filter_created_at)); 153 | } 154 | if let Some(filter_updated_at) = filter.updated_at { 155 | query = query.filter(crate::schema::todos::updated_at.eq(filter_updated_at)); 156 | } 157 | 158 | query 159 | } 160 | 161 | /// Update a row in `todos`, identified by the primary key with [`UpdateTodos`] 162 | pub fn update(db: &mut ConnectionType, param_id: i32, item: &UpdateTodos) -> diesel::QueryResult { 163 | use crate::schema::todos::dsl::*; 164 | 165 | diesel::update(todos.filter(id.eq(param_id))).set(item).get_result(db) 166 | } 167 | 168 | /// Delete a row in `todos`, identified by the primary key 169 | pub fn delete(db: &mut ConnectionType, param_id: i32) -> diesel::QueryResult { 170 | use crate::schema::todos::dsl::*; 171 | 172 | diesel::delete(todos.filter(id.eq(param_id))).execute(db) 173 | } 174 | } 175 | #[derive(Debug, Default, Clone)] 176 | pub struct TodosFilter { 177 | pub id: Option, 178 | pub text: Option, 179 | pub completed: Option, 180 | pub type_: Option, 181 | pub smallint: Option, 182 | pub bigint: Option, 183 | pub created_at: Option>, 184 | pub updated_at: Option, 185 | } 186 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dsync 2 | 3 | License: MIT OR Apache-2.0 4 | 5 | A utility to generate database structs and querying code from diesel schema files. Primarily built for [create-rust-app](https://github.com/Wulf/create-rust-app). 6 | 7 | Currently, it's more advantageous to generate code over deriving code with macros because intellisense and autocompletion isn't quite there when it comes to macro expansion. 8 | 9 | ## Demo 10 | 11 | Given the following schema: 12 | 13 | ```rust 14 | // schema.rs 15 | diesel::table! { 16 | todos (id) { 17 | id -> Int4, 18 | text -> Text, 19 | completed -> Bool, 20 | } 21 | } 22 | ``` 23 | 24 | We run: 25 | 26 | ```sh 27 | dsync -i schema.rs -o models 28 | ``` 29 | 30 | Now we have everything we need! 31 | 32 | ```rust 33 | use models::todos; 34 | 35 | async fn demo(db: Connection) { 36 | let created_todo = todos::create(&mut db, todos::CreateTodo { 37 | text: "Create a demo", 38 | completed: false, 39 | })?; 40 | 41 | let updated_todo = todos::update(&mut db, created_todo.id, UpdateTodo { 42 | text: created_todo.text, 43 | completed: true, 44 | })?; 45 | } 46 | ``` 47 | 48 | For a complete example, see [`test/simple_table_sqlite/schema.rs`](test/simple_table_sqlite/schema.rs) which generates all the code in [`test/simple_schema_sqlite/models`](test/simple_table_sqlite/models). 49 | 50 | ## Usage as a library 51 | 52 | 1. Add this crate: 53 | 54 | ```sh 55 | cargo add dsync 56 | ``` 57 | 58 | 2. Create a new binary in your project which uses the crate (for example, `bin/dsync.rs`) 59 | 60 | ```rust 61 | use std::{collections::HashMap, path::PathBuf}; 62 | use dsync::{GenerationConfig, TableOptions}; 63 | 64 | pub fn main() { 65 | let dir = env!("CARGO_MANIFEST_DIR"); 66 | 67 | dsync::generate_files( 68 | PathBuf::from_iter([dir, "src/schema.rs"]), 69 | PathBuf::from_iter([dir, "src/models"]), 70 | GenerationConfig { 71 | connection_type: "diesel::sqlite::SqliteConnection", 72 | options: Default::default(), 73 | } 74 | ); 75 | } 76 | ``` 77 | 78 | 3. Create a `Cargo.toml` binary entry: 79 | 80 | ```toml 81 | [[bin]] 82 | name = "dsync" 83 | path = "bin/dsync.rs" 84 | ``` 85 | 86 | 4. Execute! 87 | 88 | ```sh 89 | cargo run --bin dsync 90 | ``` 91 | 92 | **Protip**: to use `cargo dsync`, create an alias in `.cargo/config`: 93 | 94 | ```toml 95 | [alias] 96 | dsync="run --bin dsync" 97 | ``` 98 | 99 | ### Pre-built binary 100 | 101 | Setting up a custom binary allows you to completely customize the generation; however, if complete customization isn't necessary, you can install the CLI directly 102 | (you'll have to make sure you keep it up-to-date by running this periodically): 103 | 104 | ```sh 105 | cargo install dsync 106 | ``` 107 | 108 | ### CLI Usage 109 | 110 | ```sh 111 | Generate rust structs & query functions from diesel schema files. 112 | 113 | Usage: dsync [OPTIONS] --input --output --connection-type 114 | dsync [OPTIONS] 115 | 116 | Commands: 117 | completions Generate shell completions 118 | 119 | Options: 120 | -i, --input 121 | Input diesel schema file 122 | 123 | -o, --output 124 | Output file, stdout if not present 125 | 126 | --tsync 127 | adds the #[tsync] attribute to all structs; see 128 | https://github.com/Wulf/tsync 129 | 130 | -g, --autogenerated-columns 131 | List of columns which are automatically generated but are not primary 132 | keys (for example: "created_at", "updated_at", etc.) 133 | 134 | -c, --connection-type 135 | rust type which describes a connection 136 | 137 | For example: 138 | - `diesel::pg::PgConnection` 139 | - `diesel::sqlite::SqliteConnection` 140 | - `diesel::mysql::MysqlConnection` 141 | - 142 | `diesel::r2d2::PooledConnection>` 143 | - or, your custom diesel connection type (struct which implements 144 | `diesel::connection::Connection`) 145 | 146 | --no-serde 147 | Disable generating serde implementations 148 | 149 | --schema-path 150 | Set custom schema use path 151 | 152 | [default: crate::schema::] 153 | 154 | --model-path 155 | Set custom model use path 156 | 157 | [default: crate::models::] 158 | 159 | --no-crud 160 | Do not generate the CRUD (impl) functions for generated models 161 | 162 | --create-str 163 | Set which string type to use for Create* structs 164 | 165 | [default: string] 166 | 167 | Possible values: 168 | - string: Use "String" 169 | - str: Use "&str" 170 | - cow: Use "Cow" 171 | 172 | --update-str 173 | Set which string type to use for Update* structs 174 | 175 | [default: string] 176 | 177 | Possible values: 178 | - string: Use "String" 179 | - str: Use "&str" 180 | - cow: Use "Cow" 181 | 182 | --create-bytes 183 | Set which bytes type to use for Create* structs 184 | 185 | [default: vec] 186 | 187 | Possible values: 188 | - vec: Use "Vec" 189 | - slice: Use "&[u8]" 190 | - cow: Use "Cow<[u8]>" 191 | 192 | --update-bytes 193 | Set which bytes type to use for Update* structs 194 | 195 | [default: vec] 196 | 197 | Possible values: 198 | - vec: Use "Vec" 199 | - slice: Use "&[u8]" 200 | - cow: Use "Cow<[u8]>" 201 | 202 | --single-model-file 203 | Only Generate a single model file instead of a directory with "mod.rs" 204 | and "generated.rs" 205 | 206 | --once-common-structs 207 | Generate common structs only once in a "common.rs" file 208 | 209 | --once-connection-type 210 | Generate the "ConnectionType" type only once in a "common.rs" file 211 | 212 | --readonly-prefix 213 | A Prefix to treat a table matching this as readonly (only generate the 214 | Read struct) 215 | 216 | --readonly-suffix 217 | A Suffix to treat a table matching this as readonly (only generate the 218 | Read struct) 219 | 220 | -h, --help 221 | Print help (see a summary with '-h') 222 | 223 | -V, --version 224 | Print version 225 | ``` 226 | 227 | #### Example 228 | ```sh 229 | dsync -i src/schema.rs -o src/models 230 | ``` 231 | 232 | #### Notes 233 | 234 | - the CLI has fail-safes to prevent accidental file overwriting 235 | - *2: "readonly" tables don't have `Update*`(`UpdateTodos`) & `Create*`(`CreateTodos`) structs, only `*`(`Todos`, no suffix / prefix) structs. 236 | For example this is useful for Sqlite views, which are read-only (cannot be written to, but can be read) 237 | 238 | ## Experimental API 239 | 240 | We're currently experimenting with advanced query generation. This includes pagination, filtering/searching, and the like. Enable the `advanced-queries` feature flag to see some of it in action. 241 | 242 | Alternatively, you can see what gets generated in the advanced queries test here: [`test/advanced_queries/models`](test/advanced_queries/models) 243 | 244 | Feel free to open an issue to discuss these API and provide your feedback. 245 | 246 | ## Docs 247 | 248 | See `dsync --help` for all CLI arguments and documentation. 249 | 250 | See [docs.rs](https://docs.rs/dsync/latest/dsync/) for library documentation. 251 | 252 | Feel free to open tickets for support or feature requests. 253 | 254 | ## Development/Testing 255 | 256 | Use `./test/test_all.sh` to run tests. 257 | After running the test, there should be no unexpected changes to files in `./test` (use `git status` and `git diff` to see if there were any changes). 258 | 259 | ## License 260 | 261 | This tool is distributed under the terms of both the MIT license and the Apache License (Version 2.0). 262 | 263 | See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details. 264 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.4" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "utf8parse", 17 | ] 18 | 19 | [[package]] 20 | name = "anstyle" 21 | version = "1.0.4" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" 24 | 25 | [[package]] 26 | name = "anstyle-parse" 27 | version = "0.2.2" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" 30 | dependencies = [ 31 | "utf8parse", 32 | ] 33 | 34 | [[package]] 35 | name = "anstyle-query" 36 | version = "1.0.0" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" 39 | dependencies = [ 40 | "windows-sys", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle-wincon" 45 | version = "3.0.1" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" 48 | dependencies = [ 49 | "anstyle", 50 | "windows-sys", 51 | ] 52 | 53 | [[package]] 54 | name = "bitflags" 55 | version = "2.4.0" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" 58 | 59 | [[package]] 60 | name = "clap" 61 | version = "4.4.6" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" 64 | dependencies = [ 65 | "clap_builder", 66 | "clap_derive", 67 | ] 68 | 69 | [[package]] 70 | name = "clap_builder" 71 | version = "4.4.6" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" 74 | dependencies = [ 75 | "anstream", 76 | "anstyle", 77 | "clap_lex", 78 | "strsim", 79 | "terminal_size", 80 | ] 81 | 82 | [[package]] 83 | name = "clap_complete" 84 | version = "4.4.3" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7" 87 | dependencies = [ 88 | "clap", 89 | ] 90 | 91 | [[package]] 92 | name = "clap_derive" 93 | version = "4.4.2" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" 96 | dependencies = [ 97 | "heck", 98 | "proc-macro2", 99 | "quote", 100 | "syn", 101 | ] 102 | 103 | [[package]] 104 | name = "clap_lex" 105 | version = "0.5.1" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" 108 | 109 | [[package]] 110 | name = "colorchoice" 111 | version = "1.0.0" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 114 | 115 | [[package]] 116 | name = "dsync" 117 | version = "0.1.0" 118 | dependencies = [ 119 | "clap", 120 | "clap_complete", 121 | "heck", 122 | "indoc", 123 | "proc-macro2", 124 | "syn", 125 | "thiserror", 126 | ] 127 | 128 | [[package]] 129 | name = "errno" 130 | version = "0.3.5" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" 133 | dependencies = [ 134 | "libc", 135 | "windows-sys", 136 | ] 137 | 138 | [[package]] 139 | name = "heck" 140 | version = "0.4.1" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 143 | 144 | [[package]] 145 | name = "indoc" 146 | version = "2.0.4" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" 149 | 150 | [[package]] 151 | name = "libc" 152 | version = "0.2.149" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" 155 | 156 | [[package]] 157 | name = "linux-raw-sys" 158 | version = "0.4.10" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" 161 | 162 | [[package]] 163 | name = "proc-macro2" 164 | version = "1.0.69" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" 167 | dependencies = [ 168 | "unicode-ident", 169 | ] 170 | 171 | [[package]] 172 | name = "quote" 173 | version = "1.0.33" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 176 | dependencies = [ 177 | "proc-macro2", 178 | ] 179 | 180 | [[package]] 181 | name = "rustix" 182 | version = "0.38.18" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" 185 | dependencies = [ 186 | "bitflags", 187 | "errno", 188 | "libc", 189 | "linux-raw-sys", 190 | "windows-sys", 191 | ] 192 | 193 | [[package]] 194 | name = "strsim" 195 | version = "0.10.0" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 198 | 199 | [[package]] 200 | name = "syn" 201 | version = "2.0.38" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" 204 | dependencies = [ 205 | "proc-macro2", 206 | "quote", 207 | "unicode-ident", 208 | ] 209 | 210 | [[package]] 211 | name = "terminal_size" 212 | version = "0.3.0" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" 215 | dependencies = [ 216 | "rustix", 217 | "windows-sys", 218 | ] 219 | 220 | [[package]] 221 | name = "thiserror" 222 | version = "1.0.49" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" 225 | dependencies = [ 226 | "thiserror-impl", 227 | ] 228 | 229 | [[package]] 230 | name = "thiserror-impl" 231 | version = "1.0.49" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" 234 | dependencies = [ 235 | "proc-macro2", 236 | "quote", 237 | "syn", 238 | ] 239 | 240 | [[package]] 241 | name = "unicode-ident" 242 | version = "1.0.12" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 245 | 246 | [[package]] 247 | name = "utf8parse" 248 | version = "0.2.1" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 251 | 252 | [[package]] 253 | name = "windows-sys" 254 | version = "0.48.0" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 257 | dependencies = [ 258 | "windows-targets", 259 | ] 260 | 261 | [[package]] 262 | name = "windows-targets" 263 | version = "0.48.5" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 266 | dependencies = [ 267 | "windows_aarch64_gnullvm", 268 | "windows_aarch64_msvc", 269 | "windows_i686_gnu", 270 | "windows_i686_msvc", 271 | "windows_x86_64_gnu", 272 | "windows_x86_64_gnullvm", 273 | "windows_x86_64_msvc", 274 | ] 275 | 276 | [[package]] 277 | name = "windows_aarch64_gnullvm" 278 | version = "0.48.5" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 281 | 282 | [[package]] 283 | name = "windows_aarch64_msvc" 284 | version = "0.48.5" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 287 | 288 | [[package]] 289 | name = "windows_i686_gnu" 290 | version = "0.48.5" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 293 | 294 | [[package]] 295 | name = "windows_i686_msvc" 296 | version = "0.48.5" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 299 | 300 | [[package]] 301 | name = "windows_x86_64_gnu" 302 | version = "0.48.5" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 305 | 306 | [[package]] 307 | name = "windows_x86_64_gnullvm" 308 | version = "0.48.5" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 311 | 312 | [[package]] 313 | name = "windows_x86_64_msvc" 314 | version = "0.48.5" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 317 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! dsync library 2 | //! 3 | //! The dsync library allows creating a custom binary for dsync 4 | //! 5 | //! ## Features 6 | //! 7 | //! - `async`: enable support for [diesel_async](https://github.com/weiznich/diesel_async) 8 | //! - `tsync`: enable support for [tsync](https://github.com/Wulf/tsync) 9 | //! - `backtrace`: enable attaching backtraces to dsync errors 10 | //! - `derive-queryablebyname`: enable `diesel::QueryableByName` derives on READ structs 11 | //! - `advanced-queries`: enable experimental pagination and filter functions ([examples](https://github.com/Wulf/dsync/tree/a44afdd08f4447e367aa47ecb91fae88b57f8944/test/advanced_queries)) 12 | //! 13 | //! default features: `tsync`, `backtrace`, `derive-queryablebyname` 14 | 15 | mod code; 16 | pub mod error; 17 | mod file; 18 | mod global; 19 | mod parser; 20 | 21 | pub use global::{ 22 | BytesType, GenerationConfig, GenerationConfigOpts, StringType, TableOptions, 23 | DEFAULT_MODEL_PATH, DEFAULT_SCHEMA_PATH, 24 | }; 25 | 26 | use error::IOErrorToError; 27 | pub use error::{Error, Result}; 28 | use file::MarkedFile; 29 | use heck::ToSnakeCase; 30 | use parser::ParsedTableMacro; 31 | pub use parser::FILE_SIGNATURE; 32 | use std::fmt::Display; 33 | use std::path::{Path, PathBuf}; 34 | 35 | /// Generate a model for the given schema contents 36 | /// 37 | /// Model is returned and not saved to disk yet 38 | pub fn generate_code( 39 | diesel_schema_file_contents: &str, 40 | config: &GenerationConfig, 41 | ) -> Result> { 42 | parser::parse_and_generate_code(diesel_schema_file_contents, config) 43 | } 44 | 45 | /// Status indicating what happened to a file 46 | #[derive(Debug, Clone, PartialEq, Eq)] 47 | pub enum FileChangeStatus { 48 | /// Status for unchanged file contents 49 | Unchanged, 50 | /// Status for modified file contents 51 | Modified, 52 | /// Status if the file has been deleted 53 | Deleted, 54 | } 55 | 56 | impl Display for FileChangeStatus { 57 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 58 | write!( 59 | f, 60 | "{}", 61 | match self { 62 | FileChangeStatus::Unchanged => "Unchanged", 63 | FileChangeStatus::Modified => "Modified", 64 | FileChangeStatus::Deleted => "Deleted", 65 | } 66 | ) 67 | } 68 | } 69 | 70 | /// Status indicating what happened to a specific file 71 | #[derive(Debug, Clone, PartialEq, Eq)] 72 | pub struct FileChange { 73 | /// File in question 74 | pub file: PathBuf, 75 | /// Status of the file 76 | pub status: FileChangeStatus, 77 | } 78 | 79 | impl FileChange { 80 | pub fn new>(path: P, status: FileChangeStatus) -> Self { 81 | Self { 82 | file: path.as_ref().to_owned(), 83 | status, 84 | } 85 | } 86 | } 87 | 88 | // easily create a [FileChange] from a [MarkedFile] 89 | impl From<&MarkedFile> for FileChange { 90 | fn from(value: &MarkedFile) -> Self { 91 | if value.is_modified() { 92 | Self::new(&value.path, FileChangeStatus::Modified) 93 | } else { 94 | Self::new(&value.path, FileChangeStatus::Unchanged) 95 | } 96 | } 97 | } 98 | 99 | /// Helper function for consistent table module name generation 100 | /// this is used for the rust module path name and for the filename 101 | /// 102 | /// input: "tableA", output -> "table_a" 103 | fn get_table_module_name(table_name: &str) -> String { 104 | table_name.to_snake_case().to_lowercase() 105 | } 106 | 107 | /// Generate all Models for a given diesel schema file 108 | /// 109 | /// Models are saved to disk 110 | pub fn generate_files( 111 | input_diesel_schema_file: &Path, 112 | output_models_dir: &Path, 113 | config: GenerationConfig, 114 | ) -> Result> { 115 | global::validate_config(&config)?; 116 | 117 | let generated = generate_code( 118 | &std::fs::read_to_string(input_diesel_schema_file) 119 | .attach_path_err(input_diesel_schema_file)?, 120 | &config, 121 | )?; 122 | 123 | if !output_models_dir.exists() { 124 | std::fs::create_dir(output_models_dir).attach_path_err(output_models_dir)?; 125 | } else if !output_models_dir.is_dir() { 126 | return Err(Error::not_a_directory( 127 | "Expected output argument to be a directory or non-existent.", 128 | output_models_dir, 129 | )); 130 | } 131 | 132 | // using generated len, because that is very likely the amount (at least) for files 133 | let mut file_changes = Vec::with_capacity(generated.len()); 134 | 135 | // check that the mod.rs file exists 136 | let mut mod_rs = MarkedFile::new(output_models_dir.join("mod.rs"))?; 137 | 138 | if config.any_once_option() { 139 | let mut common_file = MarkedFile::new(output_models_dir.join("common.rs"))?; 140 | common_file.ensure_file_signature()?; 141 | common_file.change_file_contents({ 142 | let mut tmp = format!("{FILE_SIGNATURE}\n"); 143 | if config.get_once_common_structs() { 144 | tmp.push_str(&code::generate_common_structs( 145 | config.get_default_table_options(), 146 | )); 147 | } 148 | if config.get_once_connection_type() { 149 | tmp.push('\n'); 150 | tmp.push_str(&code::generate_connection_type(&config)); 151 | 152 | // add ending new-line, this should not cause duplicate new-lines because this only gets run if any of the options is set 153 | // this will need to be refactored if there should ever be more options using common_file 154 | tmp.push('\n'); 155 | } 156 | 157 | tmp 158 | }); 159 | common_file.write()?; 160 | file_changes.push(FileChange::from(&common_file)); 161 | 162 | mod_rs.ensure_mod_stmt("common"); 163 | } 164 | 165 | // pass 1: add code for new tables 166 | for table in generated.iter() { 167 | if config.get_once_common_structs() && table.name == "common" { 168 | return Err(Error::other("Cannot have a table named \"common\" while having option \"once_common_structs\" enabled")); 169 | } 170 | let table_name = table.name.to_string(); 171 | let table_filename = get_table_module_name(&table_name); 172 | let table_config = config.table(&table_name); 173 | let table_dir = if table_config.get_single_model_file() { 174 | output_models_dir.to_owned() 175 | } else { 176 | output_models_dir.join(&table_filename) 177 | }; 178 | 179 | if !table_dir.exists() { 180 | std::fs::create_dir(&table_dir).attach_path_err(&table_dir)?; 181 | } 182 | 183 | if !table_dir.is_dir() { 184 | return Err(Error::not_a_directory("Expected a directory", table_dir)); 185 | } 186 | 187 | let table_file_name = if table_config.get_single_model_file() { 188 | let mut table_name = table_name; 189 | table_name.push_str(".rs"); 190 | table_name 191 | } else { 192 | "generated.rs".into() 193 | }; 194 | 195 | let mut table_generated_rs = MarkedFile::new(table_dir.join(table_file_name))?; 196 | let mut table_mod_rs = MarkedFile::new(table_dir.join("mod.rs"))?; 197 | 198 | table_generated_rs.ensure_file_signature()?; 199 | table_generated_rs.change_file_contents(table.generated_code.clone()); 200 | table_generated_rs.write()?; 201 | 202 | file_changes.push(FileChange::from(&table_generated_rs)); 203 | 204 | if !table_config.get_single_model_file() { 205 | table_mod_rs.ensure_mod_stmt("generated"); 206 | table_mod_rs.ensure_use_stmt("generated::*"); 207 | table_mod_rs.write()?; 208 | file_changes.push(FileChange::from(&table_mod_rs)); 209 | } 210 | 211 | mod_rs.ensure_mod_stmt(&table_filename); 212 | } 213 | 214 | // pass 2: delete code for removed tables 215 | for item in std::fs::read_dir(output_models_dir).attach_path_err(output_models_dir)? { 216 | // TODO: this does not work with "single-model-file" 217 | let item = item.attach_path_err(output_models_dir)?; 218 | 219 | // check if item is a directory 220 | let file_type = item 221 | .file_type() 222 | .attach_path_msg(item.path(), "Could not determine type of file")?; 223 | if !file_type.is_dir() { 224 | continue; 225 | } 226 | 227 | // check if it's a generated file 228 | let generated_rs_path = item.path().join("generated.rs"); 229 | if !generated_rs_path.exists() 230 | || !generated_rs_path.is_file() 231 | || !MarkedFile::new(generated_rs_path.clone())?.has_file_signature() 232 | { 233 | continue; 234 | } 235 | 236 | // okay, it's generated, but we need to check if it's for a deleted table 237 | let file_name = item.file_name(); 238 | let associated_table_name = file_name.to_str().ok_or(Error::other(format!( 239 | "Could not determine name of file '{:#?}'", 240 | item.path() 241 | )))?; 242 | let found = generated.iter().find(|g| { 243 | get_table_module_name(&g.name.to_string()).eq_ignore_ascii_case(associated_table_name) 244 | }); 245 | if found.is_some() { 246 | continue; 247 | } 248 | 249 | // this table was deleted, let's delete the generated code 250 | std::fs::remove_file(&generated_rs_path).attach_path_err(&generated_rs_path)?; 251 | file_changes.push(FileChange::new( 252 | &generated_rs_path, 253 | FileChangeStatus::Deleted, 254 | )); 255 | 256 | // remove the mod.rs file if there isn't anything left in there except the use stmt 257 | let table_mod_rs_path = item.path().join("mod.rs"); 258 | if table_mod_rs_path.exists() { 259 | let mut table_mod_rs = MarkedFile::new(table_mod_rs_path)?; 260 | 261 | table_mod_rs.remove_mod_stmt("generated"); 262 | table_mod_rs.remove_use_stmt("generated::*"); 263 | table_mod_rs.write()?; 264 | 265 | if table_mod_rs.get_file_contents().trim().is_empty() { 266 | let table_mod_rs = table_mod_rs.delete()?; 267 | file_changes.push(FileChange::new(table_mod_rs, FileChangeStatus::Deleted)); 268 | } else { 269 | table_mod_rs.write()?; // write the changes we made above 270 | file_changes.push(FileChange::from(&table_mod_rs)); 271 | } 272 | } 273 | 274 | // delete the table dir if there's nothing else in there 275 | let is_empty = item 276 | .path() 277 | .read_dir() 278 | .attach_path_err(item.path())? 279 | .next() 280 | .is_none(); 281 | if is_empty { 282 | std::fs::remove_dir(item.path()).attach_path_err(item.path())?; 283 | } 284 | 285 | // remove the module from the main mod_rs file 286 | mod_rs.remove_mod_stmt(associated_table_name); 287 | } 288 | 289 | mod_rs.write()?; 290 | file_changes.push(FileChange::from(&mod_rs)); 291 | 292 | Ok(file_changes) 293 | } 294 | --------------------------------------------------------------------------------