diff --git a/Cargo.toml b/Cargo.toml index 6d61d819d..2cea433d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,7 +90,7 @@ required-features = [ "sqlite" ] [[test]] name = "sqlite-macros" -required-features = [ "sqlite" ] +required-features = [ "sqlite", "macros" ] [[test]] name = "sqlite-raw" diff --git a/sqlx-core/src/sqlite/database.rs b/sqlx-core/src/sqlite/database.rs index a6896a515..a9eb6e5e5 100644 --- a/sqlx-core/src/sqlite/database.rs +++ b/sqlx-core/src/sqlite/database.rs @@ -1,20 +1,27 @@ -use crate::database::{Database, HasCursor, HasRawValue, HasRow}; +use crate::cursor::HasCursor; +use crate::database::Database; +use crate::row::HasRow; use crate::sqlite::error::SqliteError; +use crate::sqlite::{ + SqliteArgumentValue, SqliteArguments, SqliteConnection, SqliteCursor, SqliteRow, + SqliteTypeInfo, SqliteValue, +}; +use crate::value::HasRawValue; /// **Sqlite** database driver. #[derive(Debug)] pub struct Sqlite; impl Database for Sqlite { - type Connection = super::SqliteConnection; + type Connection = SqliteConnection; - type Arguments = super::SqliteArguments; + type Arguments = SqliteArguments; - type TypeInfo = super::SqliteTypeInfo; + type TypeInfo = SqliteTypeInfo; type TableId = String; - type RawBuffer = Vec; + type RawBuffer = Vec; type Error = SqliteError; } @@ -22,15 +29,17 @@ impl Database for Sqlite { impl<'c> HasRow<'c> for Sqlite { type Database = Sqlite; - type Row = super::SqliteRow<'c>; + type Row = SqliteRow<'c>; } impl<'c, 'q> HasCursor<'c, 'q> for Sqlite { type Database = Sqlite; - type Cursor = super::SqliteCursor<'c, 'q>; + type Cursor = SqliteCursor<'c, 'q>; } impl<'c> HasRawValue<'c> for Sqlite { - type RawValue = super::SqliteValue<'c>; + type Database = Sqlite; + + type RawValue = SqliteValue<'c>; } diff --git a/sqlx-core/src/sqlite/types/mod.rs b/sqlx-core/src/sqlite/types/mod.rs index d32fcabff..7f6a37f08 100644 --- a/sqlx-core/src/sqlite/types/mod.rs +++ b/sqlx-core/src/sqlite/types/mod.rs @@ -35,6 +35,7 @@ mod str; // https://www.sqlite.org/c3ref/c_blob.html #[derive(Debug, PartialEq, Clone, Copy)] pub(crate) enum SqliteType { + Null = 0, Integer = 1, Float = 2, Text = 3, @@ -77,13 +78,16 @@ impl Display for SqliteTypeInfo { SqliteType::Integer => "INTEGER", SqliteType::Float => "DOUBLE", SqliteType::Blob => "BLOB", + SqliteType::Null => "NULL", }) } } impl TypeInfo for SqliteTypeInfo { - fn compatible(&self, other: &Self) -> bool { - self.r#type == other.r#type || self.affinity == other.affinity + #[inline] + fn compatible(&self, _other: &Self) -> bool { + // All types are compatible with all other types in SQLite + true } } diff --git a/sqlx-core/src/sqlite/value.rs b/sqlx-core/src/sqlite/value.rs index 09be2618e..9357fb9a8 100644 --- a/sqlx-core/src/sqlite/value.rs +++ b/sqlx-core/src/sqlite/value.rs @@ -5,10 +5,14 @@ use std::str::from_utf8_unchecked; use libsqlite3_sys::{ sqlite3_column_blob, sqlite3_column_bytes, sqlite3_column_double, sqlite3_column_int, - sqlite3_column_int64, sqlite3_column_text, sqlite3_column_type, SQLITE_NULL, + sqlite3_column_int64, sqlite3_column_text, sqlite3_column_type, SQLITE_BLOB, SQLITE_FLOAT, + SQLITE_INTEGER, SQLITE_NULL, SQLITE_TEXT, }; use crate::sqlite::statement::Statement; +use crate::sqlite::types::SqliteType; +use crate::sqlite::{Sqlite, SqliteTypeInfo}; +use crate::value::RawValue; pub struct SqliteValue<'c> { pub(super) index: i32, @@ -23,9 +27,23 @@ pub struct SqliteValue<'c> { impl<'c> SqliteValue<'c> { /// Returns true if the value should be intrepreted as NULL. pub(super) fn is_null(&self) -> bool { + self.r#type() == SqliteType::Null + } + + fn r#type(&self) -> SqliteType { #[allow(unsafe_code)] let type_code = unsafe { sqlite3_column_type(self.statement.handle(), self.index) }; - type_code == SQLITE_NULL + + // SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL + match type_code { + SQLITE_INTEGER => SqliteType::Integer, + SQLITE_FLOAT => SqliteType::Float, + SQLITE_TEXT => SqliteType::Text, + SQLITE_BLOB => SqliteType::Blob, + SQLITE_NULL => SqliteType::Null, + + _ => unreachable!("received unexpected column type: {}", type_code), + } } /// Returns the 32-bit INTEGER result. @@ -89,3 +107,14 @@ impl<'c> SqliteValue<'c> { } } } + +impl<'c> RawValue<'c> for SqliteValue<'c> { + type Database = Sqlite; + + fn type_info(&self) -> SqliteTypeInfo { + SqliteTypeInfo { + r#type: self.r#type(), + affinity: None, + } + } +}