Skip to main content

FromColumn

Trait FromColumn 

Source
pub trait FromColumn<'stmt>
where Self: Sized,
{ type Type: Type; // Required method fn from_column(stmt: &'stmt Statement, index: Self::Type) -> Result<Self>; }
Expand description

A type suitable for reading a single value from a prepared statement.

This trait can be used directly through Statement::column, to read multiple columns simultaneously see Row.

§Safe implementation

Note that column loading is separated into two stages: checking and loading. By separating reading a column into two stages in the underlying row API we can hopefully load references directly from the database.

The Type trait is response for checking, see it for more information.

§Examples

It is expected that this trait is implemented for types which can be conveniently read out of a row.

In order to do so, the first step is to pick the implementation of Type to associated with the Type associated type. This determines the underlying database type being loaded.

An instance of this type is then passed into FromColumn::from_column allowing the underlying type to be loaded from the statement it is associated with.

use sqll::{Connection, FromColumn, Result, Statement};
use sqll::ty;

#[derive(Debug, PartialEq, Eq)]
struct Timestamp {
    seconds: i64,
}

impl FromColumn<'_> for Timestamp {
    type Type = ty::Integer;

    #[inline]
    fn from_column(stmt: &Statement, index: ty::Integer) -> Result<Self> {
        Ok(Timestamp {
            seconds: i64::from_column(stmt, index)?,
        })
    }
}

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE test (ts INTEGER);

    INSERT INTO test (ts) VALUES (1767675413);
"#)?;

let mut stmt = c.prepare("SELECT ts FROM test")?;

assert_eq!(stmt.next::<Timestamp>()?, Some(Timestamp { seconds: 1767675413 }));

Required Associated Types§

Source

type Type: Type

The type of a column.

This must designate one of the database-primitive types as checks, like:

When this value is received in from_column it can be used to actually load the a value of the underlying type.

Required Methods§

Source

fn from_column(stmt: &'stmt Statement, index: Self::Type) -> Result<Self>

Read a value from the specified column.

For custom implementations this typically means accessing the value from the column using Statement::column.

§Examples
use sqll::{Connection, FromColumn, Result, Statement};
use sqll::ty;

let c = Connection::open_in_memory()?;

#[derive(Debug, PartialEq, Eq)]
struct Id(Vec<u8>);

impl FromColumn<'_> for Id {
    type Type = ty::Blob;

    #[inline]
    fn from_column(stmt: &Statement, index: ty::Blob) -> Result<Self> {
        Ok(Id(<_>::from_column(stmt, index)?))
    }
}

c.execute(r#"
    CREATE TABLE ids (id BLOB NOT NULL);

    INSERT INTO ids (id) VALUES (X'abcdabcd');
"#)?;

let mut select = c.prepare("SELECT id FROM ids")?;
assert!(select.step()?.is_row());

assert_eq!(select.column::<Id>(0)?, Id(vec![0xab, 0xcd, 0xab, 0xcd]));

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl FromColumn<'_> for bool

FromColumn implementation for bool.

This corresponds exactly with the internal SQLite INTEGER or Integer types where 0 is false and any non-zero value is true. It is supported by SQLite as the BOOLEAN data type.

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE booleans (value BOOLEAN);

    INSERT INTO booleans (value) VALUES (TRUE), (FALSE);
"#)?;

let mut stmt = c.prepare("SELECT value FROM booleans")?;
let values = stmt.iter::<bool>().collect::<Vec<_>>();
assert_eq!(values, vec![Ok(true), Ok(false)]);

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE booleans (value BLOB);

    INSERT INTO booleans (value) VALUES (X'01'), (X'00');
"#)?;

let mut stmt = c.prepare("SELECT value FROM booleans")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<bool>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for f32

FromColumn implementation for f32.

Getting this type requires conversion and might be subject to precision loss. To avoid this, consider using f64 instead.

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value REAL);

    INSERT INTO numbers (value) VALUES (3.14), (2.71);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<f32>()? {
    assert!(matches!(value, 3.14 | 2.71));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value REAL);

    INSERT INTO numbers (value) VALUES (3.14), (2.71);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<i32>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

type Type = Float

Source§

fn from_column(stmt: &Statement, index: Float) -> Result<Self>

Source§

impl FromColumn<'_> for f64

FromColumn implementation for f64.

This corresponds exactly with the internal SQLite FLOAT or Float types.

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value REAL);

    INSERT INTO numbers (value) VALUES (3.14), (2.71);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<f64>()? {
    assert!(matches!(value, 3.14 | 2.71));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value REAL);

    INSERT INTO numbers (value) VALUES (3.14), (2.71);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<i64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

type Type = Float

Source§

fn from_column(stmt: &Statement, index: Float) -> Result<Self>

Source§

impl FromColumn<'_> for i8

FromColumn implementation for i8.

§Errors

Getting this type requires conversion and might fail if the value cannot be represented by a i64.

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (-9223372036854775808);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

assert!(stmt.step()?.is_row());
let e = stmt.column::<i8>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<i8>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for i16

FromColumn implementation for i16.

§Errors

Getting this type requires conversion and might fail if the value cannot be represented by a i64.

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (-9223372036854775808);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

assert!(stmt.step()?.is_row());
let e = stmt.column::<i16>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<i16>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for i32

FromColumn implementation for i32.

§Errors

Getting this type requires conversion and might fail if the value cannot be represented by a i64.

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (-9223372036854775808);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

assert!(stmt.step()?.is_row());
let e = stmt.column::<i32>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<i32>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for i64

FromColumn implementation for i64.

This corresponds exactly with the internal SQLite INTEGER or Integer types.

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<i64>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for i128

FromColumn implementation for i128.

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<i128>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for u8

FromColumn implementation for u8.

§Errors

Getting this type requires conversion and might fail if the value cannot be represented by a i64.

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (-9223372036854775808);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

assert!(stmt.step()?.is_row());
let e = stmt.column::<u8>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<u8>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for u16

FromColumn implementation for u16.

§Errors

Getting this type requires conversion and might fail if the value cannot be represented by a i64.

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (-9223372036854775808);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

assert!(stmt.step()?.is_row());
let e = stmt.column::<u16>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<u16>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for u32

FromColumn implementation for u32.

§Errors

Getting this type requires conversion and might fail if the value cannot be represented by a i64.

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (-9223372036854775808);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

assert!(stmt.step()?.is_row());
let e = stmt.column::<u32>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<u32>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for u64

FromColumn implementation for u64.

§Errors

Getting this type requires conversion and might fail if the value cannot be represented by a i64.

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (-9223372036854775808);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

assert!(stmt.step()?.is_row());
let e = stmt.column::<u64>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<u64>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for u128

FromColumn implementation for u128.

§Errors

Getting this type requires conversion and might fail if the value cannot be represented by a i64.

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (-9223372036854775808);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

assert!(stmt.step()?.is_row());
let e = stmt.column::<u128>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while let Some(value) = stmt.next::<u128>()? {
    assert!(matches!(value, 3 | 2));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE numbers (value INTEGER);

    INSERT INTO numbers (value) VALUES (3), (2);
"#)?;

let mut stmt = c.prepare("SELECT value FROM numbers")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<f64>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

impl FromColumn<'_> for String

Available on crate feature alloc only.

FromColumn implementation which returns a newly allocated String.

For a more memory-efficient way of reading bytes, consider using the FromUnsizedColumn implementation for str.

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (name TEXT);

    INSERT INTO users (name) VALUES ('Alice'), ('Bob');
"#)?;

let mut stmt = c.prepare("SELECT name FROM users")?;

assert_eq!(stmt.next::<String>()?, Some(String::from("Alice")));
assert_eq!(stmt.next::<String>()?, Some(String::from("Bob")));
assert_eq!(stmt.next::<String>()?, None);

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (id INTEGER);

    INSERT INTO users (id) VALUES (1), (2);
"#)?;

let mut stmt = c.prepare("SELECT id FROM users")?;

let e = stmt.next::<String>().unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);
Source§

type Type = Text

Source§

fn from_column(stmt: &Statement, index: Text) -> Result<Self>

Source§

impl FromColumn<'_> for Vec<u8>

Available on crate feature alloc only.

FromColumn implementation which returns a newly allocated Vec.

For a more memory-efficient way of reading bytes, consider using the FromUnsizedColumn implementation for a byte slice.

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (blob BLOB);

    INSERT INTO users (blob) VALUES (X'aabb'), (X'bbcc');
"#)?;

let mut stmt = c.prepare("SELECT blob FROM users")?;

assert_eq!(stmt.next::<Vec<u8>>()?, Some(vec![0xaa, 0xbb]));
assert_eq!(stmt.next::<Vec<u8>>()?, Some(vec![0xbb, 0xcc]));
assert_eq!(stmt.next::<Vec<u8>>()?, None);

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (id INTEGER);

    INSERT INTO users (id) VALUES (1), (2);
"#)?;

let mut stmt = c.prepare("SELECT id FROM users")?;

let e = stmt.next::<Vec::<u8>>().unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);
Source§

type Type = Blob

Source§

fn from_column(stmt: &Statement, index: Blob) -> Result<Self>

Source§

impl<'stmt> FromColumn<'stmt> for &'stmt str

FromColumn implementation which returns a borrowed str.

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (name TEXT);

    INSERT INTO users (name) VALUES ('Alice'), ('Bob');
"#)?;

let mut stmt = c.prepare("SELECT name FROM users")?;

assert_eq!(stmt.next::<&str>()?, Some("Alice"));
assert_eq!(stmt.next::<&str>()?, Some("Bob"));
assert_eq!(stmt.next::<&str>()?, None);

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (id INTEGER);

    INSERT INTO users (id) VALUES (1), (2);
"#)?;

let mut stmt = c.prepare("SELECT id FROM users")?;

let e = stmt.next::<&str>().unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);
Source§

type Type = Text

Source§

fn from_column(stmt: &'stmt Statement, index: Text) -> Result<Self>

Source§

impl<'stmt> FromColumn<'stmt> for &'stmt [u8]

FromColumn implementation which returns a borrowed [u8].

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (blob BLOB);

    INSERT INTO users (blob) VALUES (X'aabb'), (X'bbcc');
"#)?;

let mut stmt = c.prepare("SELECT blob FROM users")?;

while let Some(blob) = stmt.next::<&[u8]>()? {
    assert!(matches!(blob, b"\xaa\xbb" | b"\xbb\xcc"));
}

Automatic conversion being denied:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (id INTEGER);

    INSERT INTO users (id) VALUES (1), (2);
"#)?;

let mut stmt = c.prepare("SELECT id FROM users")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<&[u8]>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
}
Source§

type Type = Blob

Source§

fn from_column(stmt: &'stmt Statement, index: Blob) -> Result<Self>

Source§

impl<'stmt, T> FromColumn<'stmt> for Option<T>
where T: FromColumn<'stmt, Type: NotNull>,

FromColumn implementation for Option.

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (name TEXT, age INTEGER);
"#)?;

let mut stmt = c.prepare("INSERT INTO users (name, age) VALUES (?, ?)")?;

stmt.execute(("Alice", None::<i64>))?;
stmt.execute(("Bob", Some(30i64)))?;

let mut stmt = c.prepare("SELECT name, age FROM users")?;

let mut names_and_ages = Vec::new();

while let Some(row) = stmt.next::<(String, Option<i64>)>()? {
    names_and_ages.push(row);
}

names_and_ages.sort();
assert_eq!(names_and_ages, vec![(String::from("Alice"), None), (String::from("Bob"), Some(30))]);
Source§

type Type = Nullable<<T as FromColumn<'stmt>>::Type>

Source§

fn from_column(stmt: &'stmt Statement, index: Nullable<T::Type>) -> Result<Self>

Source§

impl<const N: usize> FromColumn<'_> for [u8; N]

FromColumn implementation which returns an array of [u8; N].

§Examples

use sqll::Connection;

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE blobs (blob BLOB);

    INSERT INTO blobs (blob) VALUES (X'aabb'), (X'bbcc');
"#)?;

let mut stmt = c.prepare("SELECT blob FROM blobs")?;

assert_eq!(stmt.next::<[u8; 2]>()?, Some(*b"\xaa\xbb"));
assert_eq!(stmt.next::<[u8; 2]>()?, Some(*b"\xbb\xcc"));

Trying to coerce from mismatched size:

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE blobs (blob BLOB);

    INSERT INTO blobs (blob) VALUES (X'aabb'), (X'bbcc');
"#)?;

let mut stmt = c.prepare("SELECT blob FROM blobs")?;

while stmt.step()?.is_row() {
    let e = stmt.column::<[u8; 8]>(0).unwrap_err();
    assert_eq!(e.code(), Code::MISMATCH);
    assert_eq!(e.to_string(), "blob size must be exactly 8 bytes, but was 2");
}
Source§

type Type = Blob

Source§

fn from_column(stmt: &Statement, index: Blob) -> Result<Self>

Implementors§

Source§

impl FromColumn<'_> for Null

FromColumn implementation for Null.

§Examples

use sqll::{Connection, Null};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (name TEXT, age INTEGER);

    INSERT INTO users (name, age) VALUES ('Alice', NULL), ('Bob', 30);
"#)?;

let mut stmt = c.prepare("SELECT age FROM users WHERE name = ?")?;
stmt.bind("Alice")?;

assert_eq!(stmt.iter::<Null>().collect::<Vec<_>>(), [Ok(Null)]);
Source§

impl<'stmt> FromColumn<'stmt> for &'stmt Text

FromColumn implementation which returns a borrowed Text.

§Examples

use sqll::{Connection, Text};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (name TEXT);

    INSERT INTO users (name) VALUES ('Alice'), ('Bob');
"#)?;

let mut stmt = c.prepare("SELECT name FROM users")?;

assert_eq!(stmt.next::<&Text>()?, Some(Text::new(b"Alice")));
assert_eq!(stmt.next::<&Text>()?, Some(Text::new(b"Bob")));
assert_eq!(stmt.next::<&Text>()?, None);

Automatic conversion being denied:

use sqll::{Connection, Code, Text};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (id INTEGER);

    INSERT INTO users (id) VALUES (1), (2);
"#)?;

let mut stmt = c.prepare("SELECT id FROM users")?;

let e = stmt.next::<&Text>().unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);
Source§

impl<'stmt> FromColumn<'stmt> for Value<'stmt>

FromColumn implementation for Value.

§Examples

use sqll::{Connection, Value, Result};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (name TEXT, age INTEGER);

    INSERT INTO users (name, age) VALUES ('Alice', NULL), ('Bob', 30);
"#)?;

let mut stmt = c.prepare("SELECT name FROM users WHERE age IS ?")?;
stmt.bind(None::<Value<'_>>)?;

assert_eq!(stmt.next::<Value<'_>>(), Ok(Some(Value::text("Alice"))));
assert_eq!(stmt.next::<Value<'_>>(), Ok(None));
Source§

impl<const N: usize> FromColumn<'_> for FixedBlob<N>

FromColumn implementation for FixedBlob which reads at most N bytes.

If the column contains more than N bytes, a Code::MISMATCH error is returned.

§Examples

use sqll::{Connection, FixedBlob, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (id BLOB);

    INSERT INTO users (id) VALUES (X'01020304'), (X'0506070809');
"#)?;

let mut stmt = c.prepare("SELECT id FROM users")?;

assert!(stmt.step()?.is_row());
let bytes = stmt.column::<FixedBlob<4>>(0)?;
assert_eq!(bytes.as_slice(), &[1, 2, 3, 4]);

assert!(stmt.step()?.is_row());
let e = stmt.column::<FixedBlob<4>>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

let bytes = stmt.column::<FixedBlob<5>>(0)?;
assert_eq!(bytes.as_slice(), &[5, 6, 7, 8, 9]);
Source§

impl<const N: usize> FromColumn<'_> for FixedText<N>

FromColumn implementation for FixedBlob which reads at most N bytes.

If the column contains more than N bytes, a Code::MISMATCH error is returned.

§Examples

use sqll::{Connection, FixedText, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
    CREATE TABLE users (name TEXT);

    INSERT INTO users (name) VALUES ('Alice'), ('Bob');
"#)?;

let mut stmt = c.prepare("SELECT name FROM users")?;

assert!(stmt.step()?.is_row());
let bytes = stmt.column::<FixedText<5>>(0)?;
assert_eq!(bytes.as_text(), "Alice");

assert!(stmt.step()?.is_row());
let e = stmt.column::<FixedText<2>>(0).unwrap_err();
assert_eq!(e.code(), Code::MISMATCH);

let bytes = stmt.column::<FixedText<5>>(0)?;
assert_eq!(bytes.as_text(), "Bob");