-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the foundation for select clauses
This function is marked as unsafe, as we cannot verify that the types of the selected columns are actually correct. The safe wrapper for this will end up being a compile-time macro, which verifies the types of the selected columns (this is expected to still allow for an arbitrary SQL string). For implementing the safe wrapper, the biggest question is how to get the from clause statically at compile time. Hopefully switching to associated constants will allow us to grab the from clause of the source at compile time. The expected implementation will then create a prepared statement with the query, and get type information from that. I had attempted to have `FromSql` imply `Queriable`, however I received an error about conflicting implementations. The written impl was: ```rust impl<T, QS> Queriable<QS> for T where QS: QuerySource, T: FromSql<QS::SqlType>, { type Row = Self; fn build(row: Self::Row) -> Self { row } } ``` However, this led to an error about the impl for `User` conflicting. Presumably since we're grabbing an associated type from `QuerySource`, the compiler can't actually verify that there is no implementation of `FromSql` for `User`? If so, that is a strange limitation. As a result of this issue, I am using a macro to define the invocation instead.
- Loading branch information
Showing
3 changed files
with
92 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,47 @@ | ||
use super::types::{FromSql, NativeSqlType}; | ||
use types::{FromSql, NativeSqlType}; | ||
use std::marker::PhantomData; | ||
|
||
pub unsafe trait QuerySource { | ||
pub trait Queriable<QS: QuerySource> { | ||
type Row: FromSql<QS::SqlType>; | ||
|
||
fn build(row: Self::Row) -> Self; | ||
} | ||
|
||
pub unsafe trait QuerySource: Sized { | ||
type SqlType: NativeSqlType; | ||
|
||
fn select_clause(&self) -> &str; | ||
fn from_clause(&self) -> &str; | ||
|
||
unsafe fn select<A: NativeSqlType>(self, columns: &'static str) -> SelectedQuerySource<A, Self> { | ||
SelectedQuerySource { | ||
columns: columns, | ||
source: self, | ||
_marker: PhantomData, | ||
} | ||
} | ||
} | ||
|
||
pub trait Queriable<QS: QuerySource> { | ||
type Row: FromSql<QS::SqlType>; | ||
pub struct SelectedQuerySource<A, S> where | ||
A: NativeSqlType, | ||
S: QuerySource, | ||
{ | ||
columns: &'static str, | ||
source: S, | ||
_marker: PhantomData<A>, | ||
} | ||
|
||
fn build(row: Self::Row) -> Self; | ||
unsafe impl<A, S> QuerySource for SelectedQuerySource<A, S> where | ||
A: NativeSqlType, | ||
S: QuerySource, | ||
{ | ||
type SqlType = A; | ||
|
||
fn select_clause(&self) -> &str { | ||
self.columns | ||
} | ||
|
||
fn from_clause(&self) -> &str { | ||
self.source.from_clause() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters