Skip to content

Commit c20970a

Browse files
committed
substantial sqlite tests and add affected_rows
1 parent 3be37af commit c20970a

File tree

5 files changed

+118
-39
lines changed

5 files changed

+118
-39
lines changed

src/dbc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ impl Row {
132132
#[derive(Serialize, Deserialize, Debug)]
133133
pub struct QueryResult {
134134
pub rows: Vec<Row>,
135+
pub affected_rows: usize,
135136
}
136137

137138
#[derive(Serialize, Deserialize, Clone, Debug)]

src/dbc/mysql.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use std::sync::Arc;
2+
23
use mysql;
34
use mysql::prelude::Queryable;
45
use mysql_common::constants::ColumnType;
6+
57
use crate::dbc;
68

79
pub(crate) struct MySQLConnection {
@@ -19,36 +21,40 @@ impl MySQLConnection {
1921
impl dbc::Connection for MySQLConnection {
2022
fn execute(&mut self, query: &str) -> Result<dbc::QueryResult, dbc::Error> {
2123
let result = self.connection.query_iter(query)?;
22-
let columns = result.columns().as_ref().iter().map(
23-
|column| {
24-
dbc::Column {
25-
name: column.name_str().to_string(),
26-
column_type: column.column_type().into(),
27-
}
28-
}
29-
).collect::<Vec<dbc::Column>>();
24+
let affected_rows = result.affected_rows() as usize;
25+
let columns = result
26+
.columns()
27+
.as_ref()
28+
.iter()
29+
.map(|column| dbc::Column {
30+
name: column.name_str().to_string(),
31+
column_type: column.column_type().into(),
32+
})
33+
.collect::<Vec<dbc::Column>>();
3034
let columns = Arc::from(columns);
3135

32-
3336
let mut rows: Vec<dbc::Row> = Vec::new();
3437
for row in result {
3538
let row = row?;
36-
let values: Vec<dbc::Value> = row.unwrap_raw().iter().map(
37-
|value| {
39+
let values: Vec<dbc::Value> = row
40+
.unwrap_raw()
41+
.iter()
42+
.map(|value| {
3843
if value.is_none() {
3944
dbc::Value::NULL
4045
} else {
4146
value.as_ref().unwrap().into()
4247
}
43-
}
44-
).collect();
48+
})
49+
.collect();
4550
rows.push(dbc::Row {
4651
values,
4752
columns: Arc::clone(&columns),
4853
});
4954
}
50-
Ok(dbc::QueryResult{
55+
Ok(dbc::QueryResult {
5156
rows,
57+
affected_rows,
5258
})
5359
}
5460
}
@@ -62,8 +68,12 @@ impl From<&mysql::Value> for dbc::Value {
6268
mysql::Value::UInt(uint) => dbc::Value::UInt(*uint),
6369
mysql::Value::Float(float) => dbc::Value::Float(*float),
6470
mysql::Value::Double(double) => dbc::Value::Double(*double),
65-
mysql::Value::Date(year, month, day, hour, minute, second, microsecond) => dbc::Value::Date(*year, *month, *day, *hour, *minute, *second, *microsecond),
66-
mysql::Value::Time(negative, days, hours, minutes, seconds, microseconds) => dbc::Value::Time(*negative, *days, *hours, *minutes, *seconds, *microseconds),
71+
mysql::Value::Date(year, month, day, hour, minute, second, microsecond) => {
72+
dbc::Value::Date(*year, *month, *day, *hour, *minute, *second, *microsecond)
73+
}
74+
mysql::Value::Time(negative, days, hours, minutes, seconds, microseconds) => {
75+
dbc::Value::Time(*negative, *days, *hours, *minutes, *seconds, *microseconds)
76+
}
6777
}
6878
}
6979
}
@@ -107,4 +117,4 @@ impl From<ColumnType> for dbc::ColumnType {
107117
}
108118
}
109119
}
110-
}
120+
}

src/dbc/sqlite.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,34 @@ impl SQLiteConnection {
1616
} else {
1717
connection = rusqlite::Connection::open(url)?;
1818
}
19-
Ok(Box::new(SQLiteConnection {
20-
connection,
21-
}) as Box<dyn dbc::Connection>)
19+
Ok(Box::new(SQLiteConnection { connection }) as Box<dyn dbc::Connection>)
2220
}
2321
}
2422

2523
impl dbc::Connection for SQLiteConnection {
2624
fn execute(&mut self, query: &str) -> Result<dbc::QueryResult, dbc::Error> {
2725
let mut statement = self.connection.prepare(query)?;
28-
let columns = statement.column_names().iter().map(
29-
|column| {
26+
let columns = statement
27+
.column_names()
28+
.iter()
29+
.map(|column| {
3030
dbc::Column {
3131
name: column.to_string(),
3232
column_type: dbc::ColumnType::STRING, // TODO: get column type
3333
}
34-
}
35-
).collect::<Vec<dbc::Column>>();
34+
})
35+
.collect::<Vec<dbc::Column>>();
3636
let columns = Arc::from(columns);
3737
let num_columns = statement.column_count();
3838

39+
if !query.starts_with("SELECT") {
40+
let affected_rows = statement.execute([])?;
41+
return Ok(dbc::QueryResult {
42+
rows: Vec::new(),
43+
affected_rows,
44+
});
45+
}
46+
3947
let mut rows: Vec<dbc::Row> = Vec::new();
4048
let mut result = statement.query([])?;
4149
while let Some(row) = result.next()? {
@@ -50,8 +58,10 @@ impl dbc::Connection for SQLiteConnection {
5058
columns: Arc::clone(&columns),
5159
});
5260
}
61+
let affected_rows = rows.len();
5362
Ok(dbc::QueryResult {
5463
rows,
64+
affected_rows,
5565
})
5666
}
5767
}

tests/mysql_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ async fn test_mysql_query_with_params_and_serialize() -> Result<(), Error> {
128128
// Select all rows from test_table
129129
let select_query = "SELECT * FROM test_table WHERE id = ?";
130130
let result = database.execute_query_with_params_and_serialize(select_query, &["1"])?;
131-
let expected_result = r#"{"rows":[{"values":[{"Bytes":[49]},{"Bytes":[117,112,100,97,116,101,100]}],"columns":[{"name":"id","column_type":"LONG"},{"name":"name","column_type":"STRING"}]}]}"#;
131+
let expected_result = r#"{"rows":[{"values":[{"Bytes":[49]},{"Bytes":[117,112,100,97,116,101,100]}],"columns":[{"name":"id","column_type":"LONG"},{"name":"name","column_type":"STRING"}]}],"affected_rows":0}"#;
132132
assert_eq!(result, expected_result);
133133

134134
// deserialize the result and verify the data

tests/sqlite_test.rs

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,87 @@ type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
55
#[tokio::test]
66
async fn test_sqlite_simple_query() -> Result<(), Error> {
77
let mut database = dbc::Database::new("sqlite://:memory:")?;
8-
let query = "SELECT 1";
9-
let result = database.execute_query(query)?;
10-
assert_eq!(result.rows.len(), 1);
118

12-
Ok(())
13-
}
9+
// Create a test table with two rows
10+
let create_table_query = "CREATE TABLE test_table (id INTEGER PRIMARY KEY, name TEXT NOT NULL)";
11+
database.execute_query(create_table_query)?;
12+
let insert_query = "INSERT INTO test_table (name) VALUES ('test1'), ('test2')";
13+
database.execute_query(insert_query)?;
1414

15-
#[tokio::test]
16-
async fn test_sqlite_query_with_params() -> Result<(), Error> {
17-
let mut database = dbc::Database::new("sqlite://:memory:")?;
18-
let query = "SELECT ? + ?";
19-
let result = database.execute_query_with_params(query, &["1", "2"])?;
15+
// Select all rows from test_table
16+
let select_query = "SELECT * FROM test_table";
17+
let result = database.execute_query(select_query)?;
18+
assert_eq!(result.rows.len(), 2);
19+
20+
// Verify the data returned by the query
21+
let first_row = &result.rows[0];
22+
let second_row = &result.rows[1];
23+
assert_eq!(
24+
first_row.get_value_by_name("name"),
25+
Some(&dbc::Value::Bytes("test1".to_owned().into_bytes()))
26+
);
27+
assert_eq!(
28+
second_row.get_value_by_name("name"),
29+
Some(&dbc::Value::Bytes("test2".to_owned().into_bytes()))
30+
);
31+
32+
// Update the name of the first row to "updated"
33+
let update_query = "UPDATE test_table SET name = ? WHERE id = ?";
34+
let result = database.execute_query_with_params(update_query, &["updated", "1"])?;
35+
assert_eq!(result.affected_rows, 1);
36+
37+
// Select the first row from test_table where the name is "updated"
38+
let select_query = "SELECT * FROM test_table WHERE name = ?";
39+
let result = database.execute_query_with_params(select_query, &["updated"])?;
2040
assert_eq!(result.rows.len(), 1);
2141

42+
// Verify the data returned by the query
43+
let first_row = &result.rows[0];
44+
assert_eq!(
45+
first_row.get_value_by_name("name"),
46+
Some(&dbc::Value::Bytes("updated".to_owned().into_bytes()))
47+
);
48+
2249
Ok(())
2350
}
2451

2552
#[tokio::test]
2653
async fn test_sqlite_query_with_params_and_serialize() -> Result<(), Error> {
2754
let mut database = dbc::Database::new("sqlite://:memory:")?;
28-
let query = "SELECT ? + ?";
29-
let result = database.execute_query_with_params_and_serialize(query, &["1", "2"])?;
30-
assert_eq!(result, r#"{"rows":[{"values":[{"Int":2}],"columns":[{"name":"1 + 1","column_type":"STRING"}]}]}"#); // currently all columns are STRING
55+
56+
// Create a test table with two rows
57+
let create_table_query = "CREATE TABLE test_table (id INTEGER PRIMARY KEY, name TEXT NOT NULL)";
58+
database.execute_query(create_table_query)?;
59+
let insert_query = "INSERT INTO test_table (name) VALUES ('test1'), ('test2')";
60+
database.execute_query(insert_query)?;
61+
62+
// Select all rows from test_table where the name is "test1"
63+
let select_query = "SELECT * FROM test_table WHERE name = ?";
64+
let result = database.execute_query_with_params_and_serialize(select_query, &["test1"])?;
65+
assert_eq!(
66+
result,
67+
r#"{"rows":[{"values":[{"Int":1},{"Bytes":[116,101,115,116,49]}],"columns":[{"name":"id","column_type":"STRING"},{"name":"name","column_type":"STRING"}]}],"affected_rows":1}"#
68+
); // Note: The column type is STRING because the column type is not known in the current implementation
69+
70+
// Update the name of the first row to "updated"
71+
let update_query = "UPDATE test_table SET name = ? WHERE id = ?";
72+
database.execute_query_with_params_and_serialize(update_query, &["updated", "1"])?;
73+
74+
// Select the first row from test_table where the id is 1
75+
let select_query = "SELECT * FROM test_table WHERE id = ?";
76+
let result = database.execute_query_with_params_and_serialize(select_query, &["1"])?;
77+
assert_eq!(
78+
result,
79+
r#"{"rows":[{"values":[{"Int":1},{"Bytes":[117,112,100,97,116,101,100]}],"columns":[{"name":"id","column_type":"STRING"},{"name":"name","column_type":"STRING"}]}],"affected_rows":1}"#
80+
);
81+
82+
// Deserialize the result and verify the data
83+
let result: dbc::QueryResult = serde_json::from_str(&result)?;
84+
let first_row = &result.rows[0];
85+
assert_eq!(
86+
first_row.get_value_by_name("name"),
87+
Some(&dbc::Value::Bytes("updated".to_owned().into_bytes()))
88+
);
3189

3290
Ok(())
33-
}
91+
}

0 commit comments

Comments
 (0)