Giter VIP home page Giter VIP logo

rust-sqlb's Introduction

sqlb is a simple and expressive SQLBuilder for Rust for sqlx, focusing on PostgreSQL (for now).

UPDATE 2023-11-21: sqlb 0.4.x now uses sqlx 0.7.x

NOTE 2023-11-31: I am currently exploring integration synergy opportunities with sea-query, as they share similar "SQL builder" principles. Some initial integration might appear in sqlb 0.5.x. Feel free to share your perspective on our discord: https://discord.gg/W2besKCzjx

Key Concepts

  • Simple - Focused on providing an expressive, composable, and reasonably typed scheme to build and execute (via sqlx for now) parameterized SQL statements. The goal is NOT to abstract SQL but to make it expressive and composable using Rust programmatic constructs.
    • NOT a database executor/driver (Uses sqlx as an SQL executor)
    • NOT an ORM, just an SQL builder.
    • NOT a full replacement for sqlx. Dropping into sqlx when sqlb is too limiting is a valid pattern.
  • Expressive - From arbitrary typed data in and out (list of names/values) to struct and mapping rules.
  • Focused
    • sqlx - The first "database executor" provided will be sqlx.
    • PostgreSQL - First database support will be Postgres (via sqlx). Additional database support may be added based on interest and pull requests.
  • sqlb goal is to have a highly ergonomic API at a minimum performance cost. However, using sqlx directly for high batch commands or more advanced use-cases is an encouraged approach.
  • Prepared Statement ONLY!

Additional Notes

NOTE 1: SQL Builders are typically not used directly by application business logic, but rather to be wrapped in some Application Model Access Layer (e.g., DAOs or MCs - Model Controller - patterns). Even when using ORMs, it is often a good code design to wrap those access via some model access layers.

NOTE 2: sqlb has the feature runtime-tokio-rustls enabled by the sqlx crate. Do not enable a conflicting runtime feature when adding sqlx to your project.

NOTE 3: During the 0.y.z period, API changes will result in .y increments.

Goals for first 0.y.z releases:

  • sqlx - Only plan to be on top of sqlx.
  • PostgreSQL - Focus only on PostgreSQL.
  • Macros - Adding macros to keep things DRY (but they are optional. All can be implemented via trait objects)
  • Limitations - Currently, to make types work with sqlb they must implementsqlb::SqlxBindable trait. The aim is to implement SqlxBindable for all sqlx types and allowing app code to implement SqlxBindable for their specific types. If there are any external types that should be supported but are not currently, please feel free to log a ticket. A good pattern for this type is for sqlb to add type support by features (e.g., see chrono_support sqlb feature).

Early API Example (just conceptual for now)

// `sqlx::FromRow` allows to do sqlx_exec::fetch_as...
// `sqlb::Fields` allows to have:
//   - `toto.fields()` (name, value)[] (only direct or NOT Not values)
//   - `Todo::field_names()` here would return `["id", "title"]`
#[derive(sqlx::FromRow, sqlb::Fields)] 
pub struct Todo {
    id: i64,

    title: String,
	#[field(name="description")]
	desc: Option<String>,

	#[field(skip)]
	someting_else: String,
}

#[derive(sqlb::Fields)] 
pub struct TodoForCreate {
	title: String,
	desc: Option<String>,

	#[field(skip)]
	someting_else: String,	
}

#[derive(sqlb::Fields)] 
pub struct TodoForUpdate {
	title: Option<String>,
	desc: Option<String>,
}

// -- Get the field names
let field_names = Todo::field_names();
// ["id", "title", "description"]

// -- Create new row
let todo_c = TodoForCreate { title: "title 01".to_string(), desc: "desc 01".to_string() };
// will update all fields specified in TodoForCreate
let sb = sqlb::insert().table("todo").data(todo_c.all_fields());
let sb = sb.returning(&["id", "title"]);
let (_id, title) = sb.fetch_one::<_, (i64, String)>(&db_pool).await?;

// -- Select 
let sb = sqlb::select().table("todo").columns(Todo::field_names()).order_by("!id");
let todos: Vec<Todo> = sb.fetch_as_all(&db_pool).await?;

// -- Update
let todo_u - TodoForUpdate { desc: "Updated desc 01".to_string()};
let sb = sqlb::update().table("todo").data(todo_u.not_none_fields()).and_where_eq("id", 123);
let row_affected = sb.exec(&db_pool).await?;
// will not update .title because of the use of `.not_none_fields()`. 

Thanks

  • Thanks to KaiserBh for the bindable! generic type and chrono support.
  • Thanks to eboody for the potential sqlx conflict (see PR 3).

Open source is awesome! Feel free to enter ticket, ask questions, or do PR (concise and focused).

Happy coding!

Changelog

! breaking change, ^ enhancement, + addition, - fix.

  • 0.4.0 - 2023-11-21
    • ^ Updated to sqlx 0.7
  • 0.3.8 - 2023-08-03
  • 0.3.2 .. 0.3.7
    • + Add support for partial and fully qualified table and column names. #8
    • + Add SqlxBindable blanket implementation for Option<T>. #7
    • + Add .limit(..) and .offset(..) for Select.
    • + Add .count() for Select.
    • + Add #[field(skip)] and #[field(name="other_name")] to skip or rename properties.
  • 0.3.1
    • ! BREAKING CHANGE - HasFields.fields has been rename to HasFields.not_none_fields().
    • ! BREAKING CHANGE - HasFields.not_none_fields() and HasFields.all_fields() consume the self (to avoid uncessary clone).
    • + - HasFields.all_fields() - returns all fields (even the one where value are None).
    • + - HasFields::field_names(): &'static [&'static] - list of field names (i.e., column names).
    • + - Added SqlxBindable for the Option<T> (not a blanket impl at this point).
    • 0.3.0 been deprecated since did not have the ...fields(self) behavior.
  • 0.2.0
    • Changing the generic order to match sqlx. From .fetch_one::<(i64, String), _> to .fetch_one::<_, (i64, String)>
  • 0.0.7
    • sqlb::insert().table("todo") (in 0.0.7) rather than sqlb::insert("toto") (<=0.0.6) (for all SqlBuilders)

For sqlb Dev

Start a PostgreSQL

# In terminal 1 - start postges
docker run --rm --name pg -p 5432:5432  -e POSTGRES_PASSWORD=welcome  postgres:15

# In terminal 2 - (optional) launch psql on the Postgres instance above
docker exec -it -u postgres pg psql

# In terminal 3 -
cargo test

# or watch a particular test target
cargo watch -q -c -x 'test --test test_sb_insert

[sqlb github repo](https://github.com/jeremychone/rust-sqlb)

rust-sqlb's People

Contributors

eboody avatar jeremychone avatar kaiserbh avatar krivahtoo 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

rust-sqlb's Issues

Add SqlxBindable blanket implementation for Option<T>

Problem

As mentioned in #6, when a type T implement SqlxBindable there is not SqlxBindable blanket implementation for Option<T> make it impossible to have Option<T> for custom types.

Solution

Refactor sqlb code to have SqlxBindable blanket implementation for Option<T> where T: SqlxBindable

NOTES:

  1. This will require T to be Clone and Send and be a supported sqlx type.
  2. This requires a minsaro change in the SqlxBindable interface, which should not impact most code (see SqlxBindable signature if compile error)

new feature - select - add count

Problem

There is no way to do select().columns(&["count(*)"]) as sqlb will wrap everything in double quote.

Solution

The simplest to support this use case is to assume that if the column name has a ( it is not a simple column name but more of a function call.

Later we can add more special characters if needed.

Add support for dot notations in table and column names

Problem

Right now, there is no way to point to a schema. See comment on #6

The main issue is that sqlb " surround table names without anticipating eventual schema name.

Solution

If "." in a table name, each parts should be " surrounded.

So should support the following:

let todos: Vec<Todo> = sqlb::select()
	.table("public.todo")
	.columns(&["id", "todo.title", "public.todo.description"])
	.fetch_all(&db_pool)
	.await?;
...

#[derive(Debug, sqlx::FromRow, Fields)]
pub struct Todo {
	pub id: i64,
	pub title: String,
	#[sqlx(rename = "description")]
	#[field(name = "description")]
	pub desc: Option<String>,
}

Encountering errors when trying to compile the version `0.4` with chrono support

Hi @jeremychone, So am trying the latest version of sqlb which is 0.4 but encountering a few errors.

Dependencies in Cargo.toml:

sqlx = "0.7.2"
sqlb = { version = "0.4.0", features = ["chrono-support"] }
chrono = "0.4.31"

Errors I get when compiling the project:

error[E0277]: the trait bound `NaiveDateTime: Encode<'_, Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:26:40
   |
26 |                 let query = query.bind(self.clone());
   |                                   ---- ^^^^^^^^^^^^ the trait `Encode<'_, Postgres>` is not implemented for `NaiveDateTime`      
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Encode<'q, DB>`:
             <bool as Encode<'q, sqlx::Any>>
             <bool as Encode<'_, Postgres>>
             <i8 as Encode<'_, Postgres>>
             <i16 as Encode<'q, sqlx::Any>>
             <i16 as Encode<'_, Postgres>>
             <i32 as Encode<'q, sqlx::Any>>
             <i32 as Encode<'_, Postgres>>
             <i64 as Encode<'q, sqlx::Any>>
           and 39 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:32
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                ^^^^^^^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveDateTime: Type<Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:26:40
   |
26 |                 let query = query.bind(self.clone());
   |                                   ---- ^^^^^^^^^^^^ the trait `Type<Postgres>` is not implemented for `NaiveDateTime`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Type<DB>`:
             <bool as Type<Postgres>>
             <bool as Type<sqlx::Any>>
             <i8 as Type<Postgres>>
             <i16 as Type<Postgres>>
             <i16 as Type<sqlx::Any>>
             <i32 as Type<Postgres>>
             <i32 as Type<sqlx::Any>>
             <i64 as Type<Postgres>>
           and 49 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:49
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                                 ^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveDateTime: Encode<'_, Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:33:40
   |
33 |                 let query = query.bind(<$t>::clone(self));
   |                                   ---- ^^^^^^^^^^^^^^^^^ the trait `Encode<'_, Postgres>` is not implemented for `NaiveDateTime` 
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Encode<'q, DB>`:
             <bool as Encode<'q, sqlx::Any>>
             <bool as Encode<'_, Postgres>>
             <i8 as Encode<'_, Postgres>>
             <i16 as Encode<'q, sqlx::Any>>
             <i16 as Encode<'_, Postgres>>
             <i32 as Encode<'q, sqlx::Any>>
             <i32 as Encode<'_, Postgres>>
             <i64 as Encode<'q, sqlx::Any>>
           and 39 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:32
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                ^^^^^^^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveDateTime: Type<Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:33:40
   |
33 |                 let query = query.bind(<$t>::clone(self));
   |                                   ---- ^^^^^^^^^^^^^^^^^ the trait `Type<Postgres>` is not implemented for `NaiveDateTime`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Type<DB>`:
             <bool as Type<Postgres>>
             <bool as Type<sqlx::Any>>
             <i8 as Type<Postgres>>
             <i16 as Type<Postgres>>
             <i16 as Type<sqlx::Any>>
             <i32 as Type<Postgres>>
             <i32 as Type<sqlx::Any>>
             <i64 as Type<Postgres>>
           and 49 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:49
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                                 ^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveDate: Encode<'_, Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:26:40
   |
26 |                 let query = query.bind(self.clone());
   |                                   ---- ^^^^^^^^^^^^ the trait `Encode<'_, Postgres>` is not implemented for `NaiveDate`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Encode<'q, DB>`:
             <bool as Encode<'q, sqlx::Any>>
             <bool as Encode<'_, Postgres>>
             <i8 as Encode<'_, Postgres>>
             <i16 as Encode<'q, sqlx::Any>>
             <i16 as Encode<'_, Postgres>>
             <i32 as Encode<'q, sqlx::Any>>
             <i32 as Encode<'_, Postgres>>
             <i64 as Encode<'q, sqlx::Any>>
           and 39 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:32
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                ^^^^^^^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveDate: Type<Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:26:40
   |
26 |                 let query = query.bind(self.clone());
   |                                   ---- ^^^^^^^^^^^^ the trait `Type<Postgres>` is not implemented for `NaiveDate`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Type<DB>`:
             <bool as Type<Postgres>>
             <bool as Type<sqlx::Any>>
             <i8 as Type<Postgres>>
             <i16 as Type<Postgres>>
             <i16 as Type<sqlx::Any>>
             <i32 as Type<Postgres>>
             <i32 as Type<sqlx::Any>>
             <i64 as Type<Postgres>>
           and 49 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:49
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                                 ^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveDate: Encode<'_, Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:33:40
   |
33 |                 let query = query.bind(<$t>::clone(self));
   |                                   ---- ^^^^^^^^^^^^^^^^^ the trait `Encode<'_, Postgres>` is not implemented for `NaiveDate`     
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Encode<'q, DB>`:
             <bool as Encode<'q, sqlx::Any>>
             <bool as Encode<'_, Postgres>>
             <i8 as Encode<'_, Postgres>>
             <i16 as Encode<'q, sqlx::Any>>
             <i16 as Encode<'_, Postgres>>
             <i32 as Encode<'q, sqlx::Any>>
             <i32 as Encode<'_, Postgres>>
             <i64 as Encode<'q, sqlx::Any>>
           and 39 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:32
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                ^^^^^^^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveDate: Type<Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:33:40
   |
33 |                 let query = query.bind(<$t>::clone(self));
   |                                   ---- ^^^^^^^^^^^^^^^^^ the trait `Type<Postgres>` is not implemented for `NaiveDate`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Type<DB>`:
             <bool as Type<Postgres>>
             <bool as Type<sqlx::Any>>
             <i8 as Type<Postgres>>
             <i16 as Type<Postgres>>
             <i16 as Type<sqlx::Any>>
             <i32 as Type<Postgres>>
             <i32 as Type<sqlx::Any>>
             <i64 as Type<Postgres>>
           and 49 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:49
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                                 ^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveTime: Encode<'_, Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:26:40
   |
26 |                 let query = query.bind(self.clone());
   |                                   ---- ^^^^^^^^^^^^ the trait `Encode<'_, Postgres>` is not implemented for `NaiveTime`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Encode<'q, DB>`:
             <bool as Encode<'q, sqlx::Any>>
             <bool as Encode<'_, Postgres>>
             <i8 as Encode<'_, Postgres>>
             <i16 as Encode<'q, sqlx::Any>>
             <i16 as Encode<'_, Postgres>>
             <i32 as Encode<'q, sqlx::Any>>
             <i32 as Encode<'_, Postgres>>
             <i64 as Encode<'q, sqlx::Any>>
           and 39 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:32
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                ^^^^^^^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveTime: Type<Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:26:40
   |
26 |                 let query = query.bind(self.clone());
   |                                   ---- ^^^^^^^^^^^^ the trait `Type<Postgres>` is not implemented for `NaiveTime`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Type<DB>`:
             <bool as Type<Postgres>>
             <bool as Type<sqlx::Any>>
             <i8 as Type<Postgres>>
             <i16 as Type<Postgres>>
             <i16 as Type<sqlx::Any>>
             <i32 as Type<Postgres>>
             <i32 as Type<sqlx::Any>>
             <i64 as Type<Postgres>>
           and 49 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:49
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                                 ^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveTime: Encode<'_, Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:33:40
   |
33 |                 let query = query.bind(<$t>::clone(self));
   |                                   ---- ^^^^^^^^^^^^^^^^^ the trait `Encode<'_, Postgres>` is not implemented for `NaiveTime`     
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Encode<'q, DB>`:
             <bool as Encode<'q, sqlx::Any>>
             <bool as Encode<'_, Postgres>>
             <i8 as Encode<'_, Postgres>>
             <i16 as Encode<'q, sqlx::Any>>
             <i16 as Encode<'_, Postgres>>
             <i32 as Encode<'q, sqlx::Any>>
             <i32 as Encode<'_, Postgres>>
             <i64 as Encode<'q, sqlx::Any>>
           and 39 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:32
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                ^^^^^^^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `NaiveTime: Type<Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:33:40
   |
33 |                 let query = query.bind(<$t>::clone(self));
   |                                   ---- ^^^^^^^^^^^^^^^^^ the trait `Type<Postgres>` is not implemented for `NaiveTime`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Type<DB>`:
             <bool as Type<Postgres>>
             <bool as Type<sqlx::Any>>
             <i8 as Type<Postgres>>
             <i16 as Type<Postgres>>
             <i16 as Type<sqlx::Any>>
             <i32 as Type<Postgres>>
             <i32 as Type<sqlx::Any>>
             <i64 as Type<Postgres>>
           and 49 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:49
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                                 ^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `chrono::DateTime<Utc>: Encode<'_, Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:26:40
   |
26 |                 let query = query.bind(self.clone());
   |                                   ---- ^^^^^^^^^^^^ the trait `Encode<'_, Postgres>` is not implemented for `chrono::DateTime<Utc>`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Encode<'q, DB>`:
             <bool as Encode<'q, sqlx::Any>>
             <bool as Encode<'_, Postgres>>
             <i8 as Encode<'_, Postgres>>
             <i16 as Encode<'q, sqlx::Any>>
             <i16 as Encode<'_, Postgres>>
             <i32 as Encode<'q, sqlx::Any>>
             <i32 as Encode<'_, Postgres>>
             <i64 as Encode<'q, sqlx::Any>>
           and 39 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:32
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                ^^^^^^^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `chrono::DateTime<Utc>: Type<Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:26:40
   |
26 |                 let query = query.bind(self.clone());
   |                                   ---- ^^^^^^^^^^^^ the trait `Type<Postgres>` is not implemented for `chrono::DateTime<Utc>`    
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Type<DB>`:
             <bool as Type<Postgres>>
             <bool as Type<sqlx::Any>>
             <i8 as Type<Postgres>>
             <i16 as Type<Postgres>>
             <i16 as Type<sqlx::Any>>
             <i32 as Type<Postgres>>
             <i32 as Type<sqlx::Any>>
             <i64 as Type<Postgres>>
           and 49 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:49
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                                 ^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `chrono::DateTime<Utc>: Encode<'_, Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:33:40
   |
33 |                 let query = query.bind(<$t>::clone(self));
   |                                   ---- ^^^^^^^^^^^^^^^^^ the trait `Encode<'_, Postgres>` is not implemented for `chrono::DateTime<Utc>`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Encode<'q, DB>`:
             <bool as Encode<'q, sqlx::Any>>
             <bool as Encode<'_, Postgres>>
             <i8 as Encode<'_, Postgres>>
             <i16 as Encode<'q, sqlx::Any>>
             <i16 as Encode<'_, Postgres>>
             <i32 as Encode<'q, sqlx::Any>>
             <i32 as Encode<'_, Postgres>>
             <i64 as Encode<'q, sqlx::Any>>
           and 39 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:32
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                ^^^^^^^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `chrono::DateTime<Utc>: Type<Postgres>` is not satisfied
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlb-0.4.0\src\val.rs:33:40
   |
33 |                 let query = query.bind(<$t>::clone(self));
   |                                   ---- ^^^^^^^^^^^^^^^^^ the trait `Type<Postgres>` is not implemented for `chrono::DateTime<Utc>`
   |                                   |
   |                                   required by a bound introduced by this call
...
96 |     bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
   |     ------------------------------------------------------------- in this macro invocation
   |
   = help: the following other types implement trait `Type<DB>`:
             <bool as Type<Postgres>>
             <bool as Type<sqlx::Any>>
             <i8 as Type<Postgres>>
             <i16 as Type<Postgres>>
             <i16 as Type<sqlx::Any>>
             <i32 as Type<Postgres>>
             <i32 as Type<sqlx::Any>>
             <i64 as Type<Postgres>>
           and 49 others
note: required by a bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
  --> C:\Users\Adi\.cargo\registry\src\index.crates.io-6f17d22bba15001f\sqlx-core-0.7.2\src\query.rs:79:49
   |
79 |     pub fn bind<T: 'q + Send + Encode<'q, DB> + Type<DB>>(mut self, value: T) -> Self {
   |                                                 ^^^^^^^^ required by this bound in `Query::<'q, DB, <DB as HasArguments<'q>>::Arguments>::bind`
   = note: this error originates in the macro `bindable` (in Nightly builds, run with -Z macro-backtrace for more info)

My rustup toolchain is stable-x86_64-pc-windows-msvc and version of rustc is 1.72.1.

How to use count(*)?

code:

let sb = sqlb::select()
        .table("test")
        .columns(&["count(*)"]);
    println!("{}", sb.sql());

console:
SELECT "count(*)" FROM "task"

this sql ERROR: column "count(id)" does not exist

0.3.7 BUG: sqlb::Fields and sqlb::bindable! for sqlx 0.7.1

Hi @jeremychone, So am trying the latest version of rust-sqlb which is 0.3.7 but encountring few errors here.

For the Fields if I have Option won't work and gives error.

#[derive(sqlb::Fields, Clone)]
pub struct EmployeeCompanyAssociationPatch {
    pub employee_email: Option<String>,
    pub name: Option<String>,
    pub status: Option<EmployeeCompanyAssociationStatus>,
}

Compiler Error for sqlb::Fields

the trait bound `EmployeeCompanyAssociationStatus: sqlx_core::types::Type<sqlx_core::postgres::database::Postgres>` is not
satisfied [E0277] Help: the following other types implement trait `sqlx_core::types::Type<DB>`: <&T as
sqlx_core::types::Type<DB>> <() as sqlx_core::types::Type<sqlx_core::postgres::database::Postgres>> <(T1, T2) as
sqlx_core::types::Type<sqlx_core::postgres::database::Postgres>> <(T1, T2, T3) as
sqlx_core::types::Type<sqlx_core::postgres::database::Postgres>> <(T1, T2, T3, T4) as
sqlx_core::types::Type<sqlx_core::postgres::database::Postgres>> <(T1, T2, T3, T4, T5) as
sqlx_core::types::Type<sqlx_core::postgres::database::Postgres>> <(T1, T2, T3, T4, T5, T6) as
sqlx_core::types::Type<sqlx_core::postgres::database::Postgres>> <(T1, T2, T3, T4, T5, T6, T7) as
sqlx_core::types::Type<sqlx_core::postgres::database::Postgres>> and 40 others Note: required for
`std::option::Option<EmployeeCompanyAssociationStatus>` to implement `SqlxBindable` Note: required for `sqlb::Field<'_>` to
implement `From<(&str, std::option::Option<EmployeeCompanyAssociationStatus>)>` Note: required for `(&str,
std::option::Option<EmployeeCompanyAssociationStatus>)` to implement `Into<sqlb::Field<'_>>`

the trait bound `for<'r> EmployeeCompanyAssociationStatus: sqlx_core::encode::Encode<'r,
sqlx_core::postgres::database::Postgres>` is not satisfied [E0277] Help: the following other types implement trait
`sqlx_core::encode::Encode<'q, DB>`: <&T as sqlx_core::encode::Encode<'q, DB>> <&[T] as sqlx_core::encode::Encode<'q,
sqlx_core::postgres::database::Postgres>> <&[u8] as sqlx_core::encode::Encode<'_, sqlx_core::postgres::database::Postgres>>
<&str as sqlx_core::encode::Encode<'_, sqlx_core::postgres::database::Postgres>> <Cow<'_, str> as sqlx_core::encode::Encode<'_,
sqlx_core::postgres::database::Postgres>> <JsonValue as sqlx_core::encode::Encode<'q, DB>> <Uuid as
sqlx_core::encode::Encode<'_, sqlx_core::postgres::database::Postgres>> <Vec<T> as sqlx_core::encode::Encode<'q,
sqlx_core::postgres::database::Postgres>> and 26 others Note: required for
`std::option::Option<EmployeeCompanyAssociationStatus>` to implement `SqlxBindable` Note: required for `sqlb::Field<'_>` to
implement `From<(&str, std::option::Option<EmployeeCompanyAssociationStatus>)>` Note: required for `(&str,
std::option::Option<EmployeeCompanyAssociationStatus>)` to implement `Into<sqlb::Field<'_>>`

Also below is the bindable not working as well, am I still need to do it this way? or is it changed now?

#[derive(sqlx::Type, Debug, Clone, PartialEq, Eq)]
#[sqlx(type_name = "status")]
pub enum EmployeeCompanyAssociationStatus {
    Active,
    Terminated,
}
sqlb::bindable!(EmployeeCompanyAssociationStatus);
method `bind_query` has an incompatible type for trait [E0053] Note: expected signature `fn(&'q
EmployeeCompanyAssociationStatus, sqlx_core::query::Query<'q, sqlx_core::postgres::database::Postgres,
sqlx_core::postgres::arguments::PgArguments>) -> sqlx_core::query::Query<'q, sqlx_core::postgres::database::Postgres,
sqlx_core::postgres::arguments::PgArguments>` found signature `fn(&EmployeeCompanyAssociationStatus,
sqlx::query::Query<'_, Postgres, PgArguments>) -> sqlx::query::Query<'_, Postgres, PgArguments>` Help: change the parameter
type to match the trait

Bug: sqlb::Bindable! or sqlb::Fields doesn't seem to be working with custom enums

Hello Jeremy, I've been following along with your Rust Web App TodoMVC tutorials for implementing my own application. It's been a fantastic help with what I'm trying to accomplish. However, when working with sqlb I seem to be running into an issue with the bindable! macro. I've looked over your source code for the YouTube series as well as the sqlb source and I can't seem to figure out why this is returning an error. Any help is greatly appreciated and if you need more of my source code please let me know.

Thank you,

Justin Leahy

Error:

error[E0277]: the trait bound `Option<TransactionTypes>: SqlxBindable` is not satisfied
  --> src/model/portfolio.rs:49:10
   |
49 | #[derive(sqlb::Fields, Clone)]
   |          ^^^^^^^^^^^^ the trait `SqlxBindable` is not implemented for `Option<TransactionTypes>`
   |
   = help: the following other types implement trait `SqlxBindable`:
             Option<&std::string::String>
             Option<&str>
             Option<OffsetDateTime>
             Option<Uuid>
             Option<bool>
             Option<f32>
             Option<f64>
             Option<i16>
           and 4 others
   = note: required for `Field<'_>` to implement `From<(&str, Option<TransactionTypes>)>`
   = note: required for `(&str, Option<TransactionTypes>)` to implement `Into<Field<'_>>`
   = note: this error originates in the derive macro `sqlb::Fields` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.

Code:

#[derive(sqlb::Fields, Clone)]
pub struct TransactionPatch {
    pub account_id: Option<i32>,
    pub stock_id: Option<i32>,
    pub date: Option<String>,
    pub shares_whole: Option<i64>,
    pub shares_decimal: Option<i64>,
    pub shares_decimal_exponent: Option<i64>,
    pub price_dollars: Option<i64>,
    pub price_cents: Option<i64>,
    pub transaction_type: Option<TransactionTypes>
}

#[derive(sqlx::Type, Debug, Clone, PartialEq, Eq)]
#[sqlx(type_name = "transactiontypes")]
#[sqlx(rename_all = "lowercase")]
pub enum TransactionTypes {
    Buy,
    Sell,
    DRIP,
}
sqlb::bindable!(TransactionTypes);

README could mention to not enable conflicting sqlx runtime feature

I noticed that the sqlb crate has the following features enabled for sqlx:

sqlx = { version = "0.6", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] }

According to my understanding, sqlx does not support having conflicting runtime features specified. Specifically, the runtime-tokio-rustls feature conflicts with other runtime features.

I believe it would be beneficial to mention this in the sqlb crate's README file to avoid potential issues. It could be something like:

Note: sqlb has "runtime-tokio-rustls" enabled by the sqlx crate. Do not enable a conflicting runtime feature when adding sqlx to your project.

Would it be appropriate to open a PR adding this note to the README or documentation to help users have a smoother experience when using sqlb with sqlx?

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.