Giter VIP home page Giter VIP logo

ormx's People

Contributors

bram209 avatar clouds56 avatar hasezoey avatar nyxcode avatar otak avatar punie 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  avatar  avatar  avatar

ormx's Issues

unresolved import `syn::export`

Hello i want to use ormx = "0.2.0" because I'm working with sql 0.4 and actix and I can't update still to 0.5.

I'm getting this error from macros...

error[E0432]: unresolved import syn::export
--> /Users/macbookpro/.cargo/registry/src/github.com-1ecc6299db9ec823/ormx-macros-0.1.8/src/backend/common/table.rs:3:10
|
3 | use syn::export::TokenStreamExt;
| ^^^^^^ could not find export in syn

I'm using Rust 1.50

thanks for your help...

Unable to install ormx with sqlite

Hello,

I tried to install ormx to use with sqlx and sqlite, it didn't work, it looks like there might be some dependency issues? Failed on Windows and Linux:

$ cargo new ormx-test && cd ormx-test && cargo add ormx sqlx -F sqlx/sqlite -F ormx/sqlite

error: failed to select a version for the requirement `ahash = "^0.6.2"`
candidate versions found which didn't match: 0.8.6, 0.8.5, 0.8.4, ...
location searched: crates.io index
required by package `sqlx-core v0.5.1`
    ... which satisfies dependency `sqlx-core = "^0.5.1"` of package `sqlx v0.5.1`
    ... which satisfies dependency `sqlx = "^0.5"` of package `ormx v0.10.0`
    ... which satisfies dependency `ormx = "^0.10.0"` of package `ormx-test v0.1.0 (/home/max/git/ormx-test)`
perhaps a crate was updated and forgotten to be re-vendored?

`insert` taking a `&mut Connection` instead of an `impl Executor`

Hello!

I started experimenting with this crate and so far, I love it!

There is one thing that I'm curious about though:
All methods on Table take a db: impl Executor<...> argument except for insert that takes a db: &mut <Db as Database>::Connection.
Is there any reason for that? I find it quite annoying to be able to simply pass my &PgPool anywhere except for insert where I need to &mut pool.acquire().await?.

Dynamic field updates

if Dynamic updates (which can't use Patch) are really a common usecase... - NyxCode

We can use one full update query to compile check, and small generated queries for modified fields.

We must have the struct of all Option fields, with all by default None and changed are Some. Nullable fields are Option<Option<T>>.

Possible use case:

let mut update = User::new_update();
update.name = Some("asdf".to_owned());
update.update(&db);

And this use case might be also possible, but not necessary:

let mut update = User::new_update();
update.set_name("asdf".to_owned());
update.update(&db);

Here we use setters to make the variable of Some<T>. It needs to generate a lot of functions, which might be redundant? But it looks better.

Discussion of it took place in the Discord.

"unmapped" property in the #[derive(Table)] struct

I have an "unmapped" (to DB, meaning table does not contain a corresponding column) property User.phones in my struct:

use serde::{Deserialize, Serialize};
use ormx::Table;

#[derive(Serialize, Deserialize, Default, Debug, Clone, Table)]
#[ormx(table = "users", id = id, insertable)]
pub struct User {
    #[ormx(default)]
    pub id: i32,
    pub username: String,
    pub password: String,
    #[ormx(default)]
    pub phones: Vec<Phone>,
}

On compile it says: error returned from database: 1054 (42S22): Unknown column 'phones' in 'field list'

As we discussed in the Discord, it needs something like #[ormx(skip)].

Discussion: Additional features, road towards a full-fledged ORM

Hey,

I've been thinking a lot about that stuff lately and I honestly think ormx is the perfect candidate to build on and iterate towards a full-fledged ORM.

The features I'd personally like to see are more or less the featureset of Sequelize, to be more accurate:

  1. Schema definition & synchronization
  2. Migrations [done on sqlx side]
  3. Free queries with convenience methods (see Sequelize Model Finders)

Number 3 would be pretty much just additional things to implement on Table and would be the most trivial
Number 1 is a tough one, as we need to find a way to synchronize tables before sqlx compiles and checks our queries.

For instance on an empty database, a model would try to compile its queries, but the table doesn't exist yet so compilation would fail.

I'm currently experimenting here: https://github.com/OtaK/ormx/tree/otak/schema-sync

Quote identifiers in generated queries

On my current project, our naming standards require our table names to be singular, which led to the following issue in the case of the user table:

#[derive(Table)]
#[ormx(table = "user", id = id)]
struct User {
    #[ormx(column = "id")]
    id: Uuid,
    email: String,
    password_hash: String,
}

yields the following errors:

error: error returned from database: column "id" does not exist
  --> server/src/user.rs:31:10
   |
31 | #[derive(Table)]
   |          ^^^^^
   |
   = note: this error originates in the macro `$crate::sqlx_macros::expand_query` (in Nightly builds, run with -Z macro-backtrace for more info)

error: error returned from database: syntax error at or near "user"
  --> server/src/user.rs:31:10
   |
31 | #[derive(Table)]
   |          ^^^^^
   |
   = note: this error originates in the macro `$crate::sqlx_macros::expand_query` (in Nightly builds, run with -Z macro-backtrace for more info)

The message is not ideal but I managed to figure out that it is indeed the fact that user is a reserved name and that it should be quoted.
My current workaround (I'm using Postgres) is the following #[ormx(table = "\"user\"", id = id)] and it does work but I wonder if ormx should not defensively quote identifiers by default.

I understand that it requires custom logic from different backends (MySQL requires backticks `user` while Postgres requires double-quotes "user") so it is likely non-trivial to implement.
At the very least, maybe warning about that potential issue in documentation and recommending quoting identifiers in the derive macro attributes would be the way to go in the short-term.

bug: syn removed export

Linking to the issue on Syn since a number of libraries are affected -> https://github.com/dtolnay/syn/issues/956.

Having trouble compiling after installing fresh, getting 2 issues from the syn change

 use syn::export::TokenStreamExt;
                ^^^^^^ could not find `export` in `syn`

And

out.append_all(quote!(as #ty))
       ^^^^^^^^^^ method not found in `TokenStream2`

EDIT: to clarify both these are in ormx-macros 1.8

Batched inserts

Hello! Loving the library, thank you so much!

The only thing I'm missing for my use case is batched inserts. I need to ingest millions of rows into a DB as quickly as possible, and non-batched inserts would be an issue. I know sqlx supports it, so I imagine it shouldn't be that difficult to implement. I could take a crack at it myself, if you're interested - although I am not very experienced with sqlx.

What do you think? Personally, it would mean I would never have to look at other ORMs again :)

Cheers, have a great day!

Can not use sqlx FromRow or Encode with ormx

Sorry for opening another issue :/
When I try add FromRow derive to my struct at the same time as Table from ormx I got:

error: proc-macro derive panicked
  --> src/models/users/list.rs:38:41
   |
38 | #[derive(Debug, Serialize, Deserialize, FromRow, ormx::Table, Clone, Eq, PartialEq)]
   |                                         ^^^^^^^
   |
   = help: message: called `Result::unwrap()` on an `Err` value: Error("expected literal")

And when I try add Encode I got:

error: expected literal
  --> src/models/users/list.rs:39:1
   |
39 | #[ormx(table = "users.list", id = id, insertable)]

Can sqlx and ormx coexist at the same time on the same struct?

Discussion: get_many getters are impractical

Hey!

I've been trying to work with the get_many getters lately and they're essentially useless IMO because:

  • They take a single argument and perform a = test on it in the SQL query
  • They will return a single row in cases you're searching something like a UNIQUE index.

Meaning that you will have to resort to manual SQL queries if you're doing something as trivial as looking multiple records by a batched id/unique key.

I suggest changing the query in get_many to use a IN() statement instead of = and accepting a slice of arguments instead of a single one as it would semantically work as well.

But of course, as it'd be a breaking change, I'm triggering a discussion here.

I can take care of the implementation.

example is broken

I'm trying to use ormx and I can't even get the example to run. If I use the schema

create table users (
  id serial4 primary key,
  first_name varchar,
  last_name varchar,
  email varchar,
  last_login timestamp
);

and just a simple cargo build I get a bunch of errors.

error[E0308]: mismatched types
  --> src/schema.rs:21:10
   |
21 | #[derive(ormx::Table)]
   |          ^^^^^^^^^^^ expected `u32`, found `i32`
   |
   = note: this error originates in the macro `$crate::sqlx_macros::expand_query` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
  --> src/schema.rs:21:10
   |
21 | #[derive(ormx::Table)]
   |          ^^^^^^^^^^^ expected struct `std::string::String`, found enum `Option`
   |
   = note: expected struct `std::string::String`
                found enum `Option<std::string::String>`
   = note: this error originates in the macro `$crate::sqlx_macros::expand_query` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
  --> src/schema.rs:21:10
   |
21 | #[derive(ormx::Table)]
   |          ^^^^^^^^^^^ expected `i32`, found `u32`
   |
   = note: this error originates in the derive macro `ormx::Table` (in Nightly builds, run with -Z macro-backtrace for more info)

because these are type mismatches in the compiler, they're almost impossible to debug. I'm using the latest postgres.

Add a mechanism to describe partial updates

I think it would be valuable to add a mechanism for partial updates to ormx similar to what the AsChangeset derive from diesel does.

There are however various possible solutions, the most straightforward one being to require all fields in Patch structs to be wrapped in an Option:

  • None would not perform the update for the field
  • Some(None) would set a nullable field to NULL
  • Some(Some(val)) would set a nullable field to val
  • Some(val) would set a non-nullable field to val

I started discussing this on the discord and @NyxCode kindly responded with interesting alternative ideas that I think are very much worth exploring. I'm quoting their message here to help start the discussion:

yeah so I did think about this a bit in the past.
I found that in most cases, it's most comfortable to avoid having to deal with nested Options and stuff like you would have to with diesel. That's also what I needed the most at the time.
I do think supporting this would be great though! Would having an attribute like #[ormx(ignore_if_none)] (that name is mediocre, im sure we can come up with something better) work when deriving Patch?
I guess we would need something a bit more sophisticated when we still want to be able to derive Patch for the same struct which represents the Table
Regardless, I'd definetely appraciate if you would open an issue for this, possibly outlining possible approaches like this

Using attribute `default` with `custom_struct` produces strange compile errors

Sorry for not having a more minimal example (I might post one soonish) but this should be fairly straightforward if not minimal.

This code gives : wildcard overrides are only allowed with an explicit record type, e.g. query_as!() and its variants

#[derive(Debug, ormx::Table)]
#[ormx(
    table = "Account",
    id = id,
    insertable,
    deletable
)]
pub struct Account {
    #[ormx(default, get_many=get_many_by_id)]
    id: i32,
    #[ormx(get_one, get_many=get_many_by_email, set)]
    email: String,
    #[ormx(set)]
    password_hash: String,
    #[ormx(default)]
    creation_time: OffsetDateTime,
    #[ormx(default, custom_type, set)]  //<-- removing the default attribute fixes the compile error
    account_type: AccountType,
    #[ormx(default, set)]
    suspended: bool,
}

Here's the custom type in question :

#[derive(
    PartialEq, Debug, Copy, Clone, sqlx::Type, Serialize, Deserialize, AsRefStr, IntoStaticStr,
)]
#[sqlx(type_name = "AccountType")]
pub enum AccountType {
    Temporary,
    Guest,
    Admin,
}

And here's the database schema I'm compiling against :

CREATE TABLE Account
(
    id            SERIAL UNIQUE,
    email         TEXT PRIMARY KEY,
    password_hash TEXT                     NOT NULL,
    creation_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
    account_type  AccountType              NOT NULL DEFAULT 'Temporary',
    suspended     BOOLEAN                  NOT NULL DEFAULT false
);

request: add conditional_query! macro?

Would it be possible to add a conditional_query! macro? I use query! from sqlx much more than query_as! so I'd love to be able to replicate some of the possibilities with filtering and pattern matching that you have enabled, but with the other macro.

sqlite

Why not support sqlite

Support for `GENERATED ALWAYS AS IDENTITY` columns

As far as I know, it is generally considered best practice to enforce that the ID column will always be generated. The GENERATED ALWAYS modifier allows this. Additionally, the AS IDENTITY modifier creates the numeric sequence.

The documentation for deriving Table states that:

ormx will generate a helper struct for inserting rows into the database when using #[ormx(insertable)].
This struct will contain all fields of the struct, except

  • the ID
  • fields annotated with #[ormx(default)]

since the value of these fields will be generated by the database.

However, the implementation of the derive macro for the Insertable trait does not follow this:

let insert_fields: Vec<&TableField<PgBackend>> = table.insertable_fields().collect();

pub fn insertable_fields(&self) -> impl Iterator<Item = &TableField<B>> + Clone {
self.fields.iter().filter(|field| !field.default)
}

I believe insertable_fields should also exclude the ID, or maybe the ID should be marked as having a default value by setting the default field to true.

syntax error at or near "desc"

Hi!
Why I try to use ormx with my model:

#[derive(Debug, Serialize, Deserialize, FromRow, Encode, Eq, PartialEq, Clone, ormx::Table)]
#[ormx(table = "users.list", id = id, insertable)]
pub struct User {
    #[serde(default)]
    pub id: i32,
    pub login: Option<String>,
    // #[serde(skip)]
    pub password: Option<String>,
    pub name: Option<String>,
    pub subname: Option<String>,
    pub phone: Option<String>,
    pub desc: Option<String>,
    pub access_card: Option<i32>,
    pub owner_id: Option<i32>,
    pub register_date: Option<chrono::NaiveDateTime>,
}

I got an error:

error: error returned from database: syntax error at or near "desc"

I think the problem is that you don't escape columns names and desc is a keyword in PostgreSQL :/.
I think this should be easy to fix?

Why boxed Future and stream?

I'm interested why ormx chose to return boxed future and stream instead of impl Future and impl Stream respectively?

Table:: All + Paginated + get_many queries lack "order by"

Firstly, thanks for a useful crate.

I have encountered an issue that seems to affect Table::all / all_paginated/ stream-all / stream_all_paginated / get_many. There appears to be no way currently to specify the order of the results and the order varies after updates or inserts, this makes the paginated functions not too useful. If I am mistaken could the documentation be changed to show how.

I am using postgres but as SQL does not guarantee an ordering for a select, this would apply to all databases. Sql standard states "If an is not specified, then the ordering of the rows of Q is implementation-dependent."

Would there be a way to specify at the Table level an "order by"

#[ormx(table = "...",order="id asc")]
or for several
#[ormx(table = "...",order="firstname asc, lastname asc")]

#[ormx(get_many,order="firstname asc, lastname asc"))]:

or if not then could you add an example to do order by, offset and limit using the conditional_query_as macro, and maybe clarify in the methods mentioned that the order is not guaranteed.

Thanks

Upgrade sqlx from 0.6 to 0.7

I am trying to update sqlx to 0.7, but Insert trait let mut tx = db.begin().await?; db: impl Executor has no begin method on sqlx 0.7

         db: &mut <Db as Database>::Connection,
         row: impl Insert<Table = Self>,
     ) -> BoxFuture<Result<Self>> {
-        row.insert(db)
+        row.insert(&mut *db)
     }

     /// Insert a row into the database, returning the inserted row.
-    fn insert<'a, 'c: 'a>(
+    fn insert(
         self,
-        db: impl Executor<'c, Database = Db> + 'a,
-    ) -> BoxFuture<'a, Result<Self::Table>>;
+        db: &mut impl sqlx::Connection<Database = Db, Options=sqlx::mysql::MySqlConnectOptions>,
+    ) -> BoxFuture<Result<Self::Table>>;
 }

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.