diff --git a/Cargo.toml b/Cargo.toml index a5f2e6e2..d807c9f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,9 +24,7 @@ byteorder = { version = "1.3.2", default-features = false } bytes = "0.4.12" crossbeam-queue = "0.1.2" crossbeam-utils = { version = "0.6.6", default-features = false } -# enum-tryfrom = "0.2.1" -# enum-tryfrom-derive = "0.2.1" -# failure = "0.1.5" +failure = "0.1.5" futures-util-preview = "=0.3.0-alpha.18" futures-channel-preview = "=0.3.0-alpha.18" futures-core-preview = "=0.3.0-alpha.18" diff --git a/src/mariadb/protocol/encode.rs b/src/mariadb/protocol/encode.rs index 6ff59a32..96275667 100644 --- a/src/mariadb/protocol/encode.rs +++ b/src/mariadb/protocol/encode.rs @@ -111,7 +111,7 @@ pub trait BufMut { fn put_byte_eof(&mut self, bytes: &Bytes); #[inline] - fn put_param(&mut self, bytes: &Bytes, ty: &FieldType); + fn put_param(&mut self, bytes: &Bytes, ty: FieldType); } impl BufMut for Vec { @@ -328,39 +328,40 @@ impl BufMut for Vec { } #[inline] - fn put_param(&mut self, bytes: &Bytes, ty: &FieldType) { + fn put_param(&mut self, bytes: &Bytes, ty: FieldType) { match ty { - FieldType::MysqlTypeDecimal => self.put_string_lenenc(bytes), - FieldType::MysqlTypeTiny => self.put_int_1(bytes), - FieldType::MysqlTypeShort => self.put_int_2(bytes), - FieldType::MysqlTypeLong => self.put_int_4(bytes), - FieldType::MysqlTypeFloat => self.put_int_4(bytes), - FieldType::MysqlTypeDouble => self.put_int_8(bytes), - FieldType::MysqlTypeNull => panic!("Type cannot be FieldType::MysqlTypeNull"), - FieldType::MysqlTypeTimestamp => unimplemented!(), - FieldType::MysqlTypeLonglong => self.put_int_8(bytes), - FieldType::MysqlTypeInt24 => self.put_int_4(bytes), - FieldType::MysqlTypeDate => unimplemented!(), - FieldType::MysqlTypeTime => unimplemented!(), - FieldType::MysqlTypeDatetime => unimplemented!(), - FieldType::MysqlTypeYear => self.put_int_4(bytes), - FieldType::MysqlTypeNewdate => unimplemented!(), - FieldType::MysqlTypeVarchar => self.put_string_lenenc(bytes), - FieldType::MysqlTypeBit => self.put_string_lenenc(bytes), - FieldType::MysqlTypeTimestamp2 => unimplemented!(), - FieldType::MysqlTypeDatetime2 => unimplemented!(), - FieldType::MysqlTypeTime2 => unimplemented!(), - FieldType::MysqlTypeJson => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeNewdecimal => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeEnum => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeSet => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeTinyBlob => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeMediumBlob => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeLongBlob => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeBlob => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeVarString => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeString => self.put_byte_lenenc(bytes), - FieldType::MysqlTypeGeometry => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_DECIMAL => self.put_string_lenenc(bytes), + FieldType::MYSQL_TYPE_TINY => self.put_int_1(bytes), + FieldType::MYSQL_TYPE_SHORT => self.put_int_2(bytes), + FieldType::MYSQL_TYPE_LONG => self.put_int_4(bytes), + FieldType::MYSQL_TYPE_FLOAT => self.put_int_4(bytes), + FieldType::MYSQL_TYPE_DOUBLE => self.put_int_8(bytes), + FieldType::MYSQL_TYPE_NULL => panic!("Type cannot be FieldType::MysqlTypeNull"), + FieldType::MYSQL_TYPE_TIMESTAMP => unimplemented!(), + FieldType::MYSQL_TYPE_LONGLONG => self.put_int_8(bytes), + FieldType::MYSQL_TYPE_INT24 => self.put_int_4(bytes), + FieldType::MYSQL_TYPE_DATE => unimplemented!(), + FieldType::MYSQL_TYPE_TIME => unimplemented!(), + FieldType::MYSQL_TYPE_DATETIME => unimplemented!(), + FieldType::MYSQL_TYPE_YEAR => self.put_int_4(bytes), + FieldType::MYSQL_TYPE_NEWDATE => unimplemented!(), + FieldType::MYSQL_TYPE_VARCHAR => self.put_string_lenenc(bytes), + FieldType::MYSQL_TYPE_BIT => self.put_string_lenenc(bytes), + FieldType::MYSQL_TYPE_TIMESTAMP2 => unimplemented!(), + FieldType::MYSQL_TYPE_DATETIME2 => unimplemented!(), + FieldType::MYSQL_TYPE_TIME2 => unimplemented!(), + FieldType::MYSQL_TYPE_JSON => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_NEWDECIMAL => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_ENUM => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_SET => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_TINY_BLOB => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_MEDIUM_BLOB => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_LONG_BLOB => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_BLOB => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_VAR_STRING => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_STRING => self.put_byte_lenenc(bytes), + FieldType::MYSQL_TYPE_GEOMETRY => self.put_byte_lenenc(bytes), + _ => panic!("Unrecognized field type"), } } } diff --git a/src/mariadb/protocol/packets/binary/com_stmt_exec.rs b/src/mariadb/protocol/packets/binary/com_stmt_exec.rs index f3f26162..2f2385da 100644 --- a/src/mariadb/protocol/packets/binary/com_stmt_exec.rs +++ b/src/mariadb/protocol/packets/binary/com_stmt_exec.rs @@ -20,7 +20,7 @@ impl Encode for ComStmtExec { buf.put_int_u8(super::BinaryProtocol::ComStmtExec.into()); buf.put_int_i32(self.stmt_id); - buf.put_int_u8(self.flags as u8); + buf.put_int_u8(self.flags.0); buf.put_int_u32(1); match (&self.params, &self.param_defs) { @@ -49,7 +49,7 @@ impl Encode for ComStmtExec { if send_type > 0 { for param in param_defs { - buf.put_int_u8(param.field_type as u8); + buf.put_int_u8(param.field_type.0); buf.put_int_u8(0); } } @@ -94,7 +94,7 @@ mod tests { length_of_fixed_fields: Some(0x0Cu64), char_set: 1, max_columns: 1, - field_type: FieldType::MysqlTypeString, + field_type: FieldType::MYSQL_TYPE_STRING, field_details: FieldDetailFlag::NOT_NULL, decimals: 0, }]), diff --git a/src/mariadb/protocol/packets/binary/result_row.rs b/src/mariadb/protocol/packets/binary/result_row.rs index 0bf40a22..a43add17 100644 --- a/src/mariadb/protocol/packets/binary/result_row.rs +++ b/src/mariadb/protocol/packets/binary/result_row.rs @@ -35,70 +35,71 @@ impl crate::mariadb::Decode for ResultRow { } else { match column_defs[index].field_type { // Ordered by https://mariadb.com/kb/en/library/resultset-row/#binary-resultset-row - FieldType::MysqlTypeDouble => Some(decoder.decode_binary_double()), - FieldType::MysqlTypeLonglong => { + FieldType::MYSQL_TYPE_DOUBLE => Some(decoder.decode_binary_double()), + FieldType::MYSQL_TYPE_LONGLONG => { Some(decoder.decode_binary_bigint()) } // Is this MYSQL_TYPE_INTEGER? - FieldType::MysqlTypeLong => Some(decoder.decode_binary_int()), + FieldType::MYSQL_TYPE_LONG => Some(decoder.decode_binary_int()), // Is this MYSQL_TYPE_MEDIUMINTEGER? - FieldType::MysqlTypeInt24 => { + FieldType::MYSQL_TYPE_INT24 => { Some(decoder.decode_binary_mediumint()) } - FieldType::MysqlTypeFloat => Some(decoder.decode_binary_float()), + FieldType::MYSQL_TYPE_FLOAT => Some(decoder.decode_binary_float()), // Is this MYSQL_TYPE_SMALLINT? - FieldType::MysqlTypeShort => Some(decoder.decode_binary_smallint()), + FieldType::MYSQL_TYPE_SHORT => Some(decoder.decode_binary_smallint()), - FieldType::MysqlTypeYear => Some(decoder.decode_binary_year()), - FieldType::MysqlTypeTiny => Some(decoder.decode_binary_tinyint()), - FieldType::MysqlTypeDate => Some(decoder.decode_binary_date()), - FieldType::MysqlTypeTimestamp => { + FieldType::MYSQL_TYPE_YEAR => Some(decoder.decode_binary_year()), + FieldType::MYSQL_TYPE_TINY => Some(decoder.decode_binary_tinyint()), + FieldType::MYSQL_TYPE_DATE => Some(decoder.decode_binary_date()), + FieldType::MYSQL_TYPE_TIMESTAMP => { Some(decoder.decode_binary_timestamp()) } - FieldType::MysqlTypeDatetime => { + FieldType::MYSQL_TYPE_DATETIME => { Some(decoder.decode_binary_datetime()) } - FieldType::MysqlTypeTime => Some(decoder.decode_binary_time()), - FieldType::MysqlTypeNewdecimal => { + FieldType::MYSQL_TYPE_TIME => Some(decoder.decode_binary_time()), + FieldType::MYSQL_TYPE_NEWDECIMAL => { Some(decoder.decode_binary_decimal()) } // This group of types are all encoded as byte - FieldType::MysqlTypeTinyBlob => Some(decoder.decode_byte_lenenc()), - FieldType::MysqlTypeMediumBlob => { + FieldType::MYSQL_TYPE_TINY_BLOB => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_MEDIUM_BLOB => { Some(decoder.decode_byte_lenenc()) } - FieldType::MysqlTypeLongBlob => Some(decoder.decode_byte_lenenc()), - FieldType::MysqlTypeBlob => Some(decoder.decode_byte_lenenc()), - FieldType::MysqlTypeVarchar => Some(decoder.decode_byte_lenenc()), - FieldType::MysqlTypeVarString => Some(decoder.decode_byte_lenenc()), - FieldType::MysqlTypeString => Some(decoder.decode_byte_lenenc()), - FieldType::MysqlTypeGeometry => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_LONG_BLOB => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_BLOB => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_VARCHAR => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_VAR_STRING => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_STRING => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_GEOMETRY => Some(decoder.decode_byte_lenenc()), // The following did not have defined binary encoding, so I guessed. // Perhaps you cannot get these types back from the server if you're using // prepared statements? In that case we should error out here instead of // proceeding to decode. - FieldType::MysqlTypeDecimal => { + FieldType::MYSQL_TYPE_DECIMAL => { Some(decoder.decode_binary_decimal()) } - FieldType::MysqlTypeNull => panic!("Cannot decode MysqlTypeNull"), - FieldType::MysqlTypeNewdate => Some(decoder.decode_binary_date()), - FieldType::MysqlTypeBit => Some(decoder.decode_byte_fix(1)), - FieldType::MysqlTypeTimestamp2 => { + FieldType::MYSQL_TYPE_NULL => panic!("Cannot decode MysqlTypeNull"), + FieldType::MYSQL_TYPE_NEWDATE => Some(decoder.decode_binary_date()), + FieldType::MYSQL_TYPE_BIT => Some(decoder.decode_byte_fix(1)), + FieldType::MYSQL_TYPE_TIMESTAMP2 => { Some(decoder.decode_binary_timestamp()) } - FieldType::MysqlTypeDatetime2 => { + FieldType::MYSQL_TYPE_DATETIME2 => { Some(decoder.decode_binary_datetime()) } - FieldType::MysqlTypeTime2 => Some(decoder.decode_binary_time()), - FieldType::MysqlTypeJson => Some(decoder.decode_byte_lenenc()), - FieldType::MysqlTypeEnum => Some(decoder.decode_byte_lenenc()), - FieldType::MysqlTypeSet => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_TIME2 => Some(decoder.decode_binary_time()), + FieldType::MYSQL_TYPE_JSON => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_ENUM => Some(decoder.decode_byte_lenenc()), + FieldType::MYSQL_TYPE_SET => Some(decoder.decode_byte_lenenc()), + _ => panic!("Unrecognized FieldType received from MaraiDB"), } } }) diff --git a/src/mariadb/protocol/packets/column_def.rs b/src/mariadb/protocol/packets/column_def.rs index 4c150489..1c14e70f 100644 --- a/src/mariadb/protocol/packets/column_def.rs +++ b/src/mariadb/protocol/packets/column_def.rs @@ -46,7 +46,7 @@ impl Decode for ColumnDefPacket { // int<4> max. column size let max_columns = decoder.decode_int_i32(); // int<1> Field types - let field_type = FieldType::try_from(decoder.decode_int_u8())?; + let field_type = FieldType(decoder.decode_int_u8()); // int<2> Field detail flag let field_details = FieldDetailFlag::from_bits_truncate(decoder.decode_int_u16()); // int<1> decimals diff --git a/src/mariadb/protocol/types.rs b/src/mariadb/protocol/types.rs index 750cb408..5cc14a34 100644 --- a/src/mariadb/protocol/types.rs +++ b/src/mariadb/protocol/types.rs @@ -1,5 +1,3 @@ -use std::convert::TryFrom; - pub enum ProtocolType { Text, Binary, @@ -80,55 +78,56 @@ pub enum SessionChangeType { SessionTrackTransactionState = 5, } -#[derive(Clone, Copy, Debug, PartialEq, TryFromPrimitive)] -#[TryFromPrimitiveType = "u8"] -pub enum FieldType { - MysqlTypeDecimal = 0, - MysqlTypeTiny = 1, - MysqlTypeShort = 2, - MysqlTypeLong = 3, - MysqlTypeFloat = 4, - MysqlTypeDouble = 5, - MysqlTypeNull = 6, - MysqlTypeTimestamp = 7, - MysqlTypeLonglong = 8, - MysqlTypeInt24 = 9, - MysqlTypeDate = 10, - MysqlTypeTime = 11, - MysqlTypeDatetime = 12, - MysqlTypeYear = 13, - MysqlTypeNewdate = 14, - MysqlTypeVarchar = 15, - MysqlTypeBit = 16, - MysqlTypeTimestamp2 = 17, - MysqlTypeDatetime2 = 18, - MysqlTypeTime2 = 19, - MysqlTypeJson = 245, - MysqlTypeNewdecimal = 246, - MysqlTypeEnum = 247, - MysqlTypeSet = 248, - MysqlTypeTinyBlob = 249, - MysqlTypeMediumBlob = 250, - MysqlTypeLongBlob = 251, - MysqlTypeBlob = 252, - MysqlTypeVarString = 253, - MysqlTypeString = 254, - MysqlTypeGeometry = 255, +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct FieldType(pub u8); +impl FieldType { + pub const MYSQL_TYPE_DECIMAL: FieldType = FieldType(0); + pub const MYSQL_TYPE_TINY: FieldType = FieldType(1); + pub const MYSQL_TYPE_SHORT: FieldType = FieldType(2); + pub const MYSQL_TYPE_LONG: FieldType = FieldType(3); + pub const MYSQL_TYPE_FLOAT: FieldType = FieldType(4); + pub const MYSQL_TYPE_DOUBLE: FieldType = FieldType(5); + pub const MYSQL_TYPE_NULL: FieldType = FieldType(6); + pub const MYSQL_TYPE_TIMESTAMP: FieldType = FieldType(7); + pub const MYSQL_TYPE_LONGLONG: FieldType = FieldType(8); + pub const MYSQL_TYPE_INT24: FieldType = FieldType(9); + pub const MYSQL_TYPE_DATE: FieldType = FieldType(10); + pub const MYSQL_TYPE_TIME: FieldType = FieldType(11); + pub const MYSQL_TYPE_DATETIME: FieldType = FieldType(12); + pub const MYSQL_TYPE_YEAR: FieldType = FieldType(13); + pub const MYSQL_TYPE_NEWDATE: FieldType = FieldType(14); + pub const MYSQL_TYPE_VARCHAR: FieldType = FieldType(15); + pub const MYSQL_TYPE_BIT: FieldType = FieldType(16); + pub const MYSQL_TYPE_TIMESTAMP2: FieldType = FieldType(17); + pub const MYSQL_TYPE_DATETIME2: FieldType = FieldType(18); + pub const MYSQL_TYPE_TIME2: FieldType = FieldType(19); + pub const MYSQL_TYPE_JSON: FieldType = FieldType(245); + pub const MYSQL_TYPE_NEWDECIMAL: FieldType = FieldType(246); + pub const MYSQL_TYPE_ENUM: FieldType = FieldType(247); + pub const MYSQL_TYPE_SET: FieldType = FieldType(248); + pub const MYSQL_TYPE_TINY_BLOB: FieldType = FieldType(249); + pub const MYSQL_TYPE_MEDIUM_BLOB: FieldType = FieldType(250); + pub const MYSQL_TYPE_LONG_BLOB: FieldType = FieldType(251); + pub const MYSQL_TYPE_BLOB: FieldType = FieldType(252); + pub const MYSQL_TYPE_VAR_STRING: FieldType = FieldType(253); + pub const MYSQL_TYPE_STRING: FieldType = FieldType(254); + pub const MYSQL_TYPE_GEOMETRY: FieldType = FieldType(255); } -#[derive(Clone, Copy, Debug, PartialEq, TryFromPrimitive)] -#[TryFromPrimitiveType = "u8"] -pub enum StmtExecFlag { - NoCursor = 0, - ReadOnly = 1, - CursorForUpdate = 2, - ScrollableCursor = 3, +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct StmtExecFlag(pub u8); +impl StmtExecFlag { + pub const NO_CURSOR: StmtExecFlag = StmtExecFlag(0); + pub const READ_ONLY: StmtExecFlag = StmtExecFlag(1); + pub const CURSOR_FOR_UPDATE: StmtExecFlag = StmtExecFlag(2); + pub const SCROLLABLE_CURSOR: StmtExecFlag = StmtExecFlag(3); } -#[derive(Clone, Copy, Debug, PartialEq, TryFromPrimitive)] -#[TryFromPrimitiveType = "u8"] -pub enum ParamFlag { - Unsigned = 128, +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct ParamFlag(pub u8); +impl ParamFlag { + pub const NONE: ParamFlag = ParamFlag(0); + pub const UNSIGNED: ParamFlag = ParamFlag(128); } impl Default for Capabilities { @@ -151,19 +150,19 @@ impl Default for FieldDetailFlag { impl Default for FieldType { fn default() -> Self { - FieldType::MysqlTypeDecimal + FieldType::MYSQL_TYPE_DECIMAL } } impl Default for StmtExecFlag { fn default() -> Self { - StmtExecFlag::NoCursor + StmtExecFlag::NO_CURSOR } } impl Default for ParamFlag { fn default() -> Self { - ParamFlag::Unsigned + ParamFlag::UNSIGNED } }