Skip to content

Commit 1aed718

Browse files
authored
Merge branch 'master' into jk_cli-list-migrations
2 parents 5b512d6 + 22dc6af commit 1aed718

27 files changed

Lines changed: 475 additions & 26 deletions

File tree

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ matrix:
4343
allow_failures:
4444
- rust: nightly
4545
include:
46-
- rust: nightly-2017-03-20
46+
- rust: nightly-2017-04-19
4747
env: CLIPPY=YESPLEASE
4848
script:
4949
- (cd diesel && cargo rustc --no-default-features --features "lint unstable chrono serde_json uuid sqlite postgres mysql" -- -Zno-trans)

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
66

77
## Unreleased
88

9+
910
### Added
1011

1112
* Added the `migration list` command to Diesel CLI for listing all available migrations and marking those that have been applied.
1213

14+
* Added support for adding two nullable columns.
15+
16+
1317
## [0.12.0] - 2016-03-16
1418

1519
### Added

diesel/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,20 @@ categories = ["database"]
1414
[dependencies]
1515
byteorder = "1.0"
1616
chrono = { version = "0.3", optional = true }
17-
clippy = { optional = true, version = "=0.0.121" }
18-
libsqlite3-sys = { version = ">=0.7.1, <0.8.0", optional = true }
17+
clippy = { optional = true, version = "=0.0.125" }
18+
libsqlite3-sys = { version = ">=0.8.0, <0.9.0", optional = true, features = ["min_sqlite_version_3_7_16"] }
1919
mysqlclient-sys = { version = ">=0.1.0, <0.3.0", optional = true }
2020
pq-sys = { version = ">=0.3.0, <0.5.0", optional = true }
2121
quickcheck = { version = "0.3.1", optional = true }
22-
serde_json = { version = ">=0.8.0, <0.10.0", optional = true }
22+
serde_json = { version = ">=0.8.0, <2.0", optional = true }
2323
time = { version = "0.1", optional = true }
2424
url = { version = "1.4.0", optional = true }
2525
uuid = { version = ">=0.2.0, <0.5.0", optional = true, features = ["use_std"] }
2626

2727
[dev-dependencies]
2828
cfg-if = "0.1.0"
2929
diesel_codegen = "0.12.0"
30-
dotenv = "0.8.0"
30+
dotenv = ">=0.8, <0.10"
3131
quickcheck = "0.3.1"
3232
tempdir = "^0.3.4"
3333

diesel/src/associations/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
//!
4444
//! [Identifiable]: trait.Identifiable.html
4545
//!
46+
//! If the name of your foreign key doesn't follow the convention `tablename_id`, you can specify a
47+
//! custom one to `#[has_many]` and `#[belongs_to]` by adding a `foreign_key` argument to the
48+
//! attribute like so `#[has_many, foreign_key="mykey"]`.
49+
//!
4650
//! `#[has_many]` actually has no behavior on its own. It only enables joining between the two
4751
//! tables. If you are only writing `children.inner_join(parents)` or
4852
//! `Child::belonging_to(&parents)`, you only need to define the `#[belongs_to]` side.

diesel/src/connection/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@ pub trait Connection: SimpleConnection + Sized + Send {
3636
/// a transaction is already occurring, savepoints will be used to emulate a nested
3737
/// transaction.
3838
///
39-
/// If the function returns an `Ok`, that value will be returned. If the
40-
/// function returns an `Err`,
41-
/// [`TransactionError::UserReturnedError`](../result/enum.TransactionError.html#variant.UserReturnedError)
42-
/// will be returned wrapping that value.
39+
/// The error returned from the function must implement
40+
/// `From<diesel::result::Error>`.
4341
fn transaction<T, E, F>(&self, f: F) -> Result<T, E> where
4442
F: FnOnce() -> Result<T, E>,
4543
E: From<Error>,

diesel/src/doctest_setup.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ cfg_if! {
1414
let connection = diesel::pg::PgConnection::establish(&connection_url).unwrap();
1515
connection.begin_test_transaction().unwrap();
1616
connection.execute("DROP TABLE IF EXISTS users").unwrap();
17+
connection.execute("DROP TABLE IF EXISTS animals").unwrap();
1718

1819
connection
1920
}
@@ -28,6 +29,16 @@ cfg_if! {
2829
)").unwrap();
2930
connection.execute("INSERT INTO users (name) VALUES ('Sean'), ('Tess')").unwrap();
3031

32+
connection.execute("CREATE TABLE animals (
33+
id SERIAL PRIMARY KEY,
34+
species VARCHAR NOT NULL,
35+
legs INTEGER NOT NULL,
36+
name VARCHAR
37+
)").unwrap();
38+
connection.execute("INSERT INTO animals (species, legs, name) VALUES
39+
('dog', 4, 'Jack'),
40+
('spider', 8, null)").unwrap();
41+
3142
connection
3243
}
3344
} else if #[cfg(feature = "sqlite")] {
@@ -48,6 +59,16 @@ cfg_if! {
4859
)").unwrap();
4960
connection.execute("INSERT INTO users (name) VALUES ('Sean'), ('Tess')").unwrap();
5061

62+
connection.execute("CREATE TABLE animals (
63+
id INTEGER PRIMARY KEY AUTOINCREMENT,
64+
species VARCHAR NOT NULL,
65+
legs INTEGER NOT NULL,
66+
name VARCHAR
67+
)").unwrap();
68+
connection.execute("INSERT INTO animals (species, legs, name) VALUES
69+
('dog', 4, 'Jack'),
70+
('spider', 8, null)").unwrap();
71+
5172
connection
5273
}
5374
} else if #[cfg(feature = "mysql")] {
@@ -58,6 +79,7 @@ cfg_if! {
5879
let connection_url = database_url_from_env("MYSQL_UNIT_TEST_DATABASE_URL");
5980
let connection = diesel::mysql::MysqlConnection::establish(&connection_url).unwrap();
6081
connection.execute("DROP TABLE IF EXISTS users").unwrap();
82+
connection.execute("DROP TABLE IF EXISTS animals").unwrap();
6183

6284
connection
6385
}
@@ -71,8 +93,18 @@ cfg_if! {
7193
name TEXT NOT NULL
7294
) CHARACTER SET utf8mb4").unwrap();
7395
connection.execute("INSERT INTO users (name) VALUES ('Sean'), ('Tess')").unwrap();
74-
connection.begin_test_transaction().unwrap();
7596

97+
connection.execute("CREATE TABLE animals (
98+
id INTEGER PRIMARY KEY AUTO_INCREMENT,
99+
species TEXT NOT NULL,
100+
legs INTEGER NOT NULL,
101+
name TEXT
102+
) CHARACTER SET utf8mb4").unwrap();
103+
connection.execute("INSERT INTO animals (species, legs, name) VALUES
104+
('dog', 4, 'Jack'),
105+
('spider', 8, null)").unwrap();
106+
107+
connection.begin_test_transaction().unwrap();
76108
connection
77109
}
78110
} else {
@@ -111,3 +143,39 @@ impl_Insertable! {
111143
name: String,
112144
}
113145
}
146+
147+
table! {
148+
animals {
149+
id -> Integer,
150+
species -> VarChar,
151+
legs -> Integer,
152+
name -> Nullable<VarChar>,
153+
}
154+
}
155+
156+
#[derive(Clone)]
157+
#[allow(dead_code)]
158+
struct NewAnimal {
159+
species: String,
160+
legs: i32,
161+
name: Option<String>,
162+
}
163+
164+
impl NewAnimal {
165+
pub fn new(species: &str, legs: i32, name: Option<&str>) -> Self {
166+
NewAnimal {
167+
species: species.into(),
168+
legs: legs,
169+
name: name.map(|n| n.into()),
170+
}
171+
}
172+
}
173+
174+
impl_Insertable! {
175+
(animals)
176+
struct NewAnimal {
177+
species: String,
178+
legs: i32,
179+
name: Option<String>,
180+
}
181+
}

diesel/src/expression/count.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,27 @@ use types::BigInt;
99
/// As with most bare functions, this is not exported by default. You can import
1010
/// it specifically as `diesel::expression::count`, or glob import
1111
/// `diesel::expression::dsl::*`
12+
///
13+
/// # Examples
14+
///
15+
/// ```rust
16+
/// # #[macro_use] extern crate diesel;
17+
/// # include!("src/doctest_setup.rs");
18+
/// # use diesel::expression::dsl::*;
19+
/// #
20+
/// # table! {
21+
/// # users {
22+
/// # id -> Integer,
23+
/// # name -> VarChar,
24+
/// # }
25+
/// # }
26+
/// #
27+
/// # fn main() {
28+
/// # use self::animals::dsl::*;
29+
/// # let connection = establish_connection();
30+
/// assert_eq!(Ok(1), animals.select(count(name)).first(&connection));
31+
/// # }
32+
/// ```
1233
pub fn count<T: Expression>(t: T) -> Count<T> {
1334
Count {
1435
target: t,
@@ -25,7 +46,7 @@ pub fn count<T: Expression>(t: T) -> Count<T> {
2546
/// it specifically as `diesel::expression::count_star`, or glob import
2647
/// `diesel::expression::dsl::*`
2748
///
28-
/// # Example
49+
/// # Examples
2950
///
3051
/// ```rust
3152
/// # #[macro_use] extern crate diesel;

diesel/src/expression/functions/aggregate_folding.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,53 @@ macro_rules! fold_function {
5656

5757
fold_function!(sum, Sum, "SUM",
5858
"Represents a SQL `SUM` function. This function can only take types which are
59-
Foldable.");
59+
Foldable.
60+
61+
# Examples
62+
63+
```rust
64+
# #[macro_use] extern crate diesel;
65+
# include!(\"src/doctest_setup.rs\");
66+
# use diesel::expression::dsl::*;
67+
#
68+
# table! {
69+
# users {
70+
# id -> Integer,
71+
# name -> VarChar,
72+
# }
73+
# }
74+
#
75+
# fn main() {
76+
# use self::animals::dsl::*;
77+
# let connection = establish_connection();
78+
assert_eq!(Ok(12i64), animals.select(sum(legs)).first(&connection));
79+
# }
80+
");
6081

6182
fold_function!(avg, Avg, "AVG",
6283
"Represents a SQL `AVG` function. This function can only take types which are
63-
Foldable.");
84+
Foldable.
85+
86+
# Examples
87+
88+
```rust
89+
# #[macro_use] extern crate diesel;
90+
# include!(\"src/doctest_setup.rs\");
91+
# use diesel::expression::dsl::*;
92+
#
93+
# table! {
94+
# users {
95+
# id -> Integer,
96+
# name -> VarChar,
97+
# }
98+
# }
99+
#
100+
# fn main() {
101+
# use self::animals::dsl::*;
102+
# let connection = establish_connection();
103+
// assert_eq!(Ok(6f64), animals.select(avg(legs)).first(&connection));
104+
// TODO: There doesn't currently seem to be a way to use avg with integers, since
105+
// they return a `Numeric` which doesn't have a corresponding Rust type.
106+
# }
107+
```
108+
");

diesel/src/expression/functions/aggregate_ordering.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,50 @@ macro_rules! ord_function {
5555

5656
ord_function!(max, Max, "MAX",
5757
"Represents a SQL `MAX` function. This function can only take types which are
58-
ordered.");
58+
ordered.
59+
60+
# Examples
61+
62+
```rust
63+
# #[macro_use] extern crate diesel;
64+
# include!(\"src/doctest_setup.rs\");
65+
# use diesel::expression::dsl::*;
66+
#
67+
# table! {
68+
# users {
69+
# id -> Integer,
70+
# name -> VarChar,
71+
# }
72+
# }
73+
#
74+
# fn main() {
75+
# use self::animals::dsl::*;
76+
# let connection = establish_connection();
77+
assert_eq!(Ok(Some(8)), animals.select(max(legs)).first(&connection));
78+
# }
79+
");
5980

6081
ord_function!(min, Min, "MIN",
6182
"Represents a SQL `MIN` function. This function can only take types which are
62-
ordered.");
83+
ordered.
84+
85+
# Examples
86+
87+
```rust
88+
# #[macro_use] extern crate diesel;
89+
# include!(\"src/doctest_setup.rs\");
90+
# use diesel::expression::dsl::*;
91+
#
92+
# table! {
93+
# users {
94+
# id -> Integer,
95+
# name -> VarChar,
96+
# }
97+
# }
98+
#
99+
# fn main() {
100+
# use self::animals::dsl::*;
101+
# let connection = establish_connection();
102+
assert_eq!(Ok(Some(4)), animals.select(min(legs)).first(&connection));
103+
# }
104+
");

diesel/src/expression/functions/date_and_time.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,28 @@ operator_allowed!(now, Add, add);
3939
operator_allowed!(now, Sub, sub);
4040
sql_function!(date, date_t, (x: Timestamp) -> Date,
4141
"Represents the SQL `DATE` function. The argument should be a Timestamp
42-
expression, and the return value will be an expression of type Date");
42+
expression, and the return value will be an expression of type Date.
43+
44+
# Examples
45+
46+
```ignore
47+
# #[macro_use] extern crate diesel;
48+
# extern crate chrono;
49+
# include!(\"src/doctest_setup.rs\");
50+
# use diesel::expression::dsl::*;
51+
#
52+
# table! {
53+
# users {
54+
# id -> Integer,
55+
# name -> VarChar,
56+
# }
57+
# }
58+
#
59+
# fn main() {
60+
# let connection = establish_connection();
61+
let today: chrono::NaiveDate = diesel::select(date(now)).first(&connection).unwrap();
62+
# }
63+
");
4364

4465
#[cfg(feature="postgres")]
4566
use expression::AsExpression;

0 commit comments

Comments
 (0)