Skip to content

Commit 51e4f32

Browse files
authored
Merge branch 'master' into array_subselect
2 parents f9d768f + 6e76f04 commit 51e4f32

File tree

13 files changed

+128
-43
lines changed

13 files changed

+128
-43
lines changed

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,9 @@ contact_links:
33
- name: Compiler error while compiling diesel
44
url: https://github.com/diesel-rs/diesel/issues?q=is%3Aissue+ld+returned+1+exit+status+
55
about: Failed to compile diesel? Have a look at existing issues. You've likely miss some required dependency.
6-
- name: Simple Questions
7-
url: https://gitter.im/diesel-rs/diesel
8-
about: If you have a simple question please use our gitter channel.
9-
- name: Complex Questions
6+
- name: Questions
107
url: https://github.com/diesel-rs/diesel/discussions/categories/q-a
11-
about: Do you have a larger question? Ask in our forum.
8+
about: Do you have questions? Ask in our forum.
129
- name: Feature Requests
1310
url: https://github.com/diesel-rs/diesel/discussions/categories/ideas
1411
about: If you want to suggest a new feature please create a new topic in our discussions forum

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Increasing the minimal supported Rust version will always be coupled at least wi
2121
* Added `diesel::r2d2::TestCustomizer`, which allows users to customize their `diesel::r2d2::Pool`s
2222
in a way that makes the pools suitable for use in parallel tests.
2323
* Added `Json` and `Jsonb` support for the SQLite backend.
24+
* Fixed diesel thinking `a.eq_any(b)` was non-nullable even if `a` and `b` were nullable.
2425

2526
## [2.2.2] 2024-07-19
2627

CONTRIBUTING.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
Thanks for your interest in contributing to Diesel! We very much look forward to
44
your suggestions, bug reports, and pull requests.
55

6-
We run an active [Gitter
7-
channel](https://gitter.im/diesel-rs/diesel) where you can ask Diesel-related questions and
6+
We run an active [discussion forum](https://github.com/diesel-rs/diesel/discussions) where you can ask Diesel-related questions and
87
get help. Feel free to ask there before opening a GitHub issue or
98
pull request.
109

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
# A safe, extensible ORM and Query Builder for Rust
44

55
[![Build Status](https://github.com/diesel-rs/diesel/workflows/CI%20Tests/badge.svg)](https://github.com/diesel-rs/diesel/actions?query=workflow%3A%22CI+Tests%22+branch%3Amaster)
6-
[![Gitter](https://badges.gitter.im/diesel-rs/diesel.svg)](https://gitter.im/diesel-rs/diesel?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
76
[![Crates.io](https://img.shields.io/crates/v/diesel.svg)](https://crates.io/crates/diesel)
87

98
API Documentation: [latest release](https://docs.rs/diesel)[master branch](https://docs.diesel.rs/master/diesel/index.html)
@@ -36,10 +35,8 @@ Guides on more specific features are coming soon.
3635
## Getting help
3736

3837
If you run into problems, Diesel has a very active Gitter room.
39-
You can come ask for help at
40-
[gitter.im/diesel-rs/diesel](https://gitter.im/diesel-rs/diesel).
41-
For help with longer questions and discussion about the future of Diesel,
42-
open a discussion on [GitHub Discussions](https://github.com/diesel-rs/diesel/discussions).
38+
You can come ask for help at in our [GitHub Discussions](https://github.com/diesel-rs/diesel/discussions) forum.
39+
This is also the right place to propose new features or show your applications.
4340

4441
## Usage
4542

diesel/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ pub mod helper_types {
369369
use super::query_dsl::methods::*;
370370
use super::query_dsl::*;
371371
use super::query_source::{aliasing, joins};
372+
use crate::dsl::CountStar;
372373
use crate::query_builder::select_clause::SelectClause;
373374

374375
#[doc(inline)]
@@ -699,6 +700,9 @@ pub mod helper_types {
699700
/// [`DeleteStatement::returning`](crate::query_builder::DeleteStatement::returning)
700701
pub type Returning<Q, S> =
701702
<Q as crate::query_builder::returning_clause::ReturningClauseHelper<S>>::WithReturning;
703+
704+
#[doc(hidden)] // used for `QueryDsl::count`
705+
pub type Count<Q> = Select<Q, CountStar>;
702706
}
703707

704708
pub mod prelude {

diesel/src/pg/expression/functions.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,3 +2398,86 @@ define_sql_function! {
23982398
J: JsonbOrNullableJsonb + CombinedAllNullableValue<Jsonb, B>
23992399
>(base: B, from_json: J) -> J::Out;
24002400
}
2401+
2402+
#[cfg(feature = "postgres_backend")]
2403+
define_sql_function! {
2404+
/// Returns target with the item designated by path replaced by new_value,
2405+
/// or with new_value added if create_if_missing is true (which is the default)
2406+
/// and the item designated by path does not exist.
2407+
///
2408+
/// It can't set path in scalar
2409+
///
2410+
/// All earlier steps in the path must exist, or the target is returned unchanged.
2411+
/// As with the path oriented operators, negative integers that appear in the path count from the end of JSON arrays.
2412+
/// If the last path step is an array index that is out of range,
2413+
/// and create_if_missing is true, the new value is added at the beginning of the array if the index is negative,
2414+
/// or at the end of the array if it is positive.
2415+
///
2416+
/// # Example
2417+
///
2418+
/// ```rust
2419+
/// # include!("../../doctest_setup.rs");
2420+
/// #
2421+
/// # fn main() {
2422+
/// # #[cfg(feature = "serde_json")]
2423+
/// # run_test().unwrap();
2424+
/// # }
2425+
/// #
2426+
/// # #[cfg(feature = "serde_json")]
2427+
/// # fn run_test() -> QueryResult<()> {
2428+
/// # use diesel::dsl::jsonb_set;
2429+
/// # use diesel::sql_types::{Jsonb,Array, Json, Nullable, Text};
2430+
/// # use serde_json::{json,Value};
2431+
/// # let connection = &mut establish_connection();
2432+
///
2433+
/// let result = diesel::select(jsonb_set::<Jsonb, Array<Text>, _, _, _>(
2434+
/// json!([{"f1":1,"f2":null},2,null,3]),
2435+
/// vec!["0","f1"],
2436+
/// json!([2,3,4])
2437+
/// )).get_result::<Value>(connection)?;
2438+
/// let expected: Value = json!([{"f1": [2, 3, 4], "f2": null}, 2, null, 3]);
2439+
/// assert_eq!(result, expected);
2440+
///
2441+
/// let result = diesel::select(jsonb_set::<Jsonb, Array<Text>, _, _, _>(
2442+
/// json!([{"odd":[2,4,6,8]}]),
2443+
/// // not vec!["odd"], cannot set path in scalar
2444+
/// vec!["0","odd"],
2445+
/// json!([1,3,5,7])
2446+
/// )).get_result::<Value>(connection)?;
2447+
/// let expected: Value = json!([{"odd":[1,3,5,7]}]);
2448+
/// assert_eq!(result, expected);
2449+
///
2450+
/// let empty:Vec<String> = Vec::new();
2451+
/// let result = diesel::select(jsonb_set::<Nullable<Jsonb>, Array<Nullable<Text>>, _, _, _>(
2452+
/// None::<Value>,
2453+
/// empty,
2454+
/// None::<Value>
2455+
/// )).get_result::<Option<Value>>(connection)?;
2456+
/// assert!(result.is_none());
2457+
///
2458+
/// let empty:Vec<String> = Vec::new();
2459+
/// let result = diesel::select(jsonb_set::<Jsonb, Array<Nullable<Text>>, _, _, _>(
2460+
/// // cannot be json!(null)
2461+
/// json!([]),
2462+
/// empty,
2463+
/// json!(null)
2464+
/// )).get_result::<Value>(connection)?;
2465+
/// let expected = json!([]);
2466+
/// assert_eq!(result, expected);
2467+
///
2468+
/// let result = diesel::select(jsonb_set::<Jsonb, Nullable<Array<Nullable<Text>>>, _, _, _,>(
2469+
/// json!(null),
2470+
/// None::<Vec<String>>,
2471+
/// json!({"foo": 42})
2472+
/// )).get_result::<Option<Value>>(connection)?;
2473+
/// assert!(result.is_none());
2474+
///
2475+
///
2476+
/// # Ok(())
2477+
/// # }
2478+
/// ```
2479+
fn jsonb_set<
2480+
E: JsonbOrNullableJsonb + SingleValue,
2481+
Arr: TextArrayOrNullableTextArray + CombinedNullableValue<E,Jsonb>
2482+
>(base: E, path: Arr, new_value: E) -> Arr::Out;
2483+
}

diesel/src/pg/expression/helper_types.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,3 +592,8 @@ pub type json_populate_record<B, J> =
592592
#[cfg(feature = "postgres_backend")]
593593
pub type jsonb_populate_record<B, J> =
594594
super::functions::jsonb_populate_record<SqlTypeOf<B>, SqlTypeOf<J>, B, J>;
595+
596+
/// Return type of [`jsonb_set(base, path, new_value)`](super::functions::jsonb_set())
597+
#[allow(non_camel_case_types)]
598+
#[cfg(feature = "postgres_backend")]
599+
pub type jsonb_set<B, J, R> = super::functions::jsonb_set<SqlTypeOf<B>, SqlTypeOf<J>, B, J, R>;

diesel_derives/tests/auto_type.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ fn postgres_functions() -> _ {
461461
row_to_json(pg_extras::record),
462462
json_populate_record(pg_extras::record, pg_extras::json),
463463
jsonb_populate_record(pg_extras::record, pg_extras::jsonb),
464+
jsonb_set(pg_extras::jsonb, pg_extras::text_array, pg_extras::jsonb),
464465
)
465466
}
466467

@@ -503,6 +504,11 @@ fn update_and_binary_operator_and_block() -> _ {
503504
}))
504505
}
505506

507+
#[auto_type]
508+
fn count_query() -> _ {
509+
users::table.count()
510+
}
511+
506512
// #[auto_type]
507513
// fn test_sql_fragment() -> _ {
508514
// sql("foo")

diesel_dynamic_schema/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Query schemas not known at compile time with Diesel
44
===================================================
55

66
[![Build Status](https://travis-ci.org/diesel-rs/diesel.svg)](https://travis-ci.org/diesel-rs/diesel-dynamic-schema)
7-
[![Gitter](https://badges.gitter.im/diesel-rs/diesel.svg)](https://gitter.im/diesel-rs/diesel?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
87

98
API Documentation: [latest release](https://docs.rs/diesel-dynamic-schema)
109

diesel_dynamic_schema/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@
7171
//!
7272
//! ## Getting help
7373
//!
74-
//! If you run into problems, Diesel has a very active Gitter room.
74+
//! If you run into problems, Diesel has a very active discussion forum.
7575
//! You can come ask for help at
76-
//! [gitter.im/diesel-rs/diesel](https://gitter.im/diesel-rs/diesel)
76+
//! [github.com/diesel-rs/diesel/discussions](https://github.com/diesel-rs/diesel/discussions)
7777
7878
// Built-in Lints
7979
#![warn(missing_docs)]

examples/postgres/relations/src/main.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ pub mod schema;
1010
use crate::model::*;
1111
use crate::schema::*;
1212

13+
type DbResult<T> = Result<T, Box<dyn Error + Send + Sync>>;
14+
1315
fn establish_connection() -> PgConnection {
1416
dotenv().ok();
1517

@@ -18,27 +20,23 @@ fn establish_connection() -> PgConnection {
1820
.unwrap_or_else(|_| panic!("Error connecting to {database_url}"))
1921
}
2022

21-
fn new_author(conn: &mut PgConnection, name: &str) -> Result<Author, Box<dyn Error + Send + Sync>> {
23+
fn new_author(conn: &mut PgConnection, name: &str) -> DbResult<Author> {
2224
let author = diesel::insert_into(authors::table)
2325
.values(authors::name.eq(name))
2426
.returning(Author::as_returning())
2527
.get_result(conn)?;
2628
Ok(author)
2729
}
2830

29-
fn new_book(conn: &mut PgConnection, title: &str) -> Result<Book, Box<dyn Error + Send + Sync>> {
31+
fn new_book(conn: &mut PgConnection, title: &str) -> DbResult<Book> {
3032
let book = diesel::insert_into(books::table)
3133
.values(books::title.eq(title))
3234
.returning(Book::as_returning())
3335
.get_result(conn)?;
3436
Ok(book)
3537
}
3638

37-
fn new_books_author(
38-
conn: &mut PgConnection,
39-
book_id: i32,
40-
author_id: i32,
41-
) -> Result<BookAuthor, Box<dyn Error + Send + Sync>> {
39+
fn new_books_author(conn: &mut PgConnection, book_id: i32, author_id: i32) -> DbResult<BookAuthor> {
4240
let book_author = diesel::insert_into(books_authors::table)
4341
.values((
4442
books_authors::book_id.eq(book_id),
@@ -54,7 +52,7 @@ fn new_page(
5452
page_number: i32,
5553
content: &str,
5654
book_id: i32,
57-
) -> Result<Page, Box<dyn Error + Send + Sync>> {
55+
) -> DbResult<Page> {
5856
let page = diesel::insert_into(pages::table)
5957
.values((
6058
pages::page_number.eq(page_number),
@@ -66,7 +64,7 @@ fn new_page(
6664
Ok(page)
6765
}
6866

69-
fn joins(conn: &mut PgConnection) -> Result<(), Box<dyn Error + Send + Sync>> {
67+
fn joins(conn: &mut PgConnection) -> DbResult<()> {
7068
let page_with_book = pages::table
7169
.inner_join(books::table)
7270
.filter(books::title.eq("Momo"))
@@ -84,7 +82,7 @@ fn joins(conn: &mut PgConnection) -> Result<(), Box<dyn Error + Send + Sync>> {
8482
Ok(())
8583
}
8684

87-
fn one_to_n_relations(conn: &mut PgConnection) -> Result<(), Box<dyn Error + Send + Sync>> {
85+
fn one_to_n_relations(conn: &mut PgConnection) -> DbResult<()> {
8886
let momo = books::table
8987
.filter(books::title.eq("Momo"))
9088
.select(Book::as_select())
@@ -117,7 +115,7 @@ fn one_to_n_relations(conn: &mut PgConnection) -> Result<(), Box<dyn Error + Sen
117115
Ok(())
118116
}
119117

120-
fn m_to_n_relations(conn: &mut PgConnection) -> Result<(), Box<dyn Error + Send + Sync>> {
118+
fn m_to_n_relations(conn: &mut PgConnection) -> DbResult<()> {
121119
let astrid_lindgren = authors::table
122120
.filter(authors::name.eq("Astrid Lindgren"))
123121
.select(Author::as_select())
@@ -172,7 +170,7 @@ fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
172170
Ok(())
173171
}
174172

175-
fn setup_data(conn: &mut PgConnection) -> Result<(), Box<dyn Error + Send + Sync>> {
173+
fn setup_data(conn: &mut PgConnection) -> DbResult<()> {
176174
// create a book
177175
let momo = new_book(conn, "Momo")?;
178176

examples/sqlite/relations/src/main.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ pub mod schema;
1010
use crate::model::*;
1111
use crate::schema::*;
1212

13+
type DbResult<T> = Result<T, Box<dyn Error + Send + Sync>>;
14+
1315
fn establish_connection() -> SqliteConnection {
1416
dotenv().ok();
1517

@@ -18,21 +20,15 @@ fn establish_connection() -> SqliteConnection {
1820
.unwrap_or_else(|_| panic!("Error connecting to {database_url}"))
1921
}
2022

21-
fn new_author(
22-
conn: &mut SqliteConnection,
23-
name: &str,
24-
) -> Result<Author, Box<dyn Error + Send + Sync>> {
23+
fn new_author(conn: &mut SqliteConnection, name: &str) -> DbResult<Author> {
2524
let author = diesel::insert_into(authors::table)
2625
.values(authors::name.eq(name))
2726
.returning(Author::as_returning())
2827
.get_result(conn)?;
2928
Ok(author)
3029
}
3130

32-
fn new_book(
33-
conn: &mut SqliteConnection,
34-
title: &str,
35-
) -> Result<Book, Box<dyn Error + Send + Sync>> {
31+
fn new_book(conn: &mut SqliteConnection, title: &str) -> DbResult<Book> {
3632
let book = diesel::insert_into(books::table)
3733
.values(books::title.eq(title))
3834
.returning(Book::as_returning())
@@ -44,7 +40,7 @@ fn new_books_author(
4440
conn: &mut SqliteConnection,
4541
book_id: i32,
4642
author_id: i32,
47-
) -> Result<BookAuthor, Box<dyn Error + Send + Sync>> {
43+
) -> DbResult<BookAuthor> {
4844
let book_author = diesel::insert_into(books_authors::table)
4945
.values((
5046
books_authors::book_id.eq(book_id),
@@ -60,7 +56,7 @@ fn new_page(
6056
page_number: i32,
6157
content: &str,
6258
book_id: i32,
63-
) -> Result<Page, Box<dyn Error + Send + Sync>> {
59+
) -> DbResult<Page> {
6460
let page = diesel::insert_into(pages::table)
6561
.values((
6662
pages::page_number.eq(page_number),
@@ -72,7 +68,7 @@ fn new_page(
7268
Ok(page)
7369
}
7470

75-
fn joins(conn: &mut SqliteConnection) -> Result<(), Box<dyn Error + Send + Sync>> {
71+
fn joins(conn: &mut SqliteConnection) -> DbResult<()> {
7672
let page_with_book = pages::table
7773
.inner_join(books::table)
7874
.filter(books::title.eq("Momo"))
@@ -90,7 +86,7 @@ fn joins(conn: &mut SqliteConnection) -> Result<(), Box<dyn Error + Send + Sync>
9086
Ok(())
9187
}
9288

93-
fn one_to_n_relations(conn: &mut SqliteConnection) -> Result<(), Box<dyn Error + Send + Sync>> {
89+
fn one_to_n_relations(conn: &mut SqliteConnection) -> DbResult<()> {
9490
let momo = books::table
9591
.filter(books::title.eq("Momo"))
9692
.select(Book::as_select())
@@ -123,7 +119,7 @@ fn one_to_n_relations(conn: &mut SqliteConnection) -> Result<(), Box<dyn Error +
123119
Ok(())
124120
}
125121

126-
fn m_to_n_relations(conn: &mut SqliteConnection) -> Result<(), Box<dyn Error + Send + Sync>> {
122+
fn m_to_n_relations(conn: &mut SqliteConnection) -> DbResult<()> {
127123
let astrid_lindgren = authors::table
128124
.filter(authors::name.eq("Astrid Lindgren"))
129125
.select(Author::as_select())
@@ -178,7 +174,7 @@ fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
178174
Ok(())
179175
}
180176

181-
fn setup_data(conn: &mut SqliteConnection) -> Result<(), Box<dyn Error + Send + Sync>> {
177+
fn setup_data(conn: &mut SqliteConnection) -> DbResult<()> {
182178
// create a book
183179
let momo = new_book(conn, "Momo")?;
184180

guide_drafts/trait_derives.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,9 +960,9 @@ error[E0599]: no function or associated item named `belonging_to` found for type
960960
Please check out other [official guides] and [docs]
961961
for more information on using the Diesel framework.
962962

963-
If you have any questions, join our [gitter channel],
963+
If you have any questions, join our [discussion forum],
964964
the Diesel team is happy to help.
965965

966966
[official guides]: https://diesel.rs/guides/
967967
[docs]: https://docs.diesel.rs
968-
[gitter channel]: https://gitter.im/diesel-rs/diesel
968+
[discussion forum]: https://github.com/diesel-rs/diesel/discussions

0 commit comments

Comments
 (0)