Skip to content

add partly Mysql support #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
baf05ae
Add mysql feature flags
Apr 22, 2020
702ddad
Generate an impl for LoadingHandler for diesel::mysql::Mysql
Apr 22, 2020
778fecb
Generate an impl for WundergraphBelongsTo for diesel::mysql::Mysql
Apr 22, 2020
6f76152
Generate an impl for BuildFilterHelper for diesel::mysql::Mysql
Apr 22, 2020
61641d2
Implement ApplyOffset for diesel::mysql::Mysq
May 2, 2020
0da2814
wundergraph_example supports mysql
May 2, 2020
0ebcb0d
ApplyOffset for diesel::mysql::Mysql sets mandatory limit parameter
May 4, 2020
52759f9
[UNFINISHED DRAFT] Implement HandleInsert and HandleBatchInsert for d…
May 5, 2020
5f9478d
Fix wundergraph_example to compile with the mysql backend
weiznich May 12, 2020
a92f2c5
Add mysql feature flags
Apr 22, 2020
e8e1a41
Generate an impl for LoadingHandler for diesel::mysql::Mysql
Apr 22, 2020
add2c6d
Generate an impl for WundergraphBelongsTo for diesel::mysql::Mysql
Apr 22, 2020
0e82a5c
Generate an impl for BuildFilterHelper for diesel::mysql::Mysql
Apr 22, 2020
f781c32
Implement ApplyOffset for diesel::mysql::Mysq
May 2, 2020
0bd0c52
Update wundergraph/src/query_builder/selection/offset.rs
p-alik May 16, 2020
bafc006
rustfmt adds an empty like for sake of CI
May 16, 2020
463dafc
avoid warnings: trait objects without an explicit dyn are deprecated
May 17, 2020
858d82f
wundergraph_example supports MySql
Jun 15, 2020
4ed4ca7
wundergraph_cli supports MySql
Jun 15, 2020
494511e
Merge branch 'issue-3' of git://github.com/weiznich/wundergraph into …
Jun 15, 2020
b1e714b
Merge branch 'weiznich-issue-3' into issue-3
Jun 15, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions wundergraph/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ insta = "0.12"
[features]
default = []
debug = ["wundergraph_derive/debug", "log"]
mysql = ["diesel/mysql", "wundergraph_derive/mysql"]
sqlite = ["diesel/sqlite", "wundergraph_derive/sqlite"]
postgres = ["diesel/postgres", "wundergraph_derive/postgres"]
extras = ["uuid", "chrono"]
Expand Down
3 changes: 3 additions & 0 deletions wundergraph/src/query_builder/mutations/insert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ mod pg;
#[cfg(feature = "sqlite")]
mod sqlite;

#[cfg(feature = "mysql")]
mod mysql;

#[doc(hidden)]
pub fn handle_insert<DB, I, R, Ctx>(
selection: Option<&'_ [Selection<'_, WundergraphScalarValue>]>,
Expand Down
148 changes: 148 additions & 0 deletions wundergraph/src/query_builder/mutations/insert/mysql.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
use super::{HandleBatchInsert, HandleInsert};
use crate::context::WundergraphContext;
use crate::helper::UnRef;
use crate::query_builder::selection::fields::WundergraphFieldList;
use crate::query_builder::selection::filter::build_filter::BuildFilter;
use crate::query_builder::selection::order::BuildOrder;
use crate::query_builder::selection::query_modifier::QueryModifier;
use crate::query_builder::selection::select::BuildSelect;
use crate::query_builder::selection::{LoadingHandler, SqlTypeOfPlaceholder};
use crate::scalar::WundergraphScalarValue;
use diesel::associations::HasTable;
use diesel::deserialize::FromSql;
use diesel::dsl::SqlTypeOf;
use diesel::expression::{Expression, NonAggregate, SelectableExpression};
use diesel::insertable::CanInsertInSingleQuery;
use diesel::mysql::Mysql;
use diesel::query_builder::{BoxedSelectStatement, QueryFragment};
use diesel::query_dsl::methods::{BoxedDsl, FilterDsl};
use diesel::sql_types::{Bigint, HasSqlType, Integer};
use diesel::{no_arg_sql_function, EqAll, Identifiable};
use diesel::{AppearsOnTable, Connection, Insertable, RunQueryDsl, Table};
use juniper::{ExecutionResult, Executor, Selection, Value};
use std::convert::TryFrom;

// https://dev.mysql.com/doc/refman/8.0/en/getting-unique-id.html
diesel::no_arg_sql_function!(LAST_INSERT_ID, Bigint);

impl<I, Ctx, L, T> HandleInsert<L, I, Mysql, Ctx> for T
where
T: Table + HasTable<Table = T> + 'static,
T::FromClause: QueryFragment<Mysql>,
L: LoadingHandler<Mysql, Ctx, Table = T> + 'static,
L::Columns: BuildOrder<T, Mysql>
+ BuildSelect<T, Mysql, SqlTypeOfPlaceholder<L::FieldList, Mysql, L::PrimaryKeyIndex, T, Ctx>>,
Ctx: WundergraphContext + QueryModifier<L, Mysql>,
Ctx::Connection: Connection<Backend = Mysql>,
L::FieldList: WundergraphFieldList<Mysql, L::PrimaryKeyIndex, T, Ctx>,
I: Insertable<T>,
I::Values: QueryFragment<Mysql> + CanInsertInSingleQuery<Mysql>,
T::PrimaryKey: QueryFragment<Mysql> + Default,
T: BoxedDsl<
'static,
Mysql,
Output = BoxedSelectStatement<'static, SqlTypeOf<<T as Table>::AllColumns>, T, Mysql>,
>,
<Ctx::Connection as Connection>::Backend: HasSqlType<SqlTypeOf<T::PrimaryKey>>
+ HasSqlType<SqlTypeOfPlaceholder<L::FieldList, Mysql, L::PrimaryKeyIndex, T, Ctx>>,
<L::Filter as BuildFilter<Mysql>>::Ret: AppearsOnTable<T>,
T::PrimaryKey: EqAll<i32>,
T::PrimaryKey: Expression<SqlType = diesel::sql_types::Integer>,
&'static L: Identifiable,
<&'static L as Identifiable>::Id: UnRef<'static, UnRefed = i32>,
<T::PrimaryKey as EqAll<i32>>::Output:
SelectableExpression<T> + NonAggregate + QueryFragment<Mysql> + 'static,
{
fn handle_insert(
selection: Option<&'_ [Selection<'_, WundergraphScalarValue>]>,
executor: &Executor<'_, Ctx, WundergraphScalarValue>,
insertable: I,
) -> ExecutionResult<WundergraphScalarValue> {
handle_single_insert(selection, executor, insertable)
}
}

impl<I, Ctx, L, T> HandleBatchInsert<L, I, Mysql, Ctx> for T
where
T: Table + HasTable<Table = T> + 'static,
T::FromClause: QueryFragment<Mysql>,
L: LoadingHandler<Mysql, Ctx, Table = T> + 'static,
L::Columns: BuildOrder<T, Mysql>
+ BuildSelect<T, Mysql, SqlTypeOfPlaceholder<L::FieldList, Mysql, L::PrimaryKeyIndex, T, Ctx>>,
Ctx: WundergraphContext + QueryModifier<L, Mysql>,
Ctx::Connection: Connection<Backend = Mysql>,
L::FieldList: WundergraphFieldList<Mysql, L::PrimaryKeyIndex, T, Ctx>,
I: Insertable<T>,
I::Values: QueryFragment<Mysql> + CanInsertInSingleQuery<Mysql>,
T::PrimaryKey: QueryFragment<Mysql> + Default,
T: BoxedDsl<
'static,
Mysql,
Output = BoxedSelectStatement<'static, SqlTypeOf<<T as Table>::AllColumns>, T, Mysql>,
>,
<Ctx::Connection as Connection>::Backend: HasSqlType<SqlTypeOf<T::PrimaryKey>>
+ HasSqlType<SqlTypeOfPlaceholder<L::FieldList, Mysql, L::PrimaryKeyIndex, T, Ctx>>,
<L::Filter as BuildFilter<Mysql>>::Ret: AppearsOnTable<T>,
T::PrimaryKey: EqAll<i32>,
T::PrimaryKey: Expression<SqlType = diesel::sql_types::Integer>,
&'static L: Identifiable,
<&'static L as Identifiable>::Id: UnRef<'static, UnRefed = i32>,
<T::PrimaryKey as EqAll<i32>>::Output:
SelectableExpression<T> + NonAggregate + QueryFragment<Mysql> + 'static,
{
fn handle_batch_insert(
selection: Option<&'_ [Selection<'_, WundergraphScalarValue>]>,
executor: &Executor<'_, Ctx, WundergraphScalarValue>,
batch: Vec<I>,
) -> ExecutionResult<WundergraphScalarValue> {
let r = batch
.into_iter()
.map(|i| handle_single_insert(selection, executor, i))
.collect::<Result<Vec<_>, _>>()?;
Ok(Value::List(r))
}
}

fn handle_single_insert<L, I, T, Ctx>(
selection: Option<&'_ [Selection<'_, WundergraphScalarValue>]>,
executor: &Executor<'_, Ctx, WundergraphScalarValue>,
insertable: I,
) -> ExecutionResult<WundergraphScalarValue>
where
L: LoadingHandler<Mysql, Ctx, Table = T> + 'static,
L::FieldList: WundergraphFieldList<Mysql, L::PrimaryKeyIndex, T, Ctx>,
<L::Filter as BuildFilter<Mysql>>::Ret: AppearsOnTable<T>,
L::Columns: BuildOrder<T, Mysql>
+ BuildSelect<T, Mysql, SqlTypeOfPlaceholder<L::FieldList, Mysql, L::PrimaryKeyIndex, T, Ctx>>,
&'static L: Identifiable,
I: Insertable<T>,
I::Values: QueryFragment<Mysql> + CanInsertInSingleQuery<Mysql>,
Ctx: WundergraphContext + QueryModifier<L, Mysql>,
Ctx::Connection: Connection<Backend = Mysql>,
<Ctx::Connection as Connection>::Backend: HasSqlType<SqlTypeOf<T::PrimaryKey>>
+ HasSqlType<SqlTypeOfPlaceholder<L::FieldList, Mysql, L::PrimaryKeyIndex, T, Ctx>>,
T: Table + HasTable<Table = T> + 'static,
T::FromClause: QueryFragment<Mysql>,
T: BoxedDsl<
'static,
Mysql,
Output = BoxedSelectStatement<'static, SqlTypeOf<<T as Table>::AllColumns>, T, Mysql>,
>,
T::PrimaryKey: EqAll<i32>,
T::PrimaryKey: Expression<SqlType = Integer>,
T::PrimaryKey: QueryFragment<Mysql> + Default,
<T::PrimaryKey as EqAll<i32>>::Output:
SelectableExpression<T> + NonAggregate + QueryFragment<Mysql> + 'static,
i32: FromSql<Integer, Mysql>,
{
let ctx = executor.context();
let conn = ctx.get_connection();
let look_ahead = executor.look_ahead();
insertable.insert_into(T::table()).execute(conn).unwrap();
let last_insert_id: i64 = diesel::select(LAST_INSERT_ID).first(conn)?;
let last_insert_id = i32::try_from(last_insert_id)?;
let q = L::build_query(&[], &look_ahead)?;
let q = FilterDsl::filter(q, T::PrimaryKey::default().eq_all(last_insert_id));
let items = L::load(&look_ahead, selection, executor, q)?;
Ok(items.into_iter().next().unwrap_or(Value::Null))
}
42 changes: 38 additions & 4 deletions wundergraph/src/query_builder/selection/offset.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use crate::error::Result;
#[cfg(any(feature = "postgres", feature = "sqlite"))]
#[cfg(any(feature = "postgres", feature = "sqlite", feature = "mysql"))]
use crate::error::WundergraphError;
#[cfg(any(feature = "postgres", feature = "sqlite"))]
#[cfg(any(feature = "postgres", feature = "sqlite", feature = "mysql"))]
use crate::juniper_ext::FromLookAheadValue;
use crate::query_builder::selection::{BoxedQuery, LoadingHandler};
use crate::scalar::WundergraphScalarValue;
use diesel::backend::Backend;
#[cfg(feature = "sqlite")]
#[cfg(any(feature = "sqlite", feature = "mysql"))]
use diesel::query_dsl::methods::LimitDsl;
#[cfg(any(feature = "postgres", feature = "sqlite"))]
#[cfg(any(feature = "postgres", feature = "sqlite", feature = "mysql"))]
use diesel::query_dsl::methods::OffsetDsl;

use juniper::LookAheadSelection;

/// A trait abstracting over the different behaviour of limit/offset
Expand Down Expand Up @@ -72,3 +73,36 @@ impl ApplyOffset for diesel::sqlite::Sqlite {
}
}
}

#[cfg(feature = "mysql")]
impl ApplyOffset for diesel::mysql::Mysql {
fn apply_offset<'a, L, Ctx>(
query: BoxedQuery<'a, L, Self, Ctx>,
select: &LookAheadSelection<'_, WundergraphScalarValue>,
) -> Result<BoxedQuery<'a, L, Self, Ctx>>
where
L: LoadingHandler<Self, Ctx>,
{
use juniper::LookAheadMethods;
if let Some(offset) = select.argument("offset") {
let q = <_ as OffsetDsl>::offset(
query,
i64::from_look_ahead(offset.value())
.ok_or(WundergraphError::CouldNotBuildFilterArgument)?,
);
if select.argument("limit").is_some() {
Ok(q)
} else {
// Mysql requires a limit clause in front of any offset clause
// The documentation proposes the following:
// > To retrieve all rows from a certain offset up to the end of the
// > result set, you can use some large number for the second parameter.
// https://dev.mysql.com/doc/refman/8.0/en/select.html
// Therefore we just use i64::MAX as limit here
Ok(<_ as LimitDsl>::limit(q, std::i64::MAX))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small comment why this is necessary would be nice, maybe just link the relevant mysql documentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put diesel's comment there

}
} else {
Ok(query)
}
}
}
3 changes: 2 additions & 1 deletion wundergraph_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ serde_json = "1"

[features]
default = ["postgres", "sqlite"]
sqlite = ["diesel/sqlite"]
mysql = ["diesel/mysql"]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no other changes required to get wundergraph_cli working?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've to prove it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • cargo run --features mysql --no-default-features -- print-schema mysql://**@localhost/wundergraph runs withot any warnings (after e3c50f4)
  • print_schema::tests::round_trip test requires Mysql insert migration.
  • print_schema::tests::infer_schema fails with
Snapshot file: wundergraph_cli/src/print_schema/snapshots/tests__infer_schema.snap
Snapshot: infer_schema
Source: wundergraph_cli/src/print_schema/mod.rs:178
-old snapshot
+new results
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
&s
────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    2     2 │ use wundergraph::scalar::WundergraphScalarValue;
    3     3 │ use wundergraph::WundergraphEntity;
    4     4 │
    5     5 │ table! {
    6       │-    infer_test.comments (id) {
    7       │-        id -> Int4,
    8       │-        post -> Nullable<Int4>,
    9       │-        commenter -> Nullable<Int4>,
          6 │+    comments (id) {
          7 │+        id -> Integer,
          8 │+        post -> Nullable<Integer>,
          9 │+        commenter -> Nullable<Integer>,
   10    10 │         content -> Text,
   11    11 │     }
   12    12 │ }
   13    13 │
   14    14 │ table! {
   15       │-    infer_test.posts (id) {
   16       │-        id -> Int4,
   17       │-        author -> Nullable<Int4>,
         15 │+    posts (id) {
         16 │+        id -> Integer,
         17 │+        author -> Nullable<Integer>,
   18    18 │         title -> Text,
   19       │-        datetime -> Nullable<Timestamp>,
         19 │+        datetime -> Timestamp,
   20    20 │         content -> Nullable<Text>,
   21    21 │     }
   22    22 │ }
   23    23 │
   24    24 │ table! {
   25       │-    infer_test.users (id) {
   26       │-        id -> Int4,
         25 │+    users (id) {
         26 │+        id -> Integer,
   27    27 │         name -> Text,
   28    28 │     }
   29    29 │ }
   30    30 │
   31    31 │ allow_tables_to_appear_in_same_query!(
   39    39 │ #[table_name = "comments"]
   40    40 │ #[primary_key(id)]
   41    41 │ pub struct Comment {
   42    42 │     id: i32,
   43       │-    post: Option<HasOne<i32, Post>>,
   44       │-    commenter: Option<HasOne<i32, User>>,
         43 │+    post: Option<i32>,
         44 │+    commenter: Option<i32>,
   45    45 │     content: String,
   46    46 │ }
   47    47 │
   48    48 │ #[derive(Clone, Debug, Identifiable, WundergraphEntity)]
   49    49 │ #[table_name = "posts"]
   50    50 │ #[primary_key(id)]
   51    51 │ pub struct Post {
   52    52 │     id: i32,
   53       │-    author: Option<HasOne<i32, User>>,
         53 │+    author: Option<i32>,
   54    54 │     title: String,
   55       │-    datetime: Option<chrono::naive::NaiveDateTime>,
         55 │+    datetime: chrono::naive::NaiveDateTime,
   56    56 │     content: Option<String>,
   57       │-    comments: HasMany<Comment, comments::post>,
   58    57 │ }
   59    58 │
   60    59 │ #[derive(Clone, Debug, Identifiable, WundergraphEntity)]
   61    60 │ #[table_name = "users"]
   62    61 │ #[primary_key(id)]
   63    62 │ pub struct User {
   64    63 │     id: i32,
   65    64 │     name: String,
   66       │-    comments: HasMany<Comment, comments::commenter>,
   67       │-    posts: HasMany<Post, posts::author>,
   68    65 │ }
   69    66 │
   70    67 │
   71    68 │
   72    69 │ wundergraph::query_object!{
   81    78 │ #[derive(Insertable, juniper::GraphQLInputObject, Clone, Debug)]
   82    79 │ #[graphql(scalar = "WundergraphScalarValue")]
   83    80 │ #[table_name = "comments"]
   84    81 │ pub struct NewComment {
         82 │+    id: i32,
   85    83 │     post: Option<i32>,
   86    84 │     commenter: Option<i32>,
   87    85 │     content: String,
   88    86 │ }
   89    87 │
  101    99 │ #[derive(Insertable, juniper::GraphQLInputObject, Clone, Debug)]
  102   100 │ #[graphql(scalar = "WundergraphScalarValue")]
  103   101 │ #[table_name = "posts"]
  104   102 │ pub struct NewPost {
        103 │+    id: i32,
  105   104 │     author: Option<i32>,
  106   105 │     title: String,
  107       │-    datetime: Option<chrono::naive::NaiveDateTime>,
  108   106 │     content: Option<String>,
  109   107 │ }
  110   108 │
  111   109 │ #[derive(AsChangeset, Identifiable, juniper::GraphQLInputObject, Clone, Debug)]
  112   110 │ #[graphql(scalar = "WundergraphScalarValue")]
  115   113 │ pub struct PostChangeset {
  116   114 │     id: i32,
  117   115 │     author: Option<i32>,
  118   116 │     title: String,
  119       │-    datetime: Option<chrono::naive::NaiveDateTime>,
        117 │+    datetime: chrono::naive::NaiveDateTime,
  120   118 │     content: Option<String>,
  121   119 │ }
  122   120 │
  123   121 │ #[derive(Insertable, juniper::GraphQLInputObject, Clone, Debug)]
  124   122 │ #[graphql(scalar = "WundergraphScalarValue")]
  125   123 │ #[table_name = "users"]
  126   124 │ pub struct NewUser {
        125 │+    id: i32,
  127   126 │     name: String,
  128   127 │ }
  129   128 │
  130   129 │ #[derive(AsChangeset, Identifiable, juniper::GraphQLInputObject, Clone, Debug)]
  131   130 │ #[graphql(scalar = "WundergraphScalarValue")]
────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
To update snapshots run `cargo insta review`

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically all changes to the model structs here should not happen. That means we need to filter out somehow primary keys for the New* model structs, fix foreign key relations for the query models (HasOne/HasMany and figure out what's wrong with the datetime columns. (Maybe a NOT NULL to much?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a0dc070 filters primary keys explicitly

postgres = ["diesel/postgres"]
sqlite = ["diesel/sqlite"]
4 changes: 2 additions & 2 deletions wundergraph_cli/src/infer_schema_internals/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub fn load_foreign_key_constraints(
Ok(constraints)
}

pub fn determine_column_type(attr: &ColumnInformation) -> Result<ColumnType, Box<Error>> {
pub fn determine_column_type(attr: &ColumnInformation) -> Result<ColumnType, Box<dyn Error>> {
let tpe = determine_type_name(&attr.type_name)?;
let unsigned = determine_unsigned(&attr.type_name);

Expand All @@ -91,7 +91,7 @@ pub fn determine_column_type(attr: &ColumnInformation) -> Result<ColumnType, Box
})
}

fn determine_type_name(sql_type_name: &str) -> Result<String, Box<Error>> {
fn determine_type_name(sql_type_name: &str) -> Result<String, Box<dyn Error>> {
let result = if sql_type_name == "tinyint(1)" {
"bool"
} else if sql_type_name.starts_with("int") {
Expand Down
71 changes: 68 additions & 3 deletions wundergraph_cli/src/print_schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ mod tests {
#[cfg(feature = "postgres")]
const BACKEND: &str = "postgres";

#[cfg(feature = "mysql")]
const BACKEND: &str = "mysql";

#[cfg(feature = "sqlite")]
const BACKEND: &str = "sqlite";

Expand Down Expand Up @@ -125,6 +128,36 @@ mod tests {
);"#,
];

#[cfg(feature = "mysql")]
const MIGRATION: &[&str] = &[
r#"DROP TABLE IF EXISTS comments;"#,
r#"DROP TABLE IF EXISTS posts;"#,
r#"DROP TABLE IF EXISTS users;"#,
r#"CREATE TABLE users(
id INTEGER NOT NULL AUTO_INCREMENT,
name TEXT NOT NULL,
PRIMARY KEY (`id`)
);"#,
r#"CREATE TABLE posts(
id INTEGER NOT NULL AUTO_INCREMENT,
author INTEGER DEFAULT NULL,
title TEXT NOT NULL,
datetime TIMESTAMP NULL DEFAULT NULL,
content TEXT,
PRIMARY KEY (`id`),
FOREIGN KEY (`author`) REFERENCES `users` (`id`)
);"#,
r#"CREATE TABLE comments(
id INTEGER NOT NULL AUTO_INCREMENT,
post INTEGER DEFAULT NULL,
commenter INTEGER DEFAULT NULL,
content TEXT NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`post`) REFERENCES `posts` (`id`),
FOREIGN KEY (`commenter`) REFERENCES `users` (`id`)
);"#,
];

fn setup_simple_schema(conn: &InferConnection) {
use diesel::prelude::*;
use diesel::sql_query;
Expand All @@ -141,6 +174,12 @@ mod tests {
sql_query(*m).execute(conn).unwrap();
}
}
#[cfg(feature = "mysql")]
InferConnection::Mysql(conn) => {
for m in MIGRATION {
sql_query(*m).execute(conn).unwrap();
}
}
}
}

Expand All @@ -153,7 +192,7 @@ mod tests {

#[cfg(feature = "postgres")]
print(&conn, Some("infer_test"), &mut out).unwrap();
#[cfg(feature = "sqlite")]
#[cfg(any(feature = "mysql", feature = "sqlite"))]
print(&conn, None, &mut out).unwrap();

let s = String::from_utf8(out).unwrap();
Expand Down Expand Up @@ -187,7 +226,7 @@ mod tests {
let mut api_file = File::create(api).unwrap();
#[cfg(feature = "postgres")]
print(&conn, Some("infer_test"), &mut api_file).unwrap();
#[cfg(feature = "sqlite")]
#[cfg(any(feature = "mysql", feature = "sqlite"))]
print(&conn, None, &mut api_file).unwrap();

let main = tmp_dir
Expand Down Expand Up @@ -224,6 +263,17 @@ mod tests {
)
.unwrap();

#[cfg(feature = "mysql")]
write!(
main_file,
include_str!("template_main.rs"),
conn = "MysqlConnection",
db_url = std::env::var("DATABASE_URL").unwrap(),
migrations = migrations,
listen_url = listen_url
)
.unwrap();

let cargo_toml = tmp_dir.path().join("wundergraph_roundtrip_test/Cargo.toml");
let mut cargo_toml_file = std::fs::OpenOptions::new()
.write(true)
Expand Down Expand Up @@ -269,6 +319,21 @@ mod tests {
)
.unwrap();
}
#[cfg(feature = "mysql")]
{
writeln!(
cargo_toml_file,
r#"diesel = {{version = "1.4", features = ["mysql", "chrono"]}}"#
)
.unwrap();

writeln!(
cargo_toml_file,
"wundergraph = {{path = \"{}\", features = [\"mysql\", \"chrono\"] }}",
wundergraph_dir
)
.unwrap();
}
writeln!(cargo_toml_file, r#"juniper = "0.14""#).unwrap();
writeln!(cargo_toml_file, r#"failure = "0.1""#).unwrap();
writeln!(cargo_toml_file, r#"actix-web = "1""#).unwrap();
Expand Down Expand Up @@ -316,7 +381,7 @@ mod tests {
println!("Started server");

let client = reqwest::Client::new();
std::thread::sleep(std::time::Duration::from_secs(1));
std::thread::sleep(std::time::Duration::from_secs(5));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 secs was used to run mysql tests locally. But since ci postgres test failed for same reason, I increased the sleep duration globally.


let query = "{\"query\": \"{ Users { id name } } \"}";
let mutation = r#"{"query":"mutation CreateUser {\n CreateUser(NewUser: {name: \"Max\"}) {\n id\n name\n }\n}","variables":null,"operationName":"CreateUser"}"#;
Expand Down
Loading