sea-query icon indicating copy to clipboard operation
sea-query copied to clipboard

issues-336 Array support

Open ikrivosheev opened this issue 3 years ago • 11 comments

PR Info

  • Closes https://github.com/SeaQL/sea-query/issues/336

This is continue: https://github.com/SeaQL/sea-query/pull/390

ikrivosheev avatar Aug 11 '22 19:08 ikrivosheev

Perhaps we can start from removing the object variants from Value (while keeping the primitive variants)?

tyt2y3 avatar Aug 16 '22 00:08 tyt2y3

The requirements:

  1. No downcast
  2. Keep SeaQuery clean, outsource heavy lifting of value binding to binder
  3. Include binder in sea-query's dependency but do not turn on the features by default
  4. It could be Value in sea-query, ValueTrait in binder
  5. Could we enable multiple backend support in an additive compatible way? I.e. if one downstream turned on SQLx and another turn on postgres. The ? cargo syntax should be helpful

billy1624 avatar Aug 16 '22 06:08 billy1624

@billy1624 @tyt2y3 , hello! I have a bad surprise. trait ToSql from postgres-types crate need: Self: Sized, but I cannot make ValueTrait: Sized, because I need dyn ValueTrait

ikrivosheev avatar Oct 08 '22 21:10 ikrivosheev

It looks like instead of create our own ValueTrait make all types, which hold Value should be generic...

ikrivosheev avatar Oct 08 '22 21:10 ikrivosheev

Hmmm another sought... Black magic with unsafe. This should work. I can store row pointer to data and then transmute it to value and type get from enum.

Example: https://github.com/Diggsey/ijson/

ikrivosheev avatar Oct 08 '22 22:10 ikrivosheev

May be we should postpone ValueTrait to after 0.27, and trying to get array working with sqlx-postgres for now

tyt2y3 avatar Oct 09 '22 12:10 tyt2y3

Ah, one more problem... I try something like this:

pub trait Sqlx<'q, T: Database>: Encode<'q, T> + Type<T> {}

pub trait ValueTrait
where
    Self: Debug,
{
    fn to_sql_string(&self) -> String;

    #[cfg(feature = "with-postgres")]
    fn as_postgres_to_sql(&self) -> &(dyn PostgresToSql + Sync + Send);

    #[cfg(feature = "sqlx-mysql")]
    fn as_sqlx_mysql<'q>(&'q self) -> &(dyn Sqlx<'q, MySql>);

    #[cfg(feature = "sqlx-postgres")]
    fn as_sqlx_postgres<'q>(&'q self) -> &(dyn Sqlx<'q, Postgres>);

    #[cfg(feature = "sqlx-sqlite")]
    fn as_sqlx_sqlite<'q>(&'q self) -> &(dyn Sqlx<'q, Sqlite>);
}

#[derive(Debug, Clone)]
pub enum Value {
    Bool(bool),
    TinyInt(i8),
    SmallInt(i16),
    Int(i32),
    BigInt(i64),
    TinyUnsigned(u8),
    SmallUnsigned(u16),
    Unsigned(u32),
    BigUnsigned(u64),
    Float(f32),
    Double(f64),
    #[cfg(feature = "thread-safe")]
    Object(SeaRc<Box<dyn ValueTrait + Sync + Send>>),
    #[cfg(not(feature = "thread-safe"))]
    Object(SeaRc<Box<dyn ValueTrait>>),
}

impl ValueTrait for Value {...}

Problems:

  1. I cannot combine rusqlite and sqlx in one crate (failed to select a version for libsqlite3-sys)
  2. I cannot make &dyn Sqlx because Type<T> - Sqlx cannot be made into an object` - https://github.com/launchbadge/sqlx/issues/1461
  3. sea-query-postgres throw compile error: the to_sql method cannot be invoked on a trait object`

ikrivosheev avatar Oct 09 '22 21:10 ikrivosheev

1: I think we won't combine them 2: we have to create our own trait based on that but is object safe

tyt2y3 avatar Oct 11 '22 06:10 tyt2y3

I guess we can close this?

billy1624 avatar Nov 14 '22 08:11 billy1624

I guess we can close this?

@billy1624 I think, no, we cannot... I will continue work on it.

ikrivosheev avatar Nov 14 '22 08:11 ikrivosheev

Alright, a trait based Value with array support would be cool. And a huge step forward :)

billy1624 avatar Nov 14 '22 09:11 billy1624