1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//! Traits to represent a database driver.
//!
//! # Support
//!
//! ## Tier 1
//!
//! Tier 1 support can be thought of as "guaranteed to work". Automated testing is setup to
//! ensure a high level of stability and functionality.
//!
//! | Database | Version | Driver |
//! | - | - | - |
//! | [MariaDB] | 10.1+ | [`mysql`] |
//! | [Microsoft SQL Server] | 2019 | [`mssql`] |
//! | [MySQL] | 5.6, 5.7, 8.0 | [`mysql`] |
//! | [PostgreSQL] | 9.5+ | [`postgres`] |
//! | [SQLite] | 3.20.1+ | [`sqlite`] |
//!
//! [MariaDB]: https://mariadb.com/
//! [MySQL]: https://www.mysql.com/
//! [Microsoft SQL Server]: https://www.microsoft.com/en-us/sql-server
//! [PostgreSQL]: https://www.postgresql.org/
//! [SQLite]: https://www.sqlite.org/
//!
//! [`mysql`]: crate::mysql
//! [`postgres`]: crate::postgres
//! [`mssql`]: crate::mssql
//! [`sqlite`]: crate::sqlite
//!
//! ## Tier 2
//!
//! Tier 2 support can be thought as "should work". No specific automated testing is done,
//! at this time, but there are efforts to ensure compatibility. Tier 2 support also includes
//! database distributions that provide protocols that closely match a database from Tier 1.
//!
//! _No databases are in tier 2 at this time._
//!
//! # `Any`
//!
//! Selecting a database driver is, by default, a compile-time decision. SQLx is designed this way
//! to take full advantage of the performance and type safety made available by Rust.
//!
//! We recognize that you may wish to make a runtime decision to decide the database driver. The
//! [`Any`](crate::any) driver is provided for that purpose.
//!
//! ## Example
//!
//! ```rust,ignore
//! // connect to SQLite
//! let conn = AnyConnection::connect("sqlite://file.db").await?;
//!
//! // connect to Postgres, no code change
//! // required, decided by the scheme of the URL
//! let conn = AnyConnection::connect("postgres://localhost/sqlx").await?;
//! ```

use std::fmt::Debug;

use crate::arguments::Arguments;
use crate::column::Column;
use crate::connection::Connection;
use crate::row::Row;

use crate::statement::Statement;
use crate::transaction::TransactionManager;
use crate::type_info::TypeInfo;
use crate::value::{Value, ValueRef};

/// A database driver.
///
/// This trait encapsulates a complete set of traits that implement a driver for a
/// specific database (e.g., MySQL, PostgreSQL).
pub trait Database:
    'static
    + Sized
    + Send
    + Debug
    + for<'r> HasValueRef<'r, Database = Self>
    + for<'q> HasArguments<'q, Database = Self>
    + for<'q> HasStatement<'q, Database = Self>
{
    /// The concrete `Connection` implementation for this database.
    type Connection: Connection<Database = Self>;

    /// The concrete `TransactionManager` implementation for this database.
    type TransactionManager: TransactionManager<Database = Self>;

    /// The concrete `Row` implementation for this database.
    type Row: Row<Database = Self>;

    /// The concrete `QueryResult` implementation for this database.
    type QueryResult: 'static + Sized + Send + Sync + Default + Extend<Self::QueryResult>;

    /// The concrete `Column` implementation for this database.
    type Column: Column<Database = Self>;

    /// The concrete `TypeInfo` implementation for this database.
    type TypeInfo: TypeInfo;

    /// The concrete type used to hold an owned copy of the not-yet-decoded value that was
    /// received from the database.
    type Value: Value<Database = Self> + 'static;

    /// The display name for this database driver.
    const NAME: &'static str;

    /// The schemes for database URLs that should match this driver.
    const URL_SCHEMES: &'static [&'static str];
}

/// Associate [`Database`] with a [`ValueRef`](crate::value::ValueRef) of a generic lifetime.
///
/// ---
///
/// The upcoming Rust feature, [Generic Associated Types], should obviate
/// the need for this trait.
///
/// [Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
pub trait HasValueRef<'r> {
    type Database: Database;

    /// The concrete type used to hold a reference to the not-yet-decoded value that has just been
    /// received from the database.
    type ValueRef: ValueRef<'r, Database = Self::Database>;
}

/// Associate [`Database`] with an [`Arguments`](crate::arguments::Arguments) of a generic lifetime.
///
/// ---
///
/// The upcoming Rust feature, [Generic Associated Types], should obviate
/// the need for this trait.
///
/// [Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
pub trait HasArguments<'q> {
    type Database: Database;

    /// The concrete `Arguments` implementation for this database.
    type Arguments: Arguments<'q, Database = Self::Database>;

    /// The concrete type used as a buffer for arguments while encoding.
    type ArgumentBuffer;
}

/// Associate [`Database`] with a [`Statement`](crate::statement::Statement) of a generic lifetime.
///
/// ---
///
/// The upcoming Rust feature, [Generic Associated Types], should obviate
/// the need for this trait.
///
/// [Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
pub trait HasStatement<'q> {
    type Database: Database;

    /// The concrete `Statement` implementation for this database.
    type Statement: Statement<'q, Database = Self::Database>;
}

/// A [`Database`] that maintains a client-side cache of prepared statements.
pub trait HasStatementCache {}