Skip to main content

diesel_libsql/
backend.rs

1//! The LibSql backend definition.
2
3use diesel::backend::*;
4use diesel::sql_types::TypeMetadata;
5use diesel::sqlite::SqliteType;
6
7use crate::bind_collector::LibSqlBindCollector;
8use crate::value::LibSqlValue;
9
10/// The LibSql backend type for Diesel.
11///
12/// This is a separate backend from `diesel::sqlite::Sqlite` because libsql
13/// uses its own Rust API rather than raw C `sqlite3_stmt*` pointers.
14#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)]
15pub struct LibSql;
16
17/// Query builder for the LibSql backend.
18///
19/// Uses the same SQL syntax as SQLite (backtick quoting, `?` params).
20#[derive(Default)]
21pub struct LibSqlQueryBuilder {
22    sql: String,
23}
24
25impl diesel::query_builder::QueryBuilder<LibSql> for LibSqlQueryBuilder {
26    fn push_sql(&mut self, sql: &str) {
27        self.sql.push_str(sql);
28    }
29
30    fn push_identifier(&mut self, identifier: &str) -> diesel::QueryResult<()> {
31        self.sql.push('`');
32        self.sql.push_str(&identifier.replace('`', "``"));
33        self.sql.push('`');
34        Ok(())
35    }
36
37    fn push_bind_param(&mut self) {
38        self.sql.push('?');
39    }
40
41    fn finish(self) -> String {
42        self.sql
43    }
44}
45
46impl Backend for LibSql {
47    type QueryBuilder = LibSqlQueryBuilder;
48    type RawValue<'a> = LibSqlValue;
49    type BindCollector<'a> = LibSqlBindCollector<'a>;
50}
51
52impl TypeMetadata for LibSql {
53    type TypeMetadata = SqliteType;
54    type MetadataLookup = ();
55}
56
57/// On conflict clause type for LibSql (mirrors SQLite behavior).
58#[derive(Debug, Copy, Clone)]
59pub struct LibSqlOnConflictClause;
60
61impl sql_dialect::on_conflict_clause::SupportsOnConflictClause for LibSqlOnConflictClause {}
62impl sql_dialect::on_conflict_clause::SupportsOnConflictClauseWhere for LibSqlOnConflictClause {}
63impl sql_dialect::on_conflict_clause::PgLikeOnConflictClause for LibSqlOnConflictClause {}
64
65/// Batch insert support type for LibSql.
66#[derive(Debug, Copy, Clone)]
67pub struct LibSqlBatchInsert;
68
69/// Returning clause type for LibSql.
70#[derive(Debug, Copy, Clone)]
71pub struct LibSqlReturningClause;
72
73impl sql_dialect::returning_clause::SupportsReturningClause for LibSqlReturningClause {}
74
75impl SqlDialect for LibSql {
76    type ReturningClause = LibSqlReturningClause;
77    type OnConflictClause = LibSqlOnConflictClause;
78    type InsertWithDefaultKeyword =
79        sql_dialect::default_keyword_for_insert::IsoSqlDefaultKeyword;
80    type BatchInsertSupport = LibSqlBatchInsert;
81    type ConcatClause = sql_dialect::concat_clause::ConcatWithPipesClause;
82    type DefaultValueClauseForInsert = sql_dialect::default_value_clause::AnsiDefaultValueClause;
83    type EmptyFromClauseSyntax = sql_dialect::from_clause_syntax::AnsiSqlFromClauseSyntax;
84    type SelectStatementSyntax = sql_dialect::select_statement_syntax::AnsiSqlSelectStatement;
85    type ExistsSyntax = sql_dialect::exists_syntax::AnsiSqlExistsSyntax;
86    type ArrayComparison = sql_dialect::array_comparison::AnsiSqlArrayComparison;
87    type AliasSyntax = sql_dialect::alias_syntax::AsAliasSyntax;
88    type WindowFrameClauseGroupSupport =
89        sql_dialect::window_frame_clause_group_support::IsoGroupWindowFrameUnit;
90    type WindowFrameExclusionSupport =
91        sql_dialect::window_frame_exclusion_support::FrameExclusionSupport;
92    type AggregateFunctionExpressions =
93        sql_dialect::aggregate_function_expressions::PostgresLikeAggregateFunctionExpressions;
94    type BuiltInWindowFunctionRequireOrder =
95        sql_dialect::built_in_window_function_require_order::NoOrderRequired;
96}
97
98impl DieselReserveSpecialization for LibSql {}
99impl TrustedBackend for LibSql {}