Skip to main content

fraiseql_db/
identifier.rs

1//! Database identifier quoting utilities.
2//!
3//! This module provides database-specific identifier quoting functions that handle
4//! schema-qualified identifiers (e.g., `schema.table`, `catalog.schema.table`).
5//!
6//! Each function splits on `.` and quotes each component with the appropriate syntax
7//! for the target database.
8
9/// Quote a PostgreSQL identifier.
10///
11/// PostgreSQL uses double quotes for identifiers. Schema-qualified names
12/// (e.g., `schema.table`) are split and quoted per component.
13///
14/// # Examples
15///
16/// ```rust
17/// use fraiseql_db::quote_postgres_identifier;
18/// assert_eq!(quote_postgres_identifier("v_user"), "\"v_user\"");
19/// assert_eq!(quote_postgres_identifier("benchmark.v_user"), "\"benchmark\".\"v_user\"");
20/// assert_eq!(
21///     quote_postgres_identifier("catalog.schema.table"),
22///     "\"catalog\".\"schema\".\"table\""
23/// );
24/// ```
25#[inline]
26#[must_use]
27pub fn quote_postgres_identifier(identifier: &str) -> String {
28    identifier
29        .split('.')
30        .map(|part| format!("\"{}\"", part.replace('"', "\"\"")))
31        .collect::<Vec<_>>()
32        .join(".")
33}
34
35/// Quote a MySQL identifier.
36///
37/// MySQL uses backticks for identifiers. Schema-qualified names
38/// (e.g., `database.table`) are split and quoted per component.
39///
40/// # Examples
41///
42/// ```rust
43/// use fraiseql_db::quote_mysql_identifier;
44/// assert_eq!(quote_mysql_identifier("v_user"), "`v_user`");
45/// assert_eq!(quote_mysql_identifier("mydb.v_user"), "`mydb`.`v_user`");
46/// assert_eq!(
47///     quote_mysql_identifier("catalog.schema.table"),
48///     "`catalog`.`schema`.`table`"
49/// );
50/// ```
51#[inline]
52#[must_use]
53pub fn quote_mysql_identifier(identifier: &str) -> String {
54    identifier
55        .split('.')
56        .map(|part| format!("`{}`", part.replace('`', "``")))
57        .collect::<Vec<_>>()
58        .join(".")
59}
60
61/// Quote a SQLite identifier.
62///
63/// SQLite uses double quotes for identifiers. Schema-qualified names
64/// (e.g., `schema.table`) are split and quoted per component.
65///
66/// # Examples
67///
68/// ```rust
69/// use fraiseql_db::quote_sqlite_identifier;
70/// assert_eq!(quote_sqlite_identifier("v_user"), "\"v_user\"");
71/// assert_eq!(quote_sqlite_identifier("main.v_user"), "\"main\".\"v_user\"");
72/// assert_eq!(
73///     quote_sqlite_identifier("catalog.schema.table"),
74///     "\"catalog\".\"schema\".\"table\""
75/// );
76/// ```
77#[inline]
78#[must_use]
79pub fn quote_sqlite_identifier(identifier: &str) -> String {
80    identifier
81        .split('.')
82        .map(|part| format!("\"{}\"", part.replace('"', "\"\"")))
83        .collect::<Vec<_>>()
84        .join(".")
85}
86
87/// Quote a SQL Server identifier.
88///
89/// SQL Server uses square brackets for identifiers. Schema-qualified names
90/// (e.g., `schema.table`) are split and quoted per component.
91///
92/// # Examples
93///
94/// ```rust
95/// use fraiseql_db::quote_sqlserver_identifier;
96/// assert_eq!(quote_sqlserver_identifier("v_user"), "[v_user]");
97/// assert_eq!(quote_sqlserver_identifier("dbo.v_user"), "[dbo].[v_user]");
98/// assert_eq!(
99///     quote_sqlserver_identifier("catalog.schema.table"),
100///     "[catalog].[schema].[table]"
101/// );
102/// ```
103#[inline]
104#[must_use]
105pub fn quote_sqlserver_identifier(identifier: &str) -> String {
106    identifier
107        .split('.')
108        .map(|part| format!("[{}]", part.replace(']', "]]")))
109        .collect::<Vec<_>>()
110        .join(".")
111}
112
113#[cfg(test)]
114mod tests;