Skip to main content

DrizzleSQLiteColumn

Trait DrizzleSQLiteColumn 

Source
pub trait DrizzleSQLiteColumn: Sized {
    type SQLType: SQLiteAffinity;

    const SQL_TYPE: &'static str = <Self::SQLType as SQLiteAffinity>::SQL_TYPE;

    // Required methods
    fn decode(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError>;
    fn encode(&self) -> SQLiteValue<'_>;

    // Provided method
    fn encode_owned(self) -> OwnedSQLiteValue { ... }
}
Expand description

A Rust type that can be stored in a SQLite column.

#[derive(SQLiteEnum)] implements this for enums. Implement it by hand to use your own type as a field of a #[SQLiteTable]: SQLType picks the column’s affinity, decode reads a cell, and encode writes one. Implementing it also gives the type FromSQLiteValue and From<T> for SQLiteValue.

From<T> for SQLiteValue goes through encode_owned, because insert and update models keep their values after the source is dropped. Override encode_owned when the type can hand over its buffer without copying.

§Examples

A u32 stored as four big-endian bytes:

use drizzle_core::error::DrizzleError;
use drizzle_sqlite::traits::{DrizzleSQLiteColumn, FromSQLiteValue};
use drizzle_sqlite::types::Blob;
use drizzle_sqlite::values::{SQLiteValue, SQLiteValueRef};
use std::borrow::Cow;

struct U32Be(u32);

impl DrizzleSQLiteColumn for U32Be {
    type SQLType = Blob;

    fn decode(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError> {
        let SQLiteValueRef::Blob(bytes) = value else {
            return Err(DrizzleError::ConversionError("expected a BLOB".into()));
        };
        let bytes: [u8; 4] = bytes
            .try_into()
            .map_err(|_| DrizzleError::ConversionError("expected 4 bytes".into()))?;
        Ok(Self(u32::from_be_bytes(bytes)))
    }

    fn encode(&self) -> SQLiteValue<'_> {
        SQLiteValue::Blob(Cow::Owned(self.0.to_be_bytes().to_vec()))
    }
}

let value = SQLiteValue::from(U32Be(7));
assert_eq!(value, SQLiteValue::Blob(Cow::Borrowed(&[0, 0, 0, 7][..])));
assert_eq!(U32Be::from_sqlite_blob(&[0, 0, 1, 0]).unwrap().0, 256);
assert!(U32Be::from_sqlite_text("7").is_err());

Provided Associated Constants§

Source

const SQL_TYPE: &'static str = <Self::SQLType as SQLiteAffinity>::SQL_TYPE

The affinity as written in DDL. Defaults to the affinity of SQLType.

Kept for source compatibility. Schema generation reads the affinity from SQLType, so overriding this constant does not change the column type.

Required Associated Types§

Source

type SQLType: SQLiteAffinity

The SQL type marker of the column: one of the markers in crate::types (Integer, Text, Blob, Real, Numeric, Any).

It sets the column’s affinity in DDL and which expressions the column can be used in.

Required Methods§

Source

fn decode(value: SQLiteValueRef<'_>) -> Result<Self, DrizzleError>

Decodes a cell read from the database.

Reject storage classes the type does not accept (including NULL) with DrizzleError::ConversionError.

§Errors

Returns DrizzleError::ConversionError if value cannot be decoded as this custom column type.

Source

fn encode(&self) -> SQLiteValue<'_>

Encodes the value as a bind parameter, borrowing from self where possible.

Provided Methods§

Source

fn encode_owned(self) -> OwnedSQLiteValue

Encodes the value as an owned bind parameter.

The default calls encode and copies the result. Override it when the type can move its string or byte buffer into the value instead.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§