feat(mysql): minimally implement Row and Column

This commit is contained in:
Ryan Leckey 2021-01-29 23:36:09 -08:00
parent a6c8cb02df
commit 4cbdac6884
No known key found for this signature in database
GPG Key ID: F8AA68C235AB08C9
7 changed files with 150 additions and 14 deletions

30
sqlx-mysql/src/column.rs Normal file
View File

@ -0,0 +1,30 @@
use bytestring::ByteString;
use sqlx_core::Column;
#[allow(clippy::module_name_repetitions)]
pub struct MySqlColumn {
ordinal: usize,
name: ByteString,
}
impl MySqlColumn {
pub fn name(&self) -> &str {
&self.name
}
pub const fn ordinal(&self) -> usize {
self.ordinal
}
}
impl Column for MySqlColumn {
#[inline]
fn name(&self) -> &str {
self.name()
}
#[inline]
fn ordinal(&self) -> usize {
self.ordinal()
}
}

View File

@ -1,13 +1,18 @@
use sqlx_core::{Database, HasOutput, Runtime};
use super::{MySqlConnection, MySqlRow, MySqlColumn, MySqlQueryResult};
#[derive(Debug)]
pub struct MySql;
impl<Rt> Database<Rt> for MySql
where
Rt: Runtime,
{
type Connection = super::MySqlConnection<Rt>;
impl<Rt: Runtime> Database<Rt> for MySql {
type Connection = MySqlConnection<Rt>;
type Row = MySqlRow;
type Column = MySqlColumn;
type QueryResult = MySqlQueryResult;
}
impl<'x> HasOutput<'x> for MySql {

View File

@ -24,6 +24,8 @@ mod stream;
mod connection;
mod database;
mod error;
mod column;
mod row;
mod io;
mod options;
mod query_result;
@ -33,6 +35,8 @@ mod protocol;
mod mock;
pub use query_result::MySqlQueryResult;
pub use column::MySqlColumn;
pub use row::MySqlRow;
pub use connection::MySqlConnection;
pub use database::MySql;
pub use error::MySqlDatabaseError;

View File

@ -1,13 +1,15 @@
use std::fmt::{self, Debug, Formatter};
use crate::protocol::OkPacket;
use sqlx_core::QueryResult;
use crate::protocol::{Info, OkPacket, Status};
/// Represents the execution result of an operation on the database server.
///
/// Returned from [`execute()`][sqlx_core::Executor::execute].
///
#[allow(clippy::module_name_repetitions)]
pub struct MySqlQueryResult(OkPacket);
pub struct MySqlQueryResult(pub(crate) OkPacket);
impl MySqlQueryResult {
/// Returns the number of rows changed, deleted, or inserted by the statement
@ -25,8 +27,8 @@ impl MySqlQueryResult {
/// Return the number of rows matched by the `UPDATE` statement.
///
/// This is in contrast to [`rows_affected()`] which will return the number
/// of rows actually changed by the `UPDATE statement.
/// This is in contrast to [`rows_affected()`](#method.rows_affected) which will return the number
/// of rows actually changed by the `UPDATE` statement.
///
/// Returns `0` for all other statements.
///
@ -39,7 +41,7 @@ impl MySqlQueryResult {
/// or `ALTER TABLE` statement.
///
/// For multi-row `INSERT`, this is not necessarily the number of rows actually
/// inserted because [`duplicates()`] can be non-zero.
/// inserted because [`duplicates()`](#method.duplicates) can be non-zero.
///
/// For `ALTER TABLE`, this is the number of rows that were copied while
/// making alterations.
@ -107,6 +109,45 @@ impl Debug for MySqlQueryResult {
}
}
impl Default for MySqlQueryResult {
fn default() -> Self {
Self(OkPacket {
affected_rows: 0,
last_insert_id: 0,
status: Status::empty(),
warnings: 0,
info: Info::default(),
})
}
}
impl From<OkPacket> for MySqlQueryResult {
fn from(ok: OkPacket) -> Self {
Self(ok)
}
}
impl Extend<MySqlQueryResult> for MySqlQueryResult {
fn extend<T: IntoIterator<Item = MySqlQueryResult>>(&mut self, iter: T) {
for res in iter {
self.0.affected_rows += res.0.affected_rows;
self.0.warnings += res.0.warnings;
self.0.info.records += res.0.info.records;
self.0.info.duplicates += res.0.info.duplicates;
self.0.info.matched += res.0.info.matched;
self.0.last_insert_id = res.0.last_insert_id;
self.0.status = res.0.status;
}
}
}
impl QueryResult for MySqlQueryResult {
#[inline]
fn rows_affected(&self) -> u64 {
self.rows_affected()
}
}
#[cfg(test)]
mod tests {
use bytes::Bytes;
@ -134,7 +175,8 @@ mod tests {
#[test]
fn insert_5() -> anyhow::Result<()> {
let packet = Bytes::from(&b"\0\x05\x02\x02\0\0\0&Records: 5 Duplicates: 0 Warnings: 0"[..]);
let packet =
Bytes::from(&b"\0\x05\x02\x02\0\0\0&Records: 5 Duplicates: 0 Warnings: 0"[..]);
let ok = OkPacket::deserialize_with(packet, *CAPABILITIES)?;
let res = MySqlQueryResult(ok);
@ -148,7 +190,8 @@ mod tests {
#[test]
fn insert_5_or_update_3() -> anyhow::Result<()> {
let packet = Bytes::from(&b"\0\x08\x07\x02\0\0\0&Records: 5 Duplicates: 3 Warnings: 0"[..]);
let packet =
Bytes::from(&b"\0\x08\x07\x02\0\0\0&Records: 5 Duplicates: 3 Warnings: 0"[..]);
let ok = OkPacket::deserialize_with(packet, *CAPABILITIES)?;
let res = MySqlQueryResult(ok);

48
sqlx-mysql/src/row.rs Normal file
View File

@ -0,0 +1,48 @@
use sqlx_core::Row;
use crate::{protocol, MySqlColumn};
#[allow(clippy::module_name_repetitions)]
pub struct MySqlRow(pub(crate) protocol::Row);
impl MySqlRow {
pub fn len(&self) -> usize {
self.0.values.len()
}
}
impl Row for MySqlRow {
type Column = MySqlColumn;
fn is_null(&self) -> bool {
todo!()
}
fn len(&self) -> usize {
self.len()
}
fn columns(&self) -> &[MySqlColumn] {
todo!()
}
fn column_name_of(&self, ordinal: usize) -> &str {
todo!()
}
fn try_column_name_of(&self, ordinal: usize) -> sqlx_core::Result<&str> {
todo!()
}
fn ordinal_of(&self, name: &str) -> usize {
todo!()
}
fn try_ordinal_of(&self, name: &str) -> sqlx_core::Result<usize> {
todo!()
}
fn try_get_raw(&self) -> sqlx_core::Result<&[u8]> {
todo!()
}
}

View File

@ -10,11 +10,13 @@ mod options;
#[cfg(feature = "blocking")]
mod blocking;
//
// these types are wrapped instead of re-exported
// this is to provide runtime-specialized inherent methods by taking advantage
// of through crate-local negative reasoning
pub use connection::MySqlConnection;
pub use database::MySql;
pub use options::MySqlConnectOptions;
//
// re-export the remaining types from the driver
pub use sqlx_mysql::{MySqlColumn, MySqlDatabaseError, MySqlQueryResult, MySqlRow};

View File

@ -1,4 +1,5 @@
use sqlx_core::HasOutput;
use sqlx_mysql::{MySqlColumn, MySqlQueryResult, MySqlRow};
use super::MySqlConnection;
use crate::{Database, Runtime};
@ -8,6 +9,9 @@ pub struct MySql;
impl<Rt: Runtime> Database<Rt> for MySql {
type Connection = MySqlConnection<Rt>;
type Column = MySqlColumn;
type Row = MySqlRow;
type QueryResult = MySqlQueryResult;
}
impl<'x> HasOutput<'x> for MySql {