Giter Site home page Giter Site logo

diesel_cli_ext's Introduction

Diesel CLI Extension

Diesel CLI Extension is a tool-belt that aids Diesel CLI after it built schema.rs.

Build Status Crates.io

It contains 4 functions at this moment.

  1. Generate protobuf file.(diesel_ext proto)
  2. Generate model rust structs.(diesel_ext model)
  3. Generate conversion implementations.(diesel_ext into_proto, and diesel_ext from_proto)

Installation

cargo install diesel_cli_ext

How to use

First of all, diesel print-schema > src/schema.rs

TL;DR:

Usage: target/debug/diesel_ext FILE [options]

Common Options:
    -s, --schema-file PATH
                        Set schema file path
    -h, --help          Print this help menu

Model Options:
    -m, --model         Set as model output
    -M, --map "FROM_TYPE TO_TYPE"
                        Set type mappings (can be set multiple times) e.g.
                        --map "BigInt iccc"
    -I, --import-types "TYPE"
                        This field adds use statements to the top of every
                        table! declaration. (can be set multiple times) e.g.
                        --import_types "diesel::sql_types::*"
        --derive-mod "TABLENAME MODIFIER"
                        (NOT ready)This field adds derives for certain tables.
                        (can be set multiple times) e.g. --derive-mod
                        "table_name +Debug" --derive-mod "table_name2 -Debug"
    -d, --derive DERIVES
                        set struct derives
    -r, --rust_styled_model_fields
                        set struct field names to be styled according to Rust guidelines

Proto Options:
    -t, --add-table-name 
                        Add #[table_name = x] before structs
    -p, --proto         Set as proto output
    -i, --into_proto    Set as into_proto output

(You can see it again by diesel_ext --help)

Output demonstrations are as below...

To generate model structs:

e.g. diesel_ext > src/db/db_models.rs , diesel_ext -m > src/models.rs, diesel_ext --model > src/models.rs (it is the default option)

Sample model output:

use chrono::NaiveDateTime;
use bigdecimal::BigDecimal;

#[derive(Queryable)]
pub struct CarryOverBalance {
    pub account_id : i64,
    pub debit : BigDecimal,
    pub description : String,
}

#[derive(Queryable)]
pub struct Order {
    pub id1 : i64,
    pub time : NaiveDateTime,
    pub json : String,
}

To generate prelimiting proto file:

diesel_ext -p > myproto.proto, diesel_ext --proto > myproto.proto

Sample output:

syntax = "proto3";


message CarryOverBalance {
    int64 account_id = 1;
    string debit = 2;
    string description = 3;
}
message Order {
    int64 id1 = 1;
    string time = 2;
    string json = 3;
}


message EnquireCarryOverBalanceRequest {
    int64 id =1;
}
message EnquireOrderRequest {
    int64 id =1;
}


service MessageRpc {
    rpc getCarryOverBalance (EnquireCarryOverBalanceRequest) returns (CarryOverBalance) { }
    rpc getOrder (EnquireOrderRequest) returns (Order) { }
}

To generate proto conversions:

diesel_ext -f -c class_name > proto/src/conversion/from_proto.rs, diesel_ext -i -c class_name > proto/src/conversion/into_proto.rs

(if you omit the second parameter, names will be displayed as _name_ for your search and replace.)

Sample output(from):

use models;
use proto::client_service;
use std::str::FromStr;
use std::convert::From;

impl From<class_name::CarryOverBalance> for models::CarryOverBalance {
    fn from(i: class_name::CarryOverBalance) -> Self {
        models::CarryOverBalance{
            account_id: i.get_account_id(),
            debit: i.get_debit().to_string(),
            description: i.get_description().to_string(),
        }
    }
}

impl From<class_name::Order> for models::Order {
    fn from(i: class_name::Order) -> Self {
        models::Order{
            id1: i.get_id1(),
            time: i.get_time().to_string(),
            json: i.get_json().to_string(),
        }
    }
}

into:

use models;
use proto::client_service;
use std::str::FromStr;
use std::convert::From;

impl From<models::CarryOverBalance> for class_name::CarryOverBalance {
    fn from(i: models::CarryOverBalance) -> Self {
        let mut o = class_name::CarryOverBalance::new();
        o.set_account_id(i.account_id.into());
        o.set_debit(i.debit.to_string());
        o.set_description(i.description.to_string());
        o
    }
}

impl From<models::Order> for class_name::Order {
    fn from(i: models::Order) -> Self {
        let mut o = class_name::Order::new();
        o.set_id1(i.id1.into());
        o.set_time(i.time.to_string());
        o.set_json(i.json.to_string());
        o
    }
}

diesel_cli_ext's People

Contributors

abbychau avatar alephalpha avatar arvil avatar barskern avatar davyzhang avatar frankmariette avatar getmetorajesh avatar holg avatar joelwachsler avatar mverleg avatar pruthvikar avatar vrajs16 avatar xaoctech avatar zezic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

diesel_cli_ext's Issues

Problem with generating model using schema in table names.

Hi, i am using diesel_ext to generate model.rs for my postgres database.
My up.sql:

CREATE TABLE IF NOT EXISTS machine.Country(  
     CountryId  int DEFAULT nextval('machine.SEQ_Country_CountryId') PRIMARY KEY,    
     Code  varchar(50),  
     Name  varchar(100)    
);  

Which from diesel generates schema.rs like this:

pub mod machine {  
    diesel::table! {  
        machine.country (countryid) {  
            countryid -> Int4,  
            code -> Nullable<Varchar>,  
            name -> Nullable<Varchar>,  
        }  
    }  

And diesel_ext -t -m generates this:

pub mod machine {  
    #[derive(Queryable, Debug, Identifiable)]  
    #[diesel(primary_key(countryid))]  
    #[diesel(table_name = "machine.country")]  
    pub struct country {  
        pub countryid: i32,  
        pub code: Option<String>,  
        pub name: Option<String>,  
    }  

Problems:

  • struct name should be uppercase (Country instead of country)
  • table name should be country instead of machine.country

Proposition to Community For Feature Implementation

I'm finding it annoying that everytime I update my database schema I lose all of my "models.rs macros" (derive statements and the like) and "impl blocks" and have to manually reformat the document to fix my structs and add my blocks. What if diesel_ext could only format the necessary bits of information rather than generate the entire schema.

Could this be done? I might be interested in working on a solution.

Valid UTF-8

Hi,
ENV:

  • Diesel 2.1.1
  • Then installed diesel_ext
  • cargo 1.75.0 (1d8b05cdd 2023-11-20)
  • Windows 11

diesel setup and diesel print-schema > src/schema.rs created this file

// @generated automatically by Diesel CLI.

diesel::table! {
    allergenes (id) {
        id -> Uuid,
    }
}

diesel::table! {
    allergenes_translations (allergene_id, language_id) {
        allergene_id -> Uuid,
        language_id -> Uuid,
        #[max_length = 255]
        name -> Nullable<Varchar>,
    }
}

diesel::table! {
    categories (id) {
        id -> Uuid,
    }
}

diesel::table! {
    categories_translations (category_id, language_id) {
        category_id -> Uuid,
        language_id -> Uuid,
        #[max_length = 255]
        name -> Nullable<Varchar>,
    }
}

diesel::table! {
    dish_category (dish_id, category_id) {
        dish_id -> Uuid,
        category_id -> Uuid,
    }
}

diesel::table! {
    dish_ingredients (dish_id, ingredient_id) {
        dish_id -> Uuid,
        ingredient_id -> Uuid,
    }
}

diesel::table! {
    dishes (id) {
        id -> Uuid,
        price -> Nullable<Float4>,
        enabled -> Nullable<Bool>,
    }
}

diesel::table! {
    dishes_translations (dish_id, language_id) {
        dish_id -> Uuid,
        language_id -> Uuid,
        #[max_length = 255]
        name -> Nullable<Varchar>,
    }
}

diesel::table! {
    ingredients (id) {
        id -> Uuid,
        frozen -> Nullable<Bool>,
        allergenes -> Nullable<Bool>,
    }
}

diesel::table! {
    ingredients_allergenes (ingredient_id, allergene_id) {
        ingredient_id -> Uuid,
        allergene_id -> Uuid,
    }
}

diesel::table! {
    ingredients_translations (ingredient_id, language_id) {
        ingredient_id -> Uuid,
        language_id -> Uuid,
        #[max_length = 255]
        name -> Nullable<Varchar>,
    }
}

diesel::table! {
    languages (id) {
        id -> Uuid,
        #[max_length = 3]
        language -> Nullable<Varchar>,
        #[max_length = 255]
        name -> Nullable<Varchar>,
    }
}

diesel::table! {
    notes_archive (dish_id) {
        dish_id -> Uuid,
        notes -> Nullable<Text>,
    }
}

diesel::table! {
    order_items (id) {
        id -> Uuid,
        order_id -> Nullable<Uuid>,
        dish_id -> Nullable<Uuid>,
        notes -> Nullable<Text>,
        payed -> Nullable<Bool>,
        custom_price -> Float4,
    }
}

diesel::table! {
    orders (id, table_number) {
        id -> Uuid,
        table_number -> Int4,
        order_time -> Nullable<Timestamp>,
        payed -> Nullable<Bool>,
    }
}

diesel::table! {
    orders_archive (dish_id) {
        dish_id -> Uuid,
        quantity -> Nullable<Int4>,
    }
}

diesel::table! {
    postazioni (id) {
        id -> Uuid,
    }
}

diesel::table! {
    postazioni_categories (postazione_id, category_id) {
        postazione_id -> Uuid,
        category_id -> Uuid,
    }
}

diesel::table! {
    postazioni_translations (postazione_id, language_id) {
        postazione_id -> Uuid,
        language_id -> Uuid,
        #[max_length = 255]
        name -> Nullable<Varchar>,
    }
}

diesel::joinable!(allergenes_translations -> allergenes (allergene_id));
diesel::joinable!(allergenes_translations -> languages (language_id));
diesel::joinable!(categories_translations -> categories (category_id));
diesel::joinable!(categories_translations -> languages (language_id));
diesel::joinable!(dish_category -> categories (category_id));
diesel::joinable!(dish_category -> dishes (dish_id));
diesel::joinable!(dish_ingredients -> dishes (dish_id));
diesel::joinable!(dish_ingredients -> ingredients (ingredient_id));
diesel::joinable!(dishes_translations -> dishes (dish_id));
diesel::joinable!(dishes_translations -> languages (language_id));
diesel::joinable!(ingredients_allergenes -> allergenes (allergene_id));
diesel::joinable!(ingredients_allergenes -> ingredients (ingredient_id));
diesel::joinable!(ingredients_translations -> ingredients (ingredient_id));
diesel::joinable!(ingredients_translations -> languages (language_id));
diesel::joinable!(notes_archive -> dishes (dish_id));
diesel::joinable!(order_items -> dishes (dish_id));
diesel::joinable!(orders_archive -> dishes (dish_id));
diesel::joinable!(postazioni_categories -> categories (category_id));
diesel::joinable!(postazioni_categories -> postazioni (postazione_id));
diesel::joinable!(postazioni_translations -> languages (language_id));
diesel::joinable!(postazioni_translations -> postazioni (postazione_id));

diesel::allow_tables_to_appear_in_same_query!(
    allergenes,
    allergenes_translations,
    categories,
    categories_translations,
    dish_category,
    dish_ingredients,
    dishes,
    dishes_translations,
    ingredients,
    ingredients_allergenes,
    ingredients_translations,
    languages,
    notes_archive,
    order_items,
    orders,
    orders_archive,
    postazioni,
    postazioni_categories,
    postazioni_translations,
);

Then I tried diesel_ext > src/db/db_models.rs and got:

thread 'main' panicked at C:\Users\raikoug\.cargo\registry\src\index.crates.io-6f17d22bba15001f\diesel_cli_ext-0.3.13\src/main.rs:216:10:
Something went wrong reading the file.: Error { kind: InvalidData, message: "stream did not contain valid UTF-8" }

In my tables there are translations for italian, french and german, thus character like these are expected:

รข รช รต รถ ร  รจ รฌ รฒ รน รก รฉ รญ รณ รบ รŸ

and their uppercase counterparts. Could this be the problem?

This with backtrace 1 and full

stack backtrace:
   0:     0x7ff65dbb2403 - <unknown>
   1:     0x7ff65dbc832d - <unknown>
   2:     0x7ff65dbb0b21 - <unknown>
   3:     0x7ff65dbb220a - <unknown>
   4:     0x7ff65dbb4349 - <unknown>
   5:     0x7ff65dbb400b - <unknown>
   6:     0x7ff65dbb4834 - <unknown>
   7:     0x7ff65dbb4705 - <unknown>
   8:     0x7ff65dbb2a99 - <unknown>
   9:     0x7ff65dbb4414 - <unknown>
  10:     0x7ff65dbd0c37 - <unknown>
  11:     0x7ff65dbd10f3 - <unknown>
  12:     0x7ff65db7dddc - <unknown>
  13:     0x7ff65db87956 - <unknown>
  14:     0x7ff65db86b3c - <unknown>
  15:     0x7ff65dbad008 - <unknown>
  16:     0x7ff65db86b28 - <unknown>
  17:     0x7ff65dbcd920 - <unknown>
  18:     0x7ffc7ea0257d - BaseThreadInitThunk
  19:     0x7ffc7faaaa58 - RtlUserThreadStart

Fails on schema inside `mod`

Please make it work with this:

pub mod foo {
    table! {
        ...
    }
}

Currently, it panics:

thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1'

Several types generated by print-schema for MySQL not recognized

When running print-schema against a MySQL db and then diesel_cli_ext, the following are not recognized:

  • Decimal
  • Unsigned<Decimal>
  • Nullable<Decimal>
  • Unsigned<Integer>
  • Nullable<Unsigned<Integer>>
  • Datetime
  • Nullable<Datetime>
  • Bit

BTW, thanks for the great tool!

Auto-import Uuid type

Currently, chrono::NaiveDateTime is auto-imported, but not the Uuid type.

Adding use uuid::Uuid automatically would be great.

deprecation warning for #[table_name] macro attribute

warning: #[table_name] attribute form is deprecated
  = help: use `#[diesel(table_name = coin_transaction)]` instead

I'm getting this all over my project, I guess the macro has changed, but I'm not sure how would we handle the update here, maybe a cli flag specifying a version?

Generate Custom Types for certain Columns from tables

I have a enum type defined in my column of a table.when i use diesel_ext > src/models.rs I ran into a issue of {MyEnumType} is not recognized. Please feel free to expand the HashMap.This could provide good hints: https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html is there any way to allow the custom types.There's no problem in generating schema as it finds the enum and creates some Empty structs for enums.Later i can use diesel-derive-enums for working with enums

Getting a thread 'main' panicked at 'Date is not recognized.

Getting the below err when running diesel_ext cmd

thread 'main' panicked at 'Date is not recognized. Please free feel to expand the HashMap. This could provide good hints: https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html', /Users/rajesh/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel_cli_ext-0.1.12/src/parse.rs:98:24
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Support Namespaced Schemas

First off, thanks for such a wonderful tool! It really helps speed up the prototyping process.

I am using a schema other than public in Postgres. Running diesel print-schema produces a schema.rs similar to the following:

pub mod my_schema {
    table! {
        my_schema.my_table (my_pk) {
            my_pk -> Int4,
            some_field -> Text,
        }
    }
// ...
}

Trying to dump the models from this produces the following panic:

thread 'main' panicked at ' is not recognized. Please free feel to expand the HashMap. This could provide good hints: https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html', /Users/aaron/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel_cli_ext-0.1.13/src/parse.rs:104:24
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

Moving the table declaration in schema.rs outside of the module produces what I'd expect. As a workaround, I can move all of the tables outside of the my_schema module, remove the my_schema prefix, outdent all table declarations to the left margin, generate the models, then do any other updates by hand.

Fails on schema containing `pub mod`

diesel_ext panics when used against the next Diesel schema:

// @generated automatically by Diesel CLI.

pub mod sql_types {
    #[derive(diesel::sql_types::SqlType)]
    #[diesel(postgres_type(name = "pyth_asset_type"))]
    pub struct PythAssetType;
}

diesel::table! {
    use diesel::sql_types::*;
    use super::sql_types::PythAssetType;

    pyth_product (id) {
        id -> Int2,
        symbol -> Varchar,
        asset_type -> PythAssetType,
        base -> Varchar,
        quote_currency -> Varchar,
        description -> Varchar,
        product_account -> Varchar,
        price_account -> Varchar,
    }
}

Panic message:

thread 'main' panicked at 'index out of bounds: the len is 7 but the index is 8', src/parse.rs:157:38

So, this index is out of bounds:

struct_name = propercase(vec[4 + indent_depth]);

At that point indent_depth == 4.

Suggestion: Allow using custom type for certain table columns

I have several instances of this pattern:
Table foo has a column that's TEXT NOT NULL, but it represents an enum in Rust, which is serialized as string in pg.
So the previous handwritten model struct contained an enum type for this field, but diesel_ext will generate String for it (of course).
In another similar use case, there is a typesafe newtype wrapper around a String field, which should be used in the model struct.
With the -M flag there is no way to override it, only to map ALL such types to another.
Please allow specifying custom Rust types for model fields, like:
--type "foo.bar MyEnum" --type "foo.baz MyStringWrapper".

That would be awesome, and one step closer to fully generated models.

Suggestion: Group cmd line flags into subcommands

Currently, the flags for model and proto generation are displayed in 1 list (even intermixed), making it confusing to read:

> diesel_ext -h
Usage: diesel_ext FILE [options]

Options:
    -s, --schema-file PATH
                        set file path
    -h, --help          Print this help menu
    -m, --model         model output
    -M, --map "SOURCE-TYPE DEST-TYPE"
                        type mappings that could be set multiple times e.g.
                        --map "BigInt iccc"
    -i, --into_proto    into_proto output
    -f, --from_proto    from_proto output
    -c, --class_name    proto class name
    -d, --derive        set struct derives
    -t, --add_table_name 
                        add #[table_name = x] before structs

Small suggestion:
Separate model and proto generation into 2 separate sub-commands that each take their own scoped flags.
(It's easy to do with structopt_derive using enums.)

If that's impossible with getopts, please at least separate the flags for both subcommands into separate lists in the -h output :)

thread 'main' panicked at 'index not found'

I run diesel_ext -m > src/models.rs, and print errror:

thread 'main' panicked at 'index not found', /Users/intfish/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel_cli_ext-0.3.10/src/main.rs:187:33

#[derive(Queryable, Debug{trace1})]

This commit introduced the line which excludes "id" from PKS list:

if pks_list.len() > 1 || pks_list[0] != "id".to_string() {

Why is that the case? All my tables have id as a primary key, so I'm getting #[derive(Queryable, Debug{trace1})] instead of the correct derives and #[primary_key(id)].

Suggestion: Add jsonb support

Thanks for this great crate!

Currently this generates:

#[derive(Queryable, Debug, Identifiable)]
#[primary_key(key)]
pub struct Setting {
    pub key: String,
    pub value: Jsonb,
}

for:

table! {
    settings (key) {
        key -> Varchar,
        value -> Jsonb,
    }
}

which doesn't compile because Jsonb isn't imported.

It would be great if it instead generated the correct serde type

#[derive(Queryable, Debug, Identifiable)]
#[primary_key(key)]
pub struct Setting {
    pub key: String,
    pub value: serde_json::Value,
}

Allow injecting imports

Please allow injecting imports, similar to diesel_cli, e.g.:
--import-types="crate::models::UserEventResourceType".
Short flag: -i

Allow specifying custom type mappings

Here is a diff between the generated models.rs and after I manually adapted it to how I need it:

6c6,12
< use chrono::NaiveDateTime;
---
> // <manually-inserted>
> use chrono::{DateTime, NaiveDate, Utc};
> use diesel::Queryable;
> use uuid::Uuid;
> 
> use crate::models::org::UserEventResourceType;
> // </manually-inserted>
119c125
<     pub due_date: NaiveDateTime,
---
>     pub due_date: DateTime<Utc>,
153,154c159,160
<     pub name: /* TODO: unknown type Citext */,
<     pub description: Option</* TODO: unknown type Nullable<Citext> */>,
---
>     pub name: String,
>     pub description: Option<String>,
156c162
<     pub created: Option<NaiveDateTime>,
---
>     pub created: Option<DateTime<Utc>>,
932c938
<     pub resource_type: /* TODO: unknown type User_event_resource_type */,
---
>     pub resource_type: UserEventResourceType,
946,947c952,953
<     pub old_value: Option<Jsonb>,
<     pub new_value: Option<Jsonb>,
---
>     pub old_value: Option<serde_json::Value>,
>     pub new_value: Option<serde_json::Value>,

As you can see, in order to fully generate this, I'd need to

  1. Be able to specify custom imports
  2. Be able to specify custom type mappings. E.g. I want to map Citext to String (and Nullable<Citext> to Option<String>), Timestamptz to DateTime<Utc> (instead of NaiveDateTime), and User_event_resource_type to my custom enum type UserEventResourceType (generated by diesel-derive-enum), and Jsonb to serde_json::Value.

I suggest a similar format for specifying these, as with diesel_cli: Via cmd flags of the same name (e.g. --import-types="crate::models::org::UserEventResourceType"):
http://diesel.rs/guides/configuring-diesel-cli/
Or with a config file. But please also have the cmd line flags. And option to specify the config file path with --config-file.

Suggestion: Add #[primary_key(col)] when primary key column is not named `id`

If I have a schema like:

table! {
	use crate::schema_imports::*;

	spatial_ref_sys (srid) {
		srid -> Int4,
		auth_name -> Nullable<Varchar>,
		auth_srid -> Nullable<Int4>,
		srtext -> Nullable<Varchar>,
		proj4text -> Nullable<Varchar>,
	}
}

diesel_cli_ext generates:

image

but Identifiable panics because if no primary key is specified, it assumes it must be named id.
Please generate the necessary attribute when the pkey is not named id. In this case:

#[primary_key(srid)]

Note: Primary keys can also be composite. In the schema, it will look like

table_name (col1, col2) {

which should become:

#[primary_key(col1, col2)]

`#[primary_key(..)]` is not generated

table! {
    use crate::diesel_types::org::*;

    foos (name) {
        name -> Varchar,
    }
}
pub struct Foo {
    pub name: String,
}

It should have #[primary_key(name)].

Also output #[table_name = ".."]

Please also output #[table_name = ".."], the table name can be inferred from the table!{} definition.
So that deriving QueryableByName works!

Type alias issue in Diesel 2.0

Run the command to generate schema.rs

diesel print-schema --database-url=mysql://root:root@localhost/test > src/schema.rs

In the generated src/schema.rs file, type alias Bigint used as BigInt in diesel::sql_types::*, then
in the .proto file message filed is not recognized like this:

/* TODO: unknown type Bigint */ id = 1;

Output of diesel_ext --proto > myproto.proto

diesel_ext --proto > myproto.proto
Bigint is not recognized. Please feel free to expand the HashMap. This could provide good hints: https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html
...
...
...

Support Postgres Arrays

Postgres arrays appear in the schema as: Array<T> and should be translated to a Vec.

Also, the mapping feature does not seem to support generics.

I tried --map "Array<Int8> Vec<i64>" and --map "Array" "Vec".

Would be great to get support for this.

Suggestion: per-table derive modification

Related to #30 and #27.
It would be nice if one could modify the derives for certain tables!
In a add/remove kind of way:
--derive-mod "table_name +AdditionalTrait"
--derive-mod "table_name -DontDeriveThisTrait"
This modifies the list of derives specified with -d, for the given table_name's struct.

thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1'

> RUST_BACKTRACE=full diesel_ext 
thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', /rustc/07e0c3651ce2a7b326f7678e135d8d5bbbbe5d18/src/libcore/slice/mod.rs:2681:10
stack backtrace:
   0:     0x55e071a215cb - backtrace::backtrace::libunwind::trace::hb6a132d591ca7611
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
   1:     0x55e071a215cb - backtrace::backtrace::trace_unsynchronized::h950d223225e78416
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
   2:     0x55e071a215cb - std::sys_common::backtrace::_print::h3121d410df984e93
                               at src/libstd/sys_common/backtrace.rs:47
   3:     0x55e071a215cb - std::sys_common::backtrace::print::hf99b73b5fb88a9e8
                               at src/libstd/sys_common/backtrace.rs:36
   4:     0x55e071a215cb - std::panicking::default_hook::{{closure}}::h43b3f1ecc5ba538a
                               at src/libstd/panicking.rs:200
   5:     0x55e071a212a7 - std::panicking::default_hook::hdf2c0ec346c75d51
                               at src/libstd/panicking.rs:214
   6:     0x55e071a21c90 - std::panicking::rust_panic_with_hook::haa2a258b70170199
                               at src/libstd/panicking.rs:477
   7:     0x55e071a21812 - std::panicking::continue_panic_fmt::h409559866455d39b
                               at src/libstd/panicking.rs:384
   8:     0x55e071a216f6 - rust_begin_unwind
                               at src/libstd/panicking.rs:311
   9:     0x55e071a3673d - core::panicking::panic_fmt::hffa19936292f87b2
                               at src/libcore/panicking.rs:85
  10:     0x55e071a366f5 - core::panicking::panic_bounds_check::hafbd9da0a9cd28ad
                               at src/libcore/panicking.rs:61
  11:     0x55e071a13756 - diesel_ext::parse::parse::hd25d9909a3d8f494
  12:     0x55e071a168cb - diesel_ext::main::h41398fab80d59648
  13:     0x55e071a13fd3 - std::rt::lang_start::{{closure}}::ha34c231847b61f02
  14:     0x55e071a216e3 - std::rt::lang_start_internal::{{closure}}::h5343634e8743e227
                               at src/libstd/rt.rs:49
  15:     0x55e071a216e3 - std::panicking::try::do_call::hde91867848d0925c
                               at src/libstd/panicking.rs:296
  16:     0x55e071a2375a - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:82
  17:     0x55e071a2219d - std::panicking::try::h9f691870ea820298
                               at src/libstd/panicking.rs:275
  18:     0x55e071a2219d - std::panic::catch_unwind::he819022b5b88969a
                               at src/libstd/panic.rs:394
  19:     0x55e071a2219d - std::rt::lang_start_internal::hc5b82bd8379c33f1
                               at src/libstd/rt.rs:48
  20:     0x55e071a17262 - main
  21:     0x7f434228af8a - __libc_start_main
  22:     0x55e071a0f5ba - _start
  23:                0x0 - <unknown>

Crashes with tabs as indentation

With the latest binary version:

table! {
	foo (id) {
		id -> Int8,
		bar -> Text,
	}
}
> RUST_BACKTRACE=1 diesel_ext
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4', /rustc/c6e9c76c59e3c10acd63ca9ec157a8894ea1a068/src/libcore/slice/mod.rs:2715:10
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.35/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.35/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:47
   3: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:36
   4: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:200
   5: std::panicking::default_hook
             at src/libstd/panicking.rs:214
   6: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:477
   7: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:384
   8: rust_begin_unwind
             at src/libstd/panicking.rs:311
   9: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
  10: core::panicking::panic_bounds_check
             at src/libcore/panicking.rs:61
  11: diesel_ext::parse::parse
  12: diesel_ext::main
  13: std::rt::lang_start::{{closure}}
  14: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:49
  15: std::panicking::try::do_call
             at src/libstd/panicking.rs:296
  16: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:80
  17: std::panicking::try
             at src/libstd/panicking.rs:275
  18: std::panic::catch_unwind
             at src/libstd/panic.rs:394
  19: std::rt::lang_start_internal
             at src/libstd/rt.rs:48
  20: main
  21: __libc_start_main
  22: _start

It works when I replace the tabs with spaces.
Ideally it should work with tabs, too :)

Suggestion: Better singularization of table names

I noticed when you have a table named like foo_properties it will generate struct FooPropertie.
There are ways to get the singular form from a plural, but no rust crates I'm aware of. But maybe we can find a suitable english dict text file with the necessary info.

In the meantime, as a quick fix heuristic, I suggest to do this:
If the table name ends in "ies", replace it by "y", not "ie".
This solves all the cases I've come across in my usage of diesel_cli_ext.

Although there are other cases, e.g. singular "ox", plural "oxen" that can't be solved without a lookup.

:)


To be maximally useful, diesel_cli_ext should strive to get to a point where it requires no manual post-processing.


EDIT: Another temporary but totally sufficient fix would be to allow passing singular forms in on the cmd line as flags!
-p 'ox oxen' (p for "plural")
-p 'property properties'
So it will not just work with a table called "properties", but for ALL tables ending in "properties"!
E.g. this mapping will work for "foo_properties" and "bar_properties".
I think this is the best solution for now.

add_table_name with diesel v2 is missing diesel prelude

Working with the following schema:

// @generated automatically by Diesel CLI.

diesel::table! {
    customers (id) {
        id -> Int4,
        #[max_length = 50]
        name -> Varchar,
    }
}

How to reproduce:

  • With diesel v2, use diesel_ext to generate models with table names: diesel_ext model -t > src/models.rs

What is observed

// Generated by diesel_ext

#![allow(unused)]
#![allow(clippy::all)]

use bigdecimal::BigDecimal;
use chrono::offset::Utc;
use chrono::DateTime;
use chrono::NaiveDate;
#[derive(Queryable, Debug)]
#[diesel(table_name = customers)]
pub struct Customer {
    pub id: i32,
    pub first_name: String,
    pub name: String,
}

When building:

$ cargo build
   Compiling myproject v0.1.0 (/workspace/myproject)
error: cannot find derive macro `Queryable` in this scope
  --> src/models.rs:10:10
   |
10 | #[derive(Queryable, Debug)]
   |          ^^^^^^^^^
   |
   = help: consider importing one of these items:
           crate::Queryable
           diesel::Queryable

error: cannot find attribute `diesel` in this scope
  --> src/models.rs:11:3
   |
11 | #[diesel(table_name = customers)]
   |   ^^^^^^
   |
   = note: `diesel` is in scope, but it is a crate, not an attribute

error: could not compile `myproject` (lib) due to 2 previous errors

What was expected

Code that builds, which includes a

use diesel::prelude::*

Insert spaces between derives

Currently it generates #[derive(Queryable,Debug)] but it's idiomatic to have a space after the comma like #[derive(Queryable, Debug)].
Please make this the default :)

diesel_ext -m failing to read src/schema.rs

Using latest version of diesel and diesel_cli_ext

I ran diesel print-schema > src/schema.rs without issue.
When I run diesel_ext > src/models.rs I get the following error:

thread 'main' panicked at 'Something went wrong reading the file.: Error { kind: InvalidData, message: "stream did not contain valid UTF-8" }', C:\Users\Rory.cargo\registry\src\github.com-1ecc6299db9ec823\diesel_cli_ext-0.3.7\src/main.rs:192:10
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Integer, SmallInt, Float not recognized

Unless I pass -M "Integer i32" -M "SmallInt i16" -M "Float f32", diesel_cli_ext complains about not knowing these types and inserts comments instead.
These should be supported by default, because they are standard diesel types,
generated by running diesel print-schema on my sqlite db.

Composite primary keys result in invalid model code

Schema:

table! {
    videos_tags (tag_id, video_id) {
        video_id -> Uuid,
        tag_id -> Uuid,
    }
}

Generated model:

#[derive(Queryable, Debug)]
#[primary_key(tag_id, video_id)];
pub struct VideosTag {
    pub video_id: Uuid,
    pub tag_id: Uuid,
}

Note the extra semicolon after the attribute.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.