Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: create sqlx.toml format #3383

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 51 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,19 @@ authors.workspace = true
repository.workspace = true

[package.metadata.docs.rs]
features = ["all-databases", "_unstable-all-types"]
features = ["all-databases", "_unstable-all-types", "_unstable-doc"]
rustdoc-args = ["--cfg", "docsrs"]

[features]
default = ["any", "macros", "migrate", "json"]
default = ["any", "macros", "migrate", "json", "sqlx-toml"]

derive = ["sqlx-macros/derive"]
macros = ["derive", "sqlx-macros/macros"]
migrate = ["sqlx-core/migrate", "sqlx-macros?/migrate", "sqlx-mysql?/migrate", "sqlx-postgres?/migrate", "sqlx-sqlite?/migrate"]

# Enable parsing of `sqlx.toml` for configuring macros and migrations.
sqlx-toml = ["sqlx-core/sqlx-toml", "sqlx-macros?/sqlx-toml"]

# intended mainly for CI and docs
all-databases = ["mysql", "sqlite", "postgres", "any"]
_unstable-all-types = [
Expand All @@ -73,6 +76,8 @@ _unstable-all-types = [
"uuid",
"bit-vec",
]
# Render documentation that wouldn't otherwise be shown (e.g. `sqlx_core::config`).
_unstable-doc = []

# Base runtime features without TLS
runtime-async-std = ["_rt-async-std", "sqlx-core/_rt-async-std", "sqlx-macros?/_rt-async-std"]
Expand Down
5 changes: 4 additions & 1 deletion sqlx-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ filetime = "0.2"
backoff = { version = "0.4.0", features = ["futures", "tokio"] }

[features]
default = ["postgres", "sqlite", "mysql", "native-tls", "completions"]
default = ["postgres", "sqlite", "mysql", "native-tls", "completions", "sqlx-toml"]

rustls = ["sqlx/runtime-tokio-rustls"]
native-tls = ["sqlx/runtime-tokio-native-tls"]

Expand All @@ -65,6 +66,8 @@ openssl-vendored = ["openssl/vendored"]

completions = ["dep:clap_complete"]

sqlx-toml = ["sqlx/sqlx-toml"]

[dev-dependencies]
assert_cmd = "2.0.11"
tempfile = "3.10.1"
Expand Down
9 changes: 9 additions & 0 deletions sqlx-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ _tls-none = []
# support offline/decoupled building (enables serialization of `Describe`)
offline = ["serde", "either/serde"]

# Enable parsing of `sqlx.toml`.
# For simplicity, the `config` module is always enabled,
# but disabling this disables the `serde` derives and the `toml` crate,
# which is a good bit less code to compile if the feature isn't being used.
sqlx-toml = ["serde", "toml/parse"]

_unstable-doc = ["sqlx-toml"]

[dependencies]
# Runtimes
async-std = { workspace = true, optional = true }
Expand Down Expand Up @@ -77,6 +85,7 @@ percent-encoding = "2.1.0"
regex = { version = "1.5.5", optional = true }
serde = { version = "1.0.132", features = ["derive", "rc"], optional = true }
serde_json = { version = "1.0.73", features = ["raw_value"], optional = true }
toml = { version = "0.8.16", optional = true }
sha1 = { version = "0.10.1", default-features = false, optional = true }
sha2 = { version = "0.10.0", default-features = false, optional = true }
sqlformat = "0.2.0"
Expand Down
54 changes: 54 additions & 0 deletions sqlx-core/src/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::database::Database;
use crate::error::Error;

use std::fmt::Debug;
use std::sync::Arc;

pub trait Column: 'static + Send + Sync + Debug {
type Database: Database<Column = Self>;
Expand All @@ -20,6 +21,59 @@ pub trait Column: 'static + Send + Sync + Debug {

/// Gets the type information for the column.
fn type_info(&self) -> &<Self::Database as Database>::TypeInfo;

/// If this column comes from a table, return the table and original column name.
///
/// Returns [`ColumnOrigin::Expression`] if the column is the result of an expression
/// or else the source table could not be determined.
///
/// Returns [`ColumnOrigin::Unknown`] if the database driver does not have that information,
/// or has not overridden this method.
// This method returns an owned value instead of a reference,
// to give the implementor more flexibility.
fn origin(&self) -> ColumnOrigin { ColumnOrigin::Unknown }
}

/// A [`Column`] that originates from a table.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
pub struct TableColumn {
/// The name of the table (optionally schema-qualified) that the column comes from.
pub table: Arc<str>,
/// The original name of the column.
pub name: Arc<str>,
}

/// The possible statuses for our knowledge of the origin of a [`Column`].
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
pub enum ColumnOrigin {
/// The column is known to originate from a table.
///
/// Included is the table name and original column name.
Table(TableColumn),
/// The column originates from an expression, or else its origin could not be determined.
Expression,
/// The database driver does not know the column origin at this time.
///
/// This may happen if:
/// * The connection is in the middle of executing a query,
/// and cannot query the catalog to fetch this information.
/// * The connection does not have access to the database catalog.
/// * The implementation of [`Column`] did not override [`Column::origin()`].
#[default]
Unknown,
}

impl ColumnOrigin {
/// Returns the true column origin, if known.
pub fn table_column(&self) -> Option<&TableColumn> {
if let Self::Table(table_column) = self {
Some(table_column)
} else {
None
}
}
}

/// A type that can be used to index into a [`Row`] or [`Statement`].
Expand Down
49 changes: 49 additions & 0 deletions sqlx-core/src/config/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/// Configuration shared by multiple components.
#[derive(Debug, Default)]
#[cfg_attr(
feature = "sqlx-toml",
derive(serde::Deserialize),
serde(default, rename_all = "kebab-case")
)]
pub struct Config {
/// Override the database URL environment variable.
///
/// This is used by both the macros and `sqlx-cli`.
///
/// Case-sensitive. Defaults to `DATABASE_URL`.
///
/// Example: Multi-Database Project
/// -------
/// You can use multiple databases in the same project by breaking it up into multiple crates,
/// then using a different environment variable for each.
///
/// For example, with two crates in the workspace named `foo` and `bar`:
///
/// #### `foo/sqlx.toml`
/// ```toml
/// [common]
/// database-url-var = "FOO_DATABASE_URL"
/// ```
///
/// #### `bar/sqlx.toml`
/// ```toml
/// [common]
/// database-url-var = "BAR_DATABASE_URL"
/// ```
///
/// #### `.env`
/// ```text
/// FOO_DATABASE_URL=postgres://postgres@localhost:5432/foo
/// BAR_DATABASE_URL=postgres://postgres@localhost:5432/bar
/// ```
///
/// The query macros used in `foo` will use `FOO_DATABASE_URL`,
/// and the ones used in `bar` will use `BAR_DATABASE_URL`.
pub database_url_var: Option<String>,
}

impl Config {
pub fn database_url_var(&self) -> &str {
self.database_url_var.as_deref().unwrap_or("DATABASE_URL")
}
}
Loading
Loading