pub const GUARD_MESSAGE_PREFIX: &str = "fraiseql-server: unsupported database URL";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DatabaseScheme {
Postgres,
MySql,
Sqlite,
SqlServer,
}
impl DatabaseScheme {
#[must_use]
pub const fn required_feature(self) -> Option<&'static str> {
match self {
Self::Postgres => None,
Self::MySql => Some("mysql"),
Self::Sqlite => Some("sqlite"),
Self::SqlServer => Some("sqlserver"),
}
}
}
pub fn guard_sqlite_mutations(
schema: &fraiseql_core::schema::CompiledSchema,
) -> anyhow::Result<()> {
use fraiseql_core::schema::MutationOperation;
let unsupported: Vec<&str> = schema
.mutations
.iter()
.filter(|m| {
matches!(m.operation, MutationOperation::Update { .. } | MutationOperation::Custom)
})
.map(|m| m.name.as_str())
.collect();
if unsupported.is_empty() {
return Ok(());
}
let sample: Vec<&str> = unsupported.iter().take(3).copied().collect();
let suffix = if unsupported.len() > sample.len() {
format!(", … (+{} more)", unsupported.len() - sample.len())
} else {
String::new()
};
anyhow::bail!(
"fraiseql-server: SQLite supports only direct-SQL Insert/Delete mutations, but the \
compiled schema declares {} Update or custom mutation(s) which cannot be executed \
against a SQLite database. Use a postgresql:// / mysql:// / sqlserver:// URL, or remove \
those mutations from the schema. Affected: {}{}",
unsupported.len(),
sample.join(", "),
suffix,
)
}
pub fn parse_database_url(url: &str) -> anyhow::Result<DatabaseScheme> {
let scheme = url.split("://").next().unwrap_or("");
match scheme {
"postgresql" | "postgres" => Ok(DatabaseScheme::Postgres),
"mysql" => Ok(DatabaseScheme::MySql),
"sqlite" => Ok(DatabaseScheme::Sqlite),
"sqlserver" => Ok(DatabaseScheme::SqlServer),
"" => anyhow::bail!(
"{GUARD_MESSAGE_PREFIX} — the URL has no scheme. Expected one of \
postgresql:// | postgres:// | mysql:// | sqlite:// | sqlserver://."
),
other => anyhow::bail!(
"{GUARD_MESSAGE_PREFIX} (observed URL scheme: {other:?}). The \
fraiseql-server binary dispatches on the URL scheme and supports \
postgresql:// | postgres:// | mysql:// | sqlite:// | sqlserver:// \
only."
),
}
}
#[cfg(test)]
mod tests;