#![cfg(all(
any(feature = "rusqlite", feature = "turso", feature = "libsql"),
feature = "arrayvec"
))]
use arrayvec::{ArrayString, ArrayVec};
use drizzle::core::expr::*;
use drizzle::sqlite::prelude::*;
#[SQLiteTable(NAME = "arraystring_test")]
struct ArrayStringTest {
#[column(PRIMARY)]
id: i32,
name: ArrayString<16>,
description: String,
}
#[SQLiteTable(NAME = "arrayvec_blob_test")]
struct ArrayVecBlobTest {
#[column(PRIMARY)]
id: i32,
data: ArrayVec<u8, 32>,
label: String,
}
#[SQLiteTable(NAME = "mixed_arrayvec_test")]
struct MixedArrayVecTest {
#[column(PRIMARY)]
id: i32,
short_name: ArrayString<8>,
long_name: ArrayString<64>,
small_data: ArrayVec<u8, 16>,
large_data: ArrayVec<u8, 128>,
}
#[derive(SQLiteSchema)]
struct ArrayStringSchema {
arraystring_test: ArrayStringTest,
}
#[derive(SQLiteSchema)]
struct ArrayVecBlobSchema {
arrayvec_blob_test: ArrayVecBlobTest,
}
#[derive(SQLiteSchema)]
struct MixedArrayVecSchema {
mixed_arrayvec_test: MixedArrayVecTest,
}
#[drizzle::test]
fn test_arraystring_text_storage(db: &mut TestDb<ArrayStringSchema>) {
let table = schema.arraystring_test;
let name = ArrayString::<16>::from("Hello").unwrap();
let data = InsertArrayStringTest::new(name, "test description");
db.insert(table).values([data]).execute();
let results: Vec<SelectArrayStringTest> = db
.select((table.id, table.name, table.description))
.from(table)
.r#where(eq(table.description, "test description"))
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name.as_str(), "Hello");
assert_eq!(results[0].description, "test description");
#[derive(SQLiteFromRow, Debug)]
struct ReturnResult(String);
let result: ReturnResult = db
.select(r#typeof(table.name).alias("name_type"))
.from(table)
.r#where(eq(table.id, 1))
.get();
assert_eq!(result.0, "text");
}
#[drizzle::test]
fn test_arrayvec_blob_storage(db: &mut TestDb<ArrayVecBlobSchema>) {
let table = schema.arrayvec_blob_test;
let mut data_vec = ArrayVec::<u8, 32>::new();
data_vec.extend([1, 2, 3, 4, 5].iter().copied());
let data = InsertArrayVecBlobTest::new(data_vec.clone(), "blob test");
db.insert(table).values([data]).execute();
let results: Vec<SelectArrayVecBlobTest> = db
.select((table.id, table.data, table.label))
.from(table)
.r#where(eq(table.label, "blob test"))
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].data.as_slice(), &[1, 2, 3, 4, 5]);
assert_eq!(results[0].label, "blob test");
#[derive(SQLiteFromRow, Debug)]
struct ReturnResult(String);
let result: ReturnResult = db
.select(r#typeof(table.data).alias("data_type"))
.from(table)
.r#where(eq(table.id, 1))
.get();
assert_eq!(result.0, "blob");
}
#[drizzle::test]
fn test_arraystring_roundtrip(db: &mut TestDb<ArrayStringSchema>) {
let table = schema.arraystring_test;
let test_strings = ["A", "Hello", "Test", "1234567890123"];
for (idx, test_str) in test_strings.iter().enumerate() {
let name = ArrayString::<16>::from(test_str).unwrap();
let desc = format!("test_{}", idx);
let data = InsertArrayStringTest::new(name, &desc);
db.insert(table).values([data]).execute();
}
let results: Vec<SelectArrayStringTest> = db
.select((table.id, table.name, table.description))
.from(table)
.all();
assert_eq!(results.len(), test_strings.len());
for (idx, result) in results.iter().enumerate() {
assert_eq!(result.name.as_str(), test_strings[idx]);
}
}
#[drizzle::test]
fn test_arrayvec_roundtrip(db: &mut TestDb<ArrayVecBlobSchema>) {
let table = schema.arrayvec_blob_test;
let test_data: Vec<Vec<u8>> = vec![
vec![], vec![0], vec![1, 2, 3], vec![0; 20], (0..32).collect(), ];
for (idx, test_bytes) in test_data.iter().enumerate() {
let mut data_vec = ArrayVec::<u8, 32>::new();
data_vec.extend(test_bytes.iter().copied());
let label = format!("test_{}", idx);
let data = InsertArrayVecBlobTest::new(data_vec, &label);
db.insert(table).values([data]).execute();
}
let results: Vec<SelectArrayVecBlobTest> = db
.select((table.id, table.data, table.label))
.from(table)
.all();
assert_eq!(results.len(), test_data.len());
for (idx, result) in results.iter().enumerate() {
assert_eq!(result.data.as_slice(), test_data[idx].as_slice());
}
}
#[drizzle::test]
fn test_mixed_arrayvec_types(db: &mut TestDb<MixedArrayVecSchema>) {
let table = schema.mixed_arrayvec_test;
let short_name = ArrayString::<8>::from("Short").unwrap();
let long_name =
ArrayString::<64>::from("This is a much longer name that fits in 64 chars").unwrap();
let mut small_data = ArrayVec::<u8, 16>::new();
small_data.extend([1, 2, 3, 4, 5].iter().copied());
let mut large_data = ArrayVec::<u8, 128>::new();
large_data.extend((0..100).map(|i| (i % 256) as u8));
let data = InsertMixedArrayVecTest::new(
short_name,
long_name,
small_data.clone(),
large_data.clone(),
);
db.insert(table).values([data]).execute();
let results: Vec<SelectMixedArrayVecTest> = db
.select((
table.id,
table.short_name,
table.long_name,
table.small_data,
table.large_data,
))
.from(table)
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].short_name.as_str(), "Short");
assert_eq!(
results[0].long_name.as_str(),
"This is a much longer name that fits in 64 chars"
);
assert_eq!(results[0].small_data.as_slice(), &[1, 2, 3, 4, 5]);
assert_eq!(results[0].large_data.len(), 100);
for i in 0..100 {
assert_eq!(results[0].large_data[i], (i % 256) as u8);
}
}
#[drizzle::test]
fn test_arraystring_empty(db: &mut TestDb<ArrayStringSchema>) {
let table = schema.arraystring_test;
let name = ArrayString::<16>::new();
let data = InsertArrayStringTest::new(name, "empty test");
db.insert(table).values([data]).execute();
let results: Vec<SelectArrayStringTest> = db
.select((table.id, table.name, table.description))
.from(table)
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name.as_str(), "");
}
#[drizzle::test]
fn test_arrayvec_empty(db: &mut TestDb<ArrayVecBlobSchema>) {
let table = schema.arrayvec_blob_test;
let data_vec = ArrayVec::<u8, 32>::new();
let data = InsertArrayVecBlobTest::new(data_vec, "empty blob");
db.insert(table).values([data]).execute();
let results: Vec<SelectArrayVecBlobTest> = db
.select((table.id, table.data, table.label))
.from(table)
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].data.len(), 0);
}
#[drizzle::test]
fn test_arraystring_max_capacity(db: &mut TestDb<ArrayStringSchema>) {
let table = schema.arraystring_test;
let name = ArrayString::<16>::from("1234567890123456").unwrap();
let data = InsertArrayStringTest::new(name, "max capacity");
db.insert(table).values([data]).execute();
let results: Vec<SelectArrayStringTest> = db
.select((table.id, table.name, table.description))
.from(table)
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name.as_str(), "1234567890123456");
assert_eq!(results[0].name.len(), 16);
}
#[drizzle::test]
fn test_arrayvec_max_capacity(db: &mut TestDb<ArrayVecBlobSchema>) {
let table = schema.arrayvec_blob_test;
let mut data_vec = ArrayVec::<u8, 32>::new();
for i in 0..32 {
data_vec.push(i as u8);
}
let data = InsertArrayVecBlobTest::new(data_vec, "max capacity");
db.insert(table).values([data]).execute();
let results: Vec<SelectArrayVecBlobTest> = db
.select((table.id, table.data, table.label))
.from(table)
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].data.len(), 32);
for i in 0..32 {
assert_eq!(results[0].data[i], i as u8);
}
}
#[drizzle::test]
fn test_arrayvec_update(db: &mut TestDb<ArrayVecBlobSchema>) {
let table = schema.arrayvec_blob_test;
let mut initial_data = ArrayVec::<u8, 32>::new();
initial_data.extend([1, 2, 3].iter().copied());
let data = InsertArrayVecBlobTest::new(initial_data, "update test");
db.insert(table).values([data]).execute();
let mut updated_data = ArrayVec::<u8, 32>::new();
updated_data.extend([10, 20, 30, 40].iter().copied());
db.update(table)
.set(UpdateArrayVecBlobTest::default().with_data(updated_data.clone()))
.r#where(eq(table.id, 1))
.execute();
let results: Vec<SelectArrayVecBlobTest> = db
.select((table.id, table.data, table.label))
.from(table)
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].data.as_slice(), &[10, 20, 30, 40]);
}