diesel/sqlite/types/
mod.rs

1mod date_and_time;
2#[cfg(all(feature = "sqlite", feature = "serde_json"))]
3mod json;
4mod numeric;
5
6use super::connection::SqliteValue;
7use super::Sqlite;
8use crate::deserialize::{self, FromSql, Queryable};
9use crate::expression::AsExpression;
10use crate::query_builder::QueryId;
11use crate::serialize::{self, IsNull, Output, ToSql};
12use crate::sql_types;
13use crate::sql_types::SqlType;
14
15/// The returned pointer is *only* valid for the lifetime to the argument of
16/// `from_sql`. This impl is intended for uses where you want to write a new
17/// impl in terms of `String`, but don't want to allocate. We have to return a
18/// raw pointer instead of a reference with a lifetime due to the structure of
19/// `FromSql`
20#[cfg(feature = "sqlite")]
21impl FromSql<sql_types::VarChar, Sqlite> for *const str {
22    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
23        let text = value.read_text();
24        Ok(text as *const _)
25    }
26}
27
28#[cfg(feature = "sqlite")]
29impl Queryable<sql_types::VarChar, Sqlite> for *const str {
30    type Row = Self;
31
32    fn build(row: Self::Row) -> deserialize::Result<Self> {
33        Ok(row)
34    }
35}
36
37/// The returned pointer is *only* valid for the lifetime to the argument of
38/// `from_sql`. This impl is intended for uses where you want to write a new
39/// impl in terms of `Vec<u8>`, but don't want to allocate. We have to return a
40/// raw pointer instead of a reference with a lifetime due to the structure of
41/// `FromSql`
42#[cfg(feature = "sqlite")]
43impl FromSql<sql_types::Binary, Sqlite> for *const [u8] {
44    fn from_sql(mut bytes: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
45        let bytes = bytes.read_blob();
46        Ok(bytes as *const _)
47    }
48}
49
50#[cfg(feature = "sqlite")]
51impl Queryable<sql_types::Binary, Sqlite> for *const [u8] {
52    type Row = Self;
53
54    fn build(row: Self::Row) -> deserialize::Result<Self> {
55        Ok(row)
56    }
57}
58
59#[cfg(feature = "sqlite")]
60#[allow(clippy::cast_possible_truncation)] // we want to truncate here
61impl FromSql<sql_types::SmallInt, Sqlite> for i16 {
62    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
63        Ok(value.read_integer() as i16)
64    }
65}
66
67#[cfg(feature = "sqlite")]
68impl FromSql<sql_types::Integer, Sqlite> for i32 {
69    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
70        Ok(value.read_integer())
71    }
72}
73
74#[cfg(feature = "sqlite")]
75impl FromSql<sql_types::Bool, Sqlite> for bool {
76    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
77        Ok(value.read_integer() != 0)
78    }
79}
80
81#[cfg(feature = "sqlite")]
82impl FromSql<sql_types::BigInt, Sqlite> for i64 {
83    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
84        Ok(value.read_long())
85    }
86}
87
88#[cfg(feature = "sqlite")]
89#[allow(clippy::cast_possible_truncation)] // we want to truncate here
90impl FromSql<sql_types::Float, Sqlite> for f32 {
91    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
92        Ok(value.read_double() as f32)
93    }
94}
95
96#[cfg(feature = "sqlite")]
97impl FromSql<sql_types::Double, Sqlite> for f64 {
98    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
99        Ok(value.read_double())
100    }
101}
102
103#[cfg(feature = "sqlite")]
104impl ToSql<sql_types::Bool, Sqlite> for bool {
105    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
106        let int_value = if *self { &1 } else { &0 };
107        <i32 as ToSql<sql_types::Integer, Sqlite>>::to_sql(int_value, out)
108    }
109}
110
111#[cfg(feature = "sqlite")]
112impl ToSql<sql_types::Text, Sqlite> for str {
113    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
114        out.set_value(self);
115        Ok(IsNull::No)
116    }
117}
118
119#[cfg(feature = "sqlite")]
120impl ToSql<sql_types::Binary, Sqlite> for [u8] {
121    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
122        out.set_value(self);
123        Ok(IsNull::No)
124    }
125}
126
127#[cfg(feature = "sqlite")]
128impl ToSql<sql_types::SmallInt, Sqlite> for i16 {
129    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
130        out.set_value(*self as i32);
131        Ok(IsNull::No)
132    }
133}
134
135#[cfg(feature = "sqlite")]
136impl ToSql<sql_types::Integer, Sqlite> for i32 {
137    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
138        out.set_value(*self);
139        Ok(IsNull::No)
140    }
141}
142
143#[cfg(feature = "sqlite")]
144impl ToSql<sql_types::BigInt, Sqlite> for i64 {
145    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
146        out.set_value(*self);
147        Ok(IsNull::No)
148    }
149}
150
151#[cfg(feature = "sqlite")]
152impl ToSql<sql_types::Float, Sqlite> for f32 {
153    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
154        out.set_value(*self as f64);
155        Ok(IsNull::No)
156    }
157}
158
159#[cfg(feature = "sqlite")]
160impl ToSql<sql_types::Double, Sqlite> for f64 {
161    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
162        out.set_value(*self);
163        Ok(IsNull::No)
164    }
165}
166
167/// The SQLite timestamp with time zone type
168///
169/// ### [`ToSql`] impls
170///
171/// - [`chrono::NaiveDateTime`] with `feature = "chrono"`
172/// - [`chrono::DateTime`] with `feature = "chrono"`
173/// - [`time::PrimitiveDateTime`] with `feature = "time"`
174/// - [`time::OffsetDateTime`] with `feature = "time"`
175///
176/// ### [`FromSql`] impls
177///
178/// - [`chrono::NaiveDateTime`] with `feature = "chrono"`
179/// - [`chrono::DateTime`] with `feature = "chrono"`
180/// - [`time::PrimitiveDateTime`] with `feature = "time"`
181/// - [`time::OffsetDateTime`] with `feature = "time"`
182///
183/// [`ToSql`]: crate::serialize::ToSql
184/// [`FromSql`]: crate::deserialize::FromSql
185#[cfg_attr(
186    feature = "chrono",
187    doc = " [`chrono::NaiveDateTime`]: chrono::naive::NaiveDateTime"
188)]
189#[cfg_attr(
190    not(feature = "chrono"),
191    doc = " [`chrono::NaiveDateTime`]: https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDateTime.html"
192)]
193#[cfg_attr(feature = "chrono", doc = " [`chrono::DateTime`]: chrono::DateTime")]
194#[cfg_attr(
195    not(feature = "chrono"),
196    doc = " [`chrono::DateTime`]: https://docs.rs/chrono/0.4.19/chrono/struct.DateTime.html"
197)]
198#[cfg_attr(
199    feature = "time",
200    doc = " [`time::PrimitiveDateTime`]: time::PrimitiveDateTime"
201)]
202#[cfg_attr(
203    not(feature = "time"),
204    doc = " [`time::PrimitiveDateTime`]: https://docs.rs/time/0.3.9/time/struct.PrimitiveDateTime.html"
205)]
206#[cfg_attr(
207    feature = "time",
208    doc = " [`time::OffsetDateTime`]: time::OffsetDateTime"
209)]
210#[cfg_attr(
211    not(feature = "time"),
212    doc = " [`time::OffsetDateTime`]: https://docs.rs/time/0.3.9/time/struct.OffsetDateTime.html"
213)]
214#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Timestamptz {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Timestamptz")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Timestamptz {
    #[inline]
    fn clone(&self) -> Timestamptz { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Timestamptz { }Copy, #[automatically_derived]
impl ::core::default::Default for Timestamptz {
    #[inline]
    fn default() -> Timestamptz { Timestamptz {} }
}Default, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for Timestamptz {
            type QueryId = Timestamptz<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId, const _: () =
    {
        use diesel;
        impl diesel::sql_types::SqlType for Timestamptz {
            type IsNull = diesel::sql_types::is_nullable::NotNull;
            const IS_ARRAY: bool = false;
        }
        impl diesel::sql_types::SingleValue for Timestamptz {}
        impl diesel::sql_types::HasSqlType<Timestamptz> for
            diesel::sqlite::Sqlite {
            fn metadata(_: &mut ()) -> diesel::sqlite::SqliteType {
                diesel::sqlite::SqliteType::Text
            }
        }
    };SqlType)]
215#[diesel(sqlite_type(name = "Text"))]
216#[cfg(feature = "sqlite")]
217pub struct Timestamptz;
218
219/// The SQL type for JSON validation flags
220///
221/// This type is backed by an Integer in SQLite.
222///
223/// ### [`ToSql`] impls
224///
225/// - [`JsonValidFlag`]
226///
227/// [`ToSql`]: crate::serialize::ToSql
228#[derive(#[automatically_derived]
impl ::core::fmt::Debug for JsonValidFlags {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "JsonValidFlags")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for JsonValidFlags {
    #[inline]
    fn clone(&self) -> JsonValidFlags { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for JsonValidFlags { }Copy, #[automatically_derived]
impl ::core::default::Default for JsonValidFlags {
    #[inline]
    fn default() -> JsonValidFlags { JsonValidFlags {} }
}Default, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for JsonValidFlags {
            type QueryId = JsonValidFlags<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId, const _: () =
    {
        use diesel;
        impl diesel::sql_types::SqlType for JsonValidFlags {
            type IsNull = diesel::sql_types::is_nullable::NotNull;
            const IS_ARRAY: bool = false;
        }
        impl diesel::sql_types::SingleValue for JsonValidFlags {}
        impl diesel::sql_types::HasSqlType<JsonValidFlags> for
            diesel::sqlite::Sqlite {
            fn metadata(_: &mut ()) -> diesel::sqlite::SqliteType {
                diesel::sqlite::SqliteType::Integer
            }
        }
    };SqlType)]
229#[diesel(sqlite_type(name = "Integer"))]
230#[cfg(feature = "sqlite")]
231pub struct JsonValidFlags;
232
233/// Flags for the `json_valid` function
234///
235/// These flags define what is meant by "well-formed" JSON when validating.
236///
237/// The following bits are currently defined:
238/// - `0x01` → The input is text that strictly complies with canonical RFC-8259 JSON, without any extensions.
239/// - `0x02` → The input is text that is JSON with JSON5 extensions.
240/// - `0x04` → The input is a BLOB that superficially appears to be JSONB.
241/// - `0x08` → The input is a BLOB that strictly conforms to the internal JSONB format.
242///
243/// By combining bits, the following useful values can be derived:
244/// - `Rfc8259Json` (1) → X is RFC-8259 JSON text
245/// - `Json5` (2) → X is JSON5 text
246/// - `JsonbLike` (4) → X is probably JSONB
247/// - `Rfc8259JsonOrJsonb` (5) → X is RFC-8259 JSON text or JSONB
248/// - `Json5OrJsonb` (6) → X is JSON5 text or JSONB (recommended for most use cases)
249/// - `JsonbStrict` (8) → X is strictly conforming JSONB
250/// - `Rfc8259JsonOrJsonbStrict` (9) → X is RFC-8259 or strictly conforming JSONB
251/// - `Json5OrJsonbStrict` (10) → X is JSON5 or strictly conforming JSONB
252#[derive(#[automatically_derived]
impl ::core::fmt::Debug for JsonValidFlag {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                JsonValidFlag::Rfc8259Json => "Rfc8259Json",
                JsonValidFlag::Json5 => "Json5",
                JsonValidFlag::JsonbLike => "JsonbLike",
                JsonValidFlag::Rfc8259JsonOrJsonb => "Rfc8259JsonOrJsonb",
                JsonValidFlag::Json5OrJsonb => "Json5OrJsonb",
                JsonValidFlag::JsonbStrict => "JsonbStrict",
                JsonValidFlag::Rfc8259JsonOrJsonbStrict =>
                    "Rfc8259JsonOrJsonbStrict",
                JsonValidFlag::Json5OrJsonbStrict => "Json5OrJsonbStrict",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for JsonValidFlag {
    #[inline]
    fn clone(&self) -> JsonValidFlag { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for JsonValidFlag { }Copy, const _: () =
    {
        use diesel;
        impl<'__expr> diesel::expression::AsExpression<JsonValidFlags> for
            &'__expr JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<JsonValidFlags,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<JsonValidFlags>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        impl<'__expr>
            diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>
            for &'__expr JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<diesel::sql_types::Nullable<JsonValidFlags>,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        impl<'__expr, '__expr2>
            diesel::expression::AsExpression<JsonValidFlags> for
            &'__expr2 &'__expr JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<JsonValidFlags,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<JsonValidFlags>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        impl<'__expr, '__expr2>
            diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>
            for &'__expr2 &'__expr JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<diesel::sql_types::Nullable<JsonValidFlags>,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        impl<__DB>
            diesel::serialize::ToSql<diesel::sql_types::Nullable<JsonValidFlags>,
            __DB> for JsonValidFlag where __DB: diesel::backend::Backend,
            Self: diesel::serialize::ToSql<JsonValidFlags, __DB> {
            fn to_sql<'__b>(&'__b self,
                out: &mut diesel::serialize::Output<'__b, '_, __DB>)
                -> diesel::serialize::Result {
                diesel::serialize::ToSql::<JsonValidFlags,
                        __DB>::to_sql(self, out)
            }
        }
        impl diesel::expression::AsExpression<JsonValidFlags> for
            JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<JsonValidFlags,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<JsonValidFlags>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        impl diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>
            for JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<diesel::sql_types::Nullable<JsonValidFlags>,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
    };AsExpression)]
253#[diesel(sql_type = JsonValidFlags)]
254#[cfg(feature = "sqlite")]
255#[non_exhaustive]
256pub enum JsonValidFlag {
257    /// X is RFC-8259 JSON text (flag = 1)
258    Rfc8259Json = 1,
259    /// X is JSON5 text (flag = 2)
260    Json5 = 2,
261    /// X is probably JSONB (flag = 4)
262    JsonbLike = 4,
263    /// X is RFC-8259 JSON text or JSONB (flag = 5)
264    Rfc8259JsonOrJsonb = 5,
265    /// X is JSON5 text or JSONB (flag = 6, recommended for most use cases)
266    Json5OrJsonb = 6,
267    /// X is strictly conforming JSONB (flag = 8)
268    JsonbStrict = 8,
269    /// X is RFC-8259 or strictly conforming JSONB (flag = 9)
270    Rfc8259JsonOrJsonbStrict = 9,
271    /// X is JSON5 or strictly conforming JSONB (flag = 10)
272    Json5OrJsonbStrict = 10,
273}
274
275#[cfg(feature = "sqlite")]
276impl ToSql<JsonValidFlags, Sqlite> for JsonValidFlag {
277    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
278        out.set_value(*self as i32);
279        Ok(IsNull::No)
280    }
281}