From 0d9ca28e18a951c18f301bce2620d10508dac37b Mon Sep 17 00:00:00 2001 From: Juhasz Sandor Date: Thu, 2 Sep 2021 22:20:05 +0200 Subject: [PATCH 1/6] add CLIENT_FOUND_ROWS flag to mysql connect --- diesel/src/mysql/connection/raw.rs | 5 ++-- diesel/src/mysql/connection/url.rs | 39 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/diesel/src/mysql/connection/raw.rs b/diesel/src/mysql/connection/raw.rs index 0ac4041aefab..7f3f5321a540 100644 --- a/diesel/src/mysql/connection/raw.rs +++ b/diesel/src/mysql/connection/raw.rs @@ -6,7 +6,7 @@ use std::ptr::{self, NonNull}; use std::sync::Once; use super::stmt::Statement; -use super::url::ConnectionOptions; +use super::url::{CapabilityFlags, ConnectionOptions}; use crate::result::{ConnectionError, ConnectionResult, QueryResult}; pub struct RawConnection(NonNull); @@ -46,6 +46,7 @@ impl RawConnection { let database = connection_options.database(); let port = connection_options.port(); let unix_socket = connection_options.unix_socket(); + let client_flags = connection_options.client_flags(); unsafe { // Make sure you don't use the fake one! @@ -63,7 +64,7 @@ impl RawConnection { unix_socket .map(CStr::as_ptr) .unwrap_or_else(|| ptr::null_mut()), - 0, + client_flags.unwrap_or(CapabilityFlags::empty()).bits(), ) }; diff --git a/diesel/src/mysql/connection/url.rs b/diesel/src/mysql/connection/url.rs index 7e3566777f3b..748c2c189214 100644 --- a/diesel/src/mysql/connection/url.rs +++ b/diesel/src/mysql/connection/url.rs @@ -8,6 +8,36 @@ use std::ffi::{CStr, CString}; use crate::result::{ConnectionError, ConnectionResult}; +bitflags::bitflags! { + pub struct CapabilityFlags: u32 { + const CLIENT_LONG_PASSWORD = 0x00000001; + const CLIENT_FOUND_ROWS = 0x00000002; + const CLIENT_LONG_FLAG = 0x00000004; + const CLIENT_CONNECT_WITH_DB = 0x00000008; + const CLIENT_NO_SCHEMA = 0x00000010; + const CLIENT_COMPRESS = 0x00000020; + const CLIENT_ODBC = 0x00000040; + const CLIENT_LOCAL_FILES = 0x00000080; + const CLIENT_IGNORE_SPACE = 0x00000100; + const CLIENT_PROTOCOL_41 = 0x00000200; + const CLIENT_INTERACTIVE = 0x00000400; + const CLIENT_SSL = 0x00000800; + const CLIENT_IGNORE_SIGPIPE = 0x00001000; + const CLIENT_TRANSACTIONS = 0x00002000; + const CLIENT_RESERVED = 0x00004000; + const CLIENT_SECURE_CONNECTION = 0x00008000; + const CLIENT_MULTI_STATEMENTS = 0x00010000; + const CLIENT_MULTI_RESULTS = 0x00020000; + const CLIENT_PS_MULTI_RESULTS = 0x00040000; + const CLIENT_PLUGIN_AUTH = 0x00080000; + const CLIENT_CONNECT_ATTRS = 0x00100000; + const CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA = 0x00200000; + const CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS = 0x00400000; + const CLIENT_SESSION_TRACK = 0x00800000; + const CLIENT_DEPRECATE_EOF = 0x01000000; + } +} + pub struct ConnectionOptions { host: Option, user: CString, @@ -15,6 +45,7 @@ pub struct ConnectionOptions { database: Option, port: Option, unix_socket: Option, + client_flags: Option, } impl ConnectionOptions { @@ -59,6 +90,9 @@ impl ConnectionOptions { Some(segment) => Some(CString::new(segment.as_bytes())?), }; + // this is not present in the database_url, using a default value + let client_flags = Some(CapabilityFlags::CLIENT_FOUND_ROWS); + Ok(ConnectionOptions { host: host, user: user, @@ -66,6 +100,7 @@ impl ConnectionOptions { database: database, port: url.port(), unix_socket: unix_socket, + client_flags: client_flags, }) } @@ -92,6 +127,10 @@ impl ConnectionOptions { pub fn unix_socket(&self) -> Option<&CStr> { self.unix_socket.as_deref() } + + pub fn client_flags(&self) -> Option { + self.client_flags + } } fn decode_into_cstring(s: &str) -> ConnectionResult { From 4398ac7913ea4fca7a257066309b797a67a64c65 Mon Sep 17 00:00:00 2001 From: Juhasz Sandor Date: Thu, 2 Sep 2021 23:36:10 +0200 Subject: [PATCH 2/6] fix bitflag type --- diesel/src/mysql/connection/raw.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/diesel/src/mysql/connection/raw.rs b/diesel/src/mysql/connection/raw.rs index 7f3f5321a540..5aa0ba01815c 100644 --- a/diesel/src/mysql/connection/raw.rs +++ b/diesel/src/mysql/connection/raw.rs @@ -64,7 +64,10 @@ impl RawConnection { unix_socket .map(CStr::as_ptr) .unwrap_or_else(|| ptr::null_mut()), - client_flags.unwrap_or(CapabilityFlags::empty()).bits(), + client_flags + .unwrap_or(CapabilityFlags::empty()) + .bits() + .into(), ) }; From ab73801482d5a74161907184cdd8e56730201af9 Mon Sep 17 00:00:00 2001 From: Juhasz Sandor Date: Thu, 2 Sep 2021 23:59:43 +0200 Subject: [PATCH 3/6] fix clippy warning --- diesel/src/mysql/connection/raw.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diesel/src/mysql/connection/raw.rs b/diesel/src/mysql/connection/raw.rs index 5aa0ba01815c..d985a87d8904 100644 --- a/diesel/src/mysql/connection/raw.rs +++ b/diesel/src/mysql/connection/raw.rs @@ -65,7 +65,7 @@ impl RawConnection { .map(CStr::as_ptr) .unwrap_or_else(|| ptr::null_mut()), client_flags - .unwrap_or(CapabilityFlags::empty()) + .unwrap_or_else(CapabilityFlags::empty) .bits() .into(), ) From 21c9354ff34000b0127703411f8f60590a1ef0af Mon Sep 17 00:00:00 2001 From: Juhasz Sandor Date: Fri, 3 Sep 2021 12:54:30 +0200 Subject: [PATCH 4/6] get rid of option --- diesel/src/mysql/connection/raw.rs | 7 ++----- diesel/src/mysql/connection/url.rs | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/diesel/src/mysql/connection/raw.rs b/diesel/src/mysql/connection/raw.rs index d985a87d8904..4c29c930a872 100644 --- a/diesel/src/mysql/connection/raw.rs +++ b/diesel/src/mysql/connection/raw.rs @@ -6,7 +6,7 @@ use std::ptr::{self, NonNull}; use std::sync::Once; use super::stmt::Statement; -use super::url::{CapabilityFlags, ConnectionOptions}; +use super::url::ConnectionOptions; use crate::result::{ConnectionError, ConnectionResult, QueryResult}; pub struct RawConnection(NonNull); @@ -64,10 +64,7 @@ impl RawConnection { unix_socket .map(CStr::as_ptr) .unwrap_or_else(|| ptr::null_mut()), - client_flags - .unwrap_or_else(CapabilityFlags::empty) - .bits() - .into(), + client_flags.bits().into(), ) }; diff --git a/diesel/src/mysql/connection/url.rs b/diesel/src/mysql/connection/url.rs index 748c2c189214..897cc920494a 100644 --- a/diesel/src/mysql/connection/url.rs +++ b/diesel/src/mysql/connection/url.rs @@ -45,7 +45,7 @@ pub struct ConnectionOptions { database: Option, port: Option, unix_socket: Option, - client_flags: Option, + client_flags: CapabilityFlags, } impl ConnectionOptions { @@ -91,7 +91,7 @@ impl ConnectionOptions { }; // this is not present in the database_url, using a default value - let client_flags = Some(CapabilityFlags::CLIENT_FOUND_ROWS); + let client_flags = CapabilityFlags::CLIENT_FOUND_ROWS; Ok(ConnectionOptions { host: host, @@ -128,7 +128,7 @@ impl ConnectionOptions { self.unix_socket.as_deref() } - pub fn client_flags(&self) -> Option { + pub fn client_flags(&self) -> CapabilityFlags { self.client_flags } } From fab4e6124fae3cde7fde4996e2540dd8f61f4eb8 Mon Sep 17 00:00:00 2001 From: Juhasz Sandor Date: Fri, 3 Sep 2021 13:05:56 +0200 Subject: [PATCH 5/6] changelog update --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbaf48684bc8..bbbcff7cfcf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -175,7 +175,9 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/ * The `#[table_name]` attribute for derive macros can now refer to any path and is no longer limited to identifiers from the current scope. -* Interacting with a database requires a mutable connection. +* Interacting with a database requires a mutable connection. + +* The MySQL connection is using the CLIENT_FOUND_ROWS from now on. This means that updating rows without changing any values will return the number of matched rows (like most other SQL servers do), as opposed to the number of changed rows. ### Fixed From 91a1697c362ed30da4b12250b1ebeb1303850fe1 Mon Sep 17 00:00:00 2001 From: Juhasz Sandor Date: Fri, 3 Sep 2021 13:24:39 +0200 Subject: [PATCH 6/6] test for CLIENT_FOUND_ROWS flag --- diesel/src/mysql/connection/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/diesel/src/mysql/connection/mod.rs b/diesel/src/mysql/connection/mod.rs index 04093d901d09..ef29bb5a5aa4 100644 --- a/diesel/src/mysql/connection/mod.rs +++ b/diesel/src/mysql/connection/mod.rs @@ -162,4 +162,23 @@ mod tests { assert!(connection.execute("SELECT 1").is_ok()); assert!(connection.execute("SELECT 1").is_ok()); } + + #[test] + fn check_client_found_rows_flag() { + let conn = &mut crate::test_helpers::connection(); + conn.execute("DROP TABLE IF EXISTS update_test CASCADE") + .unwrap(); + + conn.execute("CREATE TABLE update_test(id INTEGER PRIMARY KEY, num INTEGER NOT NULL)") + .unwrap(); + + conn.execute("INSERT INTO update_test(id, num) VALUES (1, 5)") + .unwrap(); + + let output = conn + .execute("UPDATE update_test SET num = 5 WHERE id = 1") + .unwrap(); + + assert_eq!(output, 1); + } }