sqlint/connector/
queryable.rs

1use super::{IsolationLevel, ResultSet, Transaction, TransactionOptions};
2use crate::ast::*;
3use async_trait::async_trait;
4
5pub trait GetRow {
6    fn get_result_row(&self) -> crate::Result<Vec<Value<'static>>>;
7}
8
9pub trait TakeRow {
10    fn take_result_row(&mut self) -> crate::Result<Vec<Value<'static>>>;
11}
12
13pub trait ToColumnNames {
14    fn to_column_names(&self) -> Vec<String>;
15}
16
17/// Represents a connection or a transaction that can be queried.
18#[async_trait]
19pub trait Queryable: Send + Sync {
20    /// Execute the given query.
21    async fn query(&self, q: Query<'_>) -> crate::Result<ResultSet>;
22
23    /// Execute a query given as SQL, interpolating the given parameters.
24    async fn query_raw(&self, sql: &str, params: &[Value<'_>]) -> crate::Result<ResultSet>;
25
26    /// Execute a query given as SQL, interpolating the given parameters.
27    ///
28    /// On Postgres, query parameters types will be inferred from the values
29    /// instead of letting Postgres infer them based on their usage in the SQL query.
30    ///
31    /// NOTE: This method will eventually be removed & merged into Queryable::query_raw().
32    async fn query_raw_typed(&self, sql: &str, params: &[Value<'_>]) -> crate::Result<ResultSet>;
33
34    /// Execute the given query, returning the number of affected rows.
35    async fn execute(&self, q: Query<'_>) -> crate::Result<u64>;
36
37    /// Execute a query given as SQL, interpolating the given parameters and
38    /// returning the number of affected rows.
39    async fn execute_raw(&self, sql: &str, params: &[Value<'_>]) -> crate::Result<u64>;
40
41    /// Execute a query given as SQL, interpolating the given parameters and
42    /// returning the number of affected rows.
43    ///
44    /// On Postgres, query parameters types will be inferred from the values
45    /// instead of letting Postgres infer them based on their usage in the SQL query.
46    ///
47    /// NOTE: This method will eventually be removed & merged into Queryable::query_raw().
48    async fn execute_raw_typed(&self, sql: &str, params: &[Value<'_>]) -> crate::Result<u64>;
49
50    /// Run a command in the database, for queries that can't be run using
51    /// prepared statements.
52    async fn raw_cmd(&self, cmd: &str) -> crate::Result<()>;
53
54    /// Return the version of the underlying database, queried directly from the
55    /// source. This corresponds to the `version()` function on PostgreSQL for
56    /// example. The version string is returned directly without any form of
57    /// parsing or normalization.
58    async fn version(&self) -> crate::Result<Option<String>>;
59
60    /// Returns false, if connection is considered to not be in a working state.
61    fn is_healthy(&self) -> bool;
62
63    /// Execute a `SELECT` query.
64    async fn select(&self, q: Select<'_>) -> crate::Result<ResultSet> {
65        self.query(q.into()).await
66    }
67
68    /// Execute an `INSERT` query.
69    async fn insert(&self, q: Insert<'_>) -> crate::Result<ResultSet> {
70        self.query(q.into()).await
71    }
72
73    /// Execute an `UPDATE` query, returning the number of affected rows.
74    async fn update(&self, q: Update<'_>) -> crate::Result<u64> {
75        self.execute(q.into()).await
76    }
77
78    /// Execute a `DELETE` query, returning the number of affected rows.
79    async fn delete(&self, q: Delete<'_>) -> crate::Result<()> {
80        self.query(q.into()).await?;
81        Ok(())
82    }
83
84    /// Execute an arbitrary function in the beginning of each transaction.
85    async fn server_reset_query(&self, _: &Transaction<'_>) -> crate::Result<()> {
86        Ok(())
87    }
88
89    /// Statement to begin a transaction
90    fn begin_statement(&self) -> &'static str {
91        "BEGIN"
92    }
93
94    /// Sets the transaction isolation level to given value.
95    /// Implementers have to make sure that the passed isolation level is valid for the underlying database.
96    async fn set_tx_isolation_level(&self, isolation_level: IsolationLevel) -> crate::Result<()>;
97
98    /// Signals if the isolation level SET needs to happen before or after the tx BEGIN.
99    fn requires_isolation_first(&self) -> bool;
100}
101
102/// A thing that can start a new transaction.
103#[async_trait]
104pub trait TransactionCapable: Queryable
105where
106    Self: Sized,
107{
108    /// Starts a new transaction
109    async fn start_transaction(&self, isolation: Option<IsolationLevel>) -> crate::Result<Transaction<'_>> {
110        let opts = TransactionOptions::new(isolation, self.requires_isolation_first());
111        Transaction::new(self, self.begin_statement(), opts).await
112    }
113}