Skip to main content

diesel/sqlite/types/
mod.rs

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