2015-11-30 00:59:46 +03:00
|
|
|
# Change Log
|
2016-09-16 20:52:51 +03:00
|
|
|
|
2015-11-30 00:59:46 +03:00
|
|
|
All user visible changes to this project will be documented in this file.
|
|
|
|
This project adheres to [Semantic Versioning](http://semver.org/), as described
|
|
|
|
for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md)
|
|
|
|
|
2018-06-01 20:56:57 +03:00
|
|
|
## Unreleased
|
|
|
|
|
2019-02-17 16:34:13 +03:00
|
|
|
### Added
|
|
|
|
|
2019-04-04 18:32:34 +03:00
|
|
|
* `Connection` and `SimpleConnection` traits are implemented for a broader range
|
|
|
|
of `r2d2::PooledConnection<M>` types when the `r2d2` feature is enabled.
|
2019-02-17 16:34:13 +03:00
|
|
|
|
2019-03-29 02:17:18 +03:00
|
|
|
* Added `DatabaseErrorKind::ReadOnlyTransaction` to allow applications to
|
|
|
|
handle errors caused by writing when only allowed to read.
|
|
|
|
|
2019-05-16 22:12:35 +03:00
|
|
|
* All expression methods can now be called on expressions of nullable types.
|
|
|
|
|
2019-09-25 11:37:36 +03:00
|
|
|
* Added `BoxedSqlQuery`. This allows users to do a variable amount of `.sql` or
|
|
|
|
`.bind` calls without changing the underlying type.
|
|
|
|
|
|
|
|
* Added `.sql` to `SqlQuery` and `UncheckedBind` to allow appending SQL code to
|
|
|
|
an existing query.
|
|
|
|
|
2019-12-17 21:53:16 +03:00
|
|
|
* The `MacAddr` SQL type can now be used without enabling the `network-address`
|
|
|
|
feature.
|
2020-04-03 18:16:31 +03:00
|
|
|
|
2019-01-25 04:59:23 +03:00
|
|
|
* Added support for SQLite's `UPSERT`.
|
2020-03-09 13:58:20 +03:00
|
|
|
You can use this feature above SQLite version 3.24.0.
|
2019-09-25 11:36:16 +03:00
|
|
|
|
2020-04-03 18:13:02 +03:00
|
|
|
* Added ability to create custom aggregate functions in SQLite.
|
|
|
|
|
Replace `NonAggregate` with something less broken
This commit implements the proposal laid out at
https://discourse.diesel.rs/t/proposed-change-replace-nonaggregate-with-something-less-broken-that-can-support-group-by/18.
The changes made in this commit now correctly enforce semantics around
the mixing of aggregate/non-aggregate expressions, and lays the
foundations required for full `GROUP BY` support in the future. This
commit does not implement `GROUP BY` as a feature in public API, though
I have added some minimal support to prove the soundness of the change.
Since this will likely be the largest breaking change in 2.0, I am going
to include as much detail as I can about the problem, the reasoning
behind the solution, and the likely impact of the change.
Recap of the problem
----
`NonAggregate` was originally introduced in
c66d96fa9cefaba0a418834e8cb0e78a0a87269a. The goal was to prevent the
following error at compile time:
[local] sean@sean=# select count(*), name from users;
ERROR: 42803: column "users.name" must appear in the GROUP BY clause or be used in an aggregate function
I didn't think about this nearly as much as I should have at the time,
which resulted in a hilariously broken implementation that has prevented
the addition of `group_by` support, and left bugs in the codebase for
more than 4 years.
At the time I was focused on "mixing aggregate and non-aggregate
expressions in a select statement". Since select uses tuples to
represent multiple values, I added a trait to represent non-aggregate
values, added it as a bound for `impl Expression for AnyTuple`, and
called it a day. This had a number of problems.
The most obvious was that it prevented valid queries involving multiple
aggregate expressions. At the time I figured we'd have a separate
trait for aggregate expressions, and then `impl Expression for AnyTuple
where AllFields: NonAggregate | AllFields: Aggregate`. This eventually
led to [RFC #1268](https://github.com/rust-lang/rfcs/pull/1268), which
doesn't seem likely to be stabilized soon, and even if it were we still
have the other issues with this solution.
The next issue is that you cannot say whether a given expression is
aggregate by looking at it on its own. The answer to "Is `users`.`name`
aggregate?" depends on whether or not that column appears in the group
by clause. So any trait which correctly handles this must be generic
over the group by clause, or it cannot be correctly implemented for
columns.
However, the most egregious issue with that commit is that it does not
handle *any* composite expressions besides tuples. Even today,
`.select((count_star(), id))` fails, but `.select(count_star() + id)`
will compile (and either error at runtime or give non-deterministic
results depending on your backend).
User Impact
----
This change will unfortunately have more breakage than I had
anticipated. That said, the breakage only affects *extremely* generic
code, and I do not believe that the majority of our users will notice or
care about this change.
There are three main ways in which the breakage will affect users:
- The additional bound on `SelectStatement<...>: SelectDsl` and
`SelectStatement<...>: Query`.
- This one broke our test suite in a few places, mainly where we have
*really* generic code to say "I can select T.eq(sql_string)". I do
not believe this is representative of real code.
- I did a GitHub-wide search of all occurances of
`SelectableExpression` (which is *not* the bound on the public API,
but is the bound on `SelectStatement`'s impl, and would point to
broken code). I found one repo which is relying on internals that
will break, and a lot of results from Wundergraph. I didnt' look at
those. This probably breaks Wundergraph. Sorry, Georg. It should be
easy to fix I promise.
- `NonAggregate` can no longer be directly implemented
- I did a GitHub-wide search for `NonAggregate`. With one exception,
every repo implementing this trait directly was on pre-1.0. The only
affected repo is manually implementing `Expression` instead of using
`#[derive(AsExpression)]`. With that change they will be
future-proofed.
- `T: NonAggregate` no longer implies `(OtherType, T): NonAggregate`
- This broke `infer_schema`, since it was relying on `AssocType:
NonAggregate` to know `(known_column, AssocType, known_column):
Expression`. Ironically, that's no longer important, it did still
break due to the first item on this list. I could not find any code
in the wild that fell into this category.
Originally I thought that the only code which would be affected by this
is code that wrote `impl NonAggregate`, since that code would need to
change to `impl ValidGrouping`. However, I missed a few things when I
made that assessment.
The first is that... Well the feature exists. The whole point of this
was to prevent `aggregate + non_aggregate` from compiling when passed to
select, which implies a new trait bound *somewhere*. While
`SelectStatement` and its impls are private API, it's really easy to
couple yourself ot the bounds on those impls. It doesn't help that
`rustc` literally recommends that folks do that when errors occur. Any
code that is written as `Foo: SelectDsl<Selection>` will be fine, but
any code that's gone down the rabbit hole and has copied the bounds from
`impl SelectDsl for SelectStatement<...>` will break. I didn't find many
cases in the wild, but I do think it's relatively common.
The second thing I missed is that "is this aggregate" is not a binary
question. Originally I expected we would have two answers to the
question, and compound expressions would enforce that their
sub-expressions all had the same answer. The issue is that `1` doesn't
care. You can have `count(*) + 1`, and you can also have `non_aggregate
+ 1`. `1` is always valid, regardless of aggregation. So we need three
answers. The problem is that this means we can't have `T: NonAggregate`
mean everything it used to.
On stable `T: NonAggregate` will mean `T: ValidGrouping<()>`, and that
`T` can be passed to everything with a `NonAggregate` bound (`filter`,
`order`, etc). On nightly, it also implies `T::IsAggregate:
MixedAggregates<is_aggregate::No, Output = is_aggregate::No>`. In
English, it implies that this is valid with no group by clause, and its
output can appear with an expression which is not aggregate (but might
be with a different group by clause). The outcome of this is that `T:
NonAggregate` implies `(T, Other): NonAggregate`. However the missing
link from both stable and unstable is `is_aggregate::No:
MixedAggregates<T::IsAggregate>` being implied, which would mean
`(Other, T): NonAggregate` would be implied.
Ultimately this is a really long-winded way of saying that `T:
NonAggregate` used to imply interactions with other types. That is no
longer consistently true. It's unlikely there are many affected users,
but any that are affected will need to directly have a `ValidGrouping`
bound.
Implementation Notes
---
Because this broke diesel_infer_schema, I had to do a version bump to
get that crate to rely on the released 1.4.
There's a note on the unsoundness of the `NonAggregate` impl of
`Subselect`. I haven't changed the bounds on that impl, but we almost
certainly should address it before 2.0 is released.
I opted to validate the new bound in `SelectDsl`, so folks get errors on
`.select` instead of `.load`. We can't validate this on calls to both
`.select` *and* `.group_by`, since a select statement valid with a group
by is often invalid without one, and a group by clause usually makes the
default select clause invalid.
While this commit does not add proper group by support, I fleshed it out
a bit to test the type constraints. Right now a column only considers
itself valid if there is no group by clause, or if the group by clause
is exactly that column.
I had more to say but I went on a call and lost my train of thought. I
need to come back and finish writing this later.
Notable Limitations
---
`SELECT lower(name) FROM users GROUP BY lower(name)` probably can't be
represented.
Unanswered Questions
---
`BoxableExpression` has been limited to only work when there's no
group by clause, and only work with types which are `is_aggregate::No`.
This is probably not what we want to do, but was the smallest change to
start.
2019-12-18 23:30:29 +03:00
|
|
|
* Multiple aggregate expressions can now appear together in the same select
|
|
|
|
clause. See [the upgrade notes](#2-0-0-upgrade-non-aggregate) for details.
|
|
|
|
|
|
|
|
* `ValidGrouping` has been added to represent whether an expression is valid for
|
|
|
|
a given group by clause, and whether or not it's aggregate. It replaces the
|
|
|
|
functionality of `NonAggregate`. See [the upgrade
|
|
|
|
notes](#2-0-0-upgrade-non-aggregate) for details.
|
|
|
|
|
2020-06-27 02:26:22 +03:00
|
|
|
* It is now possible to inspect the type of values returned from the database
|
|
|
|
in such a way to support constructing a dynamic value depending on this type.
|
|
|
|
|
2020-10-07 17:11:46 +03:00
|
|
|
* Added a `without-deprecated` feature that unconditionally disables deprecated items.
|
|
|
|
Use this feature flag to verify that none of your dependencies is setting
|
|
|
|
the `with-deprecated` flag internally.
|
|
|
|
|
2020-10-12 10:56:45 +03:00
|
|
|
* Added support for PostgreSQL's `SIMILAR TO` and `NOT SIMILAR TO`.
|
|
|
|
|
2020-11-02 08:20:44 +03:00
|
|
|
* Added `#[diesel(serialize_as)]` analogous to `#[diesel(deserialize_as)]`. This allows
|
|
|
|
customization of the serialization behaviour of `Insertable` structs.
|
|
|
|
|
2020-11-27 11:39:40 +03:00
|
|
|
* Added support for `GROUP BY` clauses
|
|
|
|
|
2020-12-03 17:04:57 +03:00
|
|
|
* Added support for `UNION`, `UNION ALL`, `INTERSECT`, `INTERSECT ALL`, `EXCEPT`, `EXCEPT ALL` clauses
|
|
|
|
|
2019-02-09 09:03:29 +03:00
|
|
|
### Removed
|
|
|
|
|
|
|
|
* All previously deprecated items have been removed.
|
2020-05-29 12:37:15 +03:00
|
|
|
* Support for `uuid` version < 0.7.0 has been removed.
|
|
|
|
* Support for `bigdecimal` < 0.0.13 has been removed.
|
|
|
|
* Support for `pq-sys` < 0.4.0 has been removed.
|
|
|
|
* Support for `mysqlclient-sys` < 0.2.0 has been removed.
|
2020-09-08 15:47:02 +03:00
|
|
|
* Support for `time` types has been removed.
|
2020-11-19 22:23:05 +03:00
|
|
|
* Support for `chrono` < 0.4.19 has been removed.
|
2020-06-27 02:26:22 +03:00
|
|
|
* The `NonNull` for sql types has been removed in favour of the new `SqlType` trait.
|
2019-02-09 09:03:29 +03:00
|
|
|
|
Deprecate `no_arg_sql_function!`
This makes the minor changes to `sql_function!` required to allow 0
argument functions to be defined with this macro. `no_arg_sql_function!`
has been deprecated. Even though we could technically remove it since
this is a major version bump, I still would prefer to deprecate things
when possible, so `no_arg_sql_function!` will live on until 3.0.
There are some changes in behavior here. The most notable is that we
generate a function rather than a unit struct. I had previously
considered having the macro create a unit struct instead of a module if
there were no arguments, but ultimately I think the difference in
behavior is confusing, and requiring folks to put `()` at the end of
calls isn't a huge migration pain.
The biggest thing that `sql_function!` doesn't support is the ability to
add a constraint to the backends allowed. This capability was originally
added for `NOW()`, back when we actually generated that SQL instead of
`CURRENT_TIMESTAMP`. We stopped using it a long time ago, and I doubt
anyone else is using this in the wild. Honestly it was a pretty poorly
thought out feature to begin with, so I'm happy to see it go. If we
decide in the future we want to support this for `sql_function!`, I
think the best way to do it is to allow `where` clauses at the end, and
any bounds that are on `DB` get magically applied to the write
impls/type variable. That behavior feels really implicit and confusing,
so I think we should probably just encourage folks to not use
`sql_function!` if they need lower level control.
One unfortunate side effect of this is that `now` still doesn't get
parenthesis, and we can't have a function and struct with the same name.
If we *really* want to migrate `now` to be consistent, we could
implement all the traits implemented on `now` for `fn() -> now`. This is
a terrible terrible awful hack but could actually work.
2019-02-16 14:35:27 +03:00
|
|
|
* `no_arg_sql_function!` has been deprecated without replacement.
|
|
|
|
[`sql_function!`][sql-function-2-0-0] can now be used for functions with zero
|
|
|
|
arguments. See [the migration guide][2-0-migration] for more details.
|
|
|
|
|
Restructure `Backend::RawValue` to allow non-references
As part of Diesel 2.0 we want to change all our backends which currently
have `type RawValue = [u8]` to instead return some opaque struct which
can possibly carry additional information. There are a lot of motivating
use cases for that change, such as including the OID on PG to allow for
working with dynamic schemas, and reducing our reliance on implicit
casts in `libmysqlclient` as attempted by #1457.
Regardless of what these opaque structs do or don't do, we will need to
move away from the signature of `&DB::RawValue`. If we keep this
signature, we would basically be forcing all backends to do what the
SQLite backend did prior to 718a32ea.
In an ideal world, [GATs] would be stable and we would just write `type
RawValue<'a>;`. However, they aren't stable. Implementation on them
appears to have barely started, so it's unlikely that they will be
stable by the time 2.0 comes out. (If it does, or appears close to
happening, we should switch to using that before releasing 2.0).
This introduces a new trait, `HasRawValue`, which acts as the "GAT" form
of the `RawValue` type. The choice to make this a separate trait vs
adding a lifetime to `Backend` was very explicit. Most code which
involves the `Backend` trait doesn't care about the type of `RawValue`,
and adding a lifetime would require virtually all bounds on `Backend`
(including the code which actually does care about `RawValue`) to change
`DB: Backend` to `DB: for<'a> Backend<'a>`.
This does have the unfortunate side effect of breaking code that isn't
currently relying on the type of `Backend` in any concrete fashion.
There's no way around this without keeping the signature of `FromSql` as
`&Something` which is a burden we really don't want to have. The
`backend::RawValue` helper type has been introduced as a forwards
compatibility shim, so code using this new helper type will continue to
work if we switch to GATs in 3.0. The only code which couldn't use this
is the code which was generic over `RawValue = [u8]`. I expect we can
abstract that away in a follow up PR (more on that below).
This was spun off from #1833 as an alternative to a major piece of that
PR which I was unhappy with. One important note is that the motivating
use case that #1833 is trying to address naturally means we can no
longer have the generic "I have some bytes please don't make me rewrite
the impls for integers/floats/byte arrays" impls. This PR is meant to be
standalone against master, so it does not attempt to address everything
done in #1833, and therefore includes some ugly bounds to keep these
impls around. I would actually like to see us keep them if possible, and
I think we can do so with an explicit trait implementation. But that
will be experimented in another PR.
[GATs]: https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
2019-02-01 01:53:45 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* The way [the `Backend` trait][backend-2-0-0] handles its `RawValue` type has
|
|
|
|
been changed to allow non-references. Users of this type (e.g. code written
|
|
|
|
`&DB::RawValue` or `&<DB as Backend>::RawValue>`) should use
|
|
|
|
[`backend::RawValue<DB>`][raw-value-2-0-0] instead. Implementors of `Backend`
|
|
|
|
should check the relevant section of [the migration guide][2-0-migration].
|
|
|
|
|
|
|
|
[backend-2-0-0]: http://docs.diesel.rs/diesel/backend/trait.Backend.html
|
|
|
|
[raw-value-2-0-0]: http://docs.diesel.rs/diesel/backend/type.RawValue.html
|
|
|
|
|
Store sign information in `Mysql::TypeMetadata`
This is the concrete implementation of the proposal described at
https://discourse.diesel.rs/t/proposed-change-add-unsigned-types-to-mysqltype/66.
I have opted for a different implementation than originally imagined --
Rather than adding variants to `MysqlType`, I have kept the flag
separate. MySQL is unlikely to add variants to the `enum_field_types`
enum for backwards compatibility, but I don't want to rule out them
paying attention to the `is_signed` flag for existing variants in the
future.
This makes the impact greater in some ways, and lesser in others. Folks
who were exhaustively matching on `MysqlType` will not have their code
break as they would have in the original code. However, anyone
implementing or calling `<Mysql as HasSqlType<_>>::metadata` will have
to work with this new struct if they were manually constructing or
maniuplating the result.
Ultimately the expected impact is the same as before -- nobody. Unless
someone is writing their own Mysql connection adapter, there's no reason
folks would have been working with this type in the first place.
The proposal left whether we should make the enum non-exhaustive as an
unresolved question. I've opted to leave it exhaustive, since exhaustive
matching is a worthwhile thing to do, and I don't expect libmysqlclient
to add new variants on their end. Under similar logic, I've opted to
allow destructuring/public construction of the new struct. The only
field that we aren't currently mapping is `is_null`, which doens't
currently make sense in our type system. I think before 2.0 ships, we'll
want to add an `is_null` field on this struct, which could be used by a
theoretical future `Null` type. With this field, we will have covered
everything in libmysqlclient's API, which I don't see them adding to,
and thus I think we are safe leaving this struct public
Since the unsigned flag is now passed around as a named field of a
struct, I don't think the enum used before carries any value over a
boolean
2019-03-28 23:22:19 +03:00
|
|
|
* The type metadata for MySQL has been changed to include sign information. If
|
2020-06-10 12:26:07 +03:00
|
|
|
you are implementing `HasSqlType` for `Mysql` manually, you may need to adjust
|
|
|
|
your implementation to fully use the new unsigned variants in `MysqlType`
|
Store sign information in `Mysql::TypeMetadata`
This is the concrete implementation of the proposal described at
https://discourse.diesel.rs/t/proposed-change-add-unsigned-types-to-mysqltype/66.
I have opted for a different implementation than originally imagined --
Rather than adding variants to `MysqlType`, I have kept the flag
separate. MySQL is unlikely to add variants to the `enum_field_types`
enum for backwards compatibility, but I don't want to rule out them
paying attention to the `is_signed` flag for existing variants in the
future.
This makes the impact greater in some ways, and lesser in others. Folks
who were exhaustively matching on `MysqlType` will not have their code
break as they would have in the original code. However, anyone
implementing or calling `<Mysql as HasSqlType<_>>::metadata` will have
to work with this new struct if they were manually constructing or
maniuplating the result.
Ultimately the expected impact is the same as before -- nobody. Unless
someone is writing their own Mysql connection adapter, there's no reason
folks would have been working with this type in the first place.
The proposal left whether we should make the enum non-exhaustive as an
unresolved question. I've opted to leave it exhaustive, since exhaustive
matching is a worthwhile thing to do, and I don't expect libmysqlclient
to add new variants on their end. Under similar logic, I've opted to
allow destructuring/public construction of the new struct. The only
field that we aren't currently mapping is `is_null`, which doens't
currently make sense in our type system. I think before 2.0 ships, we'll
want to add an `is_null` field on this struct, which could be used by a
theoretical future `Null` type. With this field, we will have covered
everything in libmysqlclient's API, which I don't see them adding to,
and thus I think we are safe leaving this struct public
Since the unsigned flag is now passed around as a named field of a
struct, I don't think the enum used before carries any value over a
boolean
2019-03-28 23:22:19 +03:00
|
|
|
|
2020-04-11 03:26:55 +03:00
|
|
|
* The minimal officially supported rustc version is now 1.40.0
|
2019-08-06 23:14:27 +03:00
|
|
|
|
2019-08-06 23:28:50 +03:00
|
|
|
* The `RawValue` types for the `Mysql` and `Postgresql` backend where changed
|
|
|
|
from `[u8]` to distinct opaque types. If you used the concrete `RawValue` type
|
|
|
|
somewhere you need to change it to `mysql::MysqlValue` or `pg::PgValue`.
|
2020-02-26 18:06:03 +03:00
|
|
|
|
2020-01-15 12:44:31 +03:00
|
|
|
* The uuidv07 feature was renamed to uuid, due to the removal of support for older uuid versions
|
2020-02-26 18:06:03 +03:00
|
|
|
|
2019-06-03 09:13:06 +03:00
|
|
|
* Boxed queries (constructed from `.into_boxed()`) are now `Send`.
|
2019-08-06 23:28:50 +03:00
|
|
|
|
Replace `NonAggregate` with something less broken
This commit implements the proposal laid out at
https://discourse.diesel.rs/t/proposed-change-replace-nonaggregate-with-something-less-broken-that-can-support-group-by/18.
The changes made in this commit now correctly enforce semantics around
the mixing of aggregate/non-aggregate expressions, and lays the
foundations required for full `GROUP BY` support in the future. This
commit does not implement `GROUP BY` as a feature in public API, though
I have added some minimal support to prove the soundness of the change.
Since this will likely be the largest breaking change in 2.0, I am going
to include as much detail as I can about the problem, the reasoning
behind the solution, and the likely impact of the change.
Recap of the problem
----
`NonAggregate` was originally introduced in
c66d96fa9cefaba0a418834e8cb0e78a0a87269a. The goal was to prevent the
following error at compile time:
[local] sean@sean=# select count(*), name from users;
ERROR: 42803: column "users.name" must appear in the GROUP BY clause or be used in an aggregate function
I didn't think about this nearly as much as I should have at the time,
which resulted in a hilariously broken implementation that has prevented
the addition of `group_by` support, and left bugs in the codebase for
more than 4 years.
At the time I was focused on "mixing aggregate and non-aggregate
expressions in a select statement". Since select uses tuples to
represent multiple values, I added a trait to represent non-aggregate
values, added it as a bound for `impl Expression for AnyTuple`, and
called it a day. This had a number of problems.
The most obvious was that it prevented valid queries involving multiple
aggregate expressions. At the time I figured we'd have a separate
trait for aggregate expressions, and then `impl Expression for AnyTuple
where AllFields: NonAggregate | AllFields: Aggregate`. This eventually
led to [RFC #1268](https://github.com/rust-lang/rfcs/pull/1268), which
doesn't seem likely to be stabilized soon, and even if it were we still
have the other issues with this solution.
The next issue is that you cannot say whether a given expression is
aggregate by looking at it on its own. The answer to "Is `users`.`name`
aggregate?" depends on whether or not that column appears in the group
by clause. So any trait which correctly handles this must be generic
over the group by clause, or it cannot be correctly implemented for
columns.
However, the most egregious issue with that commit is that it does not
handle *any* composite expressions besides tuples. Even today,
`.select((count_star(), id))` fails, but `.select(count_star() + id)`
will compile (and either error at runtime or give non-deterministic
results depending on your backend).
User Impact
----
This change will unfortunately have more breakage than I had
anticipated. That said, the breakage only affects *extremely* generic
code, and I do not believe that the majority of our users will notice or
care about this change.
There are three main ways in which the breakage will affect users:
- The additional bound on `SelectStatement<...>: SelectDsl` and
`SelectStatement<...>: Query`.
- This one broke our test suite in a few places, mainly where we have
*really* generic code to say "I can select T.eq(sql_string)". I do
not believe this is representative of real code.
- I did a GitHub-wide search of all occurances of
`SelectableExpression` (which is *not* the bound on the public API,
but is the bound on `SelectStatement`'s impl, and would point to
broken code). I found one repo which is relying on internals that
will break, and a lot of results from Wundergraph. I didnt' look at
those. This probably breaks Wundergraph. Sorry, Georg. It should be
easy to fix I promise.
- `NonAggregate` can no longer be directly implemented
- I did a GitHub-wide search for `NonAggregate`. With one exception,
every repo implementing this trait directly was on pre-1.0. The only
affected repo is manually implementing `Expression` instead of using
`#[derive(AsExpression)]`. With that change they will be
future-proofed.
- `T: NonAggregate` no longer implies `(OtherType, T): NonAggregate`
- This broke `infer_schema`, since it was relying on `AssocType:
NonAggregate` to know `(known_column, AssocType, known_column):
Expression`. Ironically, that's no longer important, it did still
break due to the first item on this list. I could not find any code
in the wild that fell into this category.
Originally I thought that the only code which would be affected by this
is code that wrote `impl NonAggregate`, since that code would need to
change to `impl ValidGrouping`. However, I missed a few things when I
made that assessment.
The first is that... Well the feature exists. The whole point of this
was to prevent `aggregate + non_aggregate` from compiling when passed to
select, which implies a new trait bound *somewhere*. While
`SelectStatement` and its impls are private API, it's really easy to
couple yourself ot the bounds on those impls. It doesn't help that
`rustc` literally recommends that folks do that when errors occur. Any
code that is written as `Foo: SelectDsl<Selection>` will be fine, but
any code that's gone down the rabbit hole and has copied the bounds from
`impl SelectDsl for SelectStatement<...>` will break. I didn't find many
cases in the wild, but I do think it's relatively common.
The second thing I missed is that "is this aggregate" is not a binary
question. Originally I expected we would have two answers to the
question, and compound expressions would enforce that their
sub-expressions all had the same answer. The issue is that `1` doesn't
care. You can have `count(*) + 1`, and you can also have `non_aggregate
+ 1`. `1` is always valid, regardless of aggregation. So we need three
answers. The problem is that this means we can't have `T: NonAggregate`
mean everything it used to.
On stable `T: NonAggregate` will mean `T: ValidGrouping<()>`, and that
`T` can be passed to everything with a `NonAggregate` bound (`filter`,
`order`, etc). On nightly, it also implies `T::IsAggregate:
MixedAggregates<is_aggregate::No, Output = is_aggregate::No>`. In
English, it implies that this is valid with no group by clause, and its
output can appear with an expression which is not aggregate (but might
be with a different group by clause). The outcome of this is that `T:
NonAggregate` implies `(T, Other): NonAggregate`. However the missing
link from both stable and unstable is `is_aggregate::No:
MixedAggregates<T::IsAggregate>` being implied, which would mean
`(Other, T): NonAggregate` would be implied.
Ultimately this is a really long-winded way of saying that `T:
NonAggregate` used to imply interactions with other types. That is no
longer consistently true. It's unlikely there are many affected users,
but any that are affected will need to directly have a `ValidGrouping`
bound.
Implementation Notes
---
Because this broke diesel_infer_schema, I had to do a version bump to
get that crate to rely on the released 1.4.
There's a note on the unsoundness of the `NonAggregate` impl of
`Subselect`. I haven't changed the bounds on that impl, but we almost
certainly should address it before 2.0 is released.
I opted to validate the new bound in `SelectDsl`, so folks get errors on
`.select` instead of `.load`. We can't validate this on calls to both
`.select` *and* `.group_by`, since a select statement valid with a group
by is often invalid without one, and a group by clause usually makes the
default select clause invalid.
While this commit does not add proper group by support, I fleshed it out
a bit to test the type constraints. Right now a column only considers
itself valid if there is no group by clause, or if the group by clause
is exactly that column.
I had more to say but I went on a call and lost my train of thought. I
need to come back and finish writing this later.
Notable Limitations
---
`SELECT lower(name) FROM users GROUP BY lower(name)` probably can't be
represented.
Unanswered Questions
---
`BoxableExpression` has been limited to only work when there's no
group by clause, and only work with types which are `is_aggregate::No`.
This is probably not what we want to do, but was the smallest change to
start.
2019-12-18 23:30:29 +03:00
|
|
|
* The handling of mixed aggregate values is more robust. Invalid queries such as
|
|
|
|
`.select(max(id) + other_column)` are now correctly rejected, and valid
|
|
|
|
queries such as `.select((count_star(), max(other_column)))` are now correctly
|
|
|
|
accepted. For more details, see [the upgrade notes](#2-0-0-upgrade-non-aggregate).
|
|
|
|
|
|
|
|
* `NonAggregate` is now a trait alias for `ValidGrouping<()>` for expressions
|
|
|
|
that are not aggregate. On stable this is a normal trait with a blanket impl,
|
|
|
|
but it should never be implemented directly. With the `unstable` feature, it
|
|
|
|
will use trait aliases which prevent manual implementations.
|
|
|
|
|
|
|
|
Due to language limitations, we cannot make the new trait alias by itself
|
|
|
|
represent everything it used to, so in some rare cases code changes may be
|
|
|
|
required. See [the upgrade notes](#2-0-0-upgrade-non-aggregate) for details.
|
|
|
|
|
2020-04-22 17:18:04 +03:00
|
|
|
* Various `__NonExhaustive` variants in different (error-) enums are replaced with
|
|
|
|
`#[non_exhaustive]`. If you matched on one of those variants explicitly you need to
|
|
|
|
introduce a wild card match instead.
|
|
|
|
|
2020-06-27 02:26:22 +03:00
|
|
|
* `FromSql::from_sql` is changed to construct value from non nullable database values.
|
|
|
|
To construct a rust value for nullable values use the new `FromSql::from_nullable_sql`
|
|
|
|
method instead.
|
|
|
|
|
|
|
|
* Custom sql types are now required to implement the new `SqlType` trait. Diesel will
|
|
|
|
automatically create implementations of that trait for all types having a `#[derive(SqlType)]`
|
|
|
|
|
|
|
|
* The workflow for manually implementing support custom types has changed. Implementing
|
|
|
|
`FromSqlRow<ST, DB>` is not required anymore, as this is now implied by implementing
|
|
|
|
`FromSql<ST, DB>`. The requirement of implementing `Queryable<ST, DB>` remains
|
|
|
|
unchanged. For types using `#[derive(FromSqlRow)]` no changes are required as the
|
|
|
|
derive automatically generates the correct code
|
|
|
|
|
|
|
|
* The structure of our deserialization trait has changed. Loading values from the database
|
|
|
|
requires now that the result type implements `FromSqlRow<ST, DB>`. Diesel provides wild
|
|
|
|
card implementations for types implementing `Queryable<ST, DB>` or `QueryableByName<DB>`
|
|
|
|
so non generic code does not require any change. For generic code you likely need to
|
|
|
|
replace a trait bound on `Queryable<ST, DB>` with a trait bound on `FromSqlRow<ST, DB>`
|
|
|
|
and a bound to `QueryableByName<DB>` with `FromSqlRow<Untyped, DB>`.
|
|
|
|
|
2019-09-30 14:19:28 +03:00
|
|
|
* CLI flags of `only-tables` and `except-tables` are now interpreted as regular expressions.
|
|
|
|
Similary, `only_tabels` and `except_tables` in `diesel.toml` are treated as regular expressions.
|
|
|
|
|
2020-10-31 17:26:19 +03:00
|
|
|
* Now you can sort column fields by name with the `column-sorting` option.
|
2021-01-26 16:38:40 +03:00
|
|
|
It can be set to either `ordinal_position` (default) or `name`.
|
|
|
|
This ensures stable sorting even if columns are removed and re-added.
|
|
|
|
|
|
|
|
* The `Queryable<ST,DB>` trait was updated to be made faillible, in order to properly handle
|
|
|
|
cases where you detect a data inconsistency between fields on deserialization
|
|
|
|
(that e.g. was supposed to be made impossible by DB `CHECK`s). The `build` function now
|
|
|
|
returns a
|
|
|
|
[`diesel::deserialize::Result<Self>`](https://docs.diesel.rs/master/diesel/deserialize/type.Result.html)
|
|
|
|
instead of a `Self`.
|
2020-10-31 17:26:19 +03:00
|
|
|
|
2021-02-11 20:22:16 +03:00
|
|
|
* `TypeMetadata::MetadataLookup` is now `?Sized`.
|
|
|
|
|
|
|
|
* Multiple implementations of `Connection<Backend=Pg>` are now possible
|
|
|
|
because of the new `PgMetadataLookup` trait.
|
|
|
|
|
|
|
|
* For the `Pg` backend, `TypeMetadata::MetadataLookup` has changed to `dyn PgMetadataLookup`.
|
|
|
|
|
2019-02-17 16:34:13 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Many types were incorrectly considered non-aggregate when they should not
|
|
|
|
have been. All types in Diesel are now correctly only considered
|
|
|
|
non-aggregate if their parts are.
|
|
|
|
|
2019-04-09 19:40:40 +03:00
|
|
|
* Offset clauses without limit clauses resulted into invalid sql using the mysql or
|
|
|
|
sqlite backend. Both do not support such clauses without a preceding limit clause.
|
|
|
|
For those backend Diesel does now generate a fake limit clause in case no explicit
|
2020-04-21 15:38:55 +03:00
|
|
|
limit clause was given. As consequence of this change generic query code may
|
|
|
|
require additional trait bounds as requested from the compiler. Third party
|
|
|
|
backends are required to explicitly provide `QueryFragment` impls for
|
|
|
|
`LimitOffsetClause<L, O>` now.
|
2019-02-17 16:34:13 +03:00
|
|
|
|
Correctly enforce nullability with nested joins
When multiple joins are nested together, the resulting type is
essentially a binary tree of each individal join. What this means is
that Diesel only has to consider one join at a time in trait
implementations.
Prior to this commit, when considering nullability, we mistakenly only
considered the outermost join. "Considering nullability" in this case
means `impl SelectableExpression<TheJoin> for column`. If that trait is
implemented, we allow selecting the column directly. If it appears on
the right side of a left join, we do not want that trait to be
implemented, but we do want it implemented for `Nullable<column>`.
The problem code lived in two generated impls in the `table!` macro. For
each individual column, we generate two relevant `SelectableExpression`
impls: one for inner joins, and one for left joins. Both of these impls
were wrong.
The impl for left joins was written as:
Left: AppearsInFromClause<$table, Count=Once>,
Right: AppearsInFromClause<$table, Count=Never>,
which in English means "where my table appears once in the left side of
the join, and doesn't appear in the right side of the join". This
incorrectly assumes that `$table` is the left-most table, or all joins
contained in `Left` are inner joins. If `Left == Join<other_table,
$table, LeftOuter>`, this constraint incorrectly holds. This first case
was much easier to solve. The first line is changed to:
Self: SelectableExpression<Left>
The inner join case was much harder to solve. The constraint was written
as:
Join<Left, Right, Inner>: AppearsInFromClause<$table, Count=Once>,
In English, this means "my table appears in this join clause exactly
once". This fails to consider that the position the table appears in may
be the right side of a left join. What we really want to write here is
something like this:
Self: SelectableExpression<Left> | SelectableExpression<Right>,
Where the pipe means "either of these constraints are true". Of course
no such impl exists. If we write two separate impls, they are
overlapping (and overlapping marker traits are not stable). So we need
something different.
Since the problem case applies only to columns, we know that the only
reason that `SelectableExpression<Left>` and
`SelectableExpression<Right>` both hold is if the table appears more
than once in the from clause, which we already reject. Because of this,
we know that when we want this impl to apply, `(<Left as
AppearsInFromClause<$table>>::Count, <Right as
AppearsInFromClause<$table>>::Count>)` will either be `(Once, Never)` or
`(Never, Once)`.
Now that we know we have two disjoint types, we can use that to
implement a new trait, which gives us either `Left` or `Right` depending
on which of the two counts was `Once`, and use that as the parameter for
`SelectableExpression`. In English, the new bounds mean "I am selectable
from whichever of these two type parameters contains my table"
Since this new trait is only meant as a hack for this single impl, and
is not public API, I wanted to avoid having it appear in compiler
errors. For this reason, I've added additional impls for all the invalid
count combinations. This will lead to an error such as:
> table3::id: SelectableExpression<this_table_does_not_appear_in_the_from_clause>
instead of
> (Never, Never): Select<table1, table2>
I did not add explicit compile tests for these errors, as I want to
allow for the deletion of those impls if they become a problem in the
future.
This lead to the final challenge which is that our `impl
SelectableExpression<Join<...>> for Nullable<T>` actually relied on this
bug. We considered `Nullable<T>: SelectableExpression<AnyJoin>` if `T:
SelectableExpression<InnerJoin>`. This of course would break if the
actual table is on the right side of a nested left join. To work around
this, we've introduced another new trait which recursively converts all
joins in a tree to inner joins, which we then use for our check. This
also simplified the various impls for `Nullable<T>`, and should
correctly ensure that `Nullable<T>` is always usable.
Fixes #2001.
2019-12-05 20:46:19 +03:00
|
|
|
* Nullability requirements are now properly enforced for nested joins.
|
|
|
|
Previously, only the rules for the outer-most join were considered. For
|
|
|
|
example, `users.left_join(posts).left_join(comments)` would allow selecting
|
|
|
|
any columns from `posts`. That will now fail to compile, and any selections
|
|
|
|
from `posts` will need to be made explicitly nullable.
|
|
|
|
|
2019-05-16 22:40:07 +03:00
|
|
|
* Diesel CLI will now look for `diesel.toml` to determine the project root
|
|
|
|
before looking for `Cargo.toml`.
|
|
|
|
|
|
|
|
* Any relative paths in `diesel.toml` will now be treated as relative to the
|
|
|
|
project root (the directory containing either `diesel.toml` or `Cargo.toml`).
|
|
|
|
They are no longer dependent on the current working directory (for all
|
|
|
|
directories in the same project)
|
|
|
|
|
2020-05-21 04:56:43 +03:00
|
|
|
* The SQLite backend is now configured to interpret URIs.
|
|
|
|
See [the SQLite URI documentation] for additional details.
|
|
|
|
|
|
|
|
[the SQLite URI documentation]: https://www.sqlite.org/uri.html
|
|
|
|
|
2020-06-06 00:36:42 +03:00
|
|
|
* We've refactored our type translation layer for Mysql to handle more types now.
|
|
|
|
|
2020-06-27 02:26:22 +03:00
|
|
|
* We've refactored our type level representation of nullable values. This allowed us to
|
|
|
|
fix multiple long standing bugs regarding the correct handling of nullable values in some
|
|
|
|
corner cases (#104, #2274)
|
2020-09-28 18:38:30 +03:00
|
|
|
|
|
|
|
* Parenthesis are now inserted around all infix operations provided by diesel's `ExpressionMethods` traits
|
2020-06-27 02:26:22 +03:00
|
|
|
|
2021-01-28 17:48:11 +03:00
|
|
|
* Queries containing a `distinct on` clause check now on compile time that a compatible order clause was set.
|
|
|
|
|
2019-02-24 04:17:52 +03:00
|
|
|
### Deprecated
|
|
|
|
|
|
|
|
* `diesel_(prefix|postfix|infix)_operator!` have been deprecated. These macros
|
|
|
|
are now available without the `diesel_` prefix. With Rust 2018 they can be
|
|
|
|
invoked as `diesel::infix_operator!` instead.
|
Restructure `Backend::RawValue` to allow non-references
As part of Diesel 2.0 we want to change all our backends which currently
have `type RawValue = [u8]` to instead return some opaque struct which
can possibly carry additional information. There are a lot of motivating
use cases for that change, such as including the OID on PG to allow for
working with dynamic schemas, and reducing our reliance on implicit
casts in `libmysqlclient` as attempted by #1457.
Regardless of what these opaque structs do or don't do, we will need to
move away from the signature of `&DB::RawValue`. If we keep this
signature, we would basically be forcing all backends to do what the
SQLite backend did prior to 718a32ea.
In an ideal world, [GATs] would be stable and we would just write `type
RawValue<'a>;`. However, they aren't stable. Implementation on them
appears to have barely started, so it's unlikely that they will be
stable by the time 2.0 comes out. (If it does, or appears close to
happening, we should switch to using that before releasing 2.0).
This introduces a new trait, `HasRawValue`, which acts as the "GAT" form
of the `RawValue` type. The choice to make this a separate trait vs
adding a lifetime to `Backend` was very explicit. Most code which
involves the `Backend` trait doesn't care about the type of `RawValue`,
and adding a lifetime would require virtually all bounds on `Backend`
(including the code which actually does care about `RawValue`) to change
`DB: Backend` to `DB: for<'a> Backend<'a>`.
This does have the unfortunate side effect of breaking code that isn't
currently relying on the type of `Backend` in any concrete fashion.
There's no way around this without keeping the signature of `FromSql` as
`&Something` which is a burden we really don't want to have. The
`backend::RawValue` helper type has been introduced as a forwards
compatibility shim, so code using this new helper type will continue to
work if we switch to GATs in 3.0. The only code which couldn't use this
is the code which was generic over `RawValue = [u8]`. I expect we can
abstract that away in a follow up PR (more on that below).
This was spun off from #1833 as an alternative to a major piece of that
PR which I was unhappy with. One important note is that the motivating
use case that #1833 is trying to address naturally means we can no
longer have the generic "I have some bytes please don't make me rewrite
the impls for integers/floats/byte arrays" impls. This PR is meant to be
standalone against master, so it does not attempt to address everything
done in #1833, and therefore includes some ugly bounds to keep these
impls around. I would actually like to see us keep them if possible, and
I think we can do so with an explicit trait implementation. But that
will be experimented in another PR.
[GATs]: https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
2019-02-01 01:53:45 +03:00
|
|
|
|
2020-03-09 13:58:20 +03:00
|
|
|
* `diesel::pg::upsert` has been deprecated to support upsert queries on more than one backend.
|
|
|
|
Please use `diesel::upsert` instead.
|
Restructure `Backend::RawValue` to allow non-references
As part of Diesel 2.0 we want to change all our backends which currently
have `type RawValue = [u8]` to instead return some opaque struct which
can possibly carry additional information. There are a lot of motivating
use cases for that change, such as including the OID on PG to allow for
working with dynamic schemas, and reducing our reliance on implicit
casts in `libmysqlclient` as attempted by #1457.
Regardless of what these opaque structs do or don't do, we will need to
move away from the signature of `&DB::RawValue`. If we keep this
signature, we would basically be forcing all backends to do what the
SQLite backend did prior to 718a32ea.
In an ideal world, [GATs] would be stable and we would just write `type
RawValue<'a>;`. However, they aren't stable. Implementation on them
appears to have barely started, so it's unlikely that they will be
stable by the time 2.0 comes out. (If it does, or appears close to
happening, we should switch to using that before releasing 2.0).
This introduces a new trait, `HasRawValue`, which acts as the "GAT" form
of the `RawValue` type. The choice to make this a separate trait vs
adding a lifetime to `Backend` was very explicit. Most code which
involves the `Backend` trait doesn't care about the type of `RawValue`,
and adding a lifetime would require virtually all bounds on `Backend`
(including the code which actually does care about `RawValue`) to change
`DB: Backend` to `DB: for<'a> Backend<'a>`.
This does have the unfortunate side effect of breaking code that isn't
currently relying on the type of `Backend` in any concrete fashion.
There's no way around this without keeping the signature of `FromSql` as
`&Something` which is a burden we really don't want to have. The
`backend::RawValue` helper type has been introduced as a forwards
compatibility shim, so code using this new helper type will continue to
work if we switch to GATs in 3.0. The only code which couldn't use this
is the code which was generic over `RawValue = [u8]`. I expect we can
abstract that away in a follow up PR (more on that below).
This was spun off from #1833 as an alternative to a major piece of that
PR which I was unhappy with. One important note is that the motivating
use case that #1833 is trying to address naturally means we can no
longer have the generic "I have some bytes please don't make me rewrite
the impls for integers/floats/byte arrays" impls. This PR is meant to be
standalone against master, so it does not attempt to address everything
done in #1833, and therefore includes some ugly bounds to keep these
impls around. I would actually like to see us keep them if possible, and
I think we can do so with an explicit trait implementation. But that
will be experimented in another PR.
[GATs]: https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
2019-02-01 01:53:45 +03:00
|
|
|
|
Replace `NonAggregate` with something less broken
This commit implements the proposal laid out at
https://discourse.diesel.rs/t/proposed-change-replace-nonaggregate-with-something-less-broken-that-can-support-group-by/18.
The changes made in this commit now correctly enforce semantics around
the mixing of aggregate/non-aggregate expressions, and lays the
foundations required for full `GROUP BY` support in the future. This
commit does not implement `GROUP BY` as a feature in public API, though
I have added some minimal support to prove the soundness of the change.
Since this will likely be the largest breaking change in 2.0, I am going
to include as much detail as I can about the problem, the reasoning
behind the solution, and the likely impact of the change.
Recap of the problem
----
`NonAggregate` was originally introduced in
c66d96fa9cefaba0a418834e8cb0e78a0a87269a. The goal was to prevent the
following error at compile time:
[local] sean@sean=# select count(*), name from users;
ERROR: 42803: column "users.name" must appear in the GROUP BY clause or be used in an aggregate function
I didn't think about this nearly as much as I should have at the time,
which resulted in a hilariously broken implementation that has prevented
the addition of `group_by` support, and left bugs in the codebase for
more than 4 years.
At the time I was focused on "mixing aggregate and non-aggregate
expressions in a select statement". Since select uses tuples to
represent multiple values, I added a trait to represent non-aggregate
values, added it as a bound for `impl Expression for AnyTuple`, and
called it a day. This had a number of problems.
The most obvious was that it prevented valid queries involving multiple
aggregate expressions. At the time I figured we'd have a separate
trait for aggregate expressions, and then `impl Expression for AnyTuple
where AllFields: NonAggregate | AllFields: Aggregate`. This eventually
led to [RFC #1268](https://github.com/rust-lang/rfcs/pull/1268), which
doesn't seem likely to be stabilized soon, and even if it were we still
have the other issues with this solution.
The next issue is that you cannot say whether a given expression is
aggregate by looking at it on its own. The answer to "Is `users`.`name`
aggregate?" depends on whether or not that column appears in the group
by clause. So any trait which correctly handles this must be generic
over the group by clause, or it cannot be correctly implemented for
columns.
However, the most egregious issue with that commit is that it does not
handle *any* composite expressions besides tuples. Even today,
`.select((count_star(), id))` fails, but `.select(count_star() + id)`
will compile (and either error at runtime or give non-deterministic
results depending on your backend).
User Impact
----
This change will unfortunately have more breakage than I had
anticipated. That said, the breakage only affects *extremely* generic
code, and I do not believe that the majority of our users will notice or
care about this change.
There are three main ways in which the breakage will affect users:
- The additional bound on `SelectStatement<...>: SelectDsl` and
`SelectStatement<...>: Query`.
- This one broke our test suite in a few places, mainly where we have
*really* generic code to say "I can select T.eq(sql_string)". I do
not believe this is representative of real code.
- I did a GitHub-wide search of all occurances of
`SelectableExpression` (which is *not* the bound on the public API,
but is the bound on `SelectStatement`'s impl, and would point to
broken code). I found one repo which is relying on internals that
will break, and a lot of results from Wundergraph. I didnt' look at
those. This probably breaks Wundergraph. Sorry, Georg. It should be
easy to fix I promise.
- `NonAggregate` can no longer be directly implemented
- I did a GitHub-wide search for `NonAggregate`. With one exception,
every repo implementing this trait directly was on pre-1.0. The only
affected repo is manually implementing `Expression` instead of using
`#[derive(AsExpression)]`. With that change they will be
future-proofed.
- `T: NonAggregate` no longer implies `(OtherType, T): NonAggregate`
- This broke `infer_schema`, since it was relying on `AssocType:
NonAggregate` to know `(known_column, AssocType, known_column):
Expression`. Ironically, that's no longer important, it did still
break due to the first item on this list. I could not find any code
in the wild that fell into this category.
Originally I thought that the only code which would be affected by this
is code that wrote `impl NonAggregate`, since that code would need to
change to `impl ValidGrouping`. However, I missed a few things when I
made that assessment.
The first is that... Well the feature exists. The whole point of this
was to prevent `aggregate + non_aggregate` from compiling when passed to
select, which implies a new trait bound *somewhere*. While
`SelectStatement` and its impls are private API, it's really easy to
couple yourself ot the bounds on those impls. It doesn't help that
`rustc` literally recommends that folks do that when errors occur. Any
code that is written as `Foo: SelectDsl<Selection>` will be fine, but
any code that's gone down the rabbit hole and has copied the bounds from
`impl SelectDsl for SelectStatement<...>` will break. I didn't find many
cases in the wild, but I do think it's relatively common.
The second thing I missed is that "is this aggregate" is not a binary
question. Originally I expected we would have two answers to the
question, and compound expressions would enforce that their
sub-expressions all had the same answer. The issue is that `1` doesn't
care. You can have `count(*) + 1`, and you can also have `non_aggregate
+ 1`. `1` is always valid, regardless of aggregation. So we need three
answers. The problem is that this means we can't have `T: NonAggregate`
mean everything it used to.
On stable `T: NonAggregate` will mean `T: ValidGrouping<()>`, and that
`T` can be passed to everything with a `NonAggregate` bound (`filter`,
`order`, etc). On nightly, it also implies `T::IsAggregate:
MixedAggregates<is_aggregate::No, Output = is_aggregate::No>`. In
English, it implies that this is valid with no group by clause, and its
output can appear with an expression which is not aggregate (but might
be with a different group by clause). The outcome of this is that `T:
NonAggregate` implies `(T, Other): NonAggregate`. However the missing
link from both stable and unstable is `is_aggregate::No:
MixedAggregates<T::IsAggregate>` being implied, which would mean
`(Other, T): NonAggregate` would be implied.
Ultimately this is a really long-winded way of saying that `T:
NonAggregate` used to imply interactions with other types. That is no
longer consistently true. It's unlikely there are many affected users,
but any that are affected will need to directly have a `ValidGrouping`
bound.
Implementation Notes
---
Because this broke diesel_infer_schema, I had to do a version bump to
get that crate to rely on the released 1.4.
There's a note on the unsoundness of the `NonAggregate` impl of
`Subselect`. I haven't changed the bounds on that impl, but we almost
certainly should address it before 2.0 is released.
I opted to validate the new bound in `SelectDsl`, so folks get errors on
`.select` instead of `.load`. We can't validate this on calls to both
`.select` *and* `.group_by`, since a select statement valid with a group
by is often invalid without one, and a group by clause usually makes the
default select clause invalid.
While this commit does not add proper group by support, I fleshed it out
a bit to test the type constraints. Right now a column only considers
itself valid if there is no group by clause, or if the group by clause
is exactly that column.
I had more to say but I went on a call and lost my train of thought. I
need to come back and finish writing this later.
Notable Limitations
---
`SELECT lower(name) FROM users GROUP BY lower(name)` probably can't be
represented.
Unanswered Questions
---
`BoxableExpression` has been limited to only work when there's no
group by clause, and only work with types which are `is_aggregate::No`.
This is probably not what we want to do, but was the smallest change to
start.
2019-12-18 23:30:29 +03:00
|
|
|
### Upgrade Notes
|
|
|
|
|
|
|
|
#### Replacement of `NonAggregate` with `ValidGrouping`
|
|
|
|
<a name="2-0-0-upgrade-non-aggregate"></a>
|
|
|
|
|
|
|
|
FIXME: This should probably be on the website, but I wanted to document it in
|
|
|
|
the PR adding the changes.
|
|
|
|
|
|
|
|
Key points:
|
|
|
|
|
|
|
|
- Rules for aggregation are now correctly enforced. They match the semantics of
|
|
|
|
PG or MySQL with `ONLY_FULL_GROUP_BY` enabled.
|
|
|
|
- As before, `sql` is the escape hatch if needed.
|
|
|
|
- MySQL users can use `ANY_VALUE`, PG users can use `DISTINCT ON`. Also
|
|
|
|
consider using max/min/etc to get deterministic values.
|
|
|
|
- Any `impl NonAggregate` must be replaced with `impl ValidGrouping`
|
|
|
|
- For most code, `T: NonAggregate` should continue to work. Unless you're
|
|
|
|
getting a compiler error, you most likely don't need to change it.
|
|
|
|
- The full equivalent of what `T: NonAggregate` used to mean is:
|
|
|
|
|
|
|
|
where
|
|
|
|
T: ValidGrouping<()>,
|
|
|
|
T::IsAggregate: MixedGrouping<is_aggregate::No, Output = is_aggregate::No>,
|
|
|
|
is_aggreagte::No: MixedGrouping<T::IsAggregate, Output = is_aggreagte::No>,
|
|
|
|
|
|
|
|
- With `feature = "unstable"`, `T: NonAggregate` implies the first two bounds,
|
|
|
|
but not the third. On stable only the first bound is implied. This is a
|
|
|
|
language limitation.
|
|
|
|
- `T: NonAggregate` can still be passed everywhere it could before, but `T:
|
|
|
|
NonAggregate` no longer implies `(OtherType, T): NonAggregate`.
|
|
|
|
- With `feature = "unstable"`, `(T, OtherType): NonAggregate` is still implied.
|
|
|
|
|
2020-10-12 07:43:48 +03:00
|
|
|
- In diesel v1.4 sql functions without arguments used the `no_arg_sql_function!` macro,
|
|
|
|
which has since been deprecated. The new `sql_function!` macro supports functions without
|
|
|
|
arguments.
|
|
|
|
|
Restructure `Backend::RawValue` to allow non-references
As part of Diesel 2.0 we want to change all our backends which currently
have `type RawValue = [u8]` to instead return some opaque struct which
can possibly carry additional information. There are a lot of motivating
use cases for that change, such as including the OID on PG to allow for
working with dynamic schemas, and reducing our reliance on implicit
casts in `libmysqlclient` as attempted by #1457.
Regardless of what these opaque structs do or don't do, we will need to
move away from the signature of `&DB::RawValue`. If we keep this
signature, we would basically be forcing all backends to do what the
SQLite backend did prior to 718a32ea.
In an ideal world, [GATs] would be stable and we would just write `type
RawValue<'a>;`. However, they aren't stable. Implementation on them
appears to have barely started, so it's unlikely that they will be
stable by the time 2.0 comes out. (If it does, or appears close to
happening, we should switch to using that before releasing 2.0).
This introduces a new trait, `HasRawValue`, which acts as the "GAT" form
of the `RawValue` type. The choice to make this a separate trait vs
adding a lifetime to `Backend` was very explicit. Most code which
involves the `Backend` trait doesn't care about the type of `RawValue`,
and adding a lifetime would require virtually all bounds on `Backend`
(including the code which actually does care about `RawValue`) to change
`DB: Backend` to `DB: for<'a> Backend<'a>`.
This does have the unfortunate side effect of breaking code that isn't
currently relying on the type of `Backend` in any concrete fashion.
There's no way around this without keeping the signature of `FromSql` as
`&Something` which is a burden we really don't want to have. The
`backend::RawValue` helper type has been introduced as a forwards
compatibility shim, so code using this new helper type will continue to
work if we switch to GATs in 3.0. The only code which couldn't use this
is the code which was generic over `RawValue = [u8]`. I expect we can
abstract that away in a follow up PR (more on that below).
This was spun off from #1833 as an alternative to a major piece of that
PR which I was unhappy with. One important note is that the motivating
use case that #1833 is trying to address naturally means we can no
longer have the generic "I have some bytes please don't make me rewrite
the impls for integers/floats/byte arrays" impls. This PR is meant to be
standalone against master, so it does not attempt to address everything
done in #1833, and therefore includes some ugly bounds to keep these
impls around. I would actually like to see us keep them if possible, and
I think we can do so with an explicit trait implementation. But that
will be experimented in another PR.
[GATs]: https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
2019-02-01 01:53:45 +03:00
|
|
|
[2-0-migration]: FIXME write a migration guide
|
2020-06-09 14:32:23 +03:00
|
|
|
|
|
|
|
## [1.4.5] - 2020-06-09
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Update several dependencies
|
|
|
|
* Fixed an issue where transactions that would fail to commit would leave the connection
|
|
|
|
in a broken non-committed non-rolled-back state.
|
|
|
|
* Fix a bug that result in leaking sockets/file descriptors on failed connection attempts
|
|
|
|
for postgresql
|
|
|
|
* Fix an incompatibility with newer `libmysqlclient` versions
|
|
|
|
* Remove some potential harmful usages of `mem::uninitialized`
|
Restructure `Backend::RawValue` to allow non-references
As part of Diesel 2.0 we want to change all our backends which currently
have `type RawValue = [u8]` to instead return some opaque struct which
can possibly carry additional information. There are a lot of motivating
use cases for that change, such as including the OID on PG to allow for
working with dynamic schemas, and reducing our reliance on implicit
casts in `libmysqlclient` as attempted by #1457.
Regardless of what these opaque structs do or don't do, we will need to
move away from the signature of `&DB::RawValue`. If we keep this
signature, we would basically be forcing all backends to do what the
SQLite backend did prior to 718a32ea.
In an ideal world, [GATs] would be stable and we would just write `type
RawValue<'a>;`. However, they aren't stable. Implementation on them
appears to have barely started, so it's unlikely that they will be
stable by the time 2.0 comes out. (If it does, or appears close to
happening, we should switch to using that before releasing 2.0).
This introduces a new trait, `HasRawValue`, which acts as the "GAT" form
of the `RawValue` type. The choice to make this a separate trait vs
adding a lifetime to `Backend` was very explicit. Most code which
involves the `Backend` trait doesn't care about the type of `RawValue`,
and adding a lifetime would require virtually all bounds on `Backend`
(including the code which actually does care about `RawValue`) to change
`DB: Backend` to `DB: for<'a> Backend<'a>`.
This does have the unfortunate side effect of breaking code that isn't
currently relying on the type of `Backend` in any concrete fashion.
There's no way around this without keeping the signature of `FromSql` as
`&Something` which is a burden we really don't want to have. The
`backend::RawValue` helper type has been introduced as a forwards
compatibility shim, so code using this new helper type will continue to
work if we switch to GATs in 3.0. The only code which couldn't use this
is the code which was generic over `RawValue = [u8]`. I expect we can
abstract that away in a follow up PR (more on that below).
This was spun off from #1833 as an alternative to a major piece of that
PR which I was unhappy with. One important note is that the motivating
use case that #1833 is trying to address naturally means we can no
longer have the generic "I have some bytes please don't make me rewrite
the impls for integers/floats/byte arrays" impls. This PR is meant to be
standalone against master, so it does not attempt to address everything
done in #1833, and therefore includes some ugly bounds to keep these
impls around. I would actually like to see us keep them if possible, and
I think we can do so with an explicit trait implementation. But that
will be experimented in another PR.
[GATs]: https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
2019-02-01 01:53:45 +03:00
|
|
|
|
2020-03-23 16:50:07 +03:00
|
|
|
## [1.4.4] - 2020-03-22
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Update several dependencies
|
|
|
|
* Fixed a bug with printing embeded migrations
|
|
|
|
|
|
|
|
## [1.4.3] - 2019-10-11
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Updated several dependencies
|
|
|
|
* Fixed an issue where the postgresql backend exploits implementation defined behaviour
|
|
|
|
* Fixed issue where rustdoc failed to build the documentation
|
|
|
|
* `diesel_derives` and `diesel_migrations` are updated to syn 1.0
|
|
|
|
|
|
|
|
|
2019-03-19 22:29:37 +03:00
|
|
|
## [1.4.2] - 2019-03-19
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Parenthesis are now inserted around all mathematical operations. This means
|
|
|
|
that `(2.into_sql() + 3) * 4` will correctly evaluate to 20 as expected.
|
|
|
|
Previously we would generate SQL that evaluated to 14. This could even result
|
|
|
|
in runtime errors if multiple types were involved (for example, `interval *
|
|
|
|
(integer + 1)`)
|
|
|
|
|
2019-01-24 22:54:44 +03:00
|
|
|
## [1.4.1] - 2019-01-24
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
Restructure `Backend::RawValue` to allow non-references
As part of Diesel 2.0 we want to change all our backends which currently
have `type RawValue = [u8]` to instead return some opaque struct which
can possibly carry additional information. There are a lot of motivating
use cases for that change, such as including the OID on PG to allow for
working with dynamic schemas, and reducing our reliance on implicit
casts in `libmysqlclient` as attempted by #1457.
Regardless of what these opaque structs do or don't do, we will need to
move away from the signature of `&DB::RawValue`. If we keep this
signature, we would basically be forcing all backends to do what the
SQLite backend did prior to 718a32ea.
In an ideal world, [GATs] would be stable and we would just write `type
RawValue<'a>;`. However, they aren't stable. Implementation on them
appears to have barely started, so it's unlikely that they will be
stable by the time 2.0 comes out. (If it does, or appears close to
happening, we should switch to using that before releasing 2.0).
This introduces a new trait, `HasRawValue`, which acts as the "GAT" form
of the `RawValue` type. The choice to make this a separate trait vs
adding a lifetime to `Backend` was very explicit. Most code which
involves the `Backend` trait doesn't care about the type of `RawValue`,
and adding a lifetime would require virtually all bounds on `Backend`
(including the code which actually does care about `RawValue`) to change
`DB: Backend` to `DB: for<'a> Backend<'a>`.
This does have the unfortunate side effect of breaking code that isn't
currently relying on the type of `Backend` in any concrete fashion.
There's no way around this without keeping the signature of `FromSql` as
`&Something` which is a burden we really don't want to have. The
`backend::RawValue` helper type has been introduced as a forwards
compatibility shim, so code using this new helper type will continue to
work if we switch to GATs in 3.0. The only code which couldn't use this
is the code which was generic over `RawValue = [u8]`. I expect we can
abstract that away in a follow up PR (more on that below).
This was spun off from #1833 as an alternative to a major piece of that
PR which I was unhappy with. One important note is that the motivating
use case that #1833 is trying to address naturally means we can no
longer have the generic "I have some bytes please don't make me rewrite
the impls for integers/floats/byte arrays" impls. This PR is meant to be
standalone against master, so it does not attempt to address everything
done in #1833, and therefore includes some ugly bounds to keep these
impls around. I would actually like to see us keep them if possible, and
I think we can do so with an explicit trait implementation. But that
will be experimented in another PR.
[GATs]: https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
2019-02-01 01:53:45 +03:00
|
|
|
* This release fixes a minor memory safety issue in SQLite. This bug would only
|
|
|
|
occur in an error handling branch that should never occur in practice.
|
2019-01-24 22:54:44 +03:00
|
|
|
|
2019-01-20 00:51:22 +03:00
|
|
|
## [1.4.0] - 2019-01-20
|
|
|
|
|
2018-06-01 20:56:57 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `embed_migrations!` will no longer emit an unused import warning
|
2019-01-20 00:51:22 +03:00
|
|
|
* Diesel now supports uuid 0.7 by adding the new feature flag `uuidv07`
|
2018-06-01 20:56:57 +03:00
|
|
|
|
2018-05-27 19:39:25 +03:00
|
|
|
### Added
|
|
|
|
|
2018-09-18 19:34:09 +03:00
|
|
|
* Diesel CLI can be configured to error if a command would result in changes
|
|
|
|
to your schema file by passing `--locked-schema`. This is intended for use
|
|
|
|
in CI and production deploys, to ensure that the committed schema file is
|
|
|
|
up to date.
|
|
|
|
|
2018-05-27 19:39:25 +03:00
|
|
|
* A helper trait has been added for implementing `ToSql` for PG composite types.
|
|
|
|
See [`WriteTuple`][write-tuple-1-4-0] for details.
|
|
|
|
|
|
|
|
[write-tuple-1-4-0]: docs.diesel.rs/diesel/serialize/trait.WriteTuple.html
|
|
|
|
|
2018-08-01 17:18:12 +03:00
|
|
|
* Added support for MySQL's `UNSIGNED TINYINT`
|
|
|
|
|
Add an explicit error kind for failed `SERIALIZABLE` transactions
"serializable" is the strictest isolation level defined in the SQL
standard. Any two transactions at this isolation level executed
concurrently must have the same results, regardless of which order they
are actually executed in. The standard also defines this as the default
isolation level, but there is no backend I'm aware of that both properly
implements the serializable isolation level, and uses is it as the
default.
We're generally very conservative about adding error kinds to this enum,
and only do so when there's a demonstrable use case for handling it
programatically. I believe this is clearly the case for this error code,
since the correct response to receiving it is almost always to retry the
transaction.
The test for this is pretty straight forward. We create two
transactions. Each one counts half the table, and then inserts a row in
the other half. When run serially, one of the transactions will get 1
for its count, and the other will get 2. Which transaction gets which
result depends on the order they are run, so one of them will fail to
commit. Interestingly, PG is too conservative in determining whether the
dependency exists. If I replace `other_i` with `i`, the transactions are
no longer dependent, but PG still thinks they are.
Currently this error is only detected on PostgreSQL, as that is the only
backend that we support isolation levels in our query builder, and the
semantics of this isolation level are unclear on other backends (SQLite
claims its the default, but the behavior it describes is `REPEATABLE
READ`. MySQL appears to just make your transactions deadlock).
This is the first half of #1612
2018-09-10 23:21:09 +03:00
|
|
|
* `DatabaseErrorKind::SerializationFailure` has been added, corresponding to
|
|
|
|
SQLSTATE code 40001 (A `SERIALIZABLE` isolation level transaction failed to
|
|
|
|
commit due to a read/write dependency on another transaction). This error is
|
|
|
|
currently only detected on PostgreSQL.
|
|
|
|
|
2018-09-12 18:58:34 +03:00
|
|
|
* Diesel CLI can now generate completions for zsh and fish. See `diesel
|
|
|
|
completions --help` for details.
|
|
|
|
|
2018-09-12 20:28:07 +03:00
|
|
|
* `#[belongs_to]` can now accept types that are generic over lifetimes (for
|
|
|
|
example, if one of the fields has the type `Cow<'a, str>`). To define an
|
|
|
|
association to such a type, write `#[belongs_to(parent = "User<'_>")]`
|
|
|
|
|
2019-01-12 19:53:35 +03:00
|
|
|
* `Nullable<Text>` now supports `ilike` expression on in PostgreSQL.
|
|
|
|
|
2018-10-03 21:23:19 +03:00
|
|
|
* `diesel_manage_updated_at('table_name')` is now available on SQLite. This
|
|
|
|
function can be called in your migrations to create a trigger which
|
|
|
|
automatically sets the `updated_at` column, unless that column was updated in
|
|
|
|
the query.
|
|
|
|
|
2018-07-17 18:12:38 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* Diesel's derives now require that `extern crate diesel;` be at your crate root
|
|
|
|
(e.g. `src/lib.rs` or `src/main.rs`)
|
|
|
|
|
2018-08-01 17:18:12 +03:00
|
|
|
* `Tinyint` has been renamed to `TinyInt` and an alias has been created from `Tinyint` to `TinyInt`.
|
|
|
|
|
2018-12-13 01:36:13 +03:00
|
|
|
* The minimal officially supported rustc version is now 1.31.0
|
2018-08-16 00:21:05 +03:00
|
|
|
|
2018-09-12 18:46:10 +03:00
|
|
|
## [1.3.3] - 2018-09-12
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Fixed an issue that occurred with MySQL 8.0 when calling `.execute` or
|
|
|
|
`.batch_execute` with a single query that returned a result set (such as our
|
|
|
|
`SELECT 1` health check in `r2d2`).
|
|
|
|
|
2018-06-14 01:57:27 +03:00
|
|
|
## [1.3.2] - 2018-06-13
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* The behavior of unsigned types in MySQL has been corrected to properly set the
|
|
|
|
`is_unsigned` flag.
|
|
|
|
|
|
|
|
* Fixed an issue with `sql_function!` when `#[sql_name]` was used on functions
|
|
|
|
with no return type.
|
|
|
|
|
2018-05-23 19:39:01 +03:00
|
|
|
## [1.3.1] - 2018-05-23
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Fixed an issue with Diesel CLI's use of temp files that caused errors on
|
|
|
|
Windows.
|
|
|
|
|
Release v1.3.0
New Features
==
This release includes a couple of major changes to how Diesel projects
are developed. In the past, we've had 2 ways to generate `schema.rs`. A
procedural macro called `infer_schema!`, and a CLI command `diesel
print-schema`. We've recommended using the CLI command for a long time,
but `infer_schema!` was still useful for early prototypes.
At the beginning of a project, your database schema changes much more
frequently. It's extremely annoying to have to remember to run a
second command after running your migrations.
Diesel CLI 1.3 now supports a configuration file to customize its
behavior. One of the new capabilities this provides is the ability to
automatically regenerate `schema.rs` whenever you run or revert a
migration. This means you no longer have to remember to run `diesel
print-schema` when things change.
Because of this, we are deprecating `diesel_infer_schema`. 1.3 will be
the final release of that crate. However, `diesel_infer_schema` 1.3 will
continue to work with `diesel` until at least Diesel 2.0. You can see
all of the capabilities of the new configuration file at
http://diesel.rs/guides/configuring-diesel-cli.
This release also includes a complete redesign of the [`sql_function!`]
macro. The new syntax is significantly closer to normal Rust. For
example, what used to be written as:
```rust
sql_function! {
lower, lower_t, (x: Text) -> Text,
"Here are the docs for `lower`
It's awkward to make multiline"
}
```
Can now be written as:
```rust
sql_function! {
/// Here are the docs for `lower`
/// It's just a normal doc comment.
fn lower(x: Text) -> Text;
}
```
The new form also supports much more than the old one, including
aggregate functions, function renaming, and generic functions. Things
like `MAX` could previously not be expressed with `sql_function!`.
However, now the definition looks like this:
```rust
sql_function! {
#[aggregate]
fn max<ST: SqlOrd + IntoNullable>(expr: ST) -> ST::Nullable;
}
```
Finally, the redesigned `sql_function!` supoprts user defined
functions on SQLite. SQLite differs from other databases, in that custom
functions aren't defined in SQL. Instead you give it a C function
pointer to use for the body. With Diesel, you can just give us any Rust
closure that takes appropriate argument types, and we'll handle gluing
that to SQLite for you.
You can find examples for all of this in [the docs for
`sql_function!`][`sql_function!`].
[`sql_function!`]: http://docs.diesel.rs/diesel/macro.sql_function.html
In addition to the headline features, this release includes a ton of
quality of life changes including expanded support for locking clauses,
more global support for mathematic operators, and more. As always, for a
full list of changes you can find it in [the changelog].
[the changelog]: https://github.com/diesel-rs/diesel/blob/v1.3.0/CHANGELOG.md
Thanks
==
Thank you to everyone who helped make this release happen through bug
reports, and discussion on Gitter. While we don't have a way to collect
stats on that form of contribution, it's greatly appreciated.
In addition to the Diesel core team, 12 people contributed code to this
release. A huge thank you to:
- Aleksey Ivanov
- Christopher Brickley
- David Reid
- Diggory Blake
- Graham Turner
- Katharina
- Matt Kraai
- Nick Babcock
- Richard Petrie
- Simon Dickson
- Sunrin SHIMURA
- Thierry Berger
2018-05-22 22:21:32 +03:00
|
|
|
## [1.3.0] - 2018-05-22
|
2018-04-07 02:05:21 +03:00
|
|
|
|
|
|
|
### Added
|
|
|
|
|
2018-05-22 22:42:56 +03:00
|
|
|
* Diesel CLI now supports a configuration file. See
|
|
|
|
diesel.rs/guides/configuring-diesel-cli for details.
|
2018-04-07 02:05:21 +03:00
|
|
|
|
Support generic and aggregate `sql_function!`s
This extends the new syntax of `sql_function!` to allow generics. To
test this, I wanted to use it internally by replacing some of our
"special" function macros with normal `sql_function!`.
To do this for our aggregate functions, I also needed to add a way to
skip the `NonAggregate` impl. Generic functions were easier than
expected, though capturing the type parameters and their bounds was
annoying as all hell since `<>` isn't a token tree...
Right now we don't support multiple bounds on a type either, which
prevents me from moving `max` and `min` over to this. I'm not sure how
I'm going to handle that, since you can't capture a sequence separated
by `+`... Ideally I'd just be able to do `$($param:ident $(:
$bound:ty)*),*` since `Foo + Bar` parses as a valid type. However, Rust
doesn't allow a type token in the bounds position, only `path` and
`lifetime`. I think we'll probably just have to support where clauses,
and say "if you need more than one bound, put it in a where clause".
Dealing with `#[aggregate]` was a bit more annoying, but it's something
we will need to eventually do in order to support `#[sql_name]` anyway.
We just do our typical token munching strategy, going through one meta
item at a time and letting `macro_rules!` branching do the work for us
as we recursively call ourselves.
The main thing that makes this annoying is that we can never capture
anything as a `meta` token, since once you do that it no longer can be
matched against, ever. Luckily for attributes in particular this is not
a huge annoyance, as the attribute itself is surrounded by `[]` making
it a single token tree.
2018-04-26 15:37:23 +03:00
|
|
|
* `sql_function!` now supports generic functions. See [the documentation for
|
|
|
|
`sql_function!`][sql-function-1-3-0] for more details.
|
|
|
|
|
|
|
|
* `sql_function!` now supports aggregate functions like `sum` and `max`, by
|
|
|
|
annotating them with `#[aggregate]`. This skips the implementation of
|
|
|
|
`NonAggregate` for your function. See [the documentation for
|
|
|
|
`sql_function!`][sql-function-1-3-0] for more details.
|
|
|
|
|
2018-05-22 21:50:53 +03:00
|
|
|
* `sql_function!` now supports renaming the function by annotating it with
|
|
|
|
`#[sql_name = "SOME_FUNCTION"]`. This can be used to support functions with
|
|
|
|
multiple signatures such as coalesce, by defining multiple rust functions
|
|
|
|
(with different names) that have the same `#[sql_name]`.
|
|
|
|
|
2018-05-04 17:08:14 +03:00
|
|
|
* Added `sqlite-bundled` feature to `diesel_cli` to make installing on
|
|
|
|
some platforms easier.
|
|
|
|
|
Support custom functions on SQLite
When the sqlite feature is enabled, we add an additional function to the
module generated by `sql_function!` called `register_impl` (we also have
`register_nondeterministic_impl`, for nondeterminitstic functions). I've
attempted to make it at least slightly difficult to register a
nondeterministic function as deterministic by taking `Fn` instead of
`FnMut`, but anything that's using internal mutability can still break
this (and you can still call rand).
For now I've restricted the closure to be `'static`, which means that
you can't, for example close over the connection. I'm not sure how I
want to handle this yet, so I've just been as restrictive as possible.
The more I think about this the more I expect this bound will just stick
around forever, and we'll need a separate API to provide the connection
if we want that. I don't think there's any use case that can't be made
`'static` other than accessing the connection.
If we ever provide access to the connection in this API, se'll also need
to change the prepared statement cache to handle concurrent access.
Allowing access to the connection in one of these functions potentially
breaks our invariant that prepared statements are always given exclusive
access (we'd panic right now if you tried to run a cacheable query
inside a SQL function). I think this will be easy to handle if/when we
want to do so, we just need to change from `borrow_mut` to
`try_borrow_mut`, and return a `CannotCache` newly prepared statement if
we fail to borrow.
The implementation is a bit messy (due to the nature of how we handle
serialization on SQLite), but I'm overall pretty happy with the API. It
meets my main criteria that I was looking for:
- Gets the type information from `sql_function!` - Works with closures -
Uses `ToSql` and `Queryable`, users don't have to care about the
plumbing. - Allows multiple arguments without manual tuple unpacking
2018-05-12 21:22:19 +03:00
|
|
|
* Custom SQL functions can now be used with SQLite. See [the
|
|
|
|
docs][sql-function-sqlite-1-3-0] for details.
|
|
|
|
|
2018-05-23 00:37:30 +03:00
|
|
|
[sql-function-sqlite-1-3-0]: http://docs.diesel.rs/diesel/macro.sql_function.html#use-with-sqlite
|
|
|
|
|
2018-05-04 20:39:07 +03:00
|
|
|
* All functions and operators provided by Diesel can now be used with numeric
|
|
|
|
operators if the SQL type supports it.
|
|
|
|
|
|
|
|
* `PgInterval` can now be used with `-`, `*`, and `/`.
|
Support custom functions on SQLite
When the sqlite feature is enabled, we add an additional function to the
module generated by `sql_function!` called `register_impl` (we also have
`register_nondeterministic_impl`, for nondeterminitstic functions). I've
attempted to make it at least slightly difficult to register a
nondeterministic function as deterministic by taking `Fn` instead of
`FnMut`, but anything that's using internal mutability can still break
this (and you can still call rand).
For now I've restricted the closure to be `'static`, which means that
you can't, for example close over the connection. I'm not sure how I
want to handle this yet, so I've just been as restrictive as possible.
The more I think about this the more I expect this bound will just stick
around forever, and we'll need a separate API to provide the connection
if we want that. I don't think there's any use case that can't be made
`'static` other than accessing the connection.
If we ever provide access to the connection in this API, se'll also need
to change the prepared statement cache to handle concurrent access.
Allowing access to the connection in one of these functions potentially
breaks our invariant that prepared statements are always given exclusive
access (we'd panic right now if you tried to run a cacheable query
inside a SQL function). I think this will be easy to handle if/when we
want to do so, we just need to change from `borrow_mut` to
`try_borrow_mut`, and return a `CannotCache` newly prepared statement if
we fail to borrow.
The implementation is a bit messy (due to the nature of how we handle
serialization on SQLite), but I'm overall pretty happy with the API. It
meets my main criteria that I was looking for:
- Gets the type information from `sql_function!` - Works with closures -
Uses `ToSql` and `Queryable`, users don't have to care about the
plumbing. - Allows multiple arguments without manual tuple unpacking
2018-05-12 21:22:19 +03:00
|
|
|
|
2018-05-22 22:42:56 +03:00
|
|
|
* `Vec<T>` is now `Insertable`. It is no longer required to always place an `&`
|
|
|
|
in front of `.values`.
|
|
|
|
|
|
|
|
* Added support for PG tuples. See [`sql_types::Record`][record-1-3-0] for details.
|
|
|
|
|
|
|
|
[record-1-3-0]: http://docs.diesel.rs/diesel/pg/types/sql_types/struct.Record.html
|
|
|
|
|
2018-05-22 23:03:37 +03:00
|
|
|
* Added support for a wider range of locking clauses, including `FOR SHARE`,
|
|
|
|
`SKIP LOCKED`, `NO WAIT`, and more. See [`QueryDsl`][locking-clause-1-3-0] for details.
|
|
|
|
|
|
|
|
[locking-clause-1-3-0]: http://docs.diesel.rs/diesel/query_dsl/trait.QueryDsl.html#method.for_update
|
|
|
|
|
Redesign `sql_function!`
TL;DR:
==
Before:
--
```rust
sql_function!(lower, lower_t, (x: Text) -> Text, "
This represents the lower function.
Unfortunately, the API of `sql_function!` makes providing a doc
string ugly as all hell.");
```
After:
--
```rust
sql_function! {
/// This represents the `lower` function.
/// Because the syntax of `sql_function!` is identical to a normal
/// extern function in Rust, editor hilighting now works,
/// and this will get picked up by ctags.
fn lower(x: Text) -> Text;
}
```
Actual commit description:
===
This redesign comes from a few main desires:
- Remove the second argument to the macro
- Make it easy to add `#[sql_name]` in the future (see #1596)
- Have the function picked up by ctags
- Generally just look more like Rust.
One other nice side effect is that we're able to pick up any/all meta
items. Right now I'm only applying them to the function, but it may be
worth applying them to the module as well to enable various `#[allow]`s
to get added by users in the event of future lints added to rust/clippy
that we are violating.
The second argument to `sql_function!` has long been a wart on Diesel.
Ultimately we want to generate these three things:
```rust
fn lower<X>(x: X) -> lower<X>
where
X: AsExpression<Text>,
{
...
}
pub struct lower<X> {
x: X,
}
pub type lower<X> = lower<<X as AsExpression<Text>>::Expression>;
```
However, we cannot have the struct and the type exist at the same time.
One of them needs to have a different name. Ultimately we don't care
about the struct. The only time it ever needs to get named is in the
body of the generated function. Virtually everything else can work with
the helper type. We will never be able to automatically generate all of
those things unless we either get stable procedural macros, or a working
form of `concat_idents!`. Ultimately all we need is for that struct to
be some unique name, or otherwise unnameable outside of the macro.
However, as I was working on this, it became clear that the helper type
is pretty rarely needed. Generally the only time you care about having
that helper type is if you are making a library to be consumed by others
(e.g. `diesel_full_text_search`), in which case you're already
re-exporting it from other places. When you're re-exporting, we can take
advantage of how Rust deals with name resolution between glob imports
and locally defined items. We actually use `sql_function!` surprisingly
little in Diesel itself, but you can see the effects of this in `date`.
I've opted to give the struct the same name as the function, and the
helper type the "generic" name. The alternative would be to give the
helper type the same name as the function, and call the struct `Repr` or
something similar. However, the struct appears in error messages, the
helper type does not.
At the end of the day though, very little code actually wants or needs
the helper type. We do use `sql_function!` quite a bit in tests, and
there's literally only one place where we were using the type (and that
place was code that was pre-0.16, which is not code I would have written
that way today in the first place).
Edge cases
---
This doesn't quite handle everything the old form does. 100% of the edge
cases we miss come from the use of `sql_function!` inside of a Rust
function. To make all of this work, we need to wrap most of the code
inside of a module. To resolve items the user expects us to, we do `use
super::*`. However, that will not resolve any items that were imported
in the function itself. To make it more concrete, this code will not
compile:
```
fn foo() {
use std::io::Stdout;
mod bar {
use super::*;
type Out = self::Stdout;
}
}
```
The only place this really affects `sql_function!` is with imported SQL
types. For example, you'll often see `use diesel::sql_types::Text`
before the definition of `lower` to avoid having to qualify it. Because
this is limited to SQL types, I've tried to lower the impact of this
caveat by adding `use diesel::sql_types::*;` at the top of the module.
However, `sql_functions!` which reference types from third party crates
will either need to be declared outside of a function, have the imports
done outside of a function, or just qualify the names.
Finally, if you use `sql_function!` inside of a Rust function, you can
never reference the helper types. There is no workaround. You'll just
have to declare the sql function outside the Rust function.
These edge cases are fine. The TL;DR workaround for all of them is
"don't use `sql_function!` inside of a Rust function". Really the only
reason to have done that in the first place is if you're dealing with a
highly variadic function like `coalesce`, where you want to just encode
the exact signature for the case you have right now. Those cases
generally still work, and once we add support for `#[sql_name]`, those
become easier to handle without abusing Rust's scoping rules anyway.
Future plans
---
I think this design has much more room for extension than the old one
did. Here's what I'd like to do with this in the future:
- Support `#[sql_name]` as a special meta item
- Discussed above. It's the primary motivation for the redesign in the
first place.
- Unify `sql_function!` and `no_arg_sql_function!`
- The main difference between them is that the no-arg form just
generates a unit struct, rather than a function. I think we can
probably generate the function no matter what, but then generate a
unit struct instead of a module if there are no arguments.
- Support where clauses
- Required for unifying `no_arg_sql_function!`. `DB` would be a
"magic" type that you can reference in the where clause to add
backend constraints. I suspect we may also want to support `where DB
== Pg` to specify that it's only available on postgres, but that's
really only useful for PG sepcific libraries, so there's not as much
gain.
- Support generics
- We have an obvious syntax we can use to get rid of `ord_function!`
and `fold_function!`. We should use it.
Fixes #1604
2018-04-15 18:03:23 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* `sql_function!` has been redesigned. The syntax is now `sql_function!(fn
|
|
|
|
lower(x: Text) -> Text);`. The output of the new syntax is slightly different
|
|
|
|
than what was generated in the past. See [the documentation for
|
|
|
|
`sql_function!`][sql-function-1-3-0] for more details.
|
|
|
|
|
Support generic and aggregate `sql_function!`s
This extends the new syntax of `sql_function!` to allow generics. To
test this, I wanted to use it internally by replacing some of our
"special" function macros with normal `sql_function!`.
To do this for our aggregate functions, I also needed to add a way to
skip the `NonAggregate` impl. Generic functions were easier than
expected, though capturing the type parameters and their bounds was
annoying as all hell since `<>` isn't a token tree...
Right now we don't support multiple bounds on a type either, which
prevents me from moving `max` and `min` over to this. I'm not sure how
I'm going to handle that, since you can't capture a sequence separated
by `+`... Ideally I'd just be able to do `$($param:ident $(:
$bound:ty)*),*` since `Foo + Bar` parses as a valid type. However, Rust
doesn't allow a type token in the bounds position, only `path` and
`lifetime`. I think we'll probably just have to support where clauses,
and say "if you need more than one bound, put it in a where clause".
Dealing with `#[aggregate]` was a bit more annoying, but it's something
we will need to eventually do in order to support `#[sql_name]` anyway.
We just do our typical token munching strategy, going through one meta
item at a time and letting `macro_rules!` branching do the work for us
as we recursively call ourselves.
The main thing that makes this annoying is that we can never capture
anything as a `meta` token, since once you do that it no longer can be
matched against, ever. Luckily for attributes in particular this is not
a huge annoyance, as the attribute itself is surrounded by `[]` making
it a single token tree.
2018-04-26 15:37:23 +03:00
|
|
|
[sql-function-1-3-0]: http://docs.diesel.rs/diesel/macro.sql_function.html
|
|
|
|
|
2018-05-22 19:26:50 +03:00
|
|
|
* Diesel's minimum supported Rust version is 1.24.0. This was already true, but
|
|
|
|
it is now tested and enforced. Any future changes to our minimum supported
|
|
|
|
version will be listed in this change log.
|
|
|
|
|
2018-04-15 18:07:48 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `diesel print-schema` and `infer_schema!` now properly handle unsigned types
|
|
|
|
in MySQL
|
|
|
|
|
Redesign `sql_function!`
TL;DR:
==
Before:
--
```rust
sql_function!(lower, lower_t, (x: Text) -> Text, "
This represents the lower function.
Unfortunately, the API of `sql_function!` makes providing a doc
string ugly as all hell.");
```
After:
--
```rust
sql_function! {
/// This represents the `lower` function.
/// Because the syntax of `sql_function!` is identical to a normal
/// extern function in Rust, editor hilighting now works,
/// and this will get picked up by ctags.
fn lower(x: Text) -> Text;
}
```
Actual commit description:
===
This redesign comes from a few main desires:
- Remove the second argument to the macro
- Make it easy to add `#[sql_name]` in the future (see #1596)
- Have the function picked up by ctags
- Generally just look more like Rust.
One other nice side effect is that we're able to pick up any/all meta
items. Right now I'm only applying them to the function, but it may be
worth applying them to the module as well to enable various `#[allow]`s
to get added by users in the event of future lints added to rust/clippy
that we are violating.
The second argument to `sql_function!` has long been a wart on Diesel.
Ultimately we want to generate these three things:
```rust
fn lower<X>(x: X) -> lower<X>
where
X: AsExpression<Text>,
{
...
}
pub struct lower<X> {
x: X,
}
pub type lower<X> = lower<<X as AsExpression<Text>>::Expression>;
```
However, we cannot have the struct and the type exist at the same time.
One of them needs to have a different name. Ultimately we don't care
about the struct. The only time it ever needs to get named is in the
body of the generated function. Virtually everything else can work with
the helper type. We will never be able to automatically generate all of
those things unless we either get stable procedural macros, or a working
form of `concat_idents!`. Ultimately all we need is for that struct to
be some unique name, or otherwise unnameable outside of the macro.
However, as I was working on this, it became clear that the helper type
is pretty rarely needed. Generally the only time you care about having
that helper type is if you are making a library to be consumed by others
(e.g. `diesel_full_text_search`), in which case you're already
re-exporting it from other places. When you're re-exporting, we can take
advantage of how Rust deals with name resolution between glob imports
and locally defined items. We actually use `sql_function!` surprisingly
little in Diesel itself, but you can see the effects of this in `date`.
I've opted to give the struct the same name as the function, and the
helper type the "generic" name. The alternative would be to give the
helper type the same name as the function, and call the struct `Repr` or
something similar. However, the struct appears in error messages, the
helper type does not.
At the end of the day though, very little code actually wants or needs
the helper type. We do use `sql_function!` quite a bit in tests, and
there's literally only one place where we were using the type (and that
place was code that was pre-0.16, which is not code I would have written
that way today in the first place).
Edge cases
---
This doesn't quite handle everything the old form does. 100% of the edge
cases we miss come from the use of `sql_function!` inside of a Rust
function. To make all of this work, we need to wrap most of the code
inside of a module. To resolve items the user expects us to, we do `use
super::*`. However, that will not resolve any items that were imported
in the function itself. To make it more concrete, this code will not
compile:
```
fn foo() {
use std::io::Stdout;
mod bar {
use super::*;
type Out = self::Stdout;
}
}
```
The only place this really affects `sql_function!` is with imported SQL
types. For example, you'll often see `use diesel::sql_types::Text`
before the definition of `lower` to avoid having to qualify it. Because
this is limited to SQL types, I've tried to lower the impact of this
caveat by adding `use diesel::sql_types::*;` at the top of the module.
However, `sql_functions!` which reference types from third party crates
will either need to be declared outside of a function, have the imports
done outside of a function, or just qualify the names.
Finally, if you use `sql_function!` inside of a Rust function, you can
never reference the helper types. There is no workaround. You'll just
have to declare the sql function outside the Rust function.
These edge cases are fine. The TL;DR workaround for all of them is
"don't use `sql_function!` inside of a Rust function". Really the only
reason to have done that in the first place is if you're dealing with a
highly variadic function like `coalesce`, where you want to just encode
the exact signature for the case you have right now. Those cases
generally still work, and once we add support for `#[sql_name]`, those
become easier to handle without abusing Rust's scoping rules anyway.
Future plans
---
I think this design has much more room for extension than the old one
did. Here's what I'd like to do with this in the future:
- Support `#[sql_name]` as a special meta item
- Discussed above. It's the primary motivation for the redesign in the
first place.
- Unify `sql_function!` and `no_arg_sql_function!`
- The main difference between them is that the no-arg form just
generates a unit struct, rather than a function. I think we can
probably generate the function no matter what, but then generate a
unit struct instead of a module if there are no arguments.
- Support where clauses
- Required for unifying `no_arg_sql_function!`. `DB` would be a
"magic" type that you can reference in the where clause to add
backend constraints. I suspect we may also want to support `where DB
== Pg` to specify that it's only available on postgres, but that's
really only useful for PG sepcific libraries, so there's not as much
gain.
- Support generics
- We have an obvious syntax we can use to get rid of `ord_function!`
and `fold_function!`. We should use it.
Fixes #1604
2018-04-15 18:03:23 +03:00
|
|
|
### Deprecated
|
|
|
|
|
2018-05-22 21:58:03 +03:00
|
|
|
* `diesel_infer_schema` has been deprecated. `diesel print-schema` is now the
|
|
|
|
only way to generate database schema. Diesel CLI can be configured to
|
|
|
|
automatically regenerate your schema file when migrations are run. See
|
|
|
|
diesel.rs/guides/configuring-diesel-cli for details.
|
|
|
|
|
Redesign `sql_function!`
TL;DR:
==
Before:
--
```rust
sql_function!(lower, lower_t, (x: Text) -> Text, "
This represents the lower function.
Unfortunately, the API of `sql_function!` makes providing a doc
string ugly as all hell.");
```
After:
--
```rust
sql_function! {
/// This represents the `lower` function.
/// Because the syntax of `sql_function!` is identical to a normal
/// extern function in Rust, editor hilighting now works,
/// and this will get picked up by ctags.
fn lower(x: Text) -> Text;
}
```
Actual commit description:
===
This redesign comes from a few main desires:
- Remove the second argument to the macro
- Make it easy to add `#[sql_name]` in the future (see #1596)
- Have the function picked up by ctags
- Generally just look more like Rust.
One other nice side effect is that we're able to pick up any/all meta
items. Right now I'm only applying them to the function, but it may be
worth applying them to the module as well to enable various `#[allow]`s
to get added by users in the event of future lints added to rust/clippy
that we are violating.
The second argument to `sql_function!` has long been a wart on Diesel.
Ultimately we want to generate these three things:
```rust
fn lower<X>(x: X) -> lower<X>
where
X: AsExpression<Text>,
{
...
}
pub struct lower<X> {
x: X,
}
pub type lower<X> = lower<<X as AsExpression<Text>>::Expression>;
```
However, we cannot have the struct and the type exist at the same time.
One of them needs to have a different name. Ultimately we don't care
about the struct. The only time it ever needs to get named is in the
body of the generated function. Virtually everything else can work with
the helper type. We will never be able to automatically generate all of
those things unless we either get stable procedural macros, or a working
form of `concat_idents!`. Ultimately all we need is for that struct to
be some unique name, or otherwise unnameable outside of the macro.
However, as I was working on this, it became clear that the helper type
is pretty rarely needed. Generally the only time you care about having
that helper type is if you are making a library to be consumed by others
(e.g. `diesel_full_text_search`), in which case you're already
re-exporting it from other places. When you're re-exporting, we can take
advantage of how Rust deals with name resolution between glob imports
and locally defined items. We actually use `sql_function!` surprisingly
little in Diesel itself, but you can see the effects of this in `date`.
I've opted to give the struct the same name as the function, and the
helper type the "generic" name. The alternative would be to give the
helper type the same name as the function, and call the struct `Repr` or
something similar. However, the struct appears in error messages, the
helper type does not.
At the end of the day though, very little code actually wants or needs
the helper type. We do use `sql_function!` quite a bit in tests, and
there's literally only one place where we were using the type (and that
place was code that was pre-0.16, which is not code I would have written
that way today in the first place).
Edge cases
---
This doesn't quite handle everything the old form does. 100% of the edge
cases we miss come from the use of `sql_function!` inside of a Rust
function. To make all of this work, we need to wrap most of the code
inside of a module. To resolve items the user expects us to, we do `use
super::*`. However, that will not resolve any items that were imported
in the function itself. To make it more concrete, this code will not
compile:
```
fn foo() {
use std::io::Stdout;
mod bar {
use super::*;
type Out = self::Stdout;
}
}
```
The only place this really affects `sql_function!` is with imported SQL
types. For example, you'll often see `use diesel::sql_types::Text`
before the definition of `lower` to avoid having to qualify it. Because
this is limited to SQL types, I've tried to lower the impact of this
caveat by adding `use diesel::sql_types::*;` at the top of the module.
However, `sql_functions!` which reference types from third party crates
will either need to be declared outside of a function, have the imports
done outside of a function, or just qualify the names.
Finally, if you use `sql_function!` inside of a Rust function, you can
never reference the helper types. There is no workaround. You'll just
have to declare the sql function outside the Rust function.
These edge cases are fine. The TL;DR workaround for all of them is
"don't use `sql_function!` inside of a Rust function". Really the only
reason to have done that in the first place is if you're dealing with a
highly variadic function like `coalesce`, where you want to just encode
the exact signature for the case you have right now. Those cases
generally still work, and once we add support for `#[sql_name]`, those
become easier to handle without abusing Rust's scoping rules anyway.
Future plans
---
I think this design has much more room for extension than the old one
did. Here's what I'd like to do with this in the future:
- Support `#[sql_name]` as a special meta item
- Discussed above. It's the primary motivation for the redesign in the
first place.
- Unify `sql_function!` and `no_arg_sql_function!`
- The main difference between them is that the no-arg form just
generates a unit struct, rather than a function. I think we can
probably generate the function no matter what, but then generate a
unit struct instead of a module if there are no arguments.
- Support where clauses
- Required for unifying `no_arg_sql_function!`. `DB` would be a
"magic" type that you can reference in the where clause to add
backend constraints. I suspect we may also want to support `where DB
== Pg` to specify that it's only available on postgres, but that's
really only useful for PG sepcific libraries, so there's not as much
gain.
- Support generics
- We have an obvious syntax we can use to get rid of `ord_function!`
and `fold_function!`. We should use it.
Fixes #1604
2018-04-15 18:03:23 +03:00
|
|
|
* Uses of `sql_function!` in the form `sql_function!(foo, foo_t, (x: Integer))`
|
|
|
|
have been deprecated in favor of a new design (listed above). Note: Due to [a
|
|
|
|
bug in Rust](https://github.com/rust-lang/rust/issues/49912), you may not see
|
|
|
|
a deprecation warning from usage of the old form. As always, if you're
|
|
|
|
concerned about relying on deprecated code, we recommend attempting to build
|
|
|
|
your app with `default-features` turned off (specifically excluding the
|
|
|
|
`with-deprecated` feature).
|
2018-05-22 21:58:03 +03:00
|
|
|
|
2018-05-21 20:27:03 +03:00
|
|
|
* The `--whitelist` and `--blacklist` options to `diesel print-schema` have been
|
|
|
|
deprecated and renamed `--only-tables` and `--exclude-tables`.
|
Redesign `sql_function!`
TL;DR:
==
Before:
--
```rust
sql_function!(lower, lower_t, (x: Text) -> Text, "
This represents the lower function.
Unfortunately, the API of `sql_function!` makes providing a doc
string ugly as all hell.");
```
After:
--
```rust
sql_function! {
/// This represents the `lower` function.
/// Because the syntax of `sql_function!` is identical to a normal
/// extern function in Rust, editor hilighting now works,
/// and this will get picked up by ctags.
fn lower(x: Text) -> Text;
}
```
Actual commit description:
===
This redesign comes from a few main desires:
- Remove the second argument to the macro
- Make it easy to add `#[sql_name]` in the future (see #1596)
- Have the function picked up by ctags
- Generally just look more like Rust.
One other nice side effect is that we're able to pick up any/all meta
items. Right now I'm only applying them to the function, but it may be
worth applying them to the module as well to enable various `#[allow]`s
to get added by users in the event of future lints added to rust/clippy
that we are violating.
The second argument to `sql_function!` has long been a wart on Diesel.
Ultimately we want to generate these three things:
```rust
fn lower<X>(x: X) -> lower<X>
where
X: AsExpression<Text>,
{
...
}
pub struct lower<X> {
x: X,
}
pub type lower<X> = lower<<X as AsExpression<Text>>::Expression>;
```
However, we cannot have the struct and the type exist at the same time.
One of them needs to have a different name. Ultimately we don't care
about the struct. The only time it ever needs to get named is in the
body of the generated function. Virtually everything else can work with
the helper type. We will never be able to automatically generate all of
those things unless we either get stable procedural macros, or a working
form of `concat_idents!`. Ultimately all we need is for that struct to
be some unique name, or otherwise unnameable outside of the macro.
However, as I was working on this, it became clear that the helper type
is pretty rarely needed. Generally the only time you care about having
that helper type is if you are making a library to be consumed by others
(e.g. `diesel_full_text_search`), in which case you're already
re-exporting it from other places. When you're re-exporting, we can take
advantage of how Rust deals with name resolution between glob imports
and locally defined items. We actually use `sql_function!` surprisingly
little in Diesel itself, but you can see the effects of this in `date`.
I've opted to give the struct the same name as the function, and the
helper type the "generic" name. The alternative would be to give the
helper type the same name as the function, and call the struct `Repr` or
something similar. However, the struct appears in error messages, the
helper type does not.
At the end of the day though, very little code actually wants or needs
the helper type. We do use `sql_function!` quite a bit in tests, and
there's literally only one place where we were using the type (and that
place was code that was pre-0.16, which is not code I would have written
that way today in the first place).
Edge cases
---
This doesn't quite handle everything the old form does. 100% of the edge
cases we miss come from the use of `sql_function!` inside of a Rust
function. To make all of this work, we need to wrap most of the code
inside of a module. To resolve items the user expects us to, we do `use
super::*`. However, that will not resolve any items that were imported
in the function itself. To make it more concrete, this code will not
compile:
```
fn foo() {
use std::io::Stdout;
mod bar {
use super::*;
type Out = self::Stdout;
}
}
```
The only place this really affects `sql_function!` is with imported SQL
types. For example, you'll often see `use diesel::sql_types::Text`
before the definition of `lower` to avoid having to qualify it. Because
this is limited to SQL types, I've tried to lower the impact of this
caveat by adding `use diesel::sql_types::*;` at the top of the module.
However, `sql_functions!` which reference types from third party crates
will either need to be declared outside of a function, have the imports
done outside of a function, or just qualify the names.
Finally, if you use `sql_function!` inside of a Rust function, you can
never reference the helper types. There is no workaround. You'll just
have to declare the sql function outside the Rust function.
These edge cases are fine. The TL;DR workaround for all of them is
"don't use `sql_function!` inside of a Rust function". Really the only
reason to have done that in the first place is if you're dealing with a
highly variadic function like `coalesce`, where you want to just encode
the exact signature for the case you have right now. Those cases
generally still work, and once we add support for `#[sql_name]`, those
become easier to handle without abusing Rust's scoping rules anyway.
Future plans
---
I think this design has much more room for extension than the old one
did. Here's what I'd like to do with this in the future:
- Support `#[sql_name]` as a special meta item
- Discussed above. It's the primary motivation for the redesign in the
first place.
- Unify `sql_function!` and `no_arg_sql_function!`
- The main difference between them is that the no-arg form just
generates a unit struct, rather than a function. I think we can
probably generate the function no matter what, but then generate a
unit struct instead of a module if there are no arguments.
- Support where clauses
- Required for unifying `no_arg_sql_function!`. `DB` would be a
"magic" type that you can reference in the where clause to add
backend constraints. I suspect we may also want to support `where DB
== Pg` to specify that it's only available on postgres, but that's
really only useful for PG sepcific libraries, so there's not as much
gain.
- Support generics
- We have an obvious syntax we can use to get rid of `ord_function!`
and `fold_function!`. We should use it.
Fixes #1604
2018-04-15 18:03:23 +03:00
|
|
|
|
2018-04-12 22:46:31 +03:00
|
|
|
## [1.2.2] - 2018-04-12
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
|
|
|
* Warnings are now allowed inside the crate. The way we had attempted to
|
|
|
|
deprecate old feature names caused builds to break. We are still not happy
|
|
|
|
with how this deprecation gets communicated, and will revisit it in the
|
|
|
|
future.
|
|
|
|
|
2018-04-11 18:59:58 +03:00
|
|
|
## [1.2.1] - 2018-04-11
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
|
|
|
* Renamed `x32-column-tables`, `x64-column-tables`, and `x128-column-tables` to
|
|
|
|
`32-column-tables`, `64-column-tables`, and `128-column-tables`. The leading
|
|
|
|
`x` was due to a bug in crates.io discovered while publishing 1.2.0. The bug
|
|
|
|
has since been fixed.
|
|
|
|
|
Release v1.2.0
Team changes
==
With this release, we'd like to welcome Georg Semmler (known on GitHub
as @weiznich). Georg is the #2 all time contributor to Diesel, and has
helped shape what the framework is today. Welcome to the team!
New Features
==
This release contains several long awaited features.
We've re-introduced the ability to use bind params with the `sql`
function, in a way which is harder to mis-use. This functionality was
present prior to 1.0, but was removed when `sql_function` was added over
concerns about its use with the rest of the query builder. Recent
developments have proved those concerns to be valid, but this new API
fills that niche. Thanks to @notryanb for taking the lead on this
feature.
We've also added the ability to insert from a select statement (e.g.
queries in the form of `INSERT INTO table (...) SELECT ...`. This is a
feature request that has come up repeatedly since release, and we're
happy to finally bring it to you. We've also added alternate forms of
our insert API which feel better when used with select statements. You
can find the full details in the changelog.
Finally, we've rewritten our custom dervies from scratch to take
advantage of new diagnostic tools in recent versions of nightly Rust. If
you turn on the `unstable` feature of Diesel on a nightly compiler,
you'll find that you get dramatically improved error messages from our
derives. For the best error messages, you should also set
`RUSTFLAGS="--cfg procmacro2_semver_exempt"`.
Additionally, as of this release, Diesel is now powered by the
blockchain. Because it's 2018 and that's how it works now I guess. See
the changelog for full details.
In addition to the headline features, there were a ton of features that
we don't have time to mention here. As always, for a full list of
changes you can find a full list in the changelog.
Thanks
==
Thank you to everyone who helped make this release happen through bug
reports, and discussion on Gitter. While we don't have a way to collect
stats on that form of contribution...
In addition to the Diesel core team, 14 people contributed code to this
release. A huge thank you to:
- Alex Kitchens
- Andrew Weiss
- Arun Kulshreshtha
- Brandur
- EloD10
- Jacob Chae
- Jordan Petridis
- Josh Leeb-du Toit
- Kerollmops
- Mathias Svensson
- Ryan Blecher
- Sander Maijers
- Seth Larson
- YetAnotherMinion
2018-04-07 02:34:45 +03:00
|
|
|
## [1.2.0] - 2018-04-06
|
2018-01-15 20:10:10 +03:00
|
|
|
|
2018-01-19 00:05:45 +03:00
|
|
|
### Added
|
|
|
|
|
2018-01-14 17:39:16 +03:00
|
|
|
* Added `SqlLiteral::bind()`.
|
|
|
|
This is intended to be used for binding values to small SQL fragments.
|
|
|
|
Use `sql_query` if you are writing full queries.
|
|
|
|
|
Add support for `INSERT INTO table (...) SELECT ...`
This feature has been in the works for a very long time, and has a lot
of context... I've added headers so if you already know about the
iteration of the API and the evolution of `InsertStatement` internally,
skip to the third section.
Getting to this API
===
I'd like to give a bit of context on the APIs that have been considered,
and how I landed on this one.
To preface, all of the iterations around this have been trying to
carefully balance three things:
- Easy to discover in the API
- Being syntactically close to the generated SQL
- Avoiding rightward drift
For most of Diesel's life, our API was `insert(values).into(table)`.
That API was originally introduced in 0.2 "to mirror `update` and
`delete` (it didn't mirror them. It was backwards. It's always been
backwards).
My main concern with the old API actually was related to this feature.
I couldn't come up with a decent API that had you specify the column
list (you basically always need to specify the column list for this
feature).
So in 0.99 we changed it to what we have now, and I had toyed around
with `insert_into(table).columns(columns).values(select)`, as well as
`insert_into(table).from_select(columns, select)`. I was leaning towards
the second one for a while (I didn't realize at the time that it was
exactly SQLAlchemy's API). I hated the `columns` method because it was
unclear what it was doing until you saw you were inserting from a select
statement. It also implied an interaction with tuples that didn't exist.
However, another thing that happened in 0.99 was that we deprecated our
old upsert API. The `from_select` form reminded me far too much of the
old `on_conflict` API, which we had just removed. In practice what that
API would give you was something like this:
```rust
insert_into(posts::table)
.from_select(
(posts::user_id, posts::title),
users::table
.select((
users::id,
users::name.concat("'s First Post"),
)),
)
```
That's just far too much rightward drift for me. Yes, you can assign the
args to local variables, but they're awkward to name and now your code
reads weird. I thought moving the columns list to another method call
would help, but it doesn't.
```rust
insert_into(posts::table)
.from_select(
users::table
.select((
users::id,
users::name.concat("'s First Post"),
)),
)
.into_columns((posts::user_id, posts::title))
```
Eventually a member of the Diesel team had the idea of making this an
`insert_into` method on select statements. This solves all of my
concerns around rightward drift, though at the cost of the other two
priorities. The API now looked like this:
```
users::table
.select((
users::id,
users::name.concat("'s First Post"),
))
.insert_into(posts::table)
.into_columns((posts::user_id, posts::title))
```
I liked the way the code flowed, but I had concerns around
discoverability, and didn't like how backwards it was from SQL. But I
could live with it and started implementing.
Up until this point I had been assuming that we would have an
`InsertFromSelectStatement` struct, which was distinct from
`InsertStatement` and necessitated the differently named methods. I
realized when I started digging into it though, that we really just want
to re-use `InsertStatement` for this. It seems obvious in hindsight.
And if we were going to use that structure, that meant that it wouldn't
be much harder to just make passing `SelectStatement` to `values` work.
This automatically solves most of my concerns around discoverability,
since it now just works exactly like every other form of insert.
That said, I really don't like the rightward drift. I liked the
`.insert_into` form for being able to avoid that. But for the final
implementation, I just generalized that feature. *Anything* that can be
written as `insert_into(table).values(values)` can now be written as
`values.insert_into(table)`.
Context around InsertStatement
===
This file has churned more than just about any other part of Diesel. I
feel like I've re-written it nearly every release at this point. I think
the reason it's churned so much is for two reasons. The first is that
it's kept a fundamental design flaw through 1.1 (which I'll get to), and
we've been constantly working around it. The second is that `INSERT` is
actually one of the most complex queries in SQL. It has less variations
than `SELECT`, but far more of its variations are backend specific, or
have different syntaxes between backends.
`InsertStatement` was originally added for 0.2 in c9894b35 which has a
very helpful commit message "WIP" (good job past Sean). At the time we
only supported PG, so we actually had two versions -- `InsertStatement`
and `InsertQuery`, the latter having a returning clause. I'm honestly
not sure why I didn't do the `ReturningClause<T>` `NoReturningClause`
dance we do now and did back then in `SelectStatement`. Maybe I thought
it'd be easier?
Anyway this file had to go through some pretty major changes in 0.5 when
we added SQLite support. We needed to disallow batch insert and
returning clauses on that backend. Additionally, the way we handle
default values had to work differently on SQLite since it doesn't
support the `DEFAULT` keyword.
At this point though, it still a few things. The query starts with
`INSERT INTO`, had a columns list, then the word `VALUES` and then some
values. It also managed all parenthesis. (Yes it was trivial to make it
generate invalid SQL at that point).
Fast forward to 0.9, I decided to support batch insert on SQLite. This
needs to do one query per row, and I felt that meant we needed a
separate struct. I didn't want to have `BatchInsertStatement` and
`BatchInsertQuery` and `InsertStatement` and `InsertQuery`, so we got
the `NoReturningClause` struct, and got a little closer to how literally
every other part of Diesel works.
In 0.14 we added `insert_default_values` which left us with
`InsertStatement`, `BatchInsertStatement`, and `DefaultInsertStatement`,
which eventually went back down to the two.
The last time the file went through a big rewrite was in 0.99 when I
finally unified it down to the one struct we have today.
However, it still had the fatal flaw I mentioned earlier. It was trying
to handle too much logic, and was too disjoint from the rest of the
query builder. It assumed that the two forms were `DEFAULT VALUES` or
`(columns) VALUES ...`, and also handled parens.
We've gone through a lot of refactoring to get rid of that. I finally
think this struct is at a point where it will stop churning, mostly
because it looks like the rest of Diesel now. It doesn't do anything at
all, and the only thing it assumes is that the word `INTO` appears in
the query (which I'm pretty sure actually is true).
The actual implementation of this commit
====
With all that said, this commit is relatively simple. The main addition
is the `InsertFromSelect` struct. It's definitely a Diesel struct, in
that it basically does nothing, and all the logic is in its `where`
clauses.
I tried to make `Insertable` work roughly everywhere that methods like
`filter` work. I couldn't actually do a blanket impl for tables in Rust
itself, because it made rustc vomit on recursion with our impls on
`Option`. That shouldn't be happening, but I suspect it's a lot of work
to fix that in the language.
I've also implemented it for references, since most of the time that you
pass values to `.values`, you pass a reference. That should "just work"
here unless we have a good reason not to.
The majority of the additions here are tests. This is a feature that
fundamentally interacts with many of our most complex features, and I've
tried to be exhaustive. Theres ~3 lines of tests for every line of code
added. I've done at least a minimal test of this feature's interaction
with every other feature on inserts that I could think of. I am not so
much worried about whether they work, but I was worried about if there
was a syntactic edge case I didn't know about. There weren't. Same with
the compile tests, I've tried to think of every way the feature could be
accidentally misused (bad arguments to `into_columns` basically), as
well as all the nonsense things we should make sure don't work (putting
it in a tuple or vec).
I didn't add any compile tests on making sure that the select statement
itself is valid. The fact that the `Query` bound only matches valid
complete select statements is already very well tested, and we don't
need to re-test that here. I also did not explicitly disallow selecting
from the same table as the insert, as this appears to be one of the few
places where the table can appear twice with no ambiguity.
Fixes #1106
2018-01-18 22:27:23 +03:00
|
|
|
* Added support for `INSERT INTO table (...) SELECT ...` queries. Tables, select
|
|
|
|
select statements, and boxed select statements can now be used just like any
|
|
|
|
other `Insertable` value.
|
|
|
|
|
|
|
|
* Any insert query written as `insert_into(table).values(values)` can now be
|
|
|
|
written as `values.insert_into(table)`. This is particularly useful when
|
|
|
|
inserting from a select statement, as select statements tend to span multiple
|
|
|
|
lines.
|
|
|
|
|
2018-02-02 18:02:31 +03:00
|
|
|
* Diesel's derives can now produce improved error messages if you are using a
|
|
|
|
nightly compiler, and enable the `unstable` feature. For the best errors, you
|
|
|
|
should also set `RUSTFLAGS="--cfg procmacro2_semver_exempt"`.
|
|
|
|
|
2018-01-19 00:05:45 +03:00
|
|
|
* Added support for specifying `ISOLATION LEVEL`, `DEFERRABLE`, and `READ ONLY`
|
|
|
|
on PG transactions. See [`PgConnection::build_transaction`] for details.
|
|
|
|
|
|
|
|
[`PgConnection::build_transaction`]: http://docs.diesel.rs/diesel/pg/struct.PgConnection.html#method.build_transaction
|
|
|
|
|
2018-01-24 18:29:55 +03:00
|
|
|
* Added support for `BEGIN IMMEDIATE` and `BEGIN EXCLUSIVE` on SQLite.
|
|
|
|
See [`SqliteConnection::immediate_transaction`] and
|
|
|
|
[`SqliteConnection::exclusive_transaction`] for details
|
|
|
|
|
|
|
|
[`SqliteConnection::immediate_transaction`]: http://docs.diesel.rs/diesel/sqlite/struct.SqliteConnection.html#method.immediate_transaction
|
|
|
|
[`SqliteConnection::exclusive_transaction`]: http://docs.diesel.rs/diesel/sqlite/struct.SqliteConnection.html#method.exclusive_transaction
|
|
|
|
|
2018-01-30 01:03:03 +03:00
|
|
|
* Tables with more than 56 columns are now supported by enabling the
|
|
|
|
`128-column-tables` feature.
|
|
|
|
|
Add `DeleteStatement::into_boxed`.
This is one half of #1128. This method (and the added type) correspond
to `SelectStatement::into_boxed` and `BoxedSelecStatement`. I had
originally stated that I thought we could just box the where clause by
default, but we could no longer do that due to backwards compatibility.
Neither of those statements are actually true.
While we can't remove the type parameter for the where clause, it is
documented that you are not allowed to rely on the types that parameter
can hold, or make any assumptions about them. So we could either change
it to be an unused parameter, or enforce that it is always a boxed where
clause.
However, we can't just change it to be unused, as we need to capture a
lifetime somewhere. So if we wanted to re-use `DeleteStatement` for
this, we'd have to go the second route of having that parameter always
be a boxed where clause. I realize now that we don't actually want to do
that though, as it would require `delete` to take the database the query
would be run against.
There's more duplicated code than I'd like (basically all of this code
was copied from either `DeleteStatement` or `BoxedSelectStatement`, but
I'm not sure that there's a ton we can do about this. It's unfortunate
that we basically have to remember to update `BoxedDeleteStatement` any
time we do anything to `DeleteStatement`, but that's no different than
the situation with selects.
While conditionally modifying the where clause of a delete statement is
definitely going to be less common than doing it for a select, I do
think that this is a reasonable feature, and one worth having.
2018-02-03 22:55:26 +03:00
|
|
|
* Delete statements can now be boxed. This is useful for conditionally modifying
|
|
|
|
the where clause of a delete statement. See [`DeleteStatement::into_boxed`]
|
|
|
|
for details.
|
|
|
|
|
|
|
|
[`DeleteStatement::into_boxed`]: http://docs.diesel.rs/diesel/query_builder/struct.DeleteStatement.html#method.into_boxed
|
|
|
|
|
2018-04-05 20:47:16 +03:00
|
|
|
* Update statements can now be boxed. This is useful for conditionally modifying
|
|
|
|
the where clause of a update statement. See [`UpdateStatement::into_boxed`]
|
|
|
|
for details.
|
|
|
|
|
|
|
|
[`UpdateStatement::into_boxed`]: http://docs.diesel.rs/diesel/query_builder/struct.UpdateStatement.html#method.into_boxed
|
|
|
|
|
2018-02-03 21:54:32 +03:00
|
|
|
* Added `order_by` as an alias for `order`.
|
|
|
|
|
|
|
|
* Added `then_order_by`, which appends to an `ORDER BY` clause rather than
|
|
|
|
replacing it. This is useful with boxed queries to dynamically construct an
|
|
|
|
order by clause containing an unknown number of columns.
|
|
|
|
|
2018-02-07 00:38:33 +03:00
|
|
|
* `#[derive(Insertable)]` can now work on structs with fields that implement
|
|
|
|
`Insertable` (meaning one field can map to more than one column). Add
|
|
|
|
`#[diesel(embed)]` to the field to enable this behavior.
|
|
|
|
|
Allow (some) subselects to appear in an expression context
A subselect can be used as an expression by wrapping it in parenthesis
as long as the query returns exactly one column, and exactly zero or one
rows. The first constraint is trivial for us to enforce, but the only
way we can enforce the second is by automatically adding `LIMIT 1` to
the query when this method is called. We also need to make the SQL type
nullable, for the same reasons as max, min, avg, etc. They all return
null if the query returns zero rows.
If disjointness on associated types ever lands, I suspect we can just
implement `AsExpression` directly, and deprecate this method. That
said, given that the SQL type has to become nullable, it may be better
to keep the explicit method, so that we don't get questions on why
`id.eq(subselect)` isn't working.
Fixes #1308.
2018-02-14 21:29:41 +03:00
|
|
|
* Queries that treat a subselect as a single value (e.g. `foo = (subselect)`)
|
|
|
|
are now supported by calling [`.single_value()`].
|
|
|
|
|
2018-03-04 16:14:31 +03:00
|
|
|
* `#[derive(Insertable)]` implements now `Insertable` also on the struct itself,
|
|
|
|
not only on references to the struct
|
|
|
|
|
Allow (some) subselects to appear in an expression context
A subselect can be used as an expression by wrapping it in parenthesis
as long as the query returns exactly one column, and exactly zero or one
rows. The first constraint is trivial for us to enforce, but the only
way we can enforce the second is by automatically adding `LIMIT 1` to
the query when this method is called. We also need to make the SQL type
nullable, for the same reasons as max, min, avg, etc. They all return
null if the query returns zero rows.
If disjointness on associated types ever lands, I suspect we can just
implement `AsExpression` directly, and deprecate this method. That
said, given that the SQL type has to become nullable, it may be better
to keep the explicit method, so that we don't get questions on why
`id.eq(subselect)` isn't working.
Fixes #1308.
2018-02-14 21:29:41 +03:00
|
|
|
[`.single_value()`]: http://docs.diesel.rs/diesel/query_dsl/trait.QueryDsl.html#method.single_value
|
|
|
|
|
2018-02-18 01:07:25 +03:00
|
|
|
* `ConnectionError` now implements `PartialEq`.
|
|
|
|
|
2018-02-28 17:28:44 +03:00
|
|
|
* Columns generated by `table!` now implement `Default`
|
|
|
|
|
2018-03-04 16:19:13 +03:00
|
|
|
* `#[derive(AsChangeset)]` now implements `AsChangeset` on the struct itself,
|
|
|
|
and not only on a reference to the struct
|
|
|
|
|
2018-04-05 19:32:21 +03:00
|
|
|
* Added support for deserializing `Numeric` into `BigDecimal` on SQLite. SQLite
|
|
|
|
has no arbitrary precision type, so the result will still have floating point
|
|
|
|
rounding issues. This is primarily to support things like `avg(int_col)`,
|
|
|
|
which we define as returning `Numeric`
|
|
|
|
|
2018-01-20 23:34:21 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* The bounds on `impl ToSql for Cow<'a, T>` have been loosened to no longer
|
|
|
|
require that `T::Owned: ToSql`.
|
|
|
|
|
2018-02-01 19:31:27 +03:00
|
|
|
* `32-column-tables` are now enabled by default.
|
|
|
|
|
2018-01-15 20:10:10 +03:00
|
|
|
### Deprecated
|
|
|
|
|
|
|
|
* `ne_any` has been renamed to `ne_all`.
|
|
|
|
|
2018-02-01 19:31:27 +03:00
|
|
|
* The `large-tables` feature has been has been renamed to `32-column-tables`.
|
|
|
|
|
|
|
|
* The `huge-tables` feature has been renamed to `64-column-tables`.
|
|
|
|
|
2018-02-05 00:20:52 +03:00
|
|
|
* `IncompleteUpdateStatement` has been removed. Use `UpdateStatement` instead.
|
|
|
|
|
2018-01-23 21:49:47 +03:00
|
|
|
### Fixed
|
|
|
|
|
2018-01-23 21:54:55 +03:00
|
|
|
* `diesel database setup` now correctly handles database URLs containing query
|
|
|
|
strings
|
2018-01-18 02:43:53 +03:00
|
|
|
|
2018-01-23 21:49:47 +03:00
|
|
|
* `diesel migration list` shows the proper migration order when mixing
|
|
|
|
old and new timestamp formats. (The migrations were always run in the correct
|
|
|
|
order, this only affects the display logic of `migration list`)
|
|
|
|
|
2018-02-02 22:28:17 +03:00
|
|
|
* `#[derive(Identifiable)]` now correctly associates `#[primary_key]` with the
|
|
|
|
column name, not field name.
|
|
|
|
|
2018-02-06 22:03:27 +03:00
|
|
|
* Select statements can no longer incorrectly appear in an expression context.
|
|
|
|
|
|
|
|
* `exists` can no longer incorrectly receive values other than select
|
|
|
|
statements.
|
|
|
|
|
2018-02-22 23:47:37 +03:00
|
|
|
* `MysqlConnection::establish` can now properly handle IPv6 addresses wrapped in
|
|
|
|
square brackets.
|
|
|
|
|
2018-02-05 01:13:56 +03:00
|
|
|
### Jokes
|
|
|
|
|
|
|
|
* Diesel is now powered by the blockchain because it's 2018.
|
|
|
|
|
2018-04-05 21:01:36 +03:00
|
|
|
## [1.1.2] - 2018-04-05
|
|
|
|
|
|
|
|
* No changes
|
|
|
|
|
2018-01-16 18:46:55 +03:00
|
|
|
## [1.1.1] - 2018-01-16
|
2018-01-16 01:48:09 +03:00
|
|
|
|
|
|
|
### Added
|
|
|
|
|
|
|
|
* Added `diesel::r2d2::PoolError` as an alias for `r2d2::Error`. Previously this
|
|
|
|
type was inaccessible due to `diesel::r2d2::Error`.
|
|
|
|
|
Release v1.1.0
Improved Support for Adding New Types
-------------------------------------
The primary focus of this release was improving the ergonomics of adding
support for new types in Diesel.
For implementing new SQL types, we've added `#[derive(SqlType)]` which
implements many traits that you need to implement for every SQL type.
See the documentation for `HasSqlType` for details on this derive.
For implementing new mappings, we've added `#[derive(FromSqlRow)]` and
`#[derive(AsExpression)]`. These derives will replace the majority of
the boilerplate that was previously required when supporting new types.
Adding support for new types in Diesel 1.1 should only require
implementing `FromSql` and `ToSql`. The derives will handle the rest.
We've also provided `FromSql` impls for `*const str` and `*const [u8]`.
Due to the design of `FromSql`, we can't provide impls for `&str` and
`&[u8]` without a breaking change. However many impls just need to parse
a string or some bytes, and don't need the allocation that would come
from `String` or `Vec<u8>`. This will require unsafe code to use, but
should make certain implementations more efficient.
Finally, we've restructured how our serialize/deserialize modules are
structured, and provided type aliases to make implementations of
`FromSql` and `ToSql` more consise.
`r2d2_diesel` is Now Part of Diesel
-----------------------------------
Finally, this release merges `r2d2_diesel` into Diesel itself. The main
benefit of doing this is that we can implement `Connection` for
`PooledConnection`, removing the need for explicit `&*` when using r2d2.
This should also help to prevent version mismatches when changing Diesel
versions.
To use the new r2d2 support, remove `r2d2` and `r2d2_diesel` from your
Cargo.toml. Add the `r2d2` to your enabled features on `diesel`. Replace
`extern crate r2d2` with `pub use diesel::r2d2`. Replace any
`r2d2_diesel::` with `diesel::r2d2::`.
Thanks
------
In addition to the headline features, there were dozens of smaller
additions which should make using Diesel even better! As always, you can
check the CHANGELOG for a full list of changes in this release.
In addition to the Diesel core team, 8 people contributed to this
release. A huge thank you to:
- Ashe Connor
- Chris Pick
- Evan
- Georg Semmler
- MarcManiez
- Martin Lindhe
- Oliver Schneider
- Ryan Blecher
2018-01-15 18:34:57 +03:00
|
|
|
## [1.1.0] - 2018-01-15
|
2018-01-02 01:31:50 +03:00
|
|
|
|
|
|
|
### Added
|
|
|
|
|
Merge r2d2-diesel into Diesel itself
The main benefit of doing this is that we can implement `Connection` for
`PooledConnection`, removing the requirement to do `&*conn` in your
outermost functions. Additionally, we can just re-export r2d2 from
within Diesel itself, so we can hopefully get fewer bug reports saying
"Hey why does it say PgConnection doesn't implement Connection". Instead
people can just `use diesel::r2d2::Pool` instead of explicitly depending
on r2d2.
The code and the tests are both stripped straight from r2d2-diesel.
(Yeah, the tests are a bit... opaque. They come from the initial commit
of that repo, with the commit message "The tests have been pretty much
ripped from r2d2-postgres, as I really don't know what else to do to
test this". So blame r2d2-postgres I guess)
The only changes between this code and what is in r2d2-diesel 1.0 is the
`Connection` impl. This impl has to be a little bit funky. I decided to
just restrict to `AnsiTransactionManager` since that's what all three
backends use at the moment. If we wanted to support anything that
implemented `diesel::Connection`, we would need to add the constraint
`C::TransactionManager: TransactionManager<Self>`. However,
`TransactionManager` has the bound that it's parameter be `Connection`,
so we just recurse infinitely. Maybe on day the language will be smarter
about this. Until then, we just have to do this weird hack.
Fixes #1348.
2018-01-09 01:34:13 +03:00
|
|
|
* `r2d2-diesel` has been merged into Diesel proper. You should no longer rely
|
|
|
|
directly on `r2d2-diesel` or `r2d2`. The functionality of both is exposed from
|
|
|
|
`diesel::r2d2`.
|
|
|
|
|
|
|
|
* `r2d2::PooledConnection` now implements `Connection`. This means that you
|
|
|
|
should no longer need to write `&*connection` when using `r2d2`.
|
|
|
|
|
2018-01-02 01:31:50 +03:00
|
|
|
* The `BINARY` column type name is now supported for SQLite.
|
|
|
|
|
2018-01-04 01:18:48 +03:00
|
|
|
* The `QueryId` trait can now be derived.
|
|
|
|
|
2018-01-09 00:20:13 +03:00
|
|
|
* `FromSqlRow` can now be derived for types which implement `FromSql`.
|
|
|
|
|
|
|
|
* `AsExpression` can now be derived for types which implement `ToSql`.
|
2018-01-06 21:18:07 +03:00
|
|
|
|
2018-01-07 22:55:04 +03:00
|
|
|
* `HasSqlType`, `NotNull`, and `SingleValue` can now be derived with
|
|
|
|
`#[derive(SqlType)]`. See the docs for those traits for more information.
|
|
|
|
|
2018-01-09 00:11:07 +03:00
|
|
|
* The return type of `FromSql`, `FromSqlRow`, and `QueryableByName` can now be
|
|
|
|
written as `deserialize::Result<Self>`.
|
|
|
|
|
|
|
|
* The return type of `ToSql` can now be written as `serialize::Result`.
|
|
|
|
|
2018-01-09 23:10:47 +03:00
|
|
|
* Added support for SQLite's `INSERT OR IGNORE` and MySQL's `INSERT IGNORE`
|
|
|
|
via the `insert_or_ignore` function.
|
|
|
|
|
2018-01-07 20:25:30 +03:00
|
|
|
* `min` and `max` can now be used with array expressions.
|
2018-01-11 00:23:30 +03:00
|
|
|
|
2018-01-12 22:43:39 +03:00
|
|
|
* Added `diesel::dsl::array`, which corresponds to a PG `ARRAY[]` literal.
|
|
|
|
|
2018-01-09 23:50:25 +03:00
|
|
|
* Added the `not_none!` macro, used by implementations of `FromSql` which do not
|
|
|
|
expect `NULL`.
|
|
|
|
|
|
|
|
* Added `result::UnexpectedNullError`, an `Error` type indicating that an
|
|
|
|
unexpected `NULL` was received during deserialization.
|
|
|
|
|
2018-01-07 20:25:30 +03:00
|
|
|
* Added `.or_filter`, which behaves identically to `.filter`, but using `OR`
|
|
|
|
instead of `AND`.
|
|
|
|
|
2017-12-14 22:50:29 +03:00
|
|
|
* `helper_types` now contains a type for every method defined in
|
|
|
|
`expression_methods`, and every function in `dsl`.
|
|
|
|
|
2018-01-07 19:32:22 +03:00
|
|
|
* Added `FromSql` impls for `*const str` and `*const [u8]` everywhere that
|
|
|
|
`String` and `Vec` are supported. These impls do not allocate, and are
|
|
|
|
intended for use by other impls which need to parse a string or bytes, and
|
|
|
|
don't want to allocate. These impls should never be used outside of another
|
|
|
|
`FromSql` impl.
|
|
|
|
|
2018-01-04 01:18:48 +03:00
|
|
|
### Deprecated
|
|
|
|
|
2018-01-15 19:21:05 +03:00
|
|
|
* *IMPORTANT NOTE* Due to [several][rust-deprecation-bug-1]
|
2018-01-09 23:50:25 +03:00
|
|
|
[bugs][rust-deprecation-bug-2] in Rust, many of the deprecations in this
|
|
|
|
release may not show a warning. If you want to ensure you are not using any
|
|
|
|
deprecated items, we recommend attempting to compile your code without the
|
|
|
|
`with-deprecated` feature by adding `default-features = false` to
|
|
|
|
`Cargo.toml`.
|
|
|
|
|
|
|
|
[rust-deprecation-bug-1]: https://github.com/rust-lang/rust/issues/47236
|
|
|
|
[rust-deprecation-bug-2]: https://github.com/rust-lang/rust/issues/47237
|
|
|
|
|
2018-01-04 01:18:48 +03:00
|
|
|
* Deprecated `impl_query_id!` in favor of `#[derive(QueryId)]`
|
|
|
|
|
2018-01-06 18:30:14 +03:00
|
|
|
* Deprecated specifying a column name as `#[column_name(foo)]`. `#[column_name =
|
|
|
|
"foo"]` should be used instead.
|
|
|
|
|
2018-01-09 23:50:25 +03:00
|
|
|
* The `types` module has been deprecated. It has been split into `sql_types`,
|
|
|
|
`serialize`, and `deserialize`.
|
|
|
|
|
|
|
|
* `query_source::Queryable` and `query_source::QueryableByName` have been
|
|
|
|
deprecated. These traits have been moved to `deserialize`.
|
|
|
|
|
|
|
|
* `backend::TypeMetadata` has been deprecated. It has been moved to `sql_types`.
|
|
|
|
|
|
|
|
* `types::ToSqlOutput` has been deprecated. It has been renamed to
|
|
|
|
`serialize::Output`.
|
|
|
|
|
2017-12-14 22:50:29 +03:00
|
|
|
* `helper_types::Not` is now `helper_types::not`
|
|
|
|
|
2018-01-09 01:50:54 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `infer_schema!` generates valid code when run against a database with no
|
|
|
|
tables.
|
|
|
|
|
2018-01-03 01:52:08 +03:00
|
|
|
## [1.0.0] - 2018-01-02
|
|
|
|
|
|
|
|
### Added
|
|
|
|
|
|
|
|
* `#[derive(QueryableByName)]` can now handle structs that have no associated
|
|
|
|
table. If the `#[table_name]` annotation is left off, you must annotate each
|
|
|
|
field with `#[sql_type = "Integer"]`
|
|
|
|
|
|
|
|
* `#[derive(QueryableByName)]` can now handle embedding other structs. To have a
|
|
|
|
field whose type is a struct which implements `QueryableByName`, rather than a
|
|
|
|
single column in the query, add the annotation `#[diesel(embed)]`
|
|
|
|
|
|
|
|
* The `QueryDsl` trait encompasses the majority of the traits that were
|
|
|
|
previously in the `query_dsl` module.
|
2017-12-13 01:08:59 +03:00
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Executing select statements on SQLite will no longer panic when the database
|
|
|
|
returns `SQLITE_BUSY`
|
|
|
|
|
2017-12-14 00:37:48 +03:00
|
|
|
* `table!`s which use the `Datetime` type with MySQL will now compile correctly,
|
|
|
|
even without the `chrono` feature enabled.
|
|
|
|
|
2017-12-20 19:10:24 +03:00
|
|
|
* `#[derive(QueryableByName)]` will now compile correctly when there is a shadowed `Result` type in scope.
|
|
|
|
|
2017-12-23 19:09:08 +03:00
|
|
|
* `BoxableExpression` can now be used with types that are not `'static`
|
|
|
|
|
2017-12-16 21:32:42 +03:00
|
|
|
### Changed
|
|
|
|
|
2018-01-03 01:52:08 +03:00
|
|
|
* `Connection::test_transaction` now requires that the error returned implement `Debug`.
|
2017-12-16 21:32:42 +03:00
|
|
|
|
2017-12-23 23:35:36 +03:00
|
|
|
* `query_builder::insert_statement::InsertStatement` is now accessed as
|
|
|
|
`query_builder::InsertStatement`
|
|
|
|
|
|
|
|
* `query_builder::insert_statement::UndecoratedInsertRecord` is now accessed as
|
|
|
|
`query_builder::UndecoratedInsertRecord`
|
|
|
|
|
2017-11-30 20:14:09 +03:00
|
|
|
* `#[derive(QueryableByName)]` now requires that the table name be explicitly
|
|
|
|
stated.
|
|
|
|
|
Unify most of the traits in `query_dsl` into a single trait
This moves most traits that represent a single method into a new
`QueryBuilder` trait. While I said I didn't want to do any more big
changes until post-1.0, this change is primarily motivated by making
our documentation easier to browse. This change will need a 0.99.2
release.
In addition to making our docs easier to read, this may improve our
error messages slightly in a few places that required using UFCS to get
a decent error message. `SelectStatement`, `BoxedSelectStatement`, and
`Table` now unconditionally implement this trait, so the method will
always be present and error messages will be about why the where clause
failed.
That said, those cases will be pretty small. Most places where you end
up doing the UFCS trick are related to `.execute` and `.load`. I think
it would make sense to do a similar change there (maybe we call it
`RunQueryDsl`?)
There were two traits which did not make sense to keep around --
`CountDsl` and `JoinDsl`. There's perhaps an argument for keeping
`CountDsl` separate, as you could have relied on it from generic code.
However, any code that was using `JoinDsl` already would have needed the
where clauses required to use it from `QueryDsl`.
I've opted to add an inherent method for `filter` back onto update and
delete statements, rather than implementing `QueryDsl` for them.
`filter` is the only method that would ever work on those types, and
having it be an inherent method makes the docs for those methods more
visible.
I've opted to leave the `impl FilterDsl` in place though, because having
some generic code which adds a where clause to both select statements
and update statements is totally a reasonable thing to do 🙃.
2017-12-03 01:49:38 +03:00
|
|
|
* Most of the traits in `query_dsl` have been moved to `query_dsl::methods`.
|
|
|
|
These traits are no longer exported in `prelude`. This should not affect most
|
|
|
|
apps, as the behavior of these traits is provided by `QueryDsl`. However, if
|
|
|
|
you were using these traits in `where` clauses for generic code, you will need
|
|
|
|
to explicitly do `use diesel::query_dsl::methods::WhateverDsl`. You may also
|
|
|
|
need to use UFCS in these cases.
|
|
|
|
|
2017-12-04 18:53:24 +03:00
|
|
|
* If you have a type which implemented `QueryFragment` or `Query`, which you
|
|
|
|
intended to be able to call `execute` or `load` on, you will need to manually
|
|
|
|
implement `RunQueryDsl` for that type. The trait should be unconditionally
|
|
|
|
implemented (no where clause beyond what your type requires), and the body
|
|
|
|
should be empty.
|
|
|
|
|
2017-11-30 18:16:10 +03:00
|
|
|
### Removed
|
|
|
|
|
|
|
|
* All deprecated items have been removed.
|
|
|
|
|
2017-12-04 18:53:24 +03:00
|
|
|
* `LoadDsl` and `FirstDsl` have been removed. Their functionality now lives in
|
|
|
|
`LoadQuery`.
|
|
|
|
|
2017-12-02 03:27:17 +03:00
|
|
|
## [0.99.1] - 2017-12-01
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
|
|
|
* Diesel CLI now properly restricts its `clap` dependency. 0.99.0 mistakenly had
|
|
|
|
no upper bound on the version.
|
|
|
|
|
Release v0.99.0 (It's basically 1.0 except it's not)
This release is by far the largest Diesel has ever had. It serves 2
purposes. You can consider this release to be a beta for 1.0. However,
1.0 will have an important significant difference. Anything that is
deprecated as of this release will not be present in the 1.0 release.
This includes functions which were newly deprecated in 0.99. We know
this may introduce a migration burden for some people, so we will
continue to support the 0.99 line with bug fixes as long as there is
demand and it is reasonable to do so.
Headline Features
----
This release is mainly focused on ergonomics. Our main new feature is
the [`sql_query`][] function. This is a new API which behaves similarly to
[`sql`][], but it is entirely focused on cases where you want to write
the *entire* query yourself. The main difference from `sql` is that you
do not need to specify the return type of the query, and values are
fetched by name rather than by index. This feature is still early, and
there's a lot of features still to come (specifically evolving
`#[derive(QueryableByName)]`, but we think this feature will ease a lot
of pains for cases where Diesel doesn't quite do what you need.
[`sql_query`]: http://docs.diesel.rs/diesel/fn.sql_query.html
[`sql`]: http://docs.diesel.rs/diesel/sql/fn.sql.html
Additionally, you can now use tuples for inserts the same as you can for
updates. If you've ever wanted to insert a row with just 1 or 2 values,
and been annoyed that you needed a struct that you're only using in this
one place, this feature will make you happy. We'll have new guides
highlighting this feature soon.
Additionally, this release comes with a ton of quality of life features.
Many of these changes are focused around making it easier to introduce
line breaks naturally in your code. For example, `.filter` is now
implemented on `UpdateStatement`, meaning you can write
`update(foo).filter(bar)` instead of `update(foo.filter(bar))`. We've
also introduced new APIs for `insert` and PG upsert which will have
similar readability improvements.
Breaking Changes
----
This release includes more deprecations than any release prior. In
particular, `insert` has been deprecated, along with our entire PG
upsert API. All deprecations in this release have direct replacements,
which will lead to code which formats much more nicely. It should be a
mostly mechanical replacement for most apps. See [the CHANGELOG file][] for
details.
[the CHANGELOG file]: https://github.com/diesel-rs/diesel/blob/v0.99.0/CHANGELOG.md
Growing the Team
----
With this release, we'd like to welcome several new members to the
Diesel committer team. @weiznich, @notryanb, and @katrinabrock you've
all done excellent work and we're very excited to officially welcome you
to the team!
Additional Thanks
----
In addition to the Diesel core and committer teams, 10 people
contributed to this release. A huge thank you to:
- Adam Perry
- Alex Kitchens
- Alexey Zabelin
- Arnar Mar Sig
- Bob
- Jordan
- Lauri Apple
- Maxime “pep” Buquet
- William Murphy
- bippityboppity
Our only remaining blockers from this release and 1.0 are documentation
changes, and having this tested in the wild. Thank you to every one of
our users for your support, and we look forward to Diesel 1.0 by the end
of the year!
2017-11-29 02:26:30 +03:00
|
|
|
## [0.99.0] - 2017-11-28
|
2017-09-05 19:43:55 +03:00
|
|
|
|
Add support for `SELECT ... FOR UPDATE`
The semantics of where this modifier is allowed are taken from PG, even
though this query is also allowed on MySQL. PG's docs are much more
thorough on the semantics of `FOR UPDATE`, and where it is or is not
allowed.
I've opted *not* to allow this with boxed queries, as a boxed query has
no way to verify that it isn't mixed with a group by/having/distinct
clause. We may want to lift this restriction in the future, depending
on what we do with `group_by` there when we add proper support for it.
If we decide to allow `group_by` on boxed queries, it will require not
that the select clause is still valid. It seems likely that boxed
queries will just end up with the gotcha of "less checking is done".
Still, for the time being I've taken the conservative approach, as we
can always change that later.
If/when we add support for having, union, intersect, and except, we will
need to ensure that those methods can only be used with no for update
clause as well.
The code is structured in a way that's a bit more generic on the backend
than is strictly necessary, but I plan to follow this up with support
for MySQL's `LOCK IN SHARE MODE` (which I believe is equivalent to `FOR
SHARE` in PG), which will need this structure in place.
I've opted for a very minimal usage example, as the test which
demonstrates its behavior is long enough that it drowns out the actual
usage.
2017-09-11 20:37:45 +03:00
|
|
|
### Added
|
|
|
|
|
|
|
|
* The `.for_update()` method has been added to select statements, allowing
|
|
|
|
construction of `SELECT ... FOR UPDATE`.
|
|
|
|
|
2017-09-21 22:40:26 +03:00
|
|
|
* Added `insert_into(table).default_values()` as a replacement for
|
2017-09-15 18:22:33 +03:00
|
|
|
`insert_default_values()`
|
|
|
|
|
2017-09-21 22:40:26 +03:00
|
|
|
* Added `insert_into(table).values(values)` as a replacement for
|
|
|
|
`insert(values).into(table)`.
|
|
|
|
|
|
|
|
* Added support for MySQL's `REPLACE INTO` as `replace_into(table)`.
|
|
|
|
|
|
|
|
* Added `replace_into(table).values(values)` as a replacement for
|
|
|
|
`insert_or_replace(values).into(table)`.
|
|
|
|
|
2017-09-22 16:49:54 +03:00
|
|
|
* Added `on_conflict_do_nothing` on `InsertStatement` as a replacement for
|
|
|
|
`on_conflict_do_nothing` on `Insertable` structs.
|
|
|
|
|
2017-09-22 17:41:05 +03:00
|
|
|
* Added `on_conflict` on `InsertStatement` as a replacement for
|
|
|
|
`on_conflict` on `Insertable` structs.
|
|
|
|
|
2017-09-25 17:22:11 +03:00
|
|
|
* `filter` can now be called on update and delete statements. This means that
|
|
|
|
instead of `update(users.filter(...))` you can write
|
|
|
|
`update(users).filter(...)`. This allows line breaks to more naturally be
|
|
|
|
introduced.
|
|
|
|
|
2017-09-26 16:40:24 +03:00
|
|
|
* Subselects can now reference columns from the outer table. For example,
|
|
|
|
`users.filter(exists(posts.filter(user_id.eq(users::id))))` will now compile.
|
|
|
|
|
2017-09-28 23:37:30 +03:00
|
|
|
* `TextExpressionMethods` is now implemented for expressions of type
|
|
|
|
`Nullable<Text>` as well as `Text`.
|
|
|
|
|
2017-10-08 20:28:41 +03:00
|
|
|
* `allow_tables_to_appear_in_same_query!` can now take more than 2 tables, and is the same
|
|
|
|
as invoking it separately for every combination of those tables.
|
|
|
|
|
Implement a new raw SQL API geared towards complete queries
`sql` has always been a bit clunky to use if you wanted to write a whole
query with it. You have to specify the SQL type of the query, which also
means you have to list every column out explicitly to ensure they're in
the expected order.
This adds a replacement API that more geared towards writing complete
queries. There are two notable differences. The first is that the SQL
type of each field is specified during deserialization, not when the
query is constructed. The types are never checked anyway (other than to
make sure the deserialization is valid), so it makes sense to defer this
to a place where we can derive it.
The second difference is that columns are deserialized by name, not by
index. This has all of the gotchas that are associated with doing that
with other libraries (name conflicts between tables, etc)
I had originally planned on having `NamedRow::get` optionally also take
a table name. However, PG gives you the OID not the name, so we'd need
to do another query to get the table name. SQLite only gives you the
table/column name if compiled with a flag to enable it, which the system
sqlite3 on mac does not.
For those two reasons, I've opted to use the column name alone. This
means that the derived `QueryableByName` is unlikely to be usable with
joins, but that's a price we'll have to pay for now.
I'd like to expand the number of cases that our derive impl can handle
(e.g. allow providing a sql type in addition to a column name), but this
is a good bare minimum place to start.
Fixes #650.
2017-09-27 18:30:30 +03:00
|
|
|
* Added `sql_query`, a new API for dropping to raw SQL that is more pleasant to
|
|
|
|
use than `sql` for complete queries. The main difference from `sql` is that
|
|
|
|
you do not need to state the return type, and data is loaded from the query by
|
|
|
|
name rather than by index.
|
|
|
|
|
2017-10-03 18:34:32 +03:00
|
|
|
* Added a way to rename a table in the `table!` macro with `#[sql_name="the_table_name"]`
|
|
|
|
|
Release v0.99.0 (It's basically 1.0 except it's not)
This release is by far the largest Diesel has ever had. It serves 2
purposes. You can consider this release to be a beta for 1.0. However,
1.0 will have an important significant difference. Anything that is
deprecated as of this release will not be present in the 1.0 release.
This includes functions which were newly deprecated in 0.99. We know
this may introduce a migration burden for some people, so we will
continue to support the 0.99 line with bug fixes as long as there is
demand and it is reasonable to do so.
Headline Features
----
This release is mainly focused on ergonomics. Our main new feature is
the [`sql_query`][] function. This is a new API which behaves similarly to
[`sql`][], but it is entirely focused on cases where you want to write
the *entire* query yourself. The main difference from `sql` is that you
do not need to specify the return type of the query, and values are
fetched by name rather than by index. This feature is still early, and
there's a lot of features still to come (specifically evolving
`#[derive(QueryableByName)]`, but we think this feature will ease a lot
of pains for cases where Diesel doesn't quite do what you need.
[`sql_query`]: http://docs.diesel.rs/diesel/fn.sql_query.html
[`sql`]: http://docs.diesel.rs/diesel/sql/fn.sql.html
Additionally, you can now use tuples for inserts the same as you can for
updates. If you've ever wanted to insert a row with just 1 or 2 values,
and been annoyed that you needed a struct that you're only using in this
one place, this feature will make you happy. We'll have new guides
highlighting this feature soon.
Additionally, this release comes with a ton of quality of life features.
Many of these changes are focused around making it easier to introduce
line breaks naturally in your code. For example, `.filter` is now
implemented on `UpdateStatement`, meaning you can write
`update(foo).filter(bar)` instead of `update(foo.filter(bar))`. We've
also introduced new APIs for `insert` and PG upsert which will have
similar readability improvements.
Breaking Changes
----
This release includes more deprecations than any release prior. In
particular, `insert` has been deprecated, along with our entire PG
upsert API. All deprecations in this release have direct replacements,
which will lead to code which formats much more nicely. It should be a
mostly mechanical replacement for most apps. See [the CHANGELOG file][] for
details.
[the CHANGELOG file]: https://github.com/diesel-rs/diesel/blob/v0.99.0/CHANGELOG.md
Growing the Team
----
With this release, we'd like to welcome several new members to the
Diesel committer team. @weiznich, @notryanb, and @katrinabrock you've
all done excellent work and we're very excited to officially welcome you
to the team!
Additional Thanks
----
In addition to the Diesel core and committer teams, 10 people
contributed to this release. A huge thank you to:
- Adam Perry
- Alex Kitchens
- Alexey Zabelin
- Arnar Mar Sig
- Bob
- Jordan
- Lauri Apple
- Maxime “pep” Buquet
- William Murphy
- bippityboppity
Our only remaining blockers from this release and 1.0 are documentation
changes, and having this tested in the wild. Thank you to every one of
our users for your support, and we look forward to Diesel 1.0 by the end
of the year!
2017-11-29 02:26:30 +03:00
|
|
|
* Added support for PostgreSQL's `DISTINCT ON`. See
|
|
|
|
[`.distinct_on()`][0.99.0-distinct-on] for more details
|
|
|
|
|
2017-09-05 19:43:55 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* The signatures of `QueryId`, `Column`, and `FromSqlRow` have all changed to
|
|
|
|
use associated constants where appropriate.
|
|
|
|
|
2017-10-08 20:28:41 +03:00
|
|
|
* You will now need to invoke `allow_tables_to_appear_in_same_query!` any time two tables
|
2018-01-04 01:26:13 +03:00
|
|
|
appear together in the same query, even if there is a `joinable!` invocation for those tables.
|
2017-10-20 13:44:09 +03:00
|
|
|
|
2017-11-29 01:21:13 +03:00
|
|
|
* `diesel_codegen` should no longer explicitly be used as a dependency. Unless
|
|
|
|
you are using `infer_schema!` or `embed_migrations!`, you can simply remove it
|
|
|
|
from your `Cargo.toml`. All other functionality is now provided by `diesel`
|
|
|
|
itself.
|
2017-11-27 21:12:35 +03:00
|
|
|
|
2017-11-29 01:21:13 +03:00
|
|
|
* Code using `infer_schema!` or `infer_table_from_schema!` must now add
|
|
|
|
`diesel_infer_schema` to `Cargo.toml`, and `#[macro_use] extern crate
|
|
|
|
diesel_infer_schema` to `src/lib.rs`
|
|
|
|
|
Release v0.99.0 (It's basically 1.0 except it's not)
This release is by far the largest Diesel has ever had. It serves 2
purposes. You can consider this release to be a beta for 1.0. However,
1.0 will have an important significant difference. Anything that is
deprecated as of this release will not be present in the 1.0 release.
This includes functions which were newly deprecated in 0.99. We know
this may introduce a migration burden for some people, so we will
continue to support the 0.99 line with bug fixes as long as there is
demand and it is reasonable to do so.
Headline Features
----
This release is mainly focused on ergonomics. Our main new feature is
the [`sql_query`][] function. This is a new API which behaves similarly to
[`sql`][], but it is entirely focused on cases where you want to write
the *entire* query yourself. The main difference from `sql` is that you
do not need to specify the return type of the query, and values are
fetched by name rather than by index. This feature is still early, and
there's a lot of features still to come (specifically evolving
`#[derive(QueryableByName)]`, but we think this feature will ease a lot
of pains for cases where Diesel doesn't quite do what you need.
[`sql_query`]: http://docs.diesel.rs/diesel/fn.sql_query.html
[`sql`]: http://docs.diesel.rs/diesel/sql/fn.sql.html
Additionally, you can now use tuples for inserts the same as you can for
updates. If you've ever wanted to insert a row with just 1 or 2 values,
and been annoyed that you needed a struct that you're only using in this
one place, this feature will make you happy. We'll have new guides
highlighting this feature soon.
Additionally, this release comes with a ton of quality of life features.
Many of these changes are focused around making it easier to introduce
line breaks naturally in your code. For example, `.filter` is now
implemented on `UpdateStatement`, meaning you can write
`update(foo).filter(bar)` instead of `update(foo.filter(bar))`. We've
also introduced new APIs for `insert` and PG upsert which will have
similar readability improvements.
Breaking Changes
----
This release includes more deprecations than any release prior. In
particular, `insert` has been deprecated, along with our entire PG
upsert API. All deprecations in this release have direct replacements,
which will lead to code which formats much more nicely. It should be a
mostly mechanical replacement for most apps. See [the CHANGELOG file][] for
details.
[the CHANGELOG file]: https://github.com/diesel-rs/diesel/blob/v0.99.0/CHANGELOG.md
Growing the Team
----
With this release, we'd like to welcome several new members to the
Diesel committer team. @weiznich, @notryanb, and @katrinabrock you've
all done excellent work and we're very excited to officially welcome you
to the team!
Additional Thanks
----
In addition to the Diesel core and committer teams, 10 people
contributed to this release. A huge thank you to:
- Adam Perry
- Alex Kitchens
- Alexey Zabelin
- Arnar Mar Sig
- Bob
- Jordan
- Lauri Apple
- Maxime “pep” Buquet
- William Murphy
- bippityboppity
Our only remaining blockers from this release and 1.0 are documentation
changes, and having this tested in the wild. Thank you to every one of
our users for your support, and we look forward to Diesel 1.0 by the end
of the year!
2017-11-29 02:26:30 +03:00
|
|
|
* Code using `embed_migrations!` must now add `diesel_migrations` to `Cargo.toml`,
|
2017-11-29 01:21:13 +03:00
|
|
|
and `#[macro_use] extern crate diesel_migrations` to `src/lib.rs`
|
|
|
|
|
|
|
|
* The `migrations` module has been moved out of `diesel` and into
|
|
|
|
`diesel_migrations`
|
2017-10-08 20:28:41 +03:00
|
|
|
|
2017-09-15 18:22:33 +03:00
|
|
|
### Deprecated
|
|
|
|
|
2017-09-21 22:40:26 +03:00
|
|
|
* Deprecated `insert_default_values()` in favor of
|
|
|
|
`insert_into(table).default_values()`
|
|
|
|
|
|
|
|
* Deprecated `insert(values).into(table)` in favor of
|
|
|
|
`insert_into(table).values(values)`.
|
|
|
|
|
|
|
|
* Deprecated `insert_or_replace(values).into(table)` in favor of
|
|
|
|
`replace_into(table).values(values)`.
|
2017-09-15 18:22:33 +03:00
|
|
|
|
2017-09-22 16:49:54 +03:00
|
|
|
* Deprecated `.values(x.on_conflict_do_nothing())` in favor of
|
|
|
|
`.values(x).on_conflict_do_nothing()`
|
|
|
|
|
2017-09-22 17:41:05 +03:00
|
|
|
* Deprecated `.values(x.on_conflict(y, do_nothing()))` in favor of
|
|
|
|
`.values(x).on_conflict(y).do_nothing()`
|
|
|
|
|
|
|
|
* Deprecated `.values(x.on_conflict(y, do_update().set(z)))` in favor of
|
|
|
|
`.values(x).on_conflict(y).do_update().set(z)`
|
|
|
|
|
2017-10-08 20:28:41 +03:00
|
|
|
* Deprecated `enable_multi_table_joins` in favor of
|
|
|
|
`allow_tables_to_appear_in_same_query!`
|
|
|
|
|
Implement a new raw SQL API geared towards complete queries
`sql` has always been a bit clunky to use if you wanted to write a whole
query with it. You have to specify the SQL type of the query, which also
means you have to list every column out explicitly to ensure they're in
the expected order.
This adds a replacement API that more geared towards writing complete
queries. There are two notable differences. The first is that the SQL
type of each field is specified during deserialization, not when the
query is constructed. The types are never checked anyway (other than to
make sure the deserialization is valid), so it makes sense to defer this
to a place where we can derive it.
The second difference is that columns are deserialized by name, not by
index. This has all of the gotchas that are associated with doing that
with other libraries (name conflicts between tables, etc)
I had originally planned on having `NamedRow::get` optionally also take
a table name. However, PG gives you the OID not the name, so we'd need
to do another query to get the table name. SQLite only gives you the
table/column name if compiled with a flag to enable it, which the system
sqlite3 on mac does not.
For those two reasons, I've opted to use the column name alone. This
means that the derived `QueryableByName` is unlikely to be usable with
joins, but that's a price we'll have to pay for now.
I'd like to expand the number of cases that our derive impl can handle
(e.g. allow providing a sql type in addition to a column name), but this
is a good bare minimum place to start.
Fixes #650.
2017-09-27 18:30:30 +03:00
|
|
|
* Deprecated `SqlLiteral#bind`. `sql` is intended for use with small fragments
|
|
|
|
of SQL, not complete queries. Writing bind parameters in raw SQL when you are
|
|
|
|
not writing the whole query is error-prone. Use `sql_query` if you need raw
|
|
|
|
SQL with bind parameters.
|
|
|
|
|
rm `BatchInsertStatement`
This brings us back to the place we want to be, where there is only one
`InsertStatement` struct. Rather than executing 0 queries when inserting
an empty slice, we instead execute a select statement that will return 0
rows (effectively turning it into a no-op query).
It'd be technically more correct for us to stick the returning clause in
the select statement, so any assertions about the number of columns or
their types would still pass. However, that implementation would be a
bit harder to write, so for now I've opted to rely on the fact that we
will never make those assertions when we have no rows to return.
With this change, we can use the blanket impl of `ExecuteDsl` for the
"normal" case (though I had to modify it a tad to ensure it is disjoint
with the sqlite slice impl, since associated types aren't taken into
account when determining disjointness).
One alternative implementation would be to remove the blanket impl
entirely. This might be something we want to do in the future, since
right now `foo.eq(bar).execute(&conn)` actually compiles. However, we'd
need to remove the blanket impl of `LoadDsl` as well if we wanted to
elminate this select statement, which I'm less inclined to do.
2017-09-19 15:33:29 +03:00
|
|
|
### Removed
|
|
|
|
|
|
|
|
* `IntoInsertStatement` and `BatchInsertStatement` have been removed. It's
|
|
|
|
unlikely that your application is using these types, but `InsertStatement` is
|
|
|
|
now the only "insert statement" type.
|
|
|
|
|
2017-09-27 16:41:48 +03:00
|
|
|
* `Citext` as a type alias for `Text` has been removed. Writing
|
|
|
|
`citext_column.eq("foo")` would perform a case-sensitive comparison. More
|
|
|
|
fleshed out support will be required.
|
|
|
|
|
2017-09-05 20:23:51 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* When using MySQL and SQLite, dates which cannot be represented by `chrono`
|
|
|
|
(such as `0000-00-00`) will now properly return an error instead of panicking.
|
|
|
|
|
2017-09-30 16:00:38 +03:00
|
|
|
* MySQL URLs will now properly percent decode the username and password.
|
|
|
|
|
2017-10-08 19:14:36 +03:00
|
|
|
* References to types other than `str` and slice can now appear on structs which
|
|
|
|
derive `Insertable` or `AsChangeset`.
|
|
|
|
|
2017-10-10 19:18:09 +03:00
|
|
|
* Deserializing a date/time/timestamp column into a chrono type on SQLite will
|
|
|
|
now handle any value that is in a format documented as valid for SQLite's
|
|
|
|
`strftime` function except for the string `'now'`.
|
|
|
|
|
Release v0.99.0 (It's basically 1.0 except it's not)
This release is by far the largest Diesel has ever had. It serves 2
purposes. You can consider this release to be a beta for 1.0. However,
1.0 will have an important significant difference. Anything that is
deprecated as of this release will not be present in the 1.0 release.
This includes functions which were newly deprecated in 0.99. We know
this may introduce a migration burden for some people, so we will
continue to support the 0.99 line with bug fixes as long as there is
demand and it is reasonable to do so.
Headline Features
----
This release is mainly focused on ergonomics. Our main new feature is
the [`sql_query`][] function. This is a new API which behaves similarly to
[`sql`][], but it is entirely focused on cases where you want to write
the *entire* query yourself. The main difference from `sql` is that you
do not need to specify the return type of the query, and values are
fetched by name rather than by index. This feature is still early, and
there's a lot of features still to come (specifically evolving
`#[derive(QueryableByName)]`, but we think this feature will ease a lot
of pains for cases where Diesel doesn't quite do what you need.
[`sql_query`]: http://docs.diesel.rs/diesel/fn.sql_query.html
[`sql`]: http://docs.diesel.rs/diesel/sql/fn.sql.html
Additionally, you can now use tuples for inserts the same as you can for
updates. If you've ever wanted to insert a row with just 1 or 2 values,
and been annoyed that you needed a struct that you're only using in this
one place, this feature will make you happy. We'll have new guides
highlighting this feature soon.
Additionally, this release comes with a ton of quality of life features.
Many of these changes are focused around making it easier to introduce
line breaks naturally in your code. For example, `.filter` is now
implemented on `UpdateStatement`, meaning you can write
`update(foo).filter(bar)` instead of `update(foo.filter(bar))`. We've
also introduced new APIs for `insert` and PG upsert which will have
similar readability improvements.
Breaking Changes
----
This release includes more deprecations than any release prior. In
particular, `insert` has been deprecated, along with our entire PG
upsert API. All deprecations in this release have direct replacements,
which will lead to code which formats much more nicely. It should be a
mostly mechanical replacement for most apps. See [the CHANGELOG file][] for
details.
[the CHANGELOG file]: https://github.com/diesel-rs/diesel/blob/v0.99.0/CHANGELOG.md
Growing the Team
----
With this release, we'd like to welcome several new members to the
Diesel committer team. @weiznich, @notryanb, and @katrinabrock you've
all done excellent work and we're very excited to officially welcome you
to the team!
Additional Thanks
----
In addition to the Diesel core and committer teams, 10 people
contributed to this release. A huge thank you to:
- Adam Perry
- Alex Kitchens
- Alexey Zabelin
- Arnar Mar Sig
- Bob
- Jordan
- Lauri Apple
- Maxime “pep” Buquet
- William Murphy
- bippityboppity
Our only remaining blockers from this release and 1.0 are documentation
changes, and having this tested in the wild. Thank you to every one of
our users for your support, and we look forward to Diesel 1.0 by the end
of the year!
2017-11-29 02:26:30 +03:00
|
|
|
[0.99.0-distinct-on]: http://docs.diesel.rs/diesel/query_dsl/trait.DistinctOnDsl.html#tymethod.distinct_on
|
|
|
|
|
2017-08-24 21:13:56 +03:00
|
|
|
## [0.16.0] - 2017-08-24
|
2017-07-27 20:14:56 +03:00
|
|
|
|
2017-07-25 01:00:17 +03:00
|
|
|
### Added
|
|
|
|
|
|
|
|
* Added helper types for inner join and left outer join
|
|
|
|
|
2017-07-29 14:17:28 +03:00
|
|
|
* `diesel::debug_query` has been added as a replacement for `debug_sql!`. This
|
2017-07-29 20:46:28 +03:00
|
|
|
function differs from the macro by allowing you to specify the backend, and
|
2017-07-29 14:17:28 +03:00
|
|
|
will generate the actual query which will be run. The returned value will
|
|
|
|
implement `Display` and `Debug` to show the query in different ways
|
2017-07-29 20:46:28 +03:00
|
|
|
|
2017-08-01 15:11:47 +03:00
|
|
|
* `diesel::pg::PgConnection`, `diesel::mysql::MysqlConnection`, and
|
|
|
|
`diesel::sqlite::SqliteConnection` are now exported from `diesel::prelude`.
|
|
|
|
You should no longer need to import these types explicitly.
|
|
|
|
|
2017-07-12 07:09:37 +03:00
|
|
|
* Added support for the Decimal datatype on MySQL, using the [BigDecimal crate][bigdecimal-0.16.0].
|
|
|
|
|
2017-08-05 20:46:49 +03:00
|
|
|
* Added support for the [Range][range-0.16.0] type on postgreSQL.
|
|
|
|
|
2017-08-08 03:11:06 +03:00
|
|
|
* Added support for the Datetime type on MySQL.
|
|
|
|
|
2017-08-12 15:50:39 +03:00
|
|
|
* Added support for the Blob type on MySQL.
|
|
|
|
|
2017-08-05 22:48:39 +03:00
|
|
|
* `infer_schema!` will now automatically detect which tables can be joined based
|
|
|
|
on the presence of foreign key constraints.
|
2017-08-17 01:57:31 +03:00
|
|
|
|
2017-08-16 10:38:16 +03:00
|
|
|
* Added support for `Add` and `Sub` to timestamp types.
|
2017-08-05 22:48:39 +03:00
|
|
|
|
2017-08-16 17:55:21 +03:00
|
|
|
* Added a way to rename columns in the table macro with `#[sql_name="the_column_name"]`
|
|
|
|
|
2017-08-24 00:12:33 +03:00
|
|
|
* Schema inference now also generates documentation comments for tables and
|
|
|
|
columns. For `infer_schema!`, this is enabled by default. If you are using
|
|
|
|
Diesel's CLI tool, pass the new `--with-docs` parameter:
|
|
|
|
`diesel print-schema --with-docs`.
|
2017-08-19 19:35:06 +03:00
|
|
|
|
2017-08-24 20:11:49 +03:00
|
|
|
* `infer_schema!` now automatically renames columns that conflict with
|
2017-08-17 01:57:31 +03:00
|
|
|
a Rust keyword by placing a _ at the end of the name. For example,
|
2017-08-24 20:11:49 +03:00
|
|
|
a column called `type` will be referenced as `type_` in Rust.
|
2017-08-17 01:57:31 +03:00
|
|
|
|
2017-07-29 20:46:28 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* The deprecated `debug_sql!` and `print_sql!` functions will now generate
|
|
|
|
backend specific SQL. (The specific backend they will generate for will be
|
|
|
|
arbitrarily chosen based on the backends enabled).
|
|
|
|
|
2017-08-04 20:00:21 +03:00
|
|
|
* `#[belongs_to]` will no longer generate the code required to join between two
|
2017-08-05 22:48:39 +03:00
|
|
|
tables. You will need to explicitly invoke `joinable!` instead, unless you are
|
|
|
|
using `infer_schema!`
|
2017-08-04 20:00:21 +03:00
|
|
|
|
2017-08-14 13:52:03 +03:00
|
|
|
* Changed the migration directory name format to `%Y-%m-%d-%H%M%S`.
|
|
|
|
|
2017-09-24 01:39:46 +03:00
|
|
|
* `between` and `not_between` now take two arguments, rather than a range.
|
|
|
|
|
2017-07-29 20:46:28 +03:00
|
|
|
### Removed
|
|
|
|
|
2017-07-29 14:17:28 +03:00
|
|
|
* `debug_sql!` has been deprecated in favor of `diesel::debug_query`.
|
2017-07-29 20:46:28 +03:00
|
|
|
|
|
|
|
* `print_sql!` has been deprecated without replacement.
|
|
|
|
|
|
|
|
* `diesel::backend::Debug` has been removed.
|
|
|
|
|
2017-08-04 20:00:21 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Diesel now properly supports joins in the form:
|
|
|
|
`grandchild.join(child.join(parent))`. Previously only
|
|
|
|
`parent.join(child.join(grandchild))` would compile.
|
|
|
|
|
Refactor encoding `BigDecimal` on PG
I had originally worked on this as part of 0.15.2, but have been
sitting on it until a new version was released so we could use
`to_bigint_and_exponent`.
The new code takes a different approach to the encoding. I've
specifically broken the code into a `From` impl to make it easier for us
to test the output.
There was an impedence mismatch in the old code. Ultimately the way
`BigDecimal` is represented is as a `BigInteger` with a scale. The way
we're transmitting it is as a `BigInteger` with a weight and scale.
Splitting it into separate integral and fractional parts, and applying
different logic was making the code difficult to understand, and
introducing unneccessary complications.
There are two differences to how `BigUint` is represented vs how PG
wants it. The first is that PG is base 10000, while `BigUint` is base
2^16. The second is that in `BigUint`, `scale` represents both the
number of significant digits, *and* the position of the decimal point.
In PG, `scale` only represents the number of significant digits, and
there is a separate `weight` to represent the position of the decimal
point.
This means that `BigUint` will store trailing zeroes that we need
to strip, but PG will need to ensure that the decimal falls on a digit
boundary in base 10k. The majority of the logic here is to handle that
portion. I've tried to make it as clear as possible what's going on
through proper naming. Unfortunately the fairly simple code of iterating
over the digits in base 10k gets drowned out by the cleanup.
The code could potentially be simplified if we could easily iterate over
the digits in big-endian order, but I could find an easy way to do that
mathematically.
2017-08-07 20:13:32 +03:00
|
|
|
* When encoding a `BigDecimal` on PG, `1.0` is no longer encoded as if it were
|
|
|
|
`1`.
|
|
|
|
|
2017-08-05 20:46:49 +03:00
|
|
|
[bigdecimal-0.16.0]: https://crates.io/crates/bigdecimal
|
2017-11-04 04:12:29 +03:00
|
|
|
[range-0.16.0]: https://docs.diesel.rs/diesel/pg/types/sql_types/struct.Range.html
|
2017-07-12 07:09:37 +03:00
|
|
|
|
2017-07-28 18:57:54 +03:00
|
|
|
## [0.15.2] - 2017-07-28
|
|
|
|
|
2017-07-27 20:14:56 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `BigDecimal` now properly encodes numbers starting with `10000` on postgres.
|
|
|
|
See [issue #1044][] for details.
|
|
|
|
|
|
|
|
[issue #1044]: https://github.com/diesel-rs/diesel/issues/1044
|
|
|
|
|
2017-07-24 18:50:10 +03:00
|
|
|
## [0.15.1] - 2017-07-24
|
|
|
|
|
|
|
|
* No changes to public API
|
|
|
|
|
|
|
|
## [0.15.0] - 2017-07-23
|
2017-07-04 16:33:45 +03:00
|
|
|
|
2017-07-05 13:35:56 +03:00
|
|
|
### Added
|
|
|
|
|
|
|
|
* Added support for the PG `IS DISTINCT FROM` operator
|
|
|
|
|
2017-07-14 19:17:32 +03:00
|
|
|
* The `ON` clause of a join can now be manually specified. See [the
|
2017-07-23 12:24:21 +03:00
|
|
|
docs][join-on-dsl-0.15.0] for details.
|
2017-07-14 19:17:32 +03:00
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[join-on-dsl-0.15.0]: https://docs.diesel.rs/diesel/prelude/trait.JoinOnDsl.html#method.on
|
2017-07-14 19:17:32 +03:00
|
|
|
|
2017-07-04 16:33:45 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* Diesel will now automatically invoke `numeric_expr!` for your columns in the
|
|
|
|
common cases. You will likely need to delete any manual invocations of this
|
|
|
|
macro.
|
|
|
|
|
2017-07-05 19:36:48 +03:00
|
|
|
* `Insertable` no longer treats all fields as nullable for type checking. What
|
|
|
|
this means for you is that if you had an impl like `impl
|
|
|
|
AsExpression<Nullable<SqlType>, DB> for CustomType` in your code base, you can
|
|
|
|
remove the `Nullable` portion (Unless you are using it with fields that are
|
|
|
|
actually nullable)
|
|
|
|
|
2017-07-14 20:28:29 +03:00
|
|
|
* Connections will now explicitly set the session time zone to UTC when the
|
|
|
|
connection is established
|
|
|
|
|
2017-07-10 18:47:31 +03:00
|
|
|
## [0.14.1] - 2017-07-10
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
2017-07-08 21:38:03 +03:00
|
|
|
* The return type of `sum` and `avg` is now always considered to be `Nullable`,
|
|
|
|
as these functions return `NULL` when against on an empty table.
|
|
|
|
|
Release v0.14.0 (The one with all the joins)
One of the oldest issues in Diesel was that we limited the number of
tables that could appear in a single query to 2. The problem was never
about having more than 2 tables, but safely and correctly proving in the
type system what would and could not be selected from that join.
With 0.14, that restriction has been removed. The query builder now
supports joins containing an arbitrary number of tables. You may find
that you need to call `enable_multi_table_joins!` for a few tables, but
that need should go away in the future as specialization matures.
In addition to the headline feature, this release includes support for
several new datatypes (including `NUMERIC`/`DECIMAL` which has been
widely requested), and other small quality of life improvements. As
always, you can see [the
CHANGELOG](https://github.com/diesel-rs/diesel/blob/v0.14.0/CHANGELOG.md)
for the full release notes.
The Road to 1.0
------
A recent point of discussion among the core team has been what remaining
blockers we have for releasing a version 1.0. The roadmap doesn't
necessarily include everything that would make us "feature complete". It
focuses on the set of changes that we think are likely to require
breaking changes.
We expect that this will be the last 0.x release. You can follow the
milestone
[here](https://github.com/diesel-rs/diesel/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.0).
Additionally, we all agreed that the biggest blocker to a 1.0 release is
improvements to our documentation. We're going to be doing a big push in
the coming months to clean things up, and are looking for help from the
community. You can follow that project
[here](https://github.com/diesel-rs/diesel/projects/1), or just come
join us in [our gitter
room](https://gitter.im/diesel-rs/diesel?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
to talk about how you can help.
There will be a blog post with more details about this in the coming
weeks.
Contributors
-----
In addition to the core team, 10 people contributed to this release. A
huge thank you to:
* Dorian Scheidt
* FliegendeWurst
* Georg Semmler
* JD Gonzales
* Jim McGrath
* Kieran
* Ruben De Smet
* Sunrin SHIMURA (keen)
* Tshepang Lekhonkhobe
* theduke
Core Team Changes
------
With this release, we are also making some changes to the core team to
better reflect the current active maintainers. In recognition of his
fantastic work, we're pleased to welcome @Eijebong to the core team.
Many early members of the team have also since moved onto other
projects. To reflect that, Mike Piccolo, Matt Casper, and Sam Phippen
are all being moved to the core team alumni.
2017-07-04 17:56:56 +03:00
|
|
|
## [0.14.0] - 2017-07-04
|
2017-06-11 14:03:15 +03:00
|
|
|
|
|
|
|
### Added
|
|
|
|
|
2017-07-04 13:49:02 +03:00
|
|
|
* Added support for joining between more than two tables. The query builder can
|
|
|
|
now be used to join between any number of tables in a single query. See the
|
|
|
|
documentation for [`JoinDsl`][join-dsl-0.14.0] for details
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[join-dsl-0.14.0]: https://docs.diesel.rs/diesel/prelude/trait.JoinDsl.html
|
2017-07-04 13:49:02 +03:00
|
|
|
|
2017-06-11 21:20:27 +03:00
|
|
|
* Added support for the [PostgreSQL network types][pg-network-0.14.0] `MACADDR`.
|
2017-05-29 08:55:59 +03:00
|
|
|
|
2017-06-21 14:51:43 +03:00
|
|
|
* Added support for the Numeric datatypes, using the [BigDecimal crate][bigdecimal-0.14.0].
|
|
|
|
|
2017-06-11 14:03:15 +03:00
|
|
|
* Added a function which maps to SQL `NOT`. See [the docs][not-0.14.0] for more
|
|
|
|
details.
|
|
|
|
|
2017-06-11 21:20:27 +03:00
|
|
|
* Added the [`insert_default_values`][insert-default-0.14.0] function.
|
|
|
|
|
|
|
|
[pg-network-0.14.0]: https://www.postgresql.org/docs/9.6/static/datatype-net-types.html
|
2017-11-04 04:12:29 +03:00
|
|
|
[not-0.14.0]: https://docs.diesel.rs/diesel/expression/dsl/fn.not.html
|
|
|
|
[insert-default-0.14.0]: https://docs.diesel.rs/diesel/fn.insert_default_values.html
|
2017-07-04 19:05:50 +03:00
|
|
|
[bigdecimal-0.14.0]: https://crates.io/crates/bigdecimal
|
2017-06-11 14:03:15 +03:00
|
|
|
|
Refactor `infix_predicate!`, add a prefix version
I've refactored `infix_predicate!` and `postfix_predicate!` to share
nearly all of their code, and added a prefix version. I've moved `not`
to use the generated operator, and renamed all of these to names I'm
comfortable with for 1.0. I want a `diesel_` prefix since these aren't
likely to be called from user code much, only plugins. I like `operator`
better here, since it's not a predicate if the return type is something
other than bool, and it's not an expression if the return type is ().
As a result of this change, `diesel_postfix_operator!` (previously
`postfix_predicate!`) gained all the functionality it was missing that
the infix form has (specifically, the ability to specify a backend).
Most of the macro was actually extremely easy to share. The only
difference between `infix_predicate_body` and `postfix_predicate_body!`
for most of the code was the number of type parameters, and the names of
the fields. This is easily solved with macro repeaters.
The two main places where the code had to differ I've moved to seprate
submacros. The first was the behavior of the body of `walk_ast`, which
needed to change based on whether it was prefix, postfix, or infix.
Secondly, if we're generating the `QueryFragment` impl for a specific
backend rather than all backends, we need to generate a second impl for
the `Debug` backend as well.
Both of these were pretty easy to solve. The resulting code is perhaps a
bit more gnarly if you're not used to macros, but I think it's better
composed than the `global_infix_predicate_to_sql!` stuff we had before.
2017-06-11 15:24:42 +03:00
|
|
|
* Added `diesel_prefix_operator!` which behaves identically to
|
|
|
|
`diesel_postfix_operator!` (previously `postfix_predicate!`), but for
|
|
|
|
operators like `NOT` which use prefix notation.
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
|
|
|
* `infix_predicate!` and `infix_expression!` have been renamed to
|
|
|
|
`diesel_infix_operator!`.
|
|
|
|
|
|
|
|
* `postfix_predicate!` and `postfix_expression!` have been renamed to
|
|
|
|
`diesel_postfix_operator!`.
|
|
|
|
|
Refactor `LoadDsl` to make it easier to introduce the raw SQL API
One of the things that's going to make our upcoming raw SQL escape hatch
different from our current `sql` function is that it's not going to
require specifying the SQL type fo the query, and it's going to load
parameters by name instead of by index. This does mean that we'll need
to provide a parallel trait to `Queryable`, but I'd prefer to avoid
introducing a parallel version of `LoadDsl`.
So in order to make the type we will introduce for this compatible with
`LoadDsl`, we needed to remove all mentions of `Queryable` from the
trait itself, and move it to bounds on the impl instead. This means we
need a new trait that is generic over the type we're deserializing, and
changed `LoadDsl` to entirely base its bounds on that.
I've opted for the name `LoadQuery` instead of something like
`InternalLoadDsl`, as this trait is one that may end up in bounds for
user code, and will certainly show up in error messages.
I had to keep a bunch of redundant bounds on `LoadDsl` in order to make
the impls of `SaveChangesDsl` remain disjoint. This is because
associated types are basically ignored for purposes of disjointness.
While we know that `Update<T, T>: !LoadQuery<SqliteConnection, U>`,
since there is that second unconstrained type parameter, we cannot use
`LoadQuery` for disjointness either since someone could in theory write
a blanket impl of `impl<T, Conn> LoadQuery<Conn, MyType> for T`
(possibly slightly more specific than that).
Finally, as some bits for clarity, I've moved `Connection#query_one`
over to `LoadDsl`, since it had no real reason to exist on the
connection. I've renamed `query_all` to `query_by_index`, since that's
how it will differ from other methods starting with `query_`. Finally,
I've moved `LoadDsl#first` off to its own trait, since the bounds are
verbose to write if you wanted to call `.first` otherwise.
2017-06-09 16:36:33 +03:00
|
|
|
* Trait bounds along the lines of `T: LoadDsl<Conn>, U: Queryable<T::SqlType,
|
|
|
|
Conn::Backend>` should be changed to `T: LoadQuery<Conn, U>`.
|
|
|
|
|
2017-07-04 17:34:51 +03:00
|
|
|
* Diesel now uses a migration to set up its timestamp helpers. To generate this
|
|
|
|
migration for your project, run `diesel database setup`.
|
|
|
|
|
Remove `#[has_many]`, it has become useless
This attribute was originally required back when we were generating
brute force impls of `SelectableExpression` for every column on both
sides of a join. That went away a few versions back, and this attribute
became mostly useless (in 0.13 you can do `child.joins(parent)` with
just `BelongsTo`, but `parent.joins(child)` requires the `has_many`).
One accidental side effect of how I implemented multi-table joins was
that the `has_many` became mandatory again. This was very unfortunate
(and means that 0.14 will generate really confusing error messages
during the upgrade) so I've just gone ahead and removed it entirely.
I expected this to be a lot simpler than it actually was. The problem is
that `#[belongs_to]` does not directly have access to the parent table.
The only way it can access it is by doing `<User as HasTable>::Table`.
Even though that is a fully monomorphic projection on a local type,
where the result is also a local type, Rust does not currently consider
this to be a local type (I think this might be a bug or oversight).
So to work around this, we instead implement the child to parent join
twice, wrapping the parent table in a marker struct for the second impl.
We then have blanket impls for every table that look for this marker,
and generate the inverse impl that we actually want.
It's a kludge, but ultimately an invisible one. The blanket impls need
to be in the generated code for tables and not in Diesel core, since if
you replace the parameter to `PleaseGenerateInverseJoinImpls` with a
type parameter, Rust will start checking infinitely recursive forms of
`PleaseGenerateInverseJoinImpls<PleaseGenerateInverseJoinImpls<...>>`
whenever a projection on that parameter is evaluated.
The problem with the impls being in the generated code is that
downstream crates cannot rely on the fact that `SelectStatement` and
friends are not tables. This was resolved by simply not having a `Table`
constraint, which lets us remove a bunch of impls in Diesel core
instead.
2017-06-11 19:18:13 +03:00
|
|
|
### Removed
|
|
|
|
|
|
|
|
* `#[has_many]` has been removed. Its functionality is now provided by
|
|
|
|
`#[belongs_to]` on the child struct. If there is no child struct to
|
|
|
|
put `#[belongs_to]` on, you can invoke `joinable!` directly instead.
|
|
|
|
|
2017-05-15 19:53:13 +03:00
|
|
|
## [0.13.0] - 2017-05-15
|
2017-04-17 05:12:20 +03:00
|
|
|
|
|
|
|
### Added
|
|
|
|
|
2016-05-26 19:48:55 +03:00
|
|
|
* Added support for chrono types with SQLite.
|
|
|
|
|
2017-05-14 21:29:36 +03:00
|
|
|
* Bind values can now be supplied to queries constructed using raw SQL. See [the
|
|
|
|
docs][sql-bind-0.13.0] for more details.
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[sql-bind-0.13.0]: https://docs.diesel.rs/diesel/expression/sql_literal/struct.SqlLiteral.html#method.bind
|
2017-05-14 21:29:36 +03:00
|
|
|
|
|
|
|
* Added support for the [PostgreSQL network types][pg-network-0.13.0] `CIDR` and
|
|
|
|
`INET`.
|
2017-05-11 17:41:33 +03:00
|
|
|
|
|
|
|
[pg-network-0.13.0]: https://www.postgresql.org/docs/9.6/static/datatype-net-types.html
|
|
|
|
|
2017-05-08 23:46:14 +03:00
|
|
|
* Added support for `ILIKE` in PostgreSQL.
|
|
|
|
|
2017-05-15 19:49:26 +03:00
|
|
|
* `diesel migration list` will show all migrations, marking those that have been
|
|
|
|
run.
|
2017-04-17 05:12:20 +03:00
|
|
|
|
2017-05-15 19:49:26 +03:00
|
|
|
* `diesel migration pending` will list any migrations which have not been run.
|
2017-04-07 20:12:17 +03:00
|
|
|
|
2017-05-15 19:49:26 +03:00
|
|
|
* Added support for numeric operations with nullable types.
|
2017-04-26 18:44:21 +03:00
|
|
|
|
2017-05-15 19:49:26 +03:00
|
|
|
* Added [`migrations::any_pending_migrations`][pending-migrations-0.13.0].
|
2017-04-26 18:44:21 +03:00
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[pending-migrations-0.13.0]: https://docs.diesel.rs/diesel/migrations/fn.any_pending_migrations.html
|
2017-04-21 00:05:08 +03:00
|
|
|
|
2017-05-12 17:44:44 +03:00
|
|
|
### Fixed
|
|
|
|
|
2017-05-15 19:49:26 +03:00
|
|
|
* Diesel CLI now respects the `--migration-dir` argument or the
|
|
|
|
`MIGRATION_DIRECTORY` environment variable for all commands.
|
2017-05-12 17:44:44 +03:00
|
|
|
|
2017-05-15 19:49:26 +03:00
|
|
|
* Diesel CLI now properly escapes the database name.
|
2017-05-12 21:01:59 +03:00
|
|
|
|
2017-05-07 15:11:31 +03:00
|
|
|
## [0.12.1] - 2017-05-07
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
|
|
|
* Locked the chrono dependency to require exactly `0.3.0` instead of a semver
|
|
|
|
restriction. This restriction is required for the 0.12 line of releases to
|
|
|
|
continue compiling, as the chrono project is including breaking changes in
|
|
|
|
patch releases.
|
2017-04-20 23:55:54 +03:00
|
|
|
|
2017-04-21 00:28:35 +03:00
|
|
|
## [0.12.0] - 2017-03-16
|
2017-02-24 19:29:27 +03:00
|
|
|
|
2017-02-26 21:35:09 +03:00
|
|
|
### Added
|
|
|
|
|
2017-03-11 12:46:43 +03:00
|
|
|
* Added support for the majority of PG upsert (`INSERT ON CONFLICT`). We now
|
|
|
|
support specifying the constraint, as well as `DO UPDATE` in addition to `DO
|
|
|
|
NOTHING`. See [the module docs][upsert-0.12.0] for details.
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[upsert-0.12.0]: https://docs.diesel.rs/diesel/pg/upsert/index.html
|
2017-03-11 12:46:43 +03:00
|
|
|
|
2017-02-26 21:35:09 +03:00
|
|
|
* Added support for the SQL concatenation operator `||`. See [the docs for
|
2017-03-04 18:56:55 +03:00
|
|
|
`.concat`][concat-0.12.0] for more details.
|
2017-02-26 21:35:09 +03:00
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[concat-0.12.0]: https://docs.diesel.rs/diesel/expression/expression_methods/text_expression_methods/trait.TextExpressionMethods.html#method.concat
|
2017-02-26 21:35:09 +03:00
|
|
|
|
2017-03-04 18:56:55 +03:00
|
|
|
* Added support for the PostgreSQL [`Money` type][pg-money-0.12.0].
|
|
|
|
|
|
|
|
[pg-money-0.12.0]: https://www.postgresql.org/docs/9.6/static/datatype-money.html
|
|
|
|
|
2017-03-16 00:27:48 +03:00
|
|
|
* Diesel CLI: Added `db` as an alias for `database`, so you can now write `diesel db setup` (which is almost 40% faster!).
|
|
|
|
|
2017-03-05 22:01:40 +03:00
|
|
|
* The `table!` macro now allows you to use types from crates outside of Diesel.
|
|
|
|
You can specify where types should be imported from by doing: `table! { use
|
|
|
|
some_modules::*; foo { columns... }`. Not specifying any any modules is
|
|
|
|
equivalent to `use diesel::types::*;`.
|
|
|
|
|
2017-02-24 19:29:27 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `diesel_codegen` will provide a more useful error message when it encounters
|
|
|
|
an unsupported type that contains a space in MySQL.
|
|
|
|
|
2017-03-15 19:37:08 +03:00
|
|
|
* `#[derive(AsChangeset)]` will now respect custom `#[primary_key]` annotations,
|
|
|
|
and avoid setting those columns.
|
|
|
|
|
2017-02-25 17:37:20 +03:00
|
|
|
### Removed
|
|
|
|
|
|
|
|
* `WithDsl` and `Aliased` have been removed. They were a feature that was
|
|
|
|
actually closer to a cross join than the names implied, and wasn't fully
|
|
|
|
thought out. The functionality they provided will return as joins are further
|
|
|
|
revamped.
|
|
|
|
|
2017-02-24 21:55:28 +03:00
|
|
|
* The internal use macro `select_column_workaround!` has been removed. If you
|
|
|
|
were relying on this internal macro, you can simply delete the line that was
|
|
|
|
calling it.
|
2017-02-27 04:10:46 +03:00
|
|
|
|
2017-03-16 19:41:51 +03:00
|
|
|
* Columns from the right side of a left join will now need to have `.nullable()`
|
|
|
|
explicitly called to be passed to `.select`. This allows it to compose better
|
|
|
|
with functions that don't normally take nullable columns (e.g.
|
|
|
|
`lower(name).nullable()`).
|
|
|
|
|
2017-02-21 13:06:55 +03:00
|
|
|
## [0.11.4] - 2017-02-21
|
2017-02-21 12:56:16 +03:00
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Corrected a memory safety violation when using MySQL.
|
|
|
|
|
2017-02-21 13:06:55 +03:00
|
|
|
## 0.11.3 - 2017-02-21
|
|
|
|
|
|
|
|
* No changes
|
|
|
|
|
2017-02-19 18:29:25 +03:00
|
|
|
## [0.11.2] - 2017-02-19
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
|
|
|
* `pq-sys` and `mysqlclient-sys` will no longer attempt to generate bindings at
|
|
|
|
compile time. Generating the bindings required a bleeding edge version of
|
|
|
|
clang, which caused too many issues.
|
|
|
|
|
|
|
|
## [0.11.1] - 2017-02-17
|
2017-02-17 18:27:42 +03:00
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `.on_conflict_do_nothing()` now interacts with slices properly.
|
|
|
|
|
2017-02-17 22:03:56 +03:00
|
|
|
* `MysqlConnection` now implements `Send`, which is required for connection
|
|
|
|
pooling.
|
|
|
|
|
Relase v0.11.0 (The one where we support MySQL)
The headline features for this release are MySQL support and limited PG
upsert support. MySQL support works exactly as you'd expect. Just add
`features = ["mysql"]` to your Cargo.toml, pass a connection URL (where
the scheme is `mysql://` and the path is the name of the database) to
`MysqlConnection::establish` and you're off. Keep in mind that if you're
following the getting started guide, MySQL does not support the
`RETURNING` clause, so methods like `get_result` and `get_results` won't
work.
PostgreSQL upsert was a feature added in PG 9.5 and has been one of our
most requested features. The full upsert API is quite complex, but we've
added support for `ON CONFLICT DO NOTHING`, as this covered the highest
percentage of use cases with the lowest amount of work. You can see
examples in [the docs][on-conflict-do-nothing]. Support for the full
upsert syntax will be coming in 0.12.
In addition to the headline features, there were plenty of quality of
life improvements and bug fixes. As always, you can see a full list of
changes by reading [the changelog][changelog].
[on-conflict-do-nothing]: http://docs.diesel.rs/diesel/pg/upsert/trait.OnConflictExtension.html#method.on_conflict_do_nothing
[changelog]: https://github.com/diesel-rs/diesel/blob/v0.11.0/CHANGELOG.md
In addition to the Diesel core team, 6 additional contributors worked on
this release. A huge thank you to:
- Brandon W Maister
- Eijebong
- Georg Semmler
- Jimmy Cuadra
- Jovansonlee Cesar
- jacob
I'd also like to thank everybody who helped this release by opening
issues, finding bugs, and asking/answering questions in our gitter room.
2017-02-16 22:49:59 +03:00
|
|
|
## [0.11.0] - 2017-02-16
|
2017-02-03 23:59:30 +03:00
|
|
|
|
Add some missing tests for PG prepared statement caching
I'm looking into extracting the prepared statement caching for SQLite
and PG into a shared module (so I don't have to re-implement it *again*
for MySQL). While I was making sure I understood the requirements of the
existing implementations, I noticed that we had no tests for PG where
the statement is cached, but not on the type id.
The only cases where `QueryFragment::is_safe_to_cache_prepared` returns
`true`, but `QueryId::has_static_query_id` returns `false` is using
`Aliased`/`with` on PG, and boxed queries. Since these tests run with no
schema, boxing is easier to test.
When I wrote these tests, I noticed that attempting to run a boxed query
with no query source failed to compile. I've added the missing impl
required for it. It's copypasta from the other impl, with the from lines
deleted, but I liked this code better than with `to_sql_before_from`,
`to_sql_after_from`, `collect_binds_before_from`, etc pulled out. We can
always refactor if these impls end up having to change a lot.
2017-02-11 16:12:35 +03:00
|
|
|
### Added
|
|
|
|
|
2017-02-16 22:32:44 +03:00
|
|
|
* Added support for MySQL as an additional backend. Diesel CLI will install with
|
|
|
|
MySQL support by default. To enable it for Diesel and Diesel Codegen, add
|
2017-02-16 22:33:18 +03:00
|
|
|
`features = ["mysql"]` to Cargo.toml. See [the docs][mysql-0.11.0] for details.
|
2017-02-16 22:32:44 +03:00
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[mysql-0.11.0]: https://docs.diesel.rs/diesel/mysql/index.html
|
2017-02-16 22:32:44 +03:00
|
|
|
|
|
|
|
* Added support for PG's `ON CONFLICT DO NOTHING` clause. See [the
|
|
|
|
docs][on-conflict-0.11.0] for details.
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[on-conflict-0.11.0]: https://docs.diesel.rs/diesel/pg/upsert/trait.OnConflictExtension.html#method.on_conflict_do_nothing
|
2017-02-16 22:32:44 +03:00
|
|
|
|
Add some missing tests for PG prepared statement caching
I'm looking into extracting the prepared statement caching for SQLite
and PG into a shared module (so I don't have to re-implement it *again*
for MySQL). While I was making sure I understood the requirements of the
existing implementations, I noticed that we had no tests for PG where
the statement is cached, but not on the type id.
The only cases where `QueryFragment::is_safe_to_cache_prepared` returns
`true`, but `QueryId::has_static_query_id` returns `false` is using
`Aliased`/`with` on PG, and boxed queries. Since these tests run with no
schema, boxing is easier to test.
When I wrote these tests, I noticed that attempting to run a boxed query
with no query source failed to compile. I've added the missing impl
required for it. It's copypasta from the other impl, with the from lines
deleted, but I liked this code better than with `to_sql_before_from`,
`to_sql_after_from`, `collect_binds_before_from`, etc pulled out. We can
always refactor if these impls end up having to change a lot.
2017-02-11 16:12:35 +03:00
|
|
|
* Queries constructed using [`diesel::select`][select-0.11.0] now work properly
|
|
|
|
when [boxed][boxed-0.11.0].
|
|
|
|
|
Relase v0.11.0 (The one where we support MySQL)
The headline features for this release are MySQL support and limited PG
upsert support. MySQL support works exactly as you'd expect. Just add
`features = ["mysql"]` to your Cargo.toml, pass a connection URL (where
the scheme is `mysql://` and the path is the name of the database) to
`MysqlConnection::establish` and you're off. Keep in mind that if you're
following the getting started guide, MySQL does not support the
`RETURNING` clause, so methods like `get_result` and `get_results` won't
work.
PostgreSQL upsert was a feature added in PG 9.5 and has been one of our
most requested features. The full upsert API is quite complex, but we've
added support for `ON CONFLICT DO NOTHING`, as this covered the highest
percentage of use cases with the lowest amount of work. You can see
examples in [the docs][on-conflict-do-nothing]. Support for the full
upsert syntax will be coming in 0.12.
In addition to the headline features, there were plenty of quality of
life improvements and bug fixes. As always, you can see a full list of
changes by reading [the changelog][changelog].
[on-conflict-do-nothing]: http://docs.diesel.rs/diesel/pg/upsert/trait.OnConflictExtension.html#method.on_conflict_do_nothing
[changelog]: https://github.com/diesel-rs/diesel/blob/v0.11.0/CHANGELOG.md
In addition to the Diesel core team, 6 additional contributors worked on
this release. A huge thank you to:
- Brandon W Maister
- Eijebong
- Georg Semmler
- Jimmy Cuadra
- Jovansonlee Cesar
- jacob
I'd also like to thank everybody who helped this release by opening
issues, finding bugs, and asking/answering questions in our gitter room.
2017-02-16 22:49:59 +03:00
|
|
|
[select-0.11.0]: https://docs.rs/diesel/0.11.0/diesel/fn.select.html
|
2017-11-04 04:18:59 +03:00
|
|
|
[boxed-0.11.0]: https://docs.rs/diesel/0.11.0/prelude/trait.BoxedDsl.html
|
Add some missing tests for PG prepared statement caching
I'm looking into extracting the prepared statement caching for SQLite
and PG into a shared module (so I don't have to re-implement it *again*
for MySQL). While I was making sure I understood the requirements of the
existing implementations, I noticed that we had no tests for PG where
the statement is cached, but not on the type id.
The only cases where `QueryFragment::is_safe_to_cache_prepared` returns
`true`, but `QueryId::has_static_query_id` returns `false` is using
`Aliased`/`with` on PG, and boxed queries. Since these tests run with no
schema, boxing is easier to test.
When I wrote these tests, I noticed that attempting to run a boxed query
with no query source failed to compile. I've added the missing impl
required for it. It's copypasta from the other impl, with the from lines
deleted, but I liked this code better than with `to_sql_before_from`,
`to_sql_after_from`, `collect_binds_before_from`, etc pulled out. We can
always refactor if these impls end up having to change a lot.
2017-02-11 16:12:35 +03:00
|
|
|
|
Allow arrays containing null to be serialized
Deserialization already worked, so there's no reason we shouldn't just
allow this. It's worth noting that there is no way to represent whether
an array is allowed to contain nulls or not within postgres's type
system. As such, the type `Array<Nullable<ST>>` will never be generated
by `infer_schema!` (I do want to make `FromSql<Array<ST>> for
`Vec<Option<T>>` just work though). Since we never provide a
`ToSql<Array<ST>> for Vec<Option<T>>`, Diesel will prevent you from
accidentally inserting nulls at compile time. Ultimately the user does
just have to make sure they represent whether the array could contain
null in the output type, however.
One alternative would be to represent the fact that all arrays can
contain null within the type system, and only provide `impl
FromSql<Array<ST>> for Vec<Option<T>>`. I suspect this would hinder
ergonomics pretty heavily, but we should consider it before 1.0.
One note about the implementation -- Technically we should be setting
`flags` to `1` if the array contains any nulls, as that's what happens
on the data sent to us. However, setting it would require us to perform
an additional level of intermediate buffering on all the values to
determine whether the flag should be set, and that flag is currently
ignored by PG. "But Sean, that's just relying on an implementation
detail!" this is true, but our entire usage of the binary format is
relying on an implementation detail (See #695).
2017-02-13 17:41:37 +03:00
|
|
|
* Arrays containing null are now supported. `infer_schema!` will never infer an
|
|
|
|
array that contains null, but a `table!` definition which specifies a type of
|
|
|
|
`Array<Nullable<X>>` can now be deserialized to `Vec<Option<T>>`
|
|
|
|
|
2017-02-15 20:22:13 +03:00
|
|
|
* [`#[belongs_to]`][belongs-to-0.11.0] associations can now be self referential.
|
|
|
|
This will generate the code required for
|
|
|
|
[`belonging_to`][belonging-to-0.11.0], without generating code for performing
|
|
|
|
a join.
|
|
|
|
|
Relase v0.11.0 (The one where we support MySQL)
The headline features for this release are MySQL support and limited PG
upsert support. MySQL support works exactly as you'd expect. Just add
`features = ["mysql"]` to your Cargo.toml, pass a connection URL (where
the scheme is `mysql://` and the path is the name of the database) to
`MysqlConnection::establish` and you're off. Keep in mind that if you're
following the getting started guide, MySQL does not support the
`RETURNING` clause, so methods like `get_result` and `get_results` won't
work.
PostgreSQL upsert was a feature added in PG 9.5 and has been one of our
most requested features. The full upsert API is quite complex, but we've
added support for `ON CONFLICT DO NOTHING`, as this covered the highest
percentage of use cases with the lowest amount of work. You can see
examples in [the docs][on-conflict-do-nothing]. Support for the full
upsert syntax will be coming in 0.12.
In addition to the headline features, there were plenty of quality of
life improvements and bug fixes. As always, you can see a full list of
changes by reading [the changelog][changelog].
[on-conflict-do-nothing]: http://docs.diesel.rs/diesel/pg/upsert/trait.OnConflictExtension.html#method.on_conflict_do_nothing
[changelog]: https://github.com/diesel-rs/diesel/blob/v0.11.0/CHANGELOG.md
In addition to the Diesel core team, 6 additional contributors worked on
this release. A huge thank you to:
- Brandon W Maister
- Eijebong
- Georg Semmler
- Jimmy Cuadra
- Jovansonlee Cesar
- jacob
I'd also like to thank everybody who helped this release by opening
issues, finding bugs, and asking/answering questions in our gitter room.
2017-02-16 22:49:59 +03:00
|
|
|
[belongs-to-0.11.0]: https://docs.rs/diesel/0.11.0/diesel/associations/trait.BelongsTo.html
|
|
|
|
[belonging-to-0.11.0]: https://docs.rs/diesel/0.11.0/diesel/prelude/trait.BelongingToDsl.html#tymethod.belonging_to
|
|
|
|
|
2017-02-16 22:40:56 +03:00
|
|
|
* Added support for the `rust-lang-deprecated/time` crate on PostgreSQL. To use
|
|
|
|
it, add `features = ["deprecated-time"]`
|
|
|
|
|
2017-02-03 23:59:30 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* It is no longer possible to exhaustively match against
|
|
|
|
`result::ConnectionError`.
|
|
|
|
|
2017-02-07 02:06:26 +03:00
|
|
|
* Updated chrono to version 0.3.
|
|
|
|
|
2017-02-11 00:24:30 +03:00
|
|
|
* [`max`][max-0.11.0] and [`min`][min-0.11.0] are now always nullable. The database will
|
|
|
|
return `NULL` when the table is empty.
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[max-0.11.0]: https://docs.diesel.rs/diesel/expression/dsl/fn.max.html
|
|
|
|
[min-0.11.0]: https://docs.diesel.rs/diesel/expression/dsl/fn.min.html
|
2017-02-11 00:24:30 +03:00
|
|
|
|
2017-02-12 20:38:10 +03:00
|
|
|
* [`now`][now-0.11.0] can now be used as an expression of type `Timestamptz`.
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[now-0.11.0]: https://docs.diesel.rs/diesel/expression/dsl/struct.now.html
|
2017-02-12 20:38:10 +03:00
|
|
|
|
2017-02-13 21:53:09 +03:00
|
|
|
* [`Connection::transaction`][transaction-0.11.0] now returns your error
|
|
|
|
directly instead of wrapping it in `TransactionError`. It requires that the
|
|
|
|
error implement `From<diesel::result::Error>`
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[transaction-0.11.0]: https://docs.diesel.rs/diesel/connection/trait.Connection.html#method.transaction
|
2017-02-13 21:53:09 +03:00
|
|
|
|
Use associated types for `SelectableExpression`
The `SelectableExpression` trait serves two purposes for us. The first
and most important role it fills is to ensure that columns from tables
that aren't in the from clause cannot be used. The second way that we
use it to make columns which are on the right side of a left outer join
be nullable.
There were two reasons that we used a type parameter instead of an
associated type. The first was to make it so that `(Nullable<X>,
Nullable<Y>)` could be treated as `Nullable<(X, Y)>`. We did this
because the return type of `users.left_outer_join(posts)` should be
`(User, Option<Post>)`, not `(User, Post)` where every field of `Post`
is an `Option`.
Since we now provide a `.nullable()` method in the core DSL, I think we
can simply require calling that method explicitly if you want that tuple
conversion to occur. I think that the most common time that conversion
will even be used is when the default select clause is used, where we
can just handle it for our users automatically.
The other reason that we went with a type parameter originally was that
it was easier, since we can provide a default value for a type parameter
but not an associated type. This turned out to actually be a drawback,
as it led to #104. This PR actually brings back aspects of that issue,
which I'll get to in a moment.
It's expected that any expression which implements
`SelectableExpression<QS>` have a `T: SelectableExpression<QS>` bound
for each of its parts. The problem is, the missing second parameter is
defaulting to `T::SqlType`, which means we are implicitly saying that
this bound only applies for `QS` which does not change the SQL type
(anything except a left outer join). This ultimately led to #621.
However, with our current structure, it is impossible to fix #621
without re-introducing at least some aspects of #104. In
https://github.com/diesel-rs/diesel/issues/104#issuecomment-172281522 I
said that we didn't need to worry about `1 + NULL`, because we didn't
implement add for any nullable types. However, I'm not sure I considered
joins when I made that statement. The statement applied to joins
previously because of that implicit "sql type doesn't change"
constraint. This commit removes that constraint, meaning #104 will be
back at least when the nullability comes from being on the right side of
a left join.
I don't think this is a serious enough issue that we need to immediately
address it, as the types of queries which would cause the issue still
just don't happen in practice. We should come up with a long term plan
for it, though. Ultimately the nullability of a field really only
matters in the select clause. Since any operation on null returns null,
and you basically want null to act as false in the where clasue, it
doesn't matter there.
So one partial step we could take is to break this out into two separate
traits. One for the "make sure this is valid given the from clause", and
one for the "make this nullable sometimes" case and only constrain on
the first one in the where clause. We could then re-add the "sql type
doesn't change" constraint on the problem cases, which will bring back
aspects of #621, but only for select clauses which is a smaller problem.
I'm not sure if I ultimately want to go the two traits route or not. If
nothing else, the problem cases are much more obvious with this commit.
Anywhere that has `type SqlTypeForSelect = Self::SqlType` is likely a
problem case when joins are involved. This will make it easier to find
all the places to apply a solution when I come up with one that I'm
happy with.
Fixes #621.
2017-02-15 15:28:24 +03:00
|
|
|
* The way tuples of columns from the right side of left outer joins interact
|
|
|
|
with `.select` has changed. If you are deserializing into an option of a tuple
|
|
|
|
(instead of a tuple of options), you will need to explicitly call
|
|
|
|
`.nullable()`. (e.g. `.select(users::name, (posts::title,
|
|
|
|
posts::body).nullable())`)
|
|
|
|
|
2017-02-13 21:53:09 +03:00
|
|
|
### Removed
|
|
|
|
|
|
|
|
* `result::TransactionError`
|
|
|
|
* `result::TransactionResult`
|
|
|
|
|
2017-02-08 19:10:20 +03:00
|
|
|
## [0.10.1] - 2017-02-08
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `infer_table_from_schema!` properly handles table names with a custom schema
|
|
|
|
specified.
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
2017-02-07 14:08:55 +03:00
|
|
|
* Updated uuid to version 0.4.
|
|
|
|
|
Release v0.10.0 (The one where we work on stable)
![It's happening](http://i.imgur.com/7drHiqr.gif)
v0.10.0 drops support for Rust 1.14 and earlier, and adds support for
Rust 1.15 (ON STABLE). `diesel_codegen_syntex` has been removed, and is
no longer supported.
Additionally, this release adds initial support for the JSON data type
in PostgreSQL. There is also a new `print-schema` subcommand in Diesel
CLI which will show you the code generated by `infer_schema!()`. As
always, you can find a full list of what has changed in [the
changelog][changelog].
In addition to the Diesel core team, 7 contributors worked on this
release. A huge thank you to
- Adrian Perez de Castro
- Eric Kidd
- Georg Semmler
- Jake Goulding
- Sergio Benitez
- Severen Redwood
- Stu Black
I'd also like to thank everybody who helped this release by opening
issues, finding bugs, and asking/answering questions in our gitter room.
There were several big features that I had hoped to get done in time for
this release, but my daughter inherited my troll gene and decided to
come early. If you were hoping for MySQL support, blame Ruby. In the
mean time, here is a picture of Ruby.
![baby ruby](https://lh3.googleusercontent.com/7vUZONdvrati-NQXriSqzKQ0CHNz6KRulOSos9kJjzMNV-JI2UT6d4Kxex9fZGO-0GTlLrKHKRwiPaf2v6hCJlCU0IgK5kWd_JWz9nG61FrZfgVARZEqXOmjoXPb5CYrbTg7XlG2VEYlcm6_Lk9oviVPh7mx3gaXgVG6g-OJRHqY_gipU-Y2REPFDoJyPWZ9QoifZH1WDGSPdyYUQ1KWeTfFkxk1Z3VP1bKAyRhsDmnXvSLaWkBQ6r5CpRS2pfVMC0lPVAfPGmrjwmNw7JmFNfscQM5IY0FOqbbwJhPJvLtNb-jOgOQhz07S8HA9BBI_cWzzXXMxbGXzaPpKBYSrioMja3MkXcb1PGB8cG7ERtG_CWwpGriRlFbrj2B0OygkAu4Q6pRiQe6BojpHYp03uyRsmsVxTbQjlH3axed6tNV_IDYSd2vz15gB7yFKUF_Je3spUUdexLmybdPDR29DfD-hBBJfezy0gdzrf7dJMMXWgQ7CW6jH18uydl-iiK3_8Ha8FUuvrjcA-Dvv0nQEXqajcb_NFCpobr92fNQvDCg6UNj3o7E7bv55Oj6sOk7N7xARchy-MmAV8Tzzc1Sx-4GKHhikH5WGMb5AzYSnoNcvWr7mD4vqAF1Wn_60Huz1KCNC5m2aBbPz9G6hBcM3pMe8J5pIM4epvKFvKUKtK98=w792-h1056-no)
[changelog]: https://github.com/diesel-rs/diesel/blob/v0.10.0/CHANGELOG.md
2017-02-02 21:17:47 +03:00
|
|
|
## [0.10.0] - 2017-02-02
|
2016-12-14 22:39:12 +03:00
|
|
|
|
2017-02-02 19:06:52 +03:00
|
|
|
### Added
|
|
|
|
|
|
|
|
* Added support for the PostgreSQL [`json` and `jsonb` types][pg-json]. They can
|
|
|
|
be mapped to/from `serde_json::Value`. The `serde` feature must be enabled to
|
|
|
|
use the JSON types.
|
|
|
|
|
|
|
|
[pg-json]: https://www.postgresql.org/docs/9.6/static/datatype-json.html
|
|
|
|
|
|
|
|
* Added the `print-schema` command to Diesel CLI. This command will print the
|
|
|
|
output of the `infer_schema!` macro. For more information run `diesel help
|
|
|
|
print-schema`.
|
|
|
|
|
2016-12-14 22:39:12 +03:00
|
|
|
### Changed
|
|
|
|
|
2016-12-14 22:51:32 +03:00
|
|
|
* When possible, we will use deprecation warnings for breaking changes.
|
|
|
|
Deprecated code requires the `with-deprecated` feature, which is enabled by
|
|
|
|
default.
|
|
|
|
|
2016-12-14 22:39:12 +03:00
|
|
|
* The `postgres` feature is no longer enabled by default by `diesel` or
|
|
|
|
`diesel_codegen_syntex`. Add `features = ["postgres"]` to your `Cargo.toml`.
|
|
|
|
|
2016-12-14 22:51:32 +03:00
|
|
|
* The `persistable` module has been renamed to `insertable`.
|
|
|
|
|
2017-01-04 17:28:04 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `#[derive(Insertable)]` allows fields of type `Option<T>` to be used with
|
|
|
|
columns that are not null if they have a default value.
|
|
|
|
|
2017-01-08 19:23:17 +03:00
|
|
|
### Removed
|
|
|
|
|
|
|
|
* `diesel_codegen_syntex` is no longer supported. `diesel_codegen` can now be
|
|
|
|
used on stable Rust.
|
|
|
|
|
|
|
|
* Dropped support for Rust 1.14 and earlier
|
|
|
|
|
2016-12-11 13:39:47 +03:00
|
|
|
## [0.9.1] - 2016-12-09
|
2016-12-10 14:00:54 +03:00
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Added missing impls for loading `chrono::NaiveDateTime` from a column of type
|
|
|
|
`Timestamptz`
|
|
|
|
|
2016-12-10 14:08:17 +03:00
|
|
|
* `#[derive(AsChangeset)]` no longer assumes that `use diesel::prelude::*` has
|
|
|
|
been done.
|
|
|
|
|
2016-12-10 19:12:10 +03:00
|
|
|
* `debug_sql!` can now properly be used with types from `chrono` or
|
|
|
|
`std::time`.
|
|
|
|
|
Construct error messages properly when libpq returns `NULL` result
I had originally thought that this was some weird condition that was the
result of the server getting a query with more than `34464` (`i16::MAX`)
bind parameters, where we got back an error but it had no message. We
panic in that case, as PG is documented that all errors have a message.
It turns out I was wrong for two reasons.
First, the number is 65535 (`u16::MAX`), not `34464`. (This might have
been something changed on the PG side in 9.6 which was released since I
last looked at this). Second, we were not getting back an error with no
message, we were getting a `NULL` return value from libpq. From [their
docs][]:
[their docs]: https://www.postgresql.org/docs/9.6/static/libpq-exec.html#LIBPQ-PQPREPARE
> A null result indicates out-of-memory or inability to send the command
> at all. Use PQerrorMessage to get more information about such errors.
`PQerrorMessage` means the error is on the connection. The reason that
we had no result was that the PG wire protocol uses a `u16` for the
number of bind parameters, so there's no way for the driver to have even
sent the message to the server.
Once we realized the error condition that we were seeing is more general
than just the bind parameter case, I've refactored the code to perform a
not null check as early as possible, and hide the `*mut PGresult`.
The test itself is written in a somewhat strange fashion. We're
constructing a query that has 70_000 bind parameters, as this is the
only case that I know of which will always cause libpq to return null. I
don't care what the error message is, just that it's not an empty
string. I've also written the test to explicitly match instead of unwrap
and use `#[should_panic]` because I want to be sure that it *didn't*
panic.
Ideally we would never see `*mut PGresult` anywhere in the code, and use
`Unique<PGresult>` instead. However, it is currently unstable. I had
originally implemented this to use `Unique` if `feature = "unstable"`
was set, but deleted it as the `#[cfg]` branches made the code harder to
comprehend. The only real benefit `Unique` gives us here is clarity of
intent. For the not-null and non-aliased hints to result in any
optimization by the compiler would require libpq to be statically
linked, and LTO to be happening at the LLVM layer, neither of which are
commonly true.
We know that `Send` and `Sync` are safe to implement on our new struct,
because the pointer is unaliased. We can delete those impls if we switch
to using `Unique` in the future, as it already implements those traits.
Fixes #446.
2016-12-10 15:19:18 +03:00
|
|
|
* When using PostgreSQL, attempting to get the error message of a query which
|
|
|
|
could not be transmitted to the server (such as a query with greater than
|
|
|
|
65535 bind parameters) will no longer panic.
|
|
|
|
|
2016-12-09 00:15:12 +03:00
|
|
|
## [0.9.0] - 2016-12-08
|
2016-12-02 19:49:10 +03:00
|
|
|
|
2016-12-02 23:41:53 +03:00
|
|
|
### Added
|
|
|
|
|
|
|
|
* Added support for SQL `NOT IN` using the `ne_any` method.
|
|
|
|
|
2016-12-02 20:30:43 +03:00
|
|
|
* The `table!` macro now allows custom schemas to be specified. Example:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
table! {
|
|
|
|
schema_1.table_1 {
|
|
|
|
id -> Integer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The generated module will still be called `table_1`.
|
|
|
|
|
2016-12-06 16:52:39 +03:00
|
|
|
* The `infer_table_from_schema!` macro now allows custom schemas to be
|
|
|
|
specified. Example:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
infer_table_from_schema!("dotenv:DATABASE_URL", "schema_1.table_1");
|
|
|
|
```
|
|
|
|
|
|
|
|
* The `infer_schema!` optionally allows a schema name as the second argument. Any
|
|
|
|
schemas other than `public` will be wrapped in a module with the same name as
|
|
|
|
the schema. For example, `schema_1.table_1` would be referenced as
|
|
|
|
`schema_1::table_1`.
|
|
|
|
|
2016-12-06 14:00:21 +03:00
|
|
|
* Added support for batch insert on SQLite. This means that you can now pass a
|
|
|
|
slice or vector to [`diesel::insert`][insert] on all backends.
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[insert]: https://docs.diesel.rs/diesel/fn.insert.html
|
2016-12-06 14:00:21 +03:00
|
|
|
|
2016-12-08 20:26:10 +03:00
|
|
|
* Added a function for SQL `EXISTS` expressions. See
|
|
|
|
[`diesel::expression::dsl::exists`][exists] for details.
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[exists]: https://docs.diesel.rs/diesel/expression/dsl/fn.sql.html
|
2016-12-08 20:26:10 +03:00
|
|
|
|
2016-12-08 19:08:47 +03:00
|
|
|
* `#[derive(Identifiable)]` can be used with structs that have primary keys
|
|
|
|
other than `id`, as well as structs with composite primary keys. You can now
|
|
|
|
annotate the struct with `#[primary_key(nonstandard)]` or `#[primary_key(foo,
|
|
|
|
bar)]`.
|
|
|
|
|
2016-12-06 17:26:50 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* All macros with the same name as traits we can derive (e.g. `Queryable!`) have
|
|
|
|
been renamed to `impl_Queryable!` or similar.
|
|
|
|
|
2016-12-02 19:49:10 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `#[derive(Identifiable)]` now works on structs with lifetimes
|
|
|
|
|
2016-12-06 14:00:21 +03:00
|
|
|
* Attempting to insert an empty slice will no longer panic. It does not execute
|
|
|
|
any queries, but the result will indicate that we successfully inserted 0
|
|
|
|
rows.
|
|
|
|
|
|
|
|
* Attempting to update a record with no changes will no longer generate invalid
|
|
|
|
SQL. The result of attempting to execute the query will still be an error, but
|
|
|
|
but it will be a `Error::QueryBuilderError`, rather than a database error.
|
|
|
|
This means that it will not abort the current transaction, and can be handled
|
|
|
|
by applications.
|
|
|
|
|
|
|
|
* Calling `eq_any` or `ne_any` with an empty array no longer panics.
|
|
|
|
`eq_any(vec![])` will return no rows. `ne_any(vec![])` will return all rows.
|
|
|
|
|
2016-11-22 20:48:29 +03:00
|
|
|
## [0.8.2] - 2016-11-22
|
Fix breakage in latest nightlies
The latest nightlies have added built-in support for custom attributes,
but have removed the ability to modify the input token stream. This
means that our bang macros now need to worry about namespace collisions.
For `embed_migrations` this doesn't matter, since the output is a module
with a known name. `infer_schema` is ok as well, since it's not expected
to be called more than once. However, `infer_table_from_schema` outputs
a module which differs, and the API currently takes a string which we
can't turn into a module name. Even if we changed the API to take an
ident instead of an expr, we can't then pass that ident into the
procedural macros. We can work around this in our invocation of it from
`infer_schema!`, but this will force this API change onto our users.
Since `infer_table_from_schema!` isn't highly used, I think this is OK,
but we might want to start looking at alternatives long term. There have
been murmurs of a proper bang macros 1.1, which is the best solution. We
could also go back to only allowing `infer_schema!` on nightly, and
change to a solution that involves Diesel CLI or build scripts, but both
of those will increase the barrier to entry for newcomers.
2016-11-12 21:34:03 +03:00
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
2016-11-22 20:48:29 +03:00
|
|
|
* Fixed support for nightlies later than 2016-11-07
|
Fix breakage in latest nightlies
The latest nightlies have added built-in support for custom attributes,
but have removed the ability to modify the input token stream. This
means that our bang macros now need to worry about namespace collisions.
For `embed_migrations` this doesn't matter, since the output is a module
with a known name. `infer_schema` is ok as well, since it's not expected
to be called more than once. However, `infer_table_from_schema` outputs
a module which differs, and the API currently takes a string which we
can't turn into a module name. Even if we changed the API to take an
ident instead of an expr, we can't then pass that ident into the
procedural macros. We can work around this in our invocation of it from
`infer_schema!`, but this will force this API change onto our users.
Since `infer_table_from_schema!` isn't highly used, I think this is OK,
but we might want to start looking at alternatives long term. There have
been murmurs of a proper bang macros 1.1, which is the best solution. We
could also go back to only allowing `infer_schema!` on nightly, and
change to a solution that involves Diesel CLI or build scripts, but both
of those will increase the barrier to entry for newcomers.
2016-11-12 21:34:03 +03:00
|
|
|
|
2016-11-22 20:48:29 +03:00
|
|
|
* Removed support for nightlies earlier than 2016-11-07
|
Fix breakage in latest nightlies
The latest nightlies have added built-in support for custom attributes,
but have removed the ability to modify the input token stream. This
means that our bang macros now need to worry about namespace collisions.
For `embed_migrations` this doesn't matter, since the output is a module
with a known name. `infer_schema` is ok as well, since it's not expected
to be called more than once. However, `infer_table_from_schema` outputs
a module which differs, and the API currently takes a string which we
can't turn into a module name. Even if we changed the API to take an
ident instead of an expr, we can't then pass that ident into the
procedural macros. We can work around this in our invocation of it from
`infer_schema!`, but this will force this API change onto our users.
Since `infer_table_from_schema!` isn't highly used, I think this is OK,
but we might want to start looking at alternatives long term. There have
been murmurs of a proper bang macros 1.1, which is the best solution. We
could also go back to only allowing `infer_schema!` on nightly, and
change to a solution that involves Diesel CLI or build scripts, but both
of those will increase the barrier to entry for newcomers.
2016-11-12 21:34:03 +03:00
|
|
|
|
|
|
|
* Calls to `infer_table_from_schema!` will need to be wrapped in a module if
|
|
|
|
called more than once. This change is to work around further limitations of
|
|
|
|
the Macros 1.1 system. Example:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
mod infer_users {
|
|
|
|
infer_table_from_schema!("dotenv:DATABASE_URL", "users");
|
|
|
|
}
|
|
|
|
pub use self::infer_users::*;
|
|
|
|
```
|
|
|
|
|
2016-11-01 21:37:00 +03:00
|
|
|
## [0.8.1] - 2016-11-01
|
|
|
|
|
|
|
|
### Added
|
|
|
|
|
|
|
|
* SQLite date and time columns can be deserialized to/from strings.
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Fixed an issue with `diesel_codegen` on nightlies >= 2016-10-20
|
|
|
|
|
2016-10-10 22:12:50 +03:00
|
|
|
## [0.8.0] - 2016-10-10
|
Reform types inferred by `infer_schema!` on SQLite (#277)
`infer_schema!` is woefully undertested. Really our tests for it at the
moment are "we use it for our test suite so the cases our suite covers
work". However, even though I defined `tinyint` == `Bool`, I wanted to
make sure that `TINYINT(1)` was treated as bool as well, as I wasn't
certain how SQLite handles limit/precision/scale.
The answer is that it doesn't, and it's way looser about allowed type
names than I had thought. The process listed at
https://www.sqlite.org/datatype3.html is a literal description, and any
possible string is a valid type.
This adds tests for every example given on that page, plus a few extras.
We create a table with as many of these fields as possible, and do a
trivial roundtrip to make sure that it *actually* infers something we
can deserialize from, and that we're not doing anything dumb.
The new logic for type inference matches pretty closely to how SQLite
handles things with a few exceptions:
- "boolean" or types containing "tiny" and "int" are treated as bool
- smallint and bigint are separated from int
- float is separated from double
- varchar is separated from text
- We do not accept random unrecognized type names as numeric
Unresolved Questions
--------------------
This actually starts to make me a bit more nervous about our semantics
with SQLite. If you're just using Diesel, everything is fine. However,
you can definitely insert values that would fail to deserialize with so
little constraints on the backend. I'm starting to wonder if we should
truly embrace SQLite's definitions and map exactly to that, allowing
only the following types:
- BigInt
- VarChar (yes, it's the ANSI text type but we treat VarChar as the
"default" string type)
- Binary
- Double
We're omitting numeric, as there's no observable difference in SQLite
between the real affinity and the numeric affinity.
This would have several *major* implications. Aside from not being able
to use basic things like an `i32`, it would also mean that there is no
boolean type, and no dates/times/datetimes. Functions for those do exist
on the SQLite side though, so some of the interactions might get super
janky.
That said, Diesel's goal is not to abstract away the backend. These are
the semantics of the backend chosen, and maybe we should go whole hog
and embrace them.
I'm still unsure. In the meantime, with our current semantics, this
should improve the reliability of `infer_schema!`
2016-04-17 23:42:11 +03:00
|
|
|
|
2016-08-11 14:16:08 +03:00
|
|
|
### Added
|
|
|
|
|
2016-10-10 22:12:50 +03:00
|
|
|
* Added partial support for composite primary keys.
|
Add initial support for composite primary keys
This pull request allows the `table!` macro and codegen to handle tables
which use more than one column for their primary key. At the moment they
are fairly useless, but they will compile.
The methods in question are primarily used for `FindDsl` and
associations. Things like update are defined in terms of `FindDsl` and
`Identifiable`. Since the generators for those traits don't handle
composite primary keys, none of that can be used (yet).
Working on this also made me realize a bit of a hole in our type system.
We implement `Expression` for a tuple of expressions as a comma
delimited list. However, a comma delimited list isn't always valid. In
particular a composite table *does* actually implement `FindDsl` for an
expression that matches it's primary key -- and would generate invalid
SQL like `pk1, pk2 = $1, $2`. Luckily, we're saved by the fact that
tuples don't implement `AsExpression`, so trying to do `.find((1, 2))`
won't compile.
I'm not sure if we should fix this or not, but the fix would basically
mean separating out "arbitrary expression" from "expression valid as a
select or returning clause", and potentially other places where tuples
appear such as set clauses and in expressions. For now though, as long
as the inproper code doesn't compile for the reasonable cases, I'm not
super worried. We should fix this eventually though, as I don't like
something that we can statically determine is invalid SQL compiling.
Ref #42
2016-08-25 18:00:54 +03:00
|
|
|
|
2016-08-07 01:43:17 +03:00
|
|
|
* Added support for PostgreSQL `NULLS FIRST` and `NULLS LAST` when sorting.
|
2017-11-04 04:12:29 +03:00
|
|
|
See https://docs.diesel.rs/diesel/prelude/trait.SortExpressionMethods.html
|
2016-08-07 01:43:17 +03:00
|
|
|
for details.
|
|
|
|
|
2016-08-18 15:54:01 +03:00
|
|
|
* Added support for the `timestamp with time zone` type in PostgreSQL (referred
|
|
|
|
to as `diesel::types::Timestamptz`)
|
|
|
|
|
2016-08-29 16:48:47 +03:00
|
|
|
* Diesel CLI can now generate bash completion. See [the readme][bash completion]
|
|
|
|
for details.
|
|
|
|
|
2016-09-08 13:45:47 +03:00
|
|
|
* `infer_schema!` and `infer_table_from_schema!` can now take `"env:foo"`
|
|
|
|
instead of `env!("foo")` and `"dotenv:foo"` instead of `dotenv!("foo")`. The
|
|
|
|
use of `dotenv` requires the `dotenv` feature on `diesel_codegen`, which is
|
|
|
|
included by default. Using `env!` and `dotenv!` will no longer work with
|
2018-01-04 01:26:13 +03:00
|
|
|
`diesel_codegen`. They continue to work with `diesel_codegen_syntex`, but that
|
2016-09-08 13:45:47 +03:00
|
|
|
crate will be deprecated when Macros 1.1 is in the beta channel for Rust.
|
|
|
|
|
2016-08-29 16:48:47 +03:00
|
|
|
[bash completion]: https://github.com/diesel-rs/diesel/blob/b1a0d9901f0f2a8c8d530ccba8173b57f332b891/diesel_cli/README.md#bash-completion
|
|
|
|
|
2016-09-13 16:45:44 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* Structs annotated with `#[has_many]` or `#[belongs_to]` now require
|
|
|
|
`#[derive(Associations)]`. This is to allow them to work with Macros 1.1.
|
|
|
|
|
2016-10-10 18:08:05 +03:00
|
|
|
* `embed_migrations!` now resolves paths relative to `Cargo.toml` instead of the
|
|
|
|
file the macro was called from. This change is required to allow this macro to
|
|
|
|
work with Macros 1.1.
|
|
|
|
|
2016-08-25 18:13:25 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `diesel migrations run` will now respect migration directories overridden by
|
|
|
|
command line argument or environment variable
|
2016-09-16 20:52:51 +03:00
|
|
|
* The `infer_schema!` macro will no longer fetch views alongside with tables.
|
|
|
|
This was a source of trouble for people that had created views or are using
|
|
|
|
any extension that automatically creates views (e.g. PostGIS)
|
2016-08-25 18:13:25 +03:00
|
|
|
|
2016-09-13 20:03:42 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* `#[changeset_for(foo)]` should now be written as
|
|
|
|
`#[derive(AsChangeset)] #[table_name="foo"]`. If you were specifying
|
|
|
|
`treat_none_as_null = "true"`, you should additionally have
|
|
|
|
`#[changeset_options(treat_none_as_null = "true")]`.
|
2016-09-30 18:52:52 +03:00
|
|
|
* `#[insertable_into(foo)]` should now be written as
|
|
|
|
`#[derive(Insertable)] #[table_name="foo"]`.
|
2016-09-13 20:03:42 +03:00
|
|
|
|
2016-08-20 15:38:16 +03:00
|
|
|
## [0.7.2] - 2016-08-20
|
|
|
|
|
|
|
|
* Updated nightly version and syntex support.
|
|
|
|
|
2016-08-11 14:16:08 +03:00
|
|
|
## [0.7.1] - 2016-08-11
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
|
|
|
* The `Copy` constraint has been removed from `Identifiable::Id`, and
|
|
|
|
`Identifiable#id` now returns `&Identifiable::Id`.
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `#[belongs_to]` now respects the `foreign_key` option when using
|
|
|
|
`diesel_codegen` or `diesel_codegen_syntex`.
|
|
|
|
|
Release v0.7.0
The headline feature of this version is associations. Just add
`#[belongs_to(User)]` above your struct, and it becomes incredibly easy
to manipulate larger batches of data. See
http://docs.diesel.rs/diesel/associations/index.html for a full guide.
Diesel is taking a slightly different approach to what you may have seen
in the past, which I'm calling "non-invasive associations". In contrast
to something like Active Record or Ecto, where the association lives on
the parent, the data is completely independent. The type of a user and
all its posts is `(User, Vec<Post>)`.
This release also marks the elimination of Diesel's reliance on
procedural macros. They're still available as an option, and their usage
is recommended. However, a lot of people have had a desire to shy away
from them. For all of our code generation that does not perform IO,
there is now a completely stable non-procedural macro, which has been
designed to work with the [custom_derive][custom-derive] crate. See [the
CHANGELOG][changelog] for a full list.
[custom-derive]: https://github.com/DanielKeep/rust-custom-derive
[changelog]: https://github.com/diesel-rs/diesel/blob/v0.7.0/CHANGELOG.md
`diesel_codegen` has been split into two crates. This is a breaking
change which will affect 100% of our users. Please see
https://github.com/diesel-rs/diesel/commit/36b8801bf5e9594443743e6a7c62e29d3dce36b7
for more information on how to migrate.
This release has also had a contributor who has gone above and beyond to
help out. I'd like to take this opportunity to announce the 4th addition
to the Diesel core team, @killercup! Your contributions have been much
appreciated, and your code review has been invaluable.
Thank you to everybody who contributed to this release.
- derekdreery
- kardeiz
- Michael Macias
- Mike Piccolo
- Pascal Hertleif
- Richard Dodd
- Tim Brooks
On to 0.8! With this release, we are approaching the benchmarks I had
set for 1.0. We will still have at least 2 more releases before the 1.0
release, but it's quickly becoming the next target. We will be
publishing a roadmap soon.
2016-08-01 22:56:01 +03:00
|
|
|
## [0.7.0] - 2016-08-01
|
|
|
|
|
Provide a syntax extension free alternative to `#[insertable_into]` (#303)
Provide a syntax extension free alternative to `#[insertable_into]`
This provides a pure stable alternative to the `#[insertable_into]`
annotation. The intention is to change the annotation to call this
macro, rather than `impl Insertable` directly. However, there are some
unaddressed issues for that, and I will submit that as a separate PR to
attempt to keep the PR size reasonable.
The tests for this are a bit messy, as the actual test body doesn't
change much -- Just the struct definition. I moved the most common case
out into a macro, but I opted to just leave the duplication for the
remaining 4-5 cases that didn't fit, instead of trying to make it so dry
it chafes.
We will continue to support syntex as an option on stable, as we can
provide much better error messages from a procedural macro. I would like
to improve the error messages in some cases if possible though (in
particular, we want to handle the case where a unit struct is passed or
where a tuple struct has unannotated fields).
The structure of the macro is intended to be compatible with the
`custom_derive` crate. This is untested, but will be fully tested once
I've moved all our annotations to stable macros. The goal is for any
struct definition to be copy pasted into this macro, and the macro
parses the struct body to create the proper implementation. For
sufficiently large structs, we can hit the recursion limit, but there's
really no way around that. People will just need to bump the limit.
One case that this macro *doesn't* handle is when there are annotations
on struct fields other than `#[column_name]`. I had originally planned
to handle these, but I realized that the only recognized annotation that
could be there on stable is `#[cfg]`, and we are *not* handling cfg
attributes. We might handle that in the future, but it'd look *really*
ugly.
Related to #99
2016-04-25 03:35:15 +03:00
|
|
|
### Added
|
|
|
|
|
2016-08-01 21:22:58 +03:00
|
|
|
* The initial APIs have been added in the form of `#[has_many]` and
|
|
|
|
`#[belongs_to]`. See [the module documentation][associations-module] for more
|
|
|
|
information.
|
|
|
|
|
Provide a syntax extension free alternative to `#[insertable_into]` (#303)
Provide a syntax extension free alternative to `#[insertable_into]`
This provides a pure stable alternative to the `#[insertable_into]`
annotation. The intention is to change the annotation to call this
macro, rather than `impl Insertable` directly. However, there are some
unaddressed issues for that, and I will submit that as a separate PR to
attempt to keep the PR size reasonable.
The tests for this are a bit messy, as the actual test body doesn't
change much -- Just the struct definition. I moved the most common case
out into a macro, but I opted to just leave the duplication for the
remaining 4-5 cases that didn't fit, instead of trying to make it so dry
it chafes.
We will continue to support syntex as an option on stable, as we can
provide much better error messages from a procedural macro. I would like
to improve the error messages in some cases if possible though (in
particular, we want to handle the case where a unit struct is passed or
where a tuple struct has unannotated fields).
The structure of the macro is intended to be compatible with the
`custom_derive` crate. This is untested, but will be fully tested once
I've moved all our annotations to stable macros. The goal is for any
struct definition to be copy pasted into this macro, and the macro
parses the struct body to create the proper implementation. For
sufficiently large structs, we can hit the recursion limit, but there's
really no way around that. People will just need to bump the limit.
One case that this macro *doesn't* handle is when there are annotations
on struct fields other than `#[column_name]`. I had originally planned
to handle these, but I realized that the only recognized annotation that
could be there on stable is `#[cfg]`, and we are *not* handling cfg
attributes. We might handle that in the future, but it'd look *really*
ugly.
Related to #99
2016-04-25 03:35:15 +03:00
|
|
|
* The `Insertable!` macro can now be used instead of `#[insertable_into]` for
|
|
|
|
those wishing to avoid syntax extensions from `diesel_codegen`. See
|
2017-11-04 04:12:29 +03:00
|
|
|
https://docs.diesel.rs/diesel/macro.Insertable!.html for details.
|
Provide a syntax extension free alternative to `#[insertable_into]` (#303)
Provide a syntax extension free alternative to `#[insertable_into]`
This provides a pure stable alternative to the `#[insertable_into]`
annotation. The intention is to change the annotation to call this
macro, rather than `impl Insertable` directly. However, there are some
unaddressed issues for that, and I will submit that as a separate PR to
attempt to keep the PR size reasonable.
The tests for this are a bit messy, as the actual test body doesn't
change much -- Just the struct definition. I moved the most common case
out into a macro, but I opted to just leave the duplication for the
remaining 4-5 cases that didn't fit, instead of trying to make it so dry
it chafes.
We will continue to support syntex as an option on stable, as we can
provide much better error messages from a procedural macro. I would like
to improve the error messages in some cases if possible though (in
particular, we want to handle the case where a unit struct is passed or
where a tuple struct has unannotated fields).
The structure of the macro is intended to be compatible with the
`custom_derive` crate. This is untested, but will be fully tested once
I've moved all our annotations to stable macros. The goal is for any
struct definition to be copy pasted into this macro, and the macro
parses the struct body to create the proper implementation. For
sufficiently large structs, we can hit the recursion limit, but there's
really no way around that. People will just need to bump the limit.
One case that this macro *doesn't* handle is when there are annotations
on struct fields other than `#[column_name]`. I had originally planned
to handle these, but I realized that the only recognized annotation that
could be there on stable is `#[cfg]`, and we are *not* handling cfg
attributes. We might handle that in the future, but it'd look *really*
ugly.
Related to #99
2016-04-25 03:35:15 +03:00
|
|
|
|
2016-05-11 22:30:27 +03:00
|
|
|
* The `Queryable!` macro can now be used instead of `#[derive(Queryable)]` for
|
|
|
|
those wishing to avoid syntax extensions from `diesel_codegen`. See
|
2017-11-04 04:12:29 +03:00
|
|
|
https://docs.diesel.rs/diesel/macro.Queryable!.html for details.
|
2016-05-11 22:30:27 +03:00
|
|
|
|
2016-05-13 14:58:35 +03:00
|
|
|
* The `Identifiable!` macro can now be used instead of `#[derive(Identifiable)]` for
|
|
|
|
those wishing to avoid syntax extensions from `diesel_codegen`. See
|
2017-11-04 04:12:29 +03:00
|
|
|
https://docs.diesel.rs/diesel/macro.Identifiable!.html for details.
|
2016-05-13 14:58:35 +03:00
|
|
|
|
2016-05-13 17:17:41 +03:00
|
|
|
* The `AsChangeset!` macro can now be used instead of `#[changeset_for(table)]`
|
|
|
|
for those wishing to avoid syntax extensions from `diesel_codegen`. See
|
2017-11-04 04:12:29 +03:00
|
|
|
https://docs.diesel.rs/diesel/macro.AsChangeset!.html for details.
|
2016-05-13 17:17:41 +03:00
|
|
|
|
2016-07-04 11:19:33 +03:00
|
|
|
* Added support for the PostgreSQL `ALL` operator. See
|
2017-11-04 04:12:29 +03:00
|
|
|
https://docs.diesel.rs/diesel/pg/expression/dsl/fn.all.html for details.
|
2016-07-04 11:19:33 +03:00
|
|
|
|
2016-05-06 23:54:16 +03:00
|
|
|
* Added support for `RETURNING` expressions in `DELETE` statements. Implicitly
|
|
|
|
these queries will use `RETURNING *`.
|
|
|
|
|
Reform types inferred by `infer_schema!` on SQLite (#277)
`infer_schema!` is woefully undertested. Really our tests for it at the
moment are "we use it for our test suite so the cases our suite covers
work". However, even though I defined `tinyint` == `Bool`, I wanted to
make sure that `TINYINT(1)` was treated as bool as well, as I wasn't
certain how SQLite handles limit/precision/scale.
The answer is that it doesn't, and it's way looser about allowed type
names than I had thought. The process listed at
https://www.sqlite.org/datatype3.html is a literal description, and any
possible string is a valid type.
This adds tests for every example given on that page, plus a few extras.
We create a table with as many of these fields as possible, and do a
trivial roundtrip to make sure that it *actually* infers something we
can deserialize from, and that we're not doing anything dumb.
The new logic for type inference matches pretty closely to how SQLite
handles things with a few exceptions:
- "boolean" or types containing "tiny" and "int" are treated as bool
- smallint and bigint are separated from int
- float is separated from double
- varchar is separated from text
- We do not accept random unrecognized type names as numeric
Unresolved Questions
--------------------
This actually starts to make me a bit more nervous about our semantics
with SQLite. If you're just using Diesel, everything is fine. However,
you can definitely insert values that would fail to deserialize with so
little constraints on the backend. I'm starting to wonder if we should
truly embrace SQLite's definitions and map exactly to that, allowing
only the following types:
- BigInt
- VarChar (yes, it's the ANSI text type but we treat VarChar as the
"default" string type)
- Binary
- Double
We're omitting numeric, as there's no observable difference in SQLite
between the real affinity and the numeric affinity.
This would have several *major* implications. Aside from not being able
to use basic things like an `i32`, it would also mean that there is no
boolean type, and no dates/times/datetimes. Functions for those do exist
on the SQLite side though, so some of the interactions might get super
janky.
That said, Diesel's goal is not to abstract away the backend. These are
the semantics of the backend chosen, and maybe we should go whole hog
and embrace them.
I'm still unsure. In the meantime, with our current semantics, this
should improve the reliability of `infer_schema!`
2016-04-17 23:42:11 +03:00
|
|
|
### Changed
|
|
|
|
|
2016-07-11 18:25:06 +03:00
|
|
|
* Diesel now targets `nightly-2016-07-07`. Future releases will update to a
|
|
|
|
newer nightly version on the date that Rust releases.
|
|
|
|
|
2016-08-01 20:43:10 +03:00
|
|
|
* `diesel_codegen` has been split into two crates. `diesel_codegen` and
|
2016-08-01 20:50:35 +03:00
|
|
|
`diesel_codegen_syntex`. See [this commit][syntex-split] for migration
|
|
|
|
information.
|
2016-08-01 20:43:10 +03:00
|
|
|
|
2016-07-04 12:43:58 +03:00
|
|
|
* Most structs that implement `Queryable` will now also need
|
|
|
|
`#[derive(Identifiable)]`.
|
|
|
|
|
Reform types inferred by `infer_schema!` on SQLite (#277)
`infer_schema!` is woefully undertested. Really our tests for it at the
moment are "we use it for our test suite so the cases our suite covers
work". However, even though I defined `tinyint` == `Bool`, I wanted to
make sure that `TINYINT(1)` was treated as bool as well, as I wasn't
certain how SQLite handles limit/precision/scale.
The answer is that it doesn't, and it's way looser about allowed type
names than I had thought. The process listed at
https://www.sqlite.org/datatype3.html is a literal description, and any
possible string is a valid type.
This adds tests for every example given on that page, plus a few extras.
We create a table with as many of these fields as possible, and do a
trivial roundtrip to make sure that it *actually* infers something we
can deserialize from, and that we're not doing anything dumb.
The new logic for type inference matches pretty closely to how SQLite
handles things with a few exceptions:
- "boolean" or types containing "tiny" and "int" are treated as bool
- smallint and bigint are separated from int
- float is separated from double
- varchar is separated from text
- We do not accept random unrecognized type names as numeric
Unresolved Questions
--------------------
This actually starts to make me a bit more nervous about our semantics
with SQLite. If you're just using Diesel, everything is fine. However,
you can definitely insert values that would fail to deserialize with so
little constraints on the backend. I'm starting to wonder if we should
truly embrace SQLite's definitions and map exactly to that, allowing
only the following types:
- BigInt
- VarChar (yes, it's the ANSI text type but we treat VarChar as the
"default" string type)
- Binary
- Double
We're omitting numeric, as there's no observable difference in SQLite
between the real affinity and the numeric affinity.
This would have several *major* implications. Aside from not being able
to use basic things like an `i32`, it would also mean that there is no
boolean type, and no dates/times/datetimes. Functions for those do exist
on the SQLite side though, so some of the interactions might get super
janky.
That said, Diesel's goal is not to abstract away the backend. These are
the semantics of the backend chosen, and maybe we should go whole hog
and embrace them.
I'm still unsure. In the meantime, with our current semantics, this
should improve the reliability of `infer_schema!`
2016-04-17 23:42:11 +03:00
|
|
|
* `infer_schema!` on SQLite now accepts a larger range of type names
|
|
|
|
|
2016-04-20 19:57:54 +03:00
|
|
|
* `types::VarChar` is now an alias for `types::Text`. Most code should be
|
|
|
|
unaffected by this. PG array columns are treated slightly differently,
|
|
|
|
however. If you are using `varchar[]`, you should switch to `text[]` instead.
|
|
|
|
|
2016-04-25 03:06:26 +03:00
|
|
|
* Struct fields annotated with `#[column_name="name"]` should be changed to
|
|
|
|
`#[column_name(name)]`.
|
|
|
|
|
2016-07-02 14:40:06 +03:00
|
|
|
* The structure of `DatabaseError` has changed to hold more information. See
|
2017-11-04 04:12:29 +03:00
|
|
|
https://docs.diesel.rs/diesel/result/enum.Error.html and
|
|
|
|
https://docs.diesel.rs/diesel/result/trait.DatabaseErrorInformation.html for
|
2016-07-02 14:40:06 +03:00
|
|
|
more information
|
|
|
|
|
2016-07-04 12:43:58 +03:00
|
|
|
* Structs which implement `Identifiable` can now be passed to `update` and
|
|
|
|
`delete`. This means you can now write `delete(&user).execute(&connection)`
|
|
|
|
instead of `delete(users.find(user.id)).execute(&connection)`
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[associations-module]: https://docs.diesel.rs/diesel/associations/index.html
|
2016-08-01 20:50:35 +03:00
|
|
|
[syntex-split]: https://github.com/diesel-rs/diesel/commit/36b8801bf5e9594443743e6a7c62e29d3dce36b7
|
|
|
|
|
2016-05-12 13:55:21 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `&&[T]` can now be used in queries. This allows using slices with things like
|
|
|
|
`#[insertable_into]`.
|
|
|
|
|
2016-04-16 17:57:43 +03:00
|
|
|
## [0.6.1] 2016-04-14
|
2016-04-15 20:33:48 +03:00
|
|
|
|
|
|
|
### Added
|
|
|
|
|
|
|
|
* Added the `escape` method to `Like` and `NotLike`, to specify the escape
|
|
|
|
character used in the pattern. See [EscapeExpressionMethods][escape] for
|
|
|
|
details.
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[escape]: https://docs.diesel.rs/diesel/expression/expression_methods/escape_expression_methods/trait.EscapeExpressionMethods.html
|
2016-04-15 20:33:48 +03:00
|
|
|
|
2016-04-16 17:41:59 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `diesel_codegen` and `diesel_cli` now properly rely on Diesel 0.6.0. The
|
|
|
|
restriction to 0.5.0 was an oversight.
|
|
|
|
|
2016-04-16 17:51:55 +03:00
|
|
|
* `infer_schema!` now properly excludes metadata tables on SQLite.
|
|
|
|
|
|
|
|
* `infer_schema!` now properly maps types on SQLite.
|
|
|
|
|
2016-04-12 22:06:36 +03:00
|
|
|
## [0.6.0] 2016-04-12
|
2016-02-01 06:42:15 +03:00
|
|
|
|
2016-03-28 02:15:46 +03:00
|
|
|
### Added
|
|
|
|
|
2016-04-07 16:41:30 +03:00
|
|
|
* Queries can now be boxed using the `into_boxed()` method. This is useful for
|
|
|
|
conditionally modifying queries without changing the type. See
|
|
|
|
[BoxedDsl][boxed_dsl] for more details.
|
|
|
|
|
2016-03-28 02:15:46 +03:00
|
|
|
* `infer_schema!` is now supported for use with SQLite3.
|
|
|
|
|
2016-03-28 22:22:43 +03:00
|
|
|
* The maximum table size can be increased to 52 by enabling the `huge-tables`
|
|
|
|
feature. This feature will substantially increase compile times.
|
|
|
|
|
2016-04-02 23:05:32 +03:00
|
|
|
* The `DISTINCT` keyword can now be added to queries via the `distinct()`
|
|
|
|
method.
|
|
|
|
|
2016-04-06 22:42:19 +03:00
|
|
|
* `SqliteConnection` now implements `Send`
|
|
|
|
|
2017-11-04 04:12:29 +03:00
|
|
|
[boxed_dsl]: https://docs.diesel.rs/diesel/prelude/trait.BoxedDsl.html
|
2016-04-07 16:41:30 +03:00
|
|
|
|
2016-03-28 02:59:10 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* `diesel::result::Error` now implements `Send` and `Sync`. This required a
|
|
|
|
change in the return type of `ToSql` and `FromSql` to have those bounds as
|
|
|
|
well.
|
|
|
|
|
Improve the error message when `insert` is called with an owned value
Prior to this commit, the error will occur when you attempt to call
`execute`, `get_result`, or `get_results`. The message will indicate
that those methods don't exist, because `InsertQuery` doesn't implement
`QueryFragment`, with a very long generic type signature. The reason for
this being that `StructName` doesn't implement `Insertable`,
`&StructName` does.
This now handles this common error as quickly and directly as possible.
The error message will now be:
```
error: mismatched types:
expected `&_`
found `StructName`
```
This does cause a minor change in functionality, as it becomes
impossible to pass an owned value to `insert`. I don't think this is a
problem, as really the only thing this removes is the ability to
construct an insert statement and the return the query without executing
it, e.g.:
```rust
fn build_insert_query(name: &str) -> Box<QueryFragment<Pg>> {
let new_user = NewUser { name: name };
insert(new_user).into(users::table)
}
```
However, this case just doesn't seem like it matters, and I'm fine with
losing support for it.
Fixes #249.
2016-03-31 20:25:34 +03:00
|
|
|
* It is no longer possible to pass an owned value to `diesel::insert`. `insert`
|
|
|
|
will now give a more helpful error message when you accidentally try to pass
|
|
|
|
an owned value instead of a reference.
|
|
|
|
|
2016-03-31 21:18:32 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `#[insertable_into]` can now be used with structs that have lifetimes with
|
|
|
|
names other than `'a'`.
|
|
|
|
|
2016-04-10 18:44:43 +03:00
|
|
|
* Tables with a single column now properly return a single element tuple. E.g.
|
|
|
|
if the column was of type integer, then `users::all_columns` is now `(id,)`
|
|
|
|
and not `id`.
|
|
|
|
|
2016-04-12 21:28:25 +03:00
|
|
|
* `infer_schema!` can now work with tables that have a primary key other than
|
|
|
|
`id`.
|
|
|
|
|
2016-04-03 01:30:01 +03:00
|
|
|
### Removed
|
|
|
|
|
|
|
|
* Removed the `no select` option for the `table!` macro. This was a niche
|
|
|
|
feature that didn't fit with Diesel's philosophies. You can write a function
|
|
|
|
that calls `select` for you if you need this functionality.
|
|
|
|
|
2016-03-24 01:25:04 +03:00
|
|
|
## [0.5.4] 2016-03-23
|
|
|
|
|
|
|
|
* Updated `diesel_codegen` to allow syntex versions up to 0.30.0.
|
|
|
|
|
2016-03-13 01:44:54 +03:00
|
|
|
## [0.5.3] 2016-03-12
|
|
|
|
|
2016-02-01 06:42:15 +03:00
|
|
|
### Added
|
|
|
|
|
|
|
|
* Added helper function `diesel_manage_updated_at('TABLE_NAME')` to postgres
|
|
|
|
upon database setup. This function sets up a trigger on the specified table
|
|
|
|
that automatically updates the `updated_at` column to the `current_timestamp`
|
|
|
|
for each affected row in `UPDATE` statements.
|
|
|
|
|
2016-03-12 01:12:30 +03:00
|
|
|
* Added support for explicit `RETURNING` expressions in `INSERT` and `UPDATE`
|
|
|
|
queries. Implicitly these queries will still use `RETURNING *`.
|
|
|
|
|
2016-03-13 01:44:54 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* Updated to work on nightly from early March
|
|
|
|
|
2016-02-27 16:33:26 +03:00
|
|
|
## [0.5.2] 2016-02-27
|
|
|
|
|
|
|
|
* Updated to work on nightly from late February
|
|
|
|
|
2016-02-11 19:36:31 +03:00
|
|
|
## [0.5.1] 2016-02-11
|
|
|
|
|
|
|
|
* Diesel CLI no longer has a hard dependency on SQLite and PostgreSQL. It
|
|
|
|
assumes both by default, but if you need to install on a system that doesn't
|
|
|
|
have one or the other, you can install it with `cargo install diesel_cli
|
|
|
|
--no-default-features --features postgres` or `cargo install diesel_cli
|
|
|
|
--no-default-features --features sqlite`
|
|
|
|
|
2016-02-06 00:36:41 +03:00
|
|
|
## [0.5.0] 2016-02-05
|
2016-01-13 21:20:12 +03:00
|
|
|
|
2016-01-15 00:09:07 +03:00
|
|
|
### Added
|
|
|
|
|
2016-02-03 17:02:10 +03:00
|
|
|
* Added support for SQLite. Diesel still uses postgres by default. To use SQLite
|
|
|
|
instead, add `default-features = false, features = ["sqlite"]` to your
|
2016-02-06 00:33:36 +03:00
|
|
|
Cargo.toml. You'll also want to add `default-features = false, features =
|
|
|
|
["sqlite"]` to `diesel_codegen`.
|
2016-02-03 17:02:10 +03:00
|
|
|
Since SQLite is a much more limited database, it does not support our full set
|
|
|
|
of features. You can use SQLite and PostgreSQL in the same project if you
|
|
|
|
desire.
|
|
|
|
|
2016-01-19 00:00:07 +03:00
|
|
|
* Added support for mapping `types::Timestamp`, `types::Date`, and `types::Time`
|
|
|
|
to/from `chrono::NaiveDateTime`, `chrono::NaiveDate`, and `chrono::NaiveTime`.
|
2016-01-15 00:09:07 +03:00
|
|
|
Add `features = ["chrono"]` to enable.
|
|
|
|
|
2016-01-19 19:51:46 +03:00
|
|
|
* Added a `treat_none_as_null` option to `changeset_for`. When set to `true`,
|
|
|
|
a model will set a field to `Null` when an optional struct field is `None`,
|
|
|
|
instead of skipping the field entirely. The default value of the option is
|
|
|
|
`false`, as we think the current behavior is a much more common use case.
|
|
|
|
|
2016-01-20 21:06:43 +03:00
|
|
|
* Added `Expression#nullable()`, to allow comparisons of not null columns with
|
|
|
|
nullable ones when required.
|
|
|
|
|
2016-01-30 05:27:33 +03:00
|
|
|
* Added `sum` and `avg` functions.
|
|
|
|
|
2016-01-31 01:48:30 +03:00
|
|
|
* Added the `diesel setup`, `diesel database setup`, and `diesel database
|
|
|
|
reset` commands to the CLI.
|
|
|
|
|
2016-02-05 23:06:44 +03:00
|
|
|
* Added support for SQL `IN` statements through the `eq_any` method.
|
|
|
|
|
2016-02-06 00:33:36 +03:00
|
|
|
* Added a top level `select` function for select statements with no from clause.
|
|
|
|
This is primarily intended to be used for testing Diesel itself, but it has
|
|
|
|
been added to the public API as it will likely be useful for third party
|
|
|
|
crates in the future. `select(foo).from(bar)` might be a supported API in the
|
|
|
|
future as an alternative to `bar.select(foo)`.
|
|
|
|
|
|
|
|
* Added `expression::dsl::sql` as a helper function for constructing
|
|
|
|
`SqlLiteral` nodes. This is primarily intended to be used for testing Diesel
|
|
|
|
itself, but is part of the public API as an escape hatch if our query builder
|
|
|
|
DSL proves inadequate for a specific case. Use of this function in any
|
|
|
|
production code is discouraged as it is inherently unsafe and avoids real type
|
|
|
|
checking.
|
|
|
|
|
2016-01-13 21:20:12 +03:00
|
|
|
### Changed
|
|
|
|
|
2016-02-05 23:06:44 +03:00
|
|
|
* Moved most of our top level trait exports into a prelude module, and
|
|
|
|
re-exported our CRUD functions from the top level.
|
|
|
|
`diesel::query_builder::update` and friends are now `diesel::update`, and you
|
|
|
|
will get them by default if you import `diesel::*`. For a less aggressive
|
|
|
|
glob, you can import `diesel::prelude::*`, which will only export our traits.
|
|
|
|
|
2016-02-02 21:18:51 +03:00
|
|
|
* `Connection` is now a trait instead of a struct. The struct that was
|
|
|
|
previously known as `Connection` can be found at `diesel::pg::PgConnection`.
|
|
|
|
|
2016-01-15 19:29:27 +03:00
|
|
|
* Rename both the `#[derive(Queriable)]` attribute and the `Queriable` trait to
|
|
|
|
use the correct spelling `Queryable`.
|
|
|
|
|
2016-02-05 23:06:44 +03:00
|
|
|
* `load` and `get_results` now return a `Vec<Model>` instead of an iterator.
|
|
|
|
|
2016-01-25 07:49:06 +03:00
|
|
|
* Replaced `Connection#find(source, id)` with
|
|
|
|
`source.find(id).first(&connection)`.
|
|
|
|
|
2016-02-06 00:34:45 +03:00
|
|
|
* The `debug_sql!` macro now uses \` for identifier quoting, and `?` for bind
|
2016-01-22 19:23:29 +03:00
|
|
|
parameters, which is closer to a "generic" backend. The previous behavior had
|
|
|
|
no identifier quoting, and used PG specific bind params.
|
|
|
|
|
Make `ToSql` and `FromSql` generic over the backend
This was a mostly mechanical change, but there were several points of
interest.
I've done my best to audit impls which I consider generic, vs impls that
are PG specific. This implies that an impl even can be considered
generic. This mostly doesn't apply to SQLite, since due to the way its
bind parameters are handled I don't expect that types will go through
`ToSql`. `FromSql` I'm still unclear on, and that might change further.
However, after reading through the `MySQL` docs for bind params, I'm
reasonably confident that for string types, binary types, and numeric
types which have an equivalent C primitive, they will always be
represented this way. SQL standard types which I believe will generally
very by backend are date/time types, and decimal.
As part of this change, our blanket impl causing `FromSql` implying
`FromSqlRow` becomes invalid. I won't go into too much detail here, as
I've written up a pre-RFC on a solution that goes into more detail at
https://internals.rust-lang.org/t/pre-rfc-sealed-traits/3108/1, and I
think this issue goes away once specialization is stable (which is
tracked at https://github.com/sgrif/diesel/issues/130).
With this change, I believe the only remaining trait which needs to be
made generic is `NativeSqlType` (though I'm legitimately unsure if we
actually want to do that, due to the complications it adds with our
expression heirarchy related to `Bool`, and I do not think I want
`Expression` to be generic over the backend)
2016-01-24 00:28:45 +03:00
|
|
|
* Many user facing types are now generic over the backend. This includes, but is
|
|
|
|
not limited to `Queryable` and `Changeset`. This change should not have much
|
|
|
|
impact, as most impls will have been generated by diesel_codegen, and that API
|
|
|
|
has not changed.
|
|
|
|
|
2016-01-24 20:08:51 +03:00
|
|
|
* The mostly internal `NativeSqlType` has been removed. It now requires a known
|
|
|
|
backend. `fn<T> foo() where T: NativeSqlType` is now `fn<T, DB> foo() where
|
|
|
|
DB: HasSqlType<T>`
|
|
|
|
|
2016-01-18 02:29:58 +03:00
|
|
|
### Removed
|
|
|
|
|
|
|
|
* `Connection#query_sql` and `Connection#query_sql_params` have been removed.
|
|
|
|
These methods were not part of the public API, and were only meant to be used
|
|
|
|
for testing Diesel itself. However, they were technically callable from any
|
|
|
|
crate, so the removal has been noted here. Their usage can be replaced with
|
|
|
|
bare `select` and `expression::dsl::sql`.
|
|
|
|
|
2016-01-11 23:17:30 +03:00
|
|
|
## [0.4.1] 2016-01-11
|
Don't output notices when running migrations
When you run just about any command via diesel_cli, you'll see this
message output to stderr.
> NOTICE: relation "__diesel_schema_migrations" already exists,
> skipping
This silences that notice when creating the table. Unfortunately the
`silence_notices` function is not necessarily idempotent, as it would
override the notice processor if a custom one was set. However, the
actual raw libpq connection is private, so we're free to do with it what
we wish.
libpq does not provide any method to get the current notice processor,
or its default. As such I've had to re-implement the same function,
based on the description at the bottom of
http://www.postgresql.org/docs/current/static/libpq-notice-processing.html
As an alternative, we could perform two queries when attempting to
create the table, but this is becoming a common need in my work on new
features, and might be a candidate for public API.
2016-01-09 19:42:11 +03:00
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
|
|
|
* Diesel CLI will no longer output notices about `__diesel_schema_migrations`
|
|
|
|
already existing.
|
|
|
|
|
2016-01-11 23:17:30 +03:00
|
|
|
* Relicensed under MIT/Apache dual
|
|
|
|
|
2016-01-09 00:48:23 +03:00
|
|
|
## [0.4.0] 2016-01-08
|
2015-12-06 21:20:51 +03:00
|
|
|
|
|
|
|
### Added
|
|
|
|
|
2016-01-09 00:48:23 +03:00
|
|
|
* Added Diesel CLI, a tool for managing your schema.
|
2016-04-20 18:49:24 +03:00
|
|
|
See [the readme](https://github.com/diesel-rs/diesel/blob/v0.4.0/README.md#database-migrations)
|
2016-01-09 00:48:23 +03:00
|
|
|
for more information.
|
|
|
|
|
2016-01-07 18:35:05 +03:00
|
|
|
* Add the ability for diesel to maintain your schema for you automatically. See
|
2017-11-04 04:12:29 +03:00
|
|
|
the [migrations](https://docs.diesel.rs/diesel/migrations/index.html)
|
2016-01-07 18:35:05 +03:00
|
|
|
module for individual methods.
|
|
|
|
|
2015-12-06 21:20:51 +03:00
|
|
|
* Add DebugQueryBuilder to build sql without requiring a connection.
|
|
|
|
|
|
|
|
* Add print_sql! and debug_sql! macros to print out and return sql strings from
|
|
|
|
QueryFragments.
|
|
|
|
|
2015-12-20 21:42:17 +03:00
|
|
|
### Fixed
|
|
|
|
|
|
|
|
* `#[changeset_for]` can now be used with structs containing a `Vec`. Fixes
|
2016-04-20 18:49:24 +03:00
|
|
|
[#63](https://github.com/diesel-rs/diesel/issues/63).
|
2015-12-20 21:42:17 +03:00
|
|
|
|
2015-12-24 00:13:06 +03:00
|
|
|
* No longer generate invalid SQL when an optional update field is not the first
|
2016-04-20 18:49:24 +03:00
|
|
|
field on a changeset. Fixes [#68](https://github.com/diesel-rs/diesel/issues/68).
|
2015-12-24 00:13:06 +03:00
|
|
|
|
2016-01-07 19:02:02 +03:00
|
|
|
* `#[changeset_for]` can now be used with structs containing only a single field
|
2016-04-20 18:49:24 +03:00
|
|
|
other than `id`. Fixes [#66](https://github.com/diesel-rs/diesel/issues/66).
|
2016-01-07 19:02:02 +03:00
|
|
|
|
2016-01-07 19:46:03 +03:00
|
|
|
* `infer_schema!` properly works with array columns. Fixes
|
2016-04-20 18:49:24 +03:00
|
|
|
[#65](https://github.com/diesel-rs/diesel/issues/65).
|
2016-01-07 19:46:03 +03:00
|
|
|
|
2015-12-05 06:05:18 +03:00
|
|
|
## [0.3.0] 2015-12-04
|
2015-12-01 01:32:42 +03:00
|
|
|
|
2015-12-04 20:13:56 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* `#[changeset_for(table)]` now treats `Option` fields as an optional update.
|
|
|
|
Previously a field with `None` for the value would insert `NULL` into the
|
|
|
|
database field. It now does not update the field if the value is `None`.
|
|
|
|
|
2015-12-05 02:11:11 +03:00
|
|
|
* `.save_changes` (generated by `#[changeset_for]`) now returns a new struct,
|
|
|
|
rather than mutating `self`. The returned struct can be any type that
|
2016-01-15 19:29:27 +03:00
|
|
|
implements `Queryable` for the right SQL type
|
2015-12-05 02:11:11 +03:00
|
|
|
|
2015-12-01 01:32:42 +03:00
|
|
|
### Fixed
|
|
|
|
|
2016-01-15 19:29:27 +03:00
|
|
|
* `#[derive(Queryable)]` now allows generic parameters on the struct.
|
2015-11-30 00:59:46 +03:00
|
|
|
|
2015-12-14 20:13:07 +03:00
|
|
|
* Table definitions can now support up to 26 columns. Because this increases our
|
|
|
|
compile time by 3x, `features = ["large-tables"]` is needed to support table
|
|
|
|
definitions above 16 columns.
|
|
|
|
|
2015-12-01 23:09:29 +03:00
|
|
|
### Added
|
|
|
|
|
|
|
|
* Quickcheck is now an optional dependency. When `features = ["quickcheck"]` is
|
|
|
|
added to `Cargo.toml`, you'll gain `Arbitrary` implementations for everything
|
|
|
|
in `diesel::data_types`.
|
|
|
|
|
2015-12-02 18:33:36 +03:00
|
|
|
* Added support for the SQL `MIN` function.
|
2015-12-01 22:51:22 +03:00
|
|
|
|
2015-12-02 18:31:28 +03:00
|
|
|
* Added support for the `Numeric` data type. Since there is no Big Decimal type
|
|
|
|
in the standard library, a dumb struct has been provided which mirrors what
|
|
|
|
Postgres provides, which can be converted into whatever crate you are using.
|
|
|
|
|
2015-12-02 22:13:12 +03:00
|
|
|
* Timestamp columns can now be used with `std::time::SystemTime` when compiled
|
|
|
|
with `--features unstable`
|
|
|
|
|
2015-12-03 02:45:47 +03:00
|
|
|
* Implemented `Send` on `Connection` (required for R2D2 support)
|
2015-12-03 02:45:03 +03:00
|
|
|
|
2015-12-05 03:23:05 +03:00
|
|
|
* Added `infer_schema!` and `infer_table_from_schema!`. Both macros take a
|
|
|
|
database URL, and will invoke `table!` for you automatically based on the
|
|
|
|
schema. `infer_schema!` queries for the table names, while
|
|
|
|
`infer_table_from_schema!` takes a table name as the second argument.
|
|
|
|
|
2015-11-30 20:29:37 +03:00
|
|
|
## [0.2.0] - 2015-11-30
|
2015-11-30 00:59:46 +03:00
|
|
|
|
2015-11-30 16:53:32 +03:00
|
|
|
### Added
|
|
|
|
|
|
|
|
* Added an `execute` method to `QueryFragment`, which is intended to replace
|
|
|
|
`Connection#execute_returning_count`. The old method still exists for use
|
|
|
|
under the hood, but has been hidden from docs and is not considered public
|
|
|
|
API.
|
|
|
|
|
2015-11-30 19:22:04 +03:00
|
|
|
* Added `get_result` and `get_results`, which work similarly to `load` and
|
|
|
|
`first`, but are intended to make code read better when working with commands
|
|
|
|
like `create` and `update`. In the future, `get_result` may also check that
|
|
|
|
only a single row was affected.
|
|
|
|
|
2015-11-30 20:26:37 +03:00
|
|
|
* Added [`insert`][insert], which mirrors the pattern of `update` and `delete`.
|
|
|
|
|
2015-11-30 00:59:46 +03:00
|
|
|
### Changed
|
|
|
|
|
|
|
|
* Added a hidden `__Nonexhaustive` variant to `result::Error`. This is not
|
|
|
|
intended to be something you can exhaustively match on, but I do want people
|
|
|
|
to be able to check for specific cases, so `Box<std::error::Error>` is
|
|
|
|
not an option.
|
|
|
|
|
For `query_one` and friends, not returning records is an error condition
Through usage, it has become clear that in the overwhelming majority of
cases, you either expect N records, or exactly 1. Expecting either 0 or
1 is uncommon.
However, it's a completely valid use case, and having to match against
`Err(NotFound)` is a pain, especially if you intend to use `try!`.
Keeping that in mind, `QueryResult` now has the `optional` method, which
converts `QueryResult<T>` to `QueryResult<Option<T>>`, treating
`NotFound` as `None`. Since [`result::Error` is not exhaustively
matchable](https://github.com/sgrif/diesel/commit/5435e30f1dc28008a8bef34c889998a0b009f0c4),
I do not think we need to change the error type in this method.
Since checking for and handling `NotFound` seems like a common case,
particularly for returning a 404 response in a web server, it has been
re-exported in the root namespace.
I was going to open a PR to get feedback on this change first, but after
making it, I feel the code quality improvement in our tests (especially
the doctests, where we've removed most `.unwrap()` calls) was enough to
convince me this is the right change.
2015-11-30 03:35:46 +03:00
|
|
|
* `query_one`, `find`, and `first` now assume a single row is returned. For
|
|
|
|
cases where you actually expect 0 or 1 rows to be returned, the `optional`
|
|
|
|
method has been added to the result, in case having a `Result<Option<T>>` is
|
2018-01-04 01:26:13 +03:00
|
|
|
more idiomatic than checking for `Err(NotFound)`.
|
For `query_one` and friends, not returning records is an error condition
Through usage, it has become clear that in the overwhelming majority of
cases, you either expect N records, or exactly 1. Expecting either 0 or
1 is uncommon.
However, it's a completely valid use case, and having to match against
`Err(NotFound)` is a pain, especially if you intend to use `try!`.
Keeping that in mind, `QueryResult` now has the `optional` method, which
converts `QueryResult<T>` to `QueryResult<Option<T>>`, treating
`NotFound` as `None`. Since [`result::Error` is not exhaustively
matchable](https://github.com/sgrif/diesel/commit/5435e30f1dc28008a8bef34c889998a0b009f0c4),
I do not think we need to change the error type in this method.
Since checking for and handling `NotFound` seems like a common case,
particularly for returning a 404 response in a web server, it has been
re-exported in the root namespace.
I was going to open a PR to get feedback on this change first, but after
making it, I feel the code quality improvement in our tests (especially
the doctests, where we've removed most `.unwrap()` calls) was enough to
convince me this is the right change.
2015-11-30 03:35:46 +03:00
|
|
|
|
2015-11-30 20:26:37 +03:00
|
|
|
### Deprecated
|
|
|
|
|
|
|
|
* `Connection#insert` and `Connection#insert_returning_count` have been
|
|
|
|
deprecated in favor of [`insert`][insert]
|
|
|
|
|
2016-12-05 22:32:57 +03:00
|
|
|
## 0.1.0 - 2015-11-29
|
2015-11-30 00:59:46 +03:00
|
|
|
|
|
|
|
* Initial release
|
2016-12-05 22:32:57 +03:00
|
|
|
|
|
|
|
[0.2.0]: https://github.com/diesel-rs/diesel/compare/v0.1.0...v0.2.0
|
|
|
|
[0.3.0]: https://github.com/diesel-rs/diesel/compare/v0.2.0...v0.3.0
|
|
|
|
[0.4.0]: https://github.com/diesel-rs/diesel/compare/v0.3.0...v0.4.0
|
|
|
|
[0.4.1]: https://github.com/diesel-rs/diesel/compare/v0.4.0...v0.4.1
|
|
|
|
[0.5.0]: https://github.com/diesel-rs/diesel/compare/v0.4.1...v0.5.0
|
|
|
|
[0.5.1]: https://github.com/diesel-rs/diesel/compare/v0.5.0...v0.5.1
|
|
|
|
[0.5.2]: https://github.com/diesel-rs/diesel/compare/v0.5.1...v0.5.2
|
|
|
|
[0.5.3]: https://github.com/diesel-rs/diesel/compare/v0.5.2...v0.5.3
|
|
|
|
[0.5.4]: https://github.com/diesel-rs/diesel/compare/v0.5.3...v0.5.4
|
|
|
|
[0.6.0]: https://github.com/diesel-rs/diesel/compare/v0.5.4...v0.6.0
|
|
|
|
[0.6.1]: https://github.com/diesel-rs/diesel/compare/v0.6.0...v0.6.1
|
|
|
|
[0.7.0]: https://github.com/diesel-rs/diesel/compare/v0.6.1...v0.7.0
|
|
|
|
[0.7.1]: https://github.com/diesel-rs/diesel/compare/v0.7.0...v0.7.1
|
|
|
|
[0.7.2]: https://github.com/diesel-rs/diesel/compare/v0.7.1...v0.7.2
|
|
|
|
[0.8.0]: https://github.com/diesel-rs/diesel/compare/v0.7.2...v0.8.0
|
|
|
|
[0.8.1]: https://github.com/diesel-rs/diesel/compare/v0.8.0...v0.8.1
|
|
|
|
[0.8.2]: https://github.com/diesel-rs/diesel/compare/v0.8.1...v0.8.2
|
2016-12-09 00:15:12 +03:00
|
|
|
[0.9.0]: https://github.com/diesel-rs/diesel/compare/v0.8.2...v0.9.0
|
2016-12-11 13:39:47 +03:00
|
|
|
[0.9.1]: https://github.com/diesel-rs/diesel/compare/v0.9.0...v0.9.1
|
Release v0.10.0 (The one where we work on stable)
![It's happening](http://i.imgur.com/7drHiqr.gif)
v0.10.0 drops support for Rust 1.14 and earlier, and adds support for
Rust 1.15 (ON STABLE). `diesel_codegen_syntex` has been removed, and is
no longer supported.
Additionally, this release adds initial support for the JSON data type
in PostgreSQL. There is also a new `print-schema` subcommand in Diesel
CLI which will show you the code generated by `infer_schema!()`. As
always, you can find a full list of what has changed in [the
changelog][changelog].
In addition to the Diesel core team, 7 contributors worked on this
release. A huge thank you to
- Adrian Perez de Castro
- Eric Kidd
- Georg Semmler
- Jake Goulding
- Sergio Benitez
- Severen Redwood
- Stu Black
I'd also like to thank everybody who helped this release by opening
issues, finding bugs, and asking/answering questions in our gitter room.
There were several big features that I had hoped to get done in time for
this release, but my daughter inherited my troll gene and decided to
come early. If you were hoping for MySQL support, blame Ruby. In the
mean time, here is a picture of Ruby.
![baby ruby](https://lh3.googleusercontent.com/7vUZONdvrati-NQXriSqzKQ0CHNz6KRulOSos9kJjzMNV-JI2UT6d4Kxex9fZGO-0GTlLrKHKRwiPaf2v6hCJlCU0IgK5kWd_JWz9nG61FrZfgVARZEqXOmjoXPb5CYrbTg7XlG2VEYlcm6_Lk9oviVPh7mx3gaXgVG6g-OJRHqY_gipU-Y2REPFDoJyPWZ9QoifZH1WDGSPdyYUQ1KWeTfFkxk1Z3VP1bKAyRhsDmnXvSLaWkBQ6r5CpRS2pfVMC0lPVAfPGmrjwmNw7JmFNfscQM5IY0FOqbbwJhPJvLtNb-jOgOQhz07S8HA9BBI_cWzzXXMxbGXzaPpKBYSrioMja3MkXcb1PGB8cG7ERtG_CWwpGriRlFbrj2B0OygkAu4Q6pRiQe6BojpHYp03uyRsmsVxTbQjlH3axed6tNV_IDYSd2vz15gB7yFKUF_Je3spUUdexLmybdPDR29DfD-hBBJfezy0gdzrf7dJMMXWgQ7CW6jH18uydl-iiK3_8Ha8FUuvrjcA-Dvv0nQEXqajcb_NFCpobr92fNQvDCg6UNj3o7E7bv55Oj6sOk7N7xARchy-MmAV8Tzzc1Sx-4GKHhikH5WGMb5AzYSnoNcvWr7mD4vqAF1Wn_60Huz1KCNC5m2aBbPz9G6hBcM3pMe8J5pIM4epvKFvKUKtK98=w792-h1056-no)
[changelog]: https://github.com/diesel-rs/diesel/blob/v0.10.0/CHANGELOG.md
2017-02-02 21:17:47 +03:00
|
|
|
[0.10.0]: https://github.com/diesel-rs/diesel/compare/v0.9.1...v0.10.0
|
2017-02-08 19:10:20 +03:00
|
|
|
[0.10.1]: https://github.com/diesel-rs/diesel/compare/v0.10.0...v0.10.1
|
Relase v0.11.0 (The one where we support MySQL)
The headline features for this release are MySQL support and limited PG
upsert support. MySQL support works exactly as you'd expect. Just add
`features = ["mysql"]` to your Cargo.toml, pass a connection URL (where
the scheme is `mysql://` and the path is the name of the database) to
`MysqlConnection::establish` and you're off. Keep in mind that if you're
following the getting started guide, MySQL does not support the
`RETURNING` clause, so methods like `get_result` and `get_results` won't
work.
PostgreSQL upsert was a feature added in PG 9.5 and has been one of our
most requested features. The full upsert API is quite complex, but we've
added support for `ON CONFLICT DO NOTHING`, as this covered the highest
percentage of use cases with the lowest amount of work. You can see
examples in [the docs][on-conflict-do-nothing]. Support for the full
upsert syntax will be coming in 0.12.
In addition to the headline features, there were plenty of quality of
life improvements and bug fixes. As always, you can see a full list of
changes by reading [the changelog][changelog].
[on-conflict-do-nothing]: http://docs.diesel.rs/diesel/pg/upsert/trait.OnConflictExtension.html#method.on_conflict_do_nothing
[changelog]: https://github.com/diesel-rs/diesel/blob/v0.11.0/CHANGELOG.md
In addition to the Diesel core team, 6 additional contributors worked on
this release. A huge thank you to:
- Brandon W Maister
- Eijebong
- Georg Semmler
- Jimmy Cuadra
- Jovansonlee Cesar
- jacob
I'd also like to thank everybody who helped this release by opening
issues, finding bugs, and asking/answering questions in our gitter room.
2017-02-16 22:49:59 +03:00
|
|
|
[0.11.0]: https://github.com/diesel-rs/diesel/compare/v0.10.1...v0.11.0
|
2017-02-19 18:29:25 +03:00
|
|
|
[0.11.1]: https://github.com/diesel-rs/diesel/compare/v0.11.0...v0.11.1
|
|
|
|
[0.11.2]: https://github.com/diesel-rs/diesel/compare/v0.11.1...v0.11.2
|
2017-02-21 13:06:55 +03:00
|
|
|
[0.11.4]: https://github.com/diesel-rs/diesel/compare/v0.11.2...v0.11.4
|
2017-03-16 19:41:51 +03:00
|
|
|
[0.12.0]: https://github.com/diesel-rs/diesel/compare/v0.11.4...v0.12.0
|
2017-05-15 19:53:13 +03:00
|
|
|
[0.12.1]: https://github.com/diesel-rs/diesel/compare/v0.12.0...v0.12.1
|
|
|
|
[0.13.0]: https://github.com/diesel-rs/diesel/compare/v0.12.1...v0.13.0
|
Release v0.14.0 (The one with all the joins)
One of the oldest issues in Diesel was that we limited the number of
tables that could appear in a single query to 2. The problem was never
about having more than 2 tables, but safely and correctly proving in the
type system what would and could not be selected from that join.
With 0.14, that restriction has been removed. The query builder now
supports joins containing an arbitrary number of tables. You may find
that you need to call `enable_multi_table_joins!` for a few tables, but
that need should go away in the future as specialization matures.
In addition to the headline feature, this release includes support for
several new datatypes (including `NUMERIC`/`DECIMAL` which has been
widely requested), and other small quality of life improvements. As
always, you can see [the
CHANGELOG](https://github.com/diesel-rs/diesel/blob/v0.14.0/CHANGELOG.md)
for the full release notes.
The Road to 1.0
------
A recent point of discussion among the core team has been what remaining
blockers we have for releasing a version 1.0. The roadmap doesn't
necessarily include everything that would make us "feature complete". It
focuses on the set of changes that we think are likely to require
breaking changes.
We expect that this will be the last 0.x release. You can follow the
milestone
[here](https://github.com/diesel-rs/diesel/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.0).
Additionally, we all agreed that the biggest blocker to a 1.0 release is
improvements to our documentation. We're going to be doing a big push in
the coming months to clean things up, and are looking for help from the
community. You can follow that project
[here](https://github.com/diesel-rs/diesel/projects/1), or just come
join us in [our gitter
room](https://gitter.im/diesel-rs/diesel?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
to talk about how you can help.
There will be a blog post with more details about this in the coming
weeks.
Contributors
-----
In addition to the core team, 10 people contributed to this release. A
huge thank you to:
* Dorian Scheidt
* FliegendeWurst
* Georg Semmler
* JD Gonzales
* Jim McGrath
* Kieran
* Ruben De Smet
* Sunrin SHIMURA (keen)
* Tshepang Lekhonkhobe
* theduke
Core Team Changes
------
With this release, we are also making some changes to the core team to
better reflect the current active maintainers. In recognition of his
fantastic work, we're pleased to welcome @Eijebong to the core team.
Many early members of the team have also since moved onto other
projects. To reflect that, Mike Piccolo, Matt Casper, and Sam Phippen
are all being moved to the core team alumni.
2017-07-04 17:56:56 +03:00
|
|
|
[0.14.0]: https://github.com/diesel-rs/diesel/compare/v0.13.0...v0.14.0
|
2017-07-10 18:47:31 +03:00
|
|
|
[0.14.1]: https://github.com/diesel-rs/diesel/compare/v0.14.0...v0.14.1
|
2017-07-23 12:45:18 +03:00
|
|
|
[0.15.0]: https://github.com/diesel-rs/diesel/compare/v0.14.1...v0.15.0
|
2017-07-24 18:50:10 +03:00
|
|
|
[0.15.1]: https://github.com/diesel-rs/diesel/compare/v0.15.0...v0.15.1
|
2017-07-28 18:57:54 +03:00
|
|
|
[0.15.2]: https://github.com/diesel-rs/diesel/compare/v0.15.1...v0.15.2
|
2017-08-24 21:13:56 +03:00
|
|
|
[0.16.0]: https://github.com/diesel-rs/diesel/compare/v0.15.2...v0.16.0
|
Release v0.99.0 (It's basically 1.0 except it's not)
This release is by far the largest Diesel has ever had. It serves 2
purposes. You can consider this release to be a beta for 1.0. However,
1.0 will have an important significant difference. Anything that is
deprecated as of this release will not be present in the 1.0 release.
This includes functions which were newly deprecated in 0.99. We know
this may introduce a migration burden for some people, so we will
continue to support the 0.99 line with bug fixes as long as there is
demand and it is reasonable to do so.
Headline Features
----
This release is mainly focused on ergonomics. Our main new feature is
the [`sql_query`][] function. This is a new API which behaves similarly to
[`sql`][], but it is entirely focused on cases where you want to write
the *entire* query yourself. The main difference from `sql` is that you
do not need to specify the return type of the query, and values are
fetched by name rather than by index. This feature is still early, and
there's a lot of features still to come (specifically evolving
`#[derive(QueryableByName)]`, but we think this feature will ease a lot
of pains for cases where Diesel doesn't quite do what you need.
[`sql_query`]: http://docs.diesel.rs/diesel/fn.sql_query.html
[`sql`]: http://docs.diesel.rs/diesel/sql/fn.sql.html
Additionally, you can now use tuples for inserts the same as you can for
updates. If you've ever wanted to insert a row with just 1 or 2 values,
and been annoyed that you needed a struct that you're only using in this
one place, this feature will make you happy. We'll have new guides
highlighting this feature soon.
Additionally, this release comes with a ton of quality of life features.
Many of these changes are focused around making it easier to introduce
line breaks naturally in your code. For example, `.filter` is now
implemented on `UpdateStatement`, meaning you can write
`update(foo).filter(bar)` instead of `update(foo.filter(bar))`. We've
also introduced new APIs for `insert` and PG upsert which will have
similar readability improvements.
Breaking Changes
----
This release includes more deprecations than any release prior. In
particular, `insert` has been deprecated, along with our entire PG
upsert API. All deprecations in this release have direct replacements,
which will lead to code which formats much more nicely. It should be a
mostly mechanical replacement for most apps. See [the CHANGELOG file][] for
details.
[the CHANGELOG file]: https://github.com/diesel-rs/diesel/blob/v0.99.0/CHANGELOG.md
Growing the Team
----
With this release, we'd like to welcome several new members to the
Diesel committer team. @weiznich, @notryanb, and @katrinabrock you've
all done excellent work and we're very excited to officially welcome you
to the team!
Additional Thanks
----
In addition to the Diesel core and committer teams, 10 people
contributed to this release. A huge thank you to:
- Adam Perry
- Alex Kitchens
- Alexey Zabelin
- Arnar Mar Sig
- Bob
- Jordan
- Lauri Apple
- Maxime “pep” Buquet
- William Murphy
- bippityboppity
Our only remaining blockers from this release and 1.0 are documentation
changes, and having this tested in the wild. Thank you to every one of
our users for your support, and we look forward to Diesel 1.0 by the end
of the year!
2017-11-29 02:26:30 +03:00
|
|
|
[0.99.0]: https://github.com/diesel-rs/diesel/compare/v0.16.0...v0.99.0
|
2017-12-04 22:31:00 +03:00
|
|
|
[0.99.1]: https://github.com/diesel-rs/diesel/compare/v0.99.0...v0.99.1
|
2018-01-03 01:52:08 +03:00
|
|
|
[1.0.0]: https://github.com/diesel-rs/diesel/compare/v0.99.1...v1.0.0
|
Release v1.1.0
Improved Support for Adding New Types
-------------------------------------
The primary focus of this release was improving the ergonomics of adding
support for new types in Diesel.
For implementing new SQL types, we've added `#[derive(SqlType)]` which
implements many traits that you need to implement for every SQL type.
See the documentation for `HasSqlType` for details on this derive.
For implementing new mappings, we've added `#[derive(FromSqlRow)]` and
`#[derive(AsExpression)]`. These derives will replace the majority of
the boilerplate that was previously required when supporting new types.
Adding support for new types in Diesel 1.1 should only require
implementing `FromSql` and `ToSql`. The derives will handle the rest.
We've also provided `FromSql` impls for `*const str` and `*const [u8]`.
Due to the design of `FromSql`, we can't provide impls for `&str` and
`&[u8]` without a breaking change. However many impls just need to parse
a string or some bytes, and don't need the allocation that would come
from `String` or `Vec<u8>`. This will require unsafe code to use, but
should make certain implementations more efficient.
Finally, we've restructured how our serialize/deserialize modules are
structured, and provided type aliases to make implementations of
`FromSql` and `ToSql` more consise.
`r2d2_diesel` is Now Part of Diesel
-----------------------------------
Finally, this release merges `r2d2_diesel` into Diesel itself. The main
benefit of doing this is that we can implement `Connection` for
`PooledConnection`, removing the need for explicit `&*` when using r2d2.
This should also help to prevent version mismatches when changing Diesel
versions.
To use the new r2d2 support, remove `r2d2` and `r2d2_diesel` from your
Cargo.toml. Add the `r2d2` to your enabled features on `diesel`. Replace
`extern crate r2d2` with `pub use diesel::r2d2`. Replace any
`r2d2_diesel::` with `diesel::r2d2::`.
Thanks
------
In addition to the headline features, there were dozens of smaller
additions which should make using Diesel even better! As always, you can
check the CHANGELOG for a full list of changes in this release.
In addition to the Diesel core team, 8 people contributed to this
release. A huge thank you to:
- Ashe Connor
- Chris Pick
- Evan
- Georg Semmler
- MarcManiez
- Martin Lindhe
- Oliver Schneider
- Ryan Blecher
2018-01-15 18:34:57 +03:00
|
|
|
[1.1.0]: https://github.com/diesel-rs/diesel/compare/v1.0.0...v1.1.0
|
2018-01-16 18:46:55 +03:00
|
|
|
[1.1.1]: https://github.com/diesel-rs/diesel/compare/v1.1.0...v1.1.1
|
Release v1.2.0
Team changes
==
With this release, we'd like to welcome Georg Semmler (known on GitHub
as @weiznich). Georg is the #2 all time contributor to Diesel, and has
helped shape what the framework is today. Welcome to the team!
New Features
==
This release contains several long awaited features.
We've re-introduced the ability to use bind params with the `sql`
function, in a way which is harder to mis-use. This functionality was
present prior to 1.0, but was removed when `sql_function` was added over
concerns about its use with the rest of the query builder. Recent
developments have proved those concerns to be valid, but this new API
fills that niche. Thanks to @notryanb for taking the lead on this
feature.
We've also added the ability to insert from a select statement (e.g.
queries in the form of `INSERT INTO table (...) SELECT ...`. This is a
feature request that has come up repeatedly since release, and we're
happy to finally bring it to you. We've also added alternate forms of
our insert API which feel better when used with select statements. You
can find the full details in the changelog.
Finally, we've rewritten our custom dervies from scratch to take
advantage of new diagnostic tools in recent versions of nightly Rust. If
you turn on the `unstable` feature of Diesel on a nightly compiler,
you'll find that you get dramatically improved error messages from our
derives. For the best error messages, you should also set
`RUSTFLAGS="--cfg procmacro2_semver_exempt"`.
Additionally, as of this release, Diesel is now powered by the
blockchain. Because it's 2018 and that's how it works now I guess. See
the changelog for full details.
In addition to the headline features, there were a ton of features that
we don't have time to mention here. As always, for a full list of
changes you can find a full list in the changelog.
Thanks
==
Thank you to everyone who helped make this release happen through bug
reports, and discussion on Gitter. While we don't have a way to collect
stats on that form of contribution...
In addition to the Diesel core team, 14 people contributed code to this
release. A huge thank you to:
- Alex Kitchens
- Andrew Weiss
- Arun Kulshreshtha
- Brandur
- EloD10
- Jacob Chae
- Jordan Petridis
- Josh Leeb-du Toit
- Kerollmops
- Mathias Svensson
- Ryan Blecher
- Sander Maijers
- Seth Larson
- YetAnotherMinion
2018-04-07 02:34:45 +03:00
|
|
|
[1.1.2]: https://github.com/diesel-rs/diesel/compare/v1.1.1...v1.1.2
|
|
|
|
[1.2.0]: https://github.com/diesel-rs/diesel/compare/v1.1.2...v1.2.0
|
2018-04-11 18:59:58 +03:00
|
|
|
[1.2.1]: https://github.com/diesel-rs/diesel/compare/v1.2.0...v1.2.1
|
2018-04-12 22:46:31 +03:00
|
|
|
[1.2.2]: https://github.com/diesel-rs/diesel/compare/v1.2.1...v1.2.2
|
Release v1.3.0
New Features
==
This release includes a couple of major changes to how Diesel projects
are developed. In the past, we've had 2 ways to generate `schema.rs`. A
procedural macro called `infer_schema!`, and a CLI command `diesel
print-schema`. We've recommended using the CLI command for a long time,
but `infer_schema!` was still useful for early prototypes.
At the beginning of a project, your database schema changes much more
frequently. It's extremely annoying to have to remember to run a
second command after running your migrations.
Diesel CLI 1.3 now supports a configuration file to customize its
behavior. One of the new capabilities this provides is the ability to
automatically regenerate `schema.rs` whenever you run or revert a
migration. This means you no longer have to remember to run `diesel
print-schema` when things change.
Because of this, we are deprecating `diesel_infer_schema`. 1.3 will be
the final release of that crate. However, `diesel_infer_schema` 1.3 will
continue to work with `diesel` until at least Diesel 2.0. You can see
all of the capabilities of the new configuration file at
http://diesel.rs/guides/configuring-diesel-cli.
This release also includes a complete redesign of the [`sql_function!`]
macro. The new syntax is significantly closer to normal Rust. For
example, what used to be written as:
```rust
sql_function! {
lower, lower_t, (x: Text) -> Text,
"Here are the docs for `lower`
It's awkward to make multiline"
}
```
Can now be written as:
```rust
sql_function! {
/// Here are the docs for `lower`
/// It's just a normal doc comment.
fn lower(x: Text) -> Text;
}
```
The new form also supports much more than the old one, including
aggregate functions, function renaming, and generic functions. Things
like `MAX` could previously not be expressed with `sql_function!`.
However, now the definition looks like this:
```rust
sql_function! {
#[aggregate]
fn max<ST: SqlOrd + IntoNullable>(expr: ST) -> ST::Nullable;
}
```
Finally, the redesigned `sql_function!` supoprts user defined
functions on SQLite. SQLite differs from other databases, in that custom
functions aren't defined in SQL. Instead you give it a C function
pointer to use for the body. With Diesel, you can just give us any Rust
closure that takes appropriate argument types, and we'll handle gluing
that to SQLite for you.
You can find examples for all of this in [the docs for
`sql_function!`][`sql_function!`].
[`sql_function!`]: http://docs.diesel.rs/diesel/macro.sql_function.html
In addition to the headline features, this release includes a ton of
quality of life changes including expanded support for locking clauses,
more global support for mathematic operators, and more. As always, for a
full list of changes you can find it in [the changelog].
[the changelog]: https://github.com/diesel-rs/diesel/blob/v1.3.0/CHANGELOG.md
Thanks
==
Thank you to everyone who helped make this release happen through bug
reports, and discussion on Gitter. While we don't have a way to collect
stats on that form of contribution, it's greatly appreciated.
In addition to the Diesel core team, 12 people contributed code to this
release. A huge thank you to:
- Aleksey Ivanov
- Christopher Brickley
- David Reid
- Diggory Blake
- Graham Turner
- Katharina
- Matt Kraai
- Nick Babcock
- Richard Petrie
- Simon Dickson
- Sunrin SHIMURA
- Thierry Berger
2018-05-22 22:21:32 +03:00
|
|
|
[1.3.0]: https://github.com/diesel-rs/diesel/compare/v1.2.2...v1.3.0
|
2018-06-14 01:57:27 +03:00
|
|
|
[1.3.1]: https://github.com/diesel-rs/diesel/compare/v1.3.0...v1.3.1
|
|
|
|
[1.3.2]: https://github.com/diesel-rs/diesel/compare/v1.3.1...v1.3.2
|
2018-09-12 20:03:35 +03:00
|
|
|
[1.3.3]: https://github.com/diesel-rs/diesel/compare/v1.3.2...v1.3.3
|
2019-01-21 12:48:37 +03:00
|
|
|
[1.4.0]: https://github.com/diesel-rs/diesel/compare/v1.3.0...v1.4.0
|
2019-01-24 22:54:44 +03:00
|
|
|
[1.4.1]: https://github.com/diesel-rs/diesel/compare/v1.4.0...v1.4.1
|
2019-03-19 22:29:37 +03:00
|
|
|
[1.4.2]: https://github.com/diesel-rs/diesel/compare/v1.4.1...v1.4.2
|
2020-03-23 16:50:07 +03:00
|
|
|
[1.4.3]: https://github.com/diesel-rs/diesel/compare/v1.4.2...v1.4.3
|
|
|
|
[1.4.4]: https://github.com/diesel-rs/diesel/compare/v1.4.3...v1.4.4
|