hotshot_query_service/data_source/storage/sql/db.rs
1// Copyright (c) 2022 Espresso Systems (espressosys.com)
2// This file is part of the HotShot Query Service library.
3//
4// This program is free software: you can redistribute it and/or modify it under the terms of the GNU
5// General Public License as published by the Free Software Foundation, either version 3 of the
6// License, or (at your option) any later version.
7// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
8// even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9// General Public License for more details.
10// You should have received a copy of the GNU General Public License along with this program. If not,
11// see <https://www.gnu.org/licenses/>.
12
13/// The underlying database type for a SQL data source.
14///
15/// Currently, only PostgreSQL and SQLite are supported, with selection based on the "embedded-db" feature flag.
16/// - When the "embedded-db" feature is enabled, SQLite is used.
17/// - When it’s disabled, PostgreSQL is used.
18///
19/// ### Design Choice
20/// The reason for taking this approach over sqlx's Any database is that we can support SQL types
21/// which are implemented for the two backends we care about (Postgres and SQLite) but not for _any_
22/// SQL database, such as MySQL. Crucially, JSON types fall in this category.
23///
24/// The reason for taking this approach rather than writing all of our code to be generic over the
25/// Database implementation is that sqlx does not have the necessary trait bounds on all of the
26/// associated types (e.g. Database::Connection does not implement Executor for all possible
27/// databases, the Executor impl lives on each concrete connection type) and Rust does not provide
28/// a good way of encapsulating a collection of trait bounds on associated types. Thus, our function
29/// signatures become untenably messy with bounds like
30///
31/// ```rust
32/// # use sqlx::{Database, Encode, Executor, IntoArguments, Type};
33/// fn foo<DB: Database>()
34/// where
35/// for<'a> &'a mut DB::Connection: Executor<'a>,
36/// for<'q> DB::Arguments<'q>: IntoArguments<'q, DB>,
37/// for<'a> i64: Type<DB> + Encode<'a, DB>,
38/// {}
39/// ```
40#[cfg(feature = "embedded-db")]
41pub type Db = sqlx::Sqlite;
42#[cfg(not(feature = "embedded-db"))]
43pub type Db = sqlx::Postgres;
44
45#[cfg(feature = "embedded-db")]
46pub mod syntax_helpers {
47 pub const MAX_FN: &str = "MAX";
48 pub const BINARY_TYPE: &str = "BLOB";
49}
50
51#[cfg(not(feature = "embedded-db"))]
52pub mod syntax_helpers {
53 pub const MAX_FN: &str = "GREATEST";
54 pub const BINARY_TYPE: &str = "BYTEA";
55}