From 1825c3040f5ee71ad26185a7a08f2657ede94df5 Mon Sep 17 00:00:00 2001 From: Stefan Majewsky Date: Thu, 17 Sep 2026 16:51:17 +0200 Subject: rebase onto gg@v1.16.0/oblast --- dialect.go | 161 ------------------------------------------------------------- 1 file changed, 161 deletions(-) delete mode 100644 dialect.go (limited to 'dialect.go') diff --git a/dialect.go b/dialect.go deleted file mode 100644 index 11842eb..0000000 --- a/dialect.go +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-FileCopyrightText: 2026 Stefan Majewsky -// SPDX-License-Identifier: Apache-2.0 - -package oblast - -import ( - "database/sql" - "fmt" - "strconv" - "strings" -) - -var ( - // force imports to make docstring links work - _ = sql.Result(nil) -) - -// Dialect accounts for differences between different SQL dialects -// that are relevant to query generation within Oblast. -// -// # Compatibility notice -// -// This interface may be extended, even within minor versions, when doing so is -// required to add support for new DB dialects that differ from previously -// supported dialects in unexpected ways. -type Dialect interface { - // Placeholder returns the placeholder for the i-th query argument. - // Most dialects use "?", but e.g. PostgreSQL uses "$1", "$2" and so on. - // The argument numbers from 0 like a slice index. - Placeholder(i int) string - - // QuoteIdentifier wraps the name of a column or table in quotes, - // in order to avoid the name from being interpreted as a keyword. - QuoteIdentifier(name string) string - - // CanUseLastInsertId returns true if this type of database system can report - // a single auto-generated int primary key using [sql.Result.LastInsertId]. - // If true, the RETURNING clause will be omitted for matching INSERT queries. - CanUseLastInsertId() bool - - // UpsertClause generates an "ON CONFLICT" or similar clause - // that can be appended to an INSERT query to make it fall back to - // behave like UPDATE if a record with the same primary key already exists. - // This is only used for record types that have a primary key. - UpsertClause(pkColumns, otherColumns []string) string - - // String returns a unique identifier for this Dialect instance. - // Different instances shall return the same string only if all their methods behave identically. - // This information is used to cache generated query plans. - String() string -} - -// MariaDBDialect is the dialect of MariaDB 10.5+ databases. -// -// This dialect does NOT support MySQL, as well as ancient MariaDB versions (10.5 was released 2020-06-24), -// because those do not understand the "INSERT ... RETURNING" syntax. -func MariaDBDialect() Dialect { - return mariadbDialect{} -} - -type mariadbDialect struct{} - -func (mariadbDialect) Placeholder(_ int) string { - return "?" -} - -func (mariadbDialect) QuoteIdentifier(name string) string { - return "`" + strings.ReplaceAll(name, "`", "``") + "`" -} - -func (mariadbDialect) CanUseLastInsertId() bool { - return true -} - -func (d mariadbDialect) UpsertClause(pkColumns, otherColumns []string) string { - clauses := make([]string, max(1, len(otherColumns))) - if len(otherColumns) == 0 { - // we need at least one UPDATE clause; if there are no non-PK columns, - // we can just use one of the PK columns, updating those is a safe no-op - clauses[0] = fmt.Sprintf(`%[1]s = VALUES(%[1]s)`, d.QuoteIdentifier(pkColumns[0])) - } else { - for idx, name := range otherColumns { - clauses[idx] = fmt.Sprintf(`%[1]s = VALUES(%[1]s)`, d.QuoteIdentifier(name)) - } - } - return ` ON DUPLICATE KEY UPDATE ` + strings.Join(clauses, ", ") -} - -func (mariadbDialect) String() string { - return "mariadb" -} - -// PostgresDialect is the dialect of PostgreSQL databases. -func PostgresDialect() Dialect { - return postgresDialect{} -} - -type postgresDialect struct{} - -func (postgresDialect) Placeholder(i int) string { - return "$" + strconv.Itoa(i+1) -} - -func (postgresDialect) QuoteIdentifier(name string) string { - return `"` + strings.ReplaceAll(name, `"`, `""`) + `"` -} - -func (postgresDialect) CanUseLastInsertId() bool { - return false -} - -func (d postgresDialect) UpsertClause(pkColumns, otherColumns []string) string { - quotedPkColumns := make([]string, len(pkColumns)) - for idx, name := range pkColumns { - quotedPkColumns[idx] = d.QuoteIdentifier(name) - } - clauses := make([]string, len(otherColumns)) - for idx, name := range otherColumns { - clauses[idx] = fmt.Sprintf(`%[1]s = EXCLUDED.%[1]s`, d.QuoteIdentifier(name)) - } - if len(otherColumns) == 0 { - return fmt.Sprintf(` ON CONFLICT (%s) DO NOTHING`, strings.Join(quotedPkColumns, ", ")) - } else { - return fmt.Sprintf(` ON CONFLICT (%s) DO UPDATE SET %s`, - strings.Join(quotedPkColumns, ", "), strings.Join(clauses, ", ")) - } -} - -func (postgresDialect) String() string { - return "postgres" -} - -// SqliteDialect is the dialect of SQLite 3.35.0+ databases. -// -// This dialect does NOT support ancient SQLite versions (3.35.0 was released 2021-03-12) -// that do not understand the "INSERT ... RETURNING" syntax. -func SqliteDialect() Dialect { - return sqliteDialect{} -} - -type sqliteDialect struct{} - -func (sqliteDialect) Placeholder(_ int) string { - return "?" -} - -func (sqliteDialect) QuoteIdentifier(name string) string { - return `"` + strings.ReplaceAll(name, `"`, `""`) + `"` -} - -func (sqliteDialect) CanUseLastInsertId() bool { - return true -} - -func (sqliteDialect) UpsertClause(pkColumns, otherColumns []string) string { - return postgresDialect{}.UpsertClause(pkColumns, otherColumns) -} - -func (sqliteDialect) String() string { - return "sqliteDialect" -} -- cgit v1.3.1