Skip to content

Commit 54ccfe7

Browse files
authored
copy changes (mongodb#283)
1 parent e315844 commit 54ccfe7

File tree

4 files changed

+125
-41
lines changed

4 files changed

+125
-41
lines changed

definitions/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -412,3 +412,11 @@ pub enum RowStatus {
412412
SQL_ROW_ERROR = 5,
413413
SQL_ROW_SUCCESS_WITH_INFO = 6,
414414
}
415+
416+
#[derive(Clone, Copy, Debug, Default, FromPrimitive, PartialEq)]
417+
#[repr(u32)]
418+
pub enum AccessMode {
419+
ReadWrite = 0,
420+
#[default]
421+
ReadOnly,
422+
}

odbc/src/api/connect_attr_tests.rs

+77-9
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@
77
mod unit {
88
use crate::{
99
errors::ODBCError,
10-
handles::definitions::{Connection, ConnectionAttributes, ConnectionState, MongoHandle},
10+
handles::definitions::{
11+
Connection, ConnectionAttributes, ConnectionState, Env, EnvState, MongoHandle,
12+
},
1113
util::connection_attribute_to_string,
12-
SQLGetConnectAttrW, SQLSetConnectAttrW,
14+
SQLGetConnectAttrW, SQLGetDiagFieldW, SQLSetConnectAttrW,
1315
};
14-
use cstr::input_text_to_string_w;
15-
use definitions::{ConnectionAttribute, Integer, Pointer, SqlReturn, UInteger};
16+
use cstr::{input_text_to_string_w, WideChar};
17+
use definitions::{
18+
AccessMode, ConnectionAttribute, HandleType, Integer, Pointer, SqlReturn, UInteger, WChar,
19+
};
20+
use std::ffi::c_void;
21+
use std::mem::size_of;
1622
use std::sync::RwLock;
1723

1824
mod get {
19-
use std::mem::size_of;
20-
21-
use cstr::WideChar;
2225

2326
use super::*;
2427

@@ -205,9 +208,74 @@ mod unit {
205208
}
206209
}
207210

208-
const UNSUPPORTED_ATTRS: [ConnectionAttribute; 18] = [
211+
// Test setting the access mode attribute
212+
#[test]
213+
fn get_set_access_mode() {
214+
unsafe {
215+
let env = &mut MongoHandle::Env(Env::with_state(EnvState::Allocated));
216+
let conn = Connection::with_state(env, ConnectionState::Connected);
217+
let mongo_handle: *mut _ = &mut MongoHandle::Connection(conn);
218+
let value_ptr: *mut std::ffi::c_void = Box::into_raw(Box::new([0u8; 40])) as *mut _;
219+
220+
// check the existing default value is read only
221+
assert_eq!(
222+
SqlReturn::SUCCESS,
223+
SQLGetConnectAttrW(
224+
mongo_handle as *mut _,
225+
ConnectionAttribute::SQL_ATTR_ACCESS_MODE as i32,
226+
value_ptr,
227+
0,
228+
&mut 0,
229+
)
230+
);
231+
assert_eq!(AccessMode::ReadOnly as u32, *(value_ptr as *mut UInteger));
232+
233+
// check that setting to ReadWrite provides sucesss with info and the value remains read only
234+
assert_eq!(
235+
SqlReturn::SUCCESS_WITH_INFO,
236+
SQLSetConnectAttrW(
237+
mongo_handle as *mut _,
238+
ConnectionAttribute::SQL_ATTR_ACCESS_MODE as i32,
239+
(AccessMode::ReadWrite as u32) as Pointer,
240+
0,
241+
)
242+
);
243+
244+
let message_text = &mut [0; 89 * size_of::<WideChar>()] as *mut _ as *mut c_void;
245+
assert_eq!(
246+
SqlReturn::SUCCESS,
247+
SQLGetDiagFieldW(
248+
HandleType::SQL_HANDLE_DBC,
249+
mongo_handle as *mut _,
250+
1,
251+
6, //DiagType::SQL_DIAG_MESSAGE_TEXT
252+
message_text,
253+
89 * size_of::<WideChar>() as i16,
254+
&mut 0
255+
)
256+
);
257+
assert_eq!(
258+
"[MongoDB][API] Invalid value for attribute SQL_MODE_READ_WRITE, changed to SQL_MODE_READ\0",
259+
cstr::from_widechar_ref_lossy(&*(message_text as *const [WideChar; 89]))
260+
);
261+
262+
assert_eq!(
263+
SqlReturn::SUCCESS,
264+
SQLGetConnectAttrW(
265+
mongo_handle as *mut _,
266+
ConnectionAttribute::SQL_ATTR_ACCESS_MODE as i32,
267+
value_ptr,
268+
0,
269+
&mut 0,
270+
)
271+
);
272+
assert_eq!(AccessMode::ReadOnly as u32, *(value_ptr as *mut UInteger));
273+
let _ = Box::from_raw(value_ptr as *mut WChar);
274+
}
275+
}
276+
277+
const UNSUPPORTED_ATTRS: [ConnectionAttribute; 17] = [
209278
ConnectionAttribute::SQL_ATTR_ASYNC_ENABLE,
210-
ConnectionAttribute::SQL_ATTR_ACCESS_MODE,
211279
ConnectionAttribute::SQL_ATTR_AUTOCOMMIT,
212280
ConnectionAttribute::SQL_ATTR_TRACE,
213281
ConnectionAttribute::SQL_ATTR_TRACEFILE,

odbc/src/api/functions.rs

+30-22
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ use mongodb::bson::{doc, Bson};
1515
use cstr::{input_text_to_string_w, input_text_to_string_w_allow_null, Charset, WideChar};
1616

1717
use definitions::{
18-
AllocType, AsyncEnable, AttrConnectionPooling, AttrCpMatch, AttrOdbcVersion, BindType,
19-
CDataType, Concurrency, ConnectionAttribute, CursorScrollable, CursorSensitivity, CursorType,
20-
Desc, DiagType, DriverConnectOption, EnvironmentAttribute, FetchOrientation, FreeStmtOption,
21-
HDbc, HDesc, HEnv, HStmt, HWnd, Handle, HandleType, Integer, Len, NoScan, Pointer, RetCode,
22-
RetrieveData, RowStatus, SmallInt, SqlBool, SqlDataType, SqlReturn, StatementAttribute, ULen,
23-
USmallInt, UseBookmarks, SQL_NTS,
18+
AccessMode, AllocType, AsyncEnable, AttrConnectionPooling, AttrCpMatch, AttrOdbcVersion,
19+
BindType, CDataType, Concurrency, ConnectionAttribute, CursorScrollable, CursorSensitivity,
20+
CursorType, Desc, DiagType, DriverConnectOption, EnvironmentAttribute, FetchOrientation,
21+
FreeStmtOption, HDbc, HDesc, HEnv, HStmt, HWnd, Handle, HandleType, Integer, Len, NoScan,
22+
Pointer, RetCode, RetrieveData, RowStatus, SmallInt, SqlBool, SqlDataType, SqlReturn,
23+
StatementAttribute, ULen, USmallInt, UseBookmarks, SQL_NTS,
2424
};
2525
use function_name::named;
2626
use log::{debug, error, info};
@@ -1184,22 +1184,10 @@ pub unsafe extern "C" fn SQLDriverConnectW(
11841184
function_name!()
11851185
);
11861186

1187-
// SQL_NO_PROMPT is the only option supported for DriverCompletion
1188-
match FromPrimitive::from_u16(driver_completion) {
1189-
Some(driver_completion) => match driver_completion {
1190-
DriverConnectOption::SQL_DRIVER_COMPLETE
1191-
| DriverConnectOption::SQL_DRIVER_COMPLETE_REQUIRED
1192-
| DriverConnectOption::SQL_DRIVER_PROMPT => {
1193-
add_diag_info!(
1194-
conn_handle,
1195-
ODBCError::UnsupportedDriverConnectOption(format!(
1196-
"{driver_completion:?}"
1197-
))
1198-
);
1199-
return SqlReturn::ERROR;
1200-
}
1201-
DriverConnectOption::SQL_DRIVER_NO_PROMPT => {}
1202-
},
1187+
// We will treat any valid option passed for DriverComplete as a no-op
1188+
// because we don't have any UI involved in the process and don't plan to add any in the future
1189+
match <DriverConnectOption as FromPrimitive>::from_u16(driver_completion) {
1190+
Some(_) => {}
12031191
None => {
12041192
add_diag_info!(
12051193
conn_handle,
@@ -1916,6 +1904,9 @@ unsafe fn sql_get_connect_attrw_helper(
19161904
let connection_timeout = attributes.connection_timeout.unwrap_or(0);
19171905
i32_len::set_output_fixed_data(&connection_timeout, value_ptr, string_length_ptr)
19181906
}
1907+
ConnectionAttribute::SQL_ATTR_ACCESS_MODE => {
1908+
i32_len::set_output_fixed_data(&AccessMode::ReadOnly, value_ptr, string_length_ptr)
1909+
}
19191910
_ => {
19201911
err = Some(ODBCError::UnsupportedConnectionAttribute(
19211912
connection_attribute_to_string(attribute),
@@ -3579,6 +3570,23 @@ unsafe fn set_connect_attrw_helper(
35793570
SqlReturn::SUCCESS_WITH_INFO
35803571
}
35813572
},
3573+
ConnectionAttribute::SQL_ATTR_ACCESS_MODE => {
3574+
match FromPrimitive::from_u32(value_ptr as u32) {
3575+
Some(AccessMode::ReadOnly) => SqlReturn::SUCCESS,
3576+
Some(AccessMode::ReadWrite) => {
3577+
conn_handle.add_diag_info(ODBCError::OptionValueChanged(
3578+
"SQL_MODE_READ_WRITE",
3579+
"SQL_MODE_READ",
3580+
));
3581+
SqlReturn::SUCCESS_WITH_INFO
3582+
}
3583+
None => {
3584+
conn_handle
3585+
.add_diag_info(ODBCError::InvalidAttrValue("SQL_ATTR_ACCESS_MODE"));
3586+
SqlReturn::ERROR
3587+
}
3588+
}
3589+
}
35823590
_ => {
35833591
err = Some(ODBCError::UnsupportedConnectionAttribute(
35843592
connection_attribute_to_string(attribute),

odbc/tests/connection_tests.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ macro_rules! test_connection_diagnostics {
9292
mod integration {
9393
use crate::common::verify_sql_diagnostics;
9494
use atsql::{SQLAllocHandle, SQLDisconnect, SQLDriverConnectW, SQLFreeHandle};
95-
use constants::{NOT_IMPLEMENTED, NO_DSN_OR_DRIVER, UNABLE_TO_CONNECT};
95+
use constants::{NO_DSN_OR_DRIVER, UNABLE_TO_CONNECT};
9696
use definitions::{DriverConnectOption, Handle, HandleType, SqlReturn};
9797
use std::ptr::null_mut;
9898

@@ -122,30 +122,30 @@ mod integration {
122122
"[MongoDB][API] Missing property \"Driver\" or \"DSN\" in connection string"
123123
);
124124
test_connection_diagnostics!(
125-
unsupported_driver_connect_option_prompt,
125+
missing_driver_driver_connect_option_prompt,
126126
in_connection_string = "USER=N_A;SERVER=N_A;PWD=N_A",
127127
driver_completion = DriverConnectOption::SQL_DRIVER_PROMPT,
128-
expected_sql_state = NOT_IMPLEMENTED,
128+
expected_sql_state = NO_DSN_OR_DRIVER,
129129
expected_sql_return = SqlReturn::ERROR,
130130
expected_error_message =
131-
"[MongoDB][API] The driver connect option SQL_DRIVER_PROMPT is not supported"
131+
"[MongoDB][API] Missing property \"Driver\" or \"DSN\" in connection string"
132132
);
133133
test_connection_diagnostics!(
134-
unsupported_driver_connect_option_complete,
134+
missing_driver_driver_connect_option_complete,
135135
in_connection_string = "USER=N_A;SERVER=N_A;PWD=N_A",
136136
driver_completion = DriverConnectOption::SQL_DRIVER_COMPLETE,
137-
expected_sql_state = NOT_IMPLEMENTED,
137+
expected_sql_state = NO_DSN_OR_DRIVER,
138138
expected_sql_return = SqlReturn::ERROR,
139139
expected_error_message =
140-
"[MongoDB][API] The driver connect option SQL_DRIVER_COMPLETE is not supported"
140+
"[MongoDB][API] Missing property \"Driver\" or \"DSN\" in connection string"
141141
);
142142
test_connection_diagnostics!(
143-
unsupported_driver_connect_option_complete_required,
143+
missing_driver_driver_connect_option_complete_required,
144144
in_connection_string = "USER=N_A;SERVER=N_A;PWD=N_A",
145145
driver_completion = DriverConnectOption::SQL_DRIVER_COMPLETE_REQUIRED,
146-
expected_sql_state = NOT_IMPLEMENTED,
146+
expected_sql_state = NO_DSN_OR_DRIVER,
147147
expected_sql_return = SqlReturn::ERROR,
148148
expected_error_message =
149-
"[MongoDB][API] The driver connect option SQL_DRIVER_COMPLETE_REQUIRED is not supported"
149+
"[MongoDB][API] Missing property \"Driver\" or \"DSN\" in connection string"
150150
);
151151
}

0 commit comments

Comments
 (0)