Skip to content

Commit 452e1b9

Browse files
committed
Add some compile tests for the new Selectable trait
1 parent 411b18d commit 452e1b9

File tree

2 files changed

+277
-0
lines changed

2 files changed

+277
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
extern crate diesel;
2+
3+
use diesel::prelude::*;
4+
5+
table! {
6+
users {
7+
id -> Integer,
8+
name -> Text,
9+
}
10+
}
11+
12+
table! {
13+
posts {
14+
id -> Integer,
15+
title -> Text,
16+
user_id -> Integer,
17+
}
18+
}
19+
20+
joinable!(posts -> users(user_id));
21+
allow_tables_to_appear_in_same_query!(users, posts);
22+
23+
#[derive(Selectable, Queryable)]
24+
#[table_name = "users"]
25+
struct UserWithEmbeddedPost {
26+
id: i32,
27+
name: String,
28+
#[diesel(embed)]
29+
post: Post,
30+
}
31+
32+
#[derive(Selectable, Queryable)]
33+
#[table_name = "users"]
34+
struct UserWithOptionalPost {
35+
id: i32,
36+
name: String,
37+
#[diesel(embed)]
38+
post: Option<Post>,
39+
}
40+
41+
#[derive(Selectable, Queryable)]
42+
#[table_name = "posts"]
43+
struct Post {
44+
id: i32,
45+
title: String,
46+
}
47+
48+
#[derive(Selectable)]
49+
#[table_name = "posts"]
50+
struct PostWithWrongField {
51+
id: i32,
52+
// There is a typo here:
53+
titel: String
54+
}
55+
56+
#[derive(Selectable)]
57+
// wrong table name here
58+
#[table_name = "post"]
59+
struct PostWithWrongTableName {
60+
id: i32,
61+
title: String,
62+
}
63+
64+
#[derive(Queryable)]
65+
struct UserWithPostCount {
66+
id: i32,
67+
name: String,
68+
post_count: i64,
69+
}
70+
71+
impl Selectable<diesel::pg::Pg> for UserWithPostCount {
72+
type SelectExpression = (users::id, users::name, diesel::dsl::count<posts::id>);
73+
74+
fn selection() -> Self::SelectExpression {
75+
(users::id, users::name, diesel::dsl::count(posts::id))
76+
}
77+
}
78+
79+
#[derive(Queryable)]
80+
struct UserWithoutSelectable {
81+
id: i32,
82+
name: String
83+
}
84+
85+
86+
fn main() {
87+
let conn = PgConnection::establish("").unwrap();
88+
89+
// supported queries
90+
//
91+
// plain queries
92+
let _: Vec<Post> = posts::table.load_into(&conn).unwrap();
93+
94+
// This works for inner joins
95+
let _: Vec<UserWithEmbeddedPost> = users::table
96+
.inner_join(posts::table)
97+
.load_into(&conn)
98+
.unwrap();
99+
100+
// also for left joins
101+
let _: Vec<UserWithOptionalPost> = users::table
102+
.left_join(posts::table)
103+
.load_into(&conn)
104+
.unwrap();
105+
106+
// allow manual impls with complex expressions
107+
// (and group by)
108+
let _ = users::table
109+
.inner_join(posts::table)
110+
.group_by(users::id)
111+
.load_into::<UserWithPostCount>(&conn)
112+
.unwrap();
113+
114+
// inserts
115+
let _ = diesel::insert_into(posts::table)
116+
.values(posts::title.eq(""))
117+
.load_into::<Post>(&conn)
118+
.unwrap();
119+
120+
// update
121+
let _ = diesel::update(posts::table)
122+
.set(posts::title.eq(""))
123+
.load_into::<Post>(&conn)
124+
.unwrap();
125+
126+
// delete
127+
let _ = diesel::delete(posts::table)
128+
.load_into::<Post>(&conn)
129+
.unwrap();
130+
131+
// forbidden queries
132+
//
133+
// left joins force nullable
134+
let _ = users::table
135+
.left_join(posts::table)
136+
.load_into::<UserWithEmbeddedPost>(&conn)
137+
.unwrap();
138+
139+
// group by clauses are considered
140+
let _ = users::table
141+
.inner_join(posts::table)
142+
.group_by(posts::id)
143+
.load_into::<UserWithEmbeddedPost>(&conn)
144+
.unwrap();
145+
146+
// missing group by clause
147+
let _ = users::table
148+
.inner_join(posts::table)
149+
.load_into::<UserWithPostCount>(&conn)
150+
.unwrap();
151+
152+
// cannot load results from more than one table via
153+
// returning clauses
154+
let _ = diesel::insert_into(users::table)
155+
.values(users::name.eq(""))
156+
.load_into::<UserWithEmbeddedPost>(&conn)
157+
.unwrap();
158+
159+
// cannot load results from more than one table via
160+
// returning clauses
161+
let _ = diesel::update(users::table)
162+
.set(users::name.eq(""))
163+
.load_into::<UserWithEmbeddedPost>(&conn)
164+
.unwrap();
165+
166+
// cannot load results from more than one table via
167+
// returning clauses
168+
let _ = diesel::delete(users::table)
169+
.load_into::<UserWithEmbeddedPost>(&conn)
170+
.unwrap();
171+
172+
// cannot use this method without deriving selectable
173+
let _ = users::table.load_into::<UserWithoutSelectable>(&conn).unwrap();
174+
175+
// cannot use backend specific selectable with other backend
176+
let conn = SqliteConnection::establish("").unwrap();
177+
let _ = users::table
178+
.inner_join(posts::table)
179+
.group_by(users::id)
180+
.load_into::<UserWithPostCount>(&conn)
181+
.unwrap();
182+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
error[E0433]: failed to resolve: use of undeclared crate or module `post`
2+
--> $DIR/selectable.rs:58:16
3+
|
4+
58 | #[table_name = "post"]
5+
| ^^^^^^ use of undeclared crate or module `post`
6+
|
7+
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error[E0412]: cannot find type `titel` in module `posts`
10+
--> $DIR/selectable.rs:53:5
11+
|
12+
53 | titel: String
13+
| ^^^^^^^^^^^^^ not found in `posts`
14+
15+
error[E0425]: cannot find value `titel` in module `posts`
16+
--> $DIR/selectable.rs:53:5
17+
|
18+
53 | titel: String
19+
| ^^^^^^^^^^^^^ not found in `posts`
20+
21+
error[E0277]: the trait bound `SelectStatement<JoinOn<diesel::query_source::joins::Join<users::table, posts::table, LeftOuter>, Grouped<diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<posts::columns::user_id>, diesel::expression::nullable::Nullable<users::columns::id>>>>>: LoadIntoDsl<_, UserWithEmbeddedPost>` is not satisfied
22+
--> $DIR/selectable.rs:136:10
23+
|
24+
136 | .load_into::<UserWithEmbeddedPost>(&conn)
25+
| ^^^^^^^^^ the trait `LoadIntoDsl<_, UserWithEmbeddedPost>` is not implemented for `SelectStatement<JoinOn<diesel::query_source::joins::Join<users::table, posts::table, LeftOuter>, Grouped<diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<posts::columns::user_id>, diesel::expression::nullable::Nullable<users::columns::id>>>>>`
26+
|
27+
= help: the following implementations were found:
28+
<SelectStatement<F, S, D, W, O, LOf, G, LC> as LoadIntoDsl<Conn, U>>
29+
30+
error[E0277]: the trait bound `SelectStatement<JoinOn<diesel::query_source::joins::Join<users::table, posts::table, Inner>, Grouped<diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<posts::columns::user_id>, diesel::expression::nullable::Nullable<users::columns::id>>>>, diesel::query_builder::select_clause::DefaultSelectClause, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::NoWhereClause, diesel::query_builder::order_clause::NoOrderClause, LimitOffsetClause<NoLimitClause, NoOffsetClause>, diesel::query_builder::group_by_clause::GroupByClause<posts::columns::id>>: LoadIntoDsl<_, UserWithEmbeddedPost>` is not satisfied
31+
--> $DIR/selectable.rs:143:10
32+
|
33+
143 | .load_into::<UserWithEmbeddedPost>(&conn)
34+
| ^^^^^^^^^ the trait `LoadIntoDsl<_, UserWithEmbeddedPost>` is not implemented for `SelectStatement<JoinOn<diesel::query_source::joins::Join<users::table, posts::table, Inner>, Grouped<diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<posts::columns::user_id>, diesel::expression::nullable::Nullable<users::columns::id>>>>, diesel::query_builder::select_clause::DefaultSelectClause, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::NoWhereClause, diesel::query_builder::order_clause::NoOrderClause, LimitOffsetClause<NoLimitClause, NoOffsetClause>, diesel::query_builder::group_by_clause::GroupByClause<posts::columns::id>>`
35+
|
36+
= help: the following implementations were found:
37+
<SelectStatement<F, S, D, W, O, LOf, G, LC> as LoadIntoDsl<Conn, U>>
38+
39+
error[E0277]: the trait bound `SelectStatement<JoinOn<diesel::query_source::joins::Join<users::table, posts::table, Inner>, Grouped<diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<posts::columns::user_id>, diesel::expression::nullable::Nullable<users::columns::id>>>>>: LoadIntoDsl<_, UserWithPostCount>` is not satisfied
40+
--> $DIR/selectable.rs:149:10
41+
|
42+
149 | .load_into::<UserWithPostCount>(&conn)
43+
| ^^^^^^^^^ the trait `LoadIntoDsl<_, UserWithPostCount>` is not implemented for `SelectStatement<JoinOn<diesel::query_source::joins::Join<users::table, posts::table, Inner>, Grouped<diesel::expression::operators::Eq<diesel::expression::nullable::Nullable<posts::columns::user_id>, diesel::expression::nullable::Nullable<users::columns::id>>>>>`
44+
|
45+
= help: the following implementations were found:
46+
<SelectStatement<F, S, D, W, O, LOf, G, LC> as LoadIntoDsl<Conn, U>>
47+
48+
error[E0277]: the trait bound `InsertStatement<users::table, ValuesClause<ColumnInsertValue<users::columns::name, diesel::expression::bound::Bound<diesel::sql_types::Text, &str>>, users::table>>: LoadIntoDsl<_, UserWithEmbeddedPost>` is not satisfied
49+
--> $DIR/selectable.rs:156:10
50+
|
51+
156 | .load_into::<UserWithEmbeddedPost>(&conn)
52+
| ^^^^^^^^^ the trait `LoadIntoDsl<_, UserWithEmbeddedPost>` is not implemented for `InsertStatement<users::table, ValuesClause<ColumnInsertValue<users::columns::name, diesel::expression::bound::Bound<diesel::sql_types::Text, &str>>, users::table>>`
53+
|
54+
= help: the following implementations were found:
55+
<InsertStatement<T, U, Op> as LoadIntoDsl<Conn, S>>
56+
57+
error[E0277]: the trait bound `UpdateStatement<users::table, diesel::query_builder::where_clause::NoWhereClause, diesel::query_builder::update_statement::changeset::Assign<users::columns::name, diesel::expression::bound::Bound<diesel::sql_types::Text, &str>>>: LoadIntoDsl<_, UserWithEmbeddedPost>` is not satisfied
58+
--> $DIR/selectable.rs:163:10
59+
|
60+
163 | .load_into::<UserWithEmbeddedPost>(&conn)
61+
| ^^^^^^^^^ the trait `LoadIntoDsl<_, UserWithEmbeddedPost>` is not implemented for `UpdateStatement<users::table, diesel::query_builder::where_clause::NoWhereClause, diesel::query_builder::update_statement::changeset::Assign<users::columns::name, diesel::expression::bound::Bound<diesel::sql_types::Text, &str>>>`
62+
|
63+
= help: the following implementations were found:
64+
<UpdateStatement<T, U, V> as LoadIntoDsl<Conn, S>>
65+
66+
error[E0277]: the trait bound `DeleteStatement<users::table, diesel::query_builder::where_clause::NoWhereClause>: LoadIntoDsl<_, UserWithEmbeddedPost>` is not satisfied
67+
--> $DIR/selectable.rs:169:10
68+
|
69+
169 | .load_into::<UserWithEmbeddedPost>(&conn)
70+
| ^^^^^^^^^ the trait `LoadIntoDsl<_, UserWithEmbeddedPost>` is not implemented for `DeleteStatement<users::table, diesel::query_builder::where_clause::NoWhereClause>`
71+
|
72+
= help: the following implementations were found:
73+
<DeleteStatement<T, U> as LoadIntoDsl<Conn, S>>
74+
75+
error[E0277]: the trait bound `UserWithoutSelectable: diesel::Selectable<_>` is not satisfied
76+
--> $DIR/selectable.rs:173:26
77+
|
78+
173 | let _ = users::table.load_into::<UserWithoutSelectable>(&conn).unwrap();
79+
| ^^^^^^^^^ the trait `diesel::Selectable<_>` is not implemented for `UserWithoutSelectable`
80+
81+
error[E0277]: the trait bound `SelectStatement<users::table>: LoadIntoDsl<_, UserWithoutSelectable>` is not satisfied
82+
--> $DIR/selectable.rs:173:26
83+
|
84+
173 | let _ = users::table.load_into::<UserWithoutSelectable>(&conn).unwrap();
85+
| ^^^^^^^^^ the trait `LoadIntoDsl<_, UserWithoutSelectable>` is not implemented for `SelectStatement<users::table>`
86+
|
87+
= help: the following implementations were found:
88+
<SelectStatement<F, S, D, W, O, LOf, G, LC> as LoadIntoDsl<Conn, U>>
89+
= note: required because of the requirements on the impl of `LoadIntoDsl<_, UserWithoutSelectable>` for `users::table`
90+
91+
error[E0271]: type mismatch resolving `<diesel::SqliteConnection as diesel::Connection>::Backend == Pg`
92+
--> $DIR/selectable.rs:180:10
93+
|
94+
180 | .load_into::<UserWithPostCount>(&conn)
95+
| ^^^^^^^^^ expected struct `Sqlite`, found struct `Pg`

0 commit comments

Comments
 (0)