#![cfg(any(feature = "rusqlite", feature = "turso", feature = "libsql"))]
#![allow(clippy::approx_constant)]
use drizzle::sqlite::prelude::*;
#[derive(SQLiteFromRow, Debug, PartialEq)]
struct AllDataTypes {
id: i32,
name: String,
age: i64,
score: f64,
active: bool,
data: Vec<u8>,
}
#[derive(SQLiteFromRow, Debug, PartialEq)]
struct IntegerTypes {
id: i32,
big_num: i64,
small_num: i16,
tiny_num: i8,
}
#[derive(SQLiteFromRow, Debug, PartialEq)]
struct FloatTypes {
id: i32,
precise: f64,
compact: f32,
}
#[SQLiteTable]
struct TypeTest {
#[column(PRIMARY)]
id: i32,
name: String,
age: i64,
score: f64,
active: bool,
data: Vec<u8>,
}
#[SQLiteTable]
struct IntegerTest {
#[column(PRIMARY)]
id: i32,
big_num: i64,
small_num: i16,
tiny_num: i8,
}
#[SQLiteTable]
struct FloatTest {
#[column(PRIMARY)]
id: i32,
precise: f64,
compact: f32,
}
#[derive(SQLiteSchema)]
pub struct TypeTestSchema {
type_test: TypeTest,
}
#[drizzle::test]
fn test_fromrow_with_all_data_types(db: &mut TestDb<TypeTestSchema>) {
let TypeTestSchema { type_test } = schema;
let test_data = InsertTypeTest::new("test_user", 25, 98.5, true, [1, 2, 3, 4, 5]);
db.insert(type_test).values([test_data]).execute();
let result: AllDataTypes = db.select(()).from(type_test).get().expect("a row");
let expected = AllDataTypes {
id: 1,
name: "test_user".to_string(),
age: 25,
score: 98.5,
active: true,
data: vec![1, 2, 3, 4, 5],
};
assert_eq!(result, expected);
}
#[derive(SQLiteSchema)]
struct IntegerSchema {
integer_test: IntegerTest,
}
#[drizzle::test]
fn test_fromrow_with_integer_sizes(db: &mut TestDb<IntegerSchema>) {
let IntegerSchema { integer_test } = schema;
let test_data = InsertIntegerTest::new(9223372036854775806i64, 32000i16, 100i8);
db.insert(integer_test).values([test_data]).execute();
let result: IntegerTypes = db.select(()).from(integer_test).get().expect("a row");
let expected = IntegerTypes {
id: 1,
big_num: 9223372036854775806i64,
small_num: 32000i16,
tiny_num: 100i8,
};
assert_eq!(result, expected);
}
#[derive(SQLiteSchema)]
struct FloatSchema {
float_test: FloatTest,
}
#[drizzle::test]
fn test_fromrow_with_float_types(db: &mut TestDb<FloatSchema>) {
let FloatSchema { float_test } = schema;
let test_data = InsertFloatTest::new(3.141592653589793, 2.718f32);
db.insert(float_test).values([test_data]).execute();
let result: FloatTypes = db.select(()).from(float_test).get().expect("a row");
let expected = FloatTypes {
id: 1,
precise: 3.141592653589793,
compact: 2.718f32,
};
assert_eq!(result, expected);
}
#[drizzle::test]
fn test_fromrow_type_conversion_edge_cases(db: &mut TestDb<TypeTestSchema>) {
let TypeTestSchema { type_test } = schema;
let test_data = InsertTypeTest::new("edge_case", 0, 0.0, false, []);
db.insert(type_test).values([test_data]).execute();
let result: AllDataTypes = db.select(()).from(type_test).get().expect("a row");
let expected = AllDataTypes {
id: 1,
name: "edge_case".to_string(),
age: 0,
score: 0.0,
active: false,
data: vec![],
};
assert_eq!(result, expected);
}
#[derive(SQLiteFromRow, Debug, Default)]
#[from(TypeTest)]
struct DerivedPartialSimple {
name: String,
}
#[derive(SQLiteFromRow, Debug, Default)]
#[from(TypeTest)]
struct DerivedSimpleWithColumns {
#[column(TypeTest::id)]
table_id: i32,
#[column(TypeTest::name)]
table_name: String,
}
#[drizzle::test]
fn test_fromrow_derive_with_partial_selection(db: &mut TestDb<TypeTestSchema>) {
let TypeTestSchema { type_test } = schema;
let test_data = InsertTypeTest::new("derive_test", 25, 98.5, true, [1, 2, 3]);
db.insert(type_test).values([test_data]).execute();
let result: DerivedPartialSimple = db
.select(DerivedPartialSimple::Select)
.from(type_test)
.get()
.expect("a row");
assert_eq!(result.name, "derive_test");
}
#[drizzle::test]
fn test_fromrow_with_column_mapping(db: &mut TestDb<TypeTestSchema>) {
let TypeTestSchema { type_test } = schema;
let test_data = InsertTypeTest::new("column_test", 25, 98.5, true, [1, 2, 3]).with_id(42);
db.insert(type_test).values([test_data]).execute();
let result: DerivedSimpleWithColumns = db
.select(DerivedSimpleWithColumns::Select)
.from(type_test)
.get()
.expect("a row");
assert_eq!(result.table_id, 42);
assert_eq!(result.table_name, "column_test");
}
#[drizzle::test]
fn test_insert_returning_select_target_infers_row(db: &mut TestDb<TypeTestSchema>) {
let TypeTestSchema { type_test } = schema;
let stmt = db
.insert(type_test)
.values([InsertTypeTest::new(
"returning_test",
30,
88.0,
true,
[1, 2, 3],
)])
.returning(DerivedPartialSimple::Select);
let result: DerivedPartialSimple = stmt.get().expect("a row");
assert_eq!(result.name, "returning_test");
}
#[derive(SQLiteFromRow, Debug, PartialEq)]
struct NamedNameId {
id: i32,
name: String,
}
#[derive(SQLiteFromRow, Debug, PartialEq)]
struct TupleNameId(String, i32);
#[drizzle::test]
fn test_fromrow_named_struct_maps_by_name(db: &mut TestDb<TypeTestSchema>) {
if __driver_name == "turso" {
return Ok(());
}
let TypeTestSchema { type_test } = schema;
let row = InsertTypeTest::new("order_test", 25, 98.5, true, [1, 2, 3]).with_id(42);
db.insert(type_test).values([row]).execute();
let stmt = db.select((type_test.id, type_test.name)).from(type_test);
let result: NamedNameId = stmt.get().expect("a row");
assert_eq!(result.id, 42);
assert_eq!(result.name, "order_test");
}
#[drizzle::test]
fn test_fromrow_tuple_struct_maps_by_index(db: &mut TestDb<TypeTestSchema>) {
let TypeTestSchema { type_test } = schema;
let row = InsertTypeTest::new("order_test", 25, 98.5, true, [1, 2, 3]).with_id(42);
db.insert(type_test).values([row]).execute();
let stmt = db.select((type_test.name, type_test.id)).from(type_test);
let result: TupleNameId = stmt.get().expect("a row");
assert_eq!(result.0, "order_test");
assert_eq!(result.1, 42);
}
#[SQLiteTable(NAME = "fromrow_left")]
struct FromRowLeft {
#[column(primary)]
id: i32,
name: String,
}
#[SQLiteTable(NAME = "fromrow_right")]
struct FromRowRight {
#[column(primary)]
id: i32,
name: String,
}
#[derive(SQLiteSchema)]
struct FromRowPairSchema {
fromrow_left: FromRowLeft,
fromrow_right: FromRowRight,
}
#[drizzle::test]
fn test_fromrow_named_struct_after_another_reads_its_own_columns(
db: &mut TestDb<FromRowPairSchema>,
) {
let FromRowPairSchema {
fromrow_left,
fromrow_right,
} = schema;
db.insert(fromrow_left)
.values([InsertFromRowLeft::new("left").with_id(1)])
.execute();
db.insert(fromrow_right)
.values([InsertFromRowRight::new("right").with_id(2)])
.execute();
let row: (NamedNameId, NamedNameId) = db
.select((
fromrow_left.id,
fromrow_left.name,
fromrow_right.id,
fromrow_right.name,
))
.from(fromrow_left)
.inner_join((fromrow_right, drizzle::core::expr::eq(fromrow_right.id, 2)))
.get()
.expect("a row");
assert_eq!(
row,
(
NamedNameId {
id: 1,
name: "left".to_string()
},
NamedNameId {
id: 2,
name: "right".to_string()
},
)
);
}
#[SQLiteTable(NAME = "fromrow_raw")]
struct FromRowRaw {
#[column(primary)]
id: i32,
r#type: String,
}
#[derive(SQLiteSchema)]
struct FromRowRawSchema {
fromrow_raw: FromRowRaw,
}
#[derive(SQLiteFromRow, Debug, PartialEq)]
struct RawTypeName {
r#type: String,
}
#[drizzle::test]
fn test_fromrow_raw_identifier_field_reads_unprefixed_column(db: &mut TestDb<FromRowRawSchema>) {
let FromRowRawSchema { fromrow_raw } = schema;
db.insert(fromrow_raw)
.values([InsertFromRowRaw::new("kind")])
.execute();
let query = db.select(RawTypeName::Select).from(fromrow_raw);
assert_eq!(query.to_sql().sql(), r#"SELECT "type" FROM "fromrow_raw""#);
let row: RawTypeName = query.get().expect("a row");
assert_eq!(row.r#type, "kind");
}