generic

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2025 License: MIT Imports: 5 Imported by: 0

README

🗄️ Generic Dialect

Part of Entiqon / Database / Dialect

The Generic Dialect is the ANSI SQL–compliant baseline implementation for the Entiqon SQL builder.
It provides a safe default when generating SQL queries against unknown or mixed databases.


✨ Features

  • ANSI-compliant quoting

    • Identifiers quoted with double quotes ("users", "UserData")
    • Lowercase simple names left unquoted (users)
  • Placeholders

    • Always ? (non-positional, ANSI style)
  • Pagination

    • Standard LIMIT and OFFSET syntax
  • Literal quoting

    • Strings: escaped and single-quoted ('O''Reilly')
    • Booleans: TRUE / FALSE
    • Numbers: plain decimal form
    • time.Time: UTC 'YYYY-MM-DD HH:MM:SS'
    • nil: NULL
  • Capabilities

    • ✅ CTE (WITH ...)
    • ✅ Window functions (OVER(...))
    • ❌ RETURNING not supported
    • ❌ MERGE not supported
    • ❌ UPSERT not supported

🚀 Usage

import (
    "fmt"
    "entiqon/db/dialect/generic"
)

func main() {
    d := generic.New()

    // Quote identifiers
    fmt.Println(d.QuoteIdentifier("users"))     // → users
    fmt.Println(d.QuoteIdentifier("UserData"))  // → "UserData"

    // Quote literals
    fmt.Println(d.QuoteLiteral("O'Reilly"))     // → 'O''Reilly'
    fmt.Println(d.QuoteLiteral(true))           // → TRUE

    // Pagination
    sql := fmt.Sprintf("SELECT %s FROM %s%s",
        d.QuoteIdentifier("id"),
        d.QuoteIdentifier("users"),
        d.PaginationSyntax(10, 0),
    )
    fmt.Println(sql)
    // → SELECT "id" FROM "users" LIMIT 10
}

🔍 When to Use

  • As a fallback when the target database dialect is unknown.
  • For unit tests to validate SQL builders in a dialect-agnostic way.
  • As a template when creating a new vendor-specific dialect (e.g. Postgres, MySQL).

Documentation

Overview

Package generic provides the ANSI-compliant SQL dialect implementation.

Overview

The generic dialect is a safe default for generating SQL statements when no vendor-specific behavior is required or when the target database is unknown. It follows the ANSI SQL standard as closely as possible:

  • Identifiers are quoted using double quotes (").
  • Placeholders are always "?" and are not positional.
  • Pagination is rendered using LIMIT and OFFSET clauses.
  • RETURNING, MERGE, and UPSERT clauses are not supported.

Usage

The generic dialect is not instantiated directly. Instead, call New() to obtain a ready-to-use instance that implements the dialect.SQLDialect interface:

d := generic.New()
sql := fmt.Sprintf(
    "SELECT %s FROM %s%s",
    d.QuoteIdentifier("id"),
    d.QuoteIdentifier("users"),
    d.PaginationSyntax(10, 0),
)
// Produces: SELECT "id" FROM "users" LIMIT 10

Capabilities

The generic dialect advertises its supported features through the Options() method. This allows builders to conditionally include clauses:

opts := d.Options()
fmt.Println(opts.SupportsCTE)          // true
fmt.Println(opts.EnableReturning)      // false
fmt.Println(opts.AllowUpsert)          // false

When to Use

Use this dialect as:

  • A fallback when no database-specific dialect is configured.
  • A baseline for testing SQL builders in a dialect-agnostic way.
  • A template for implementing new dialects (e.g., Postgres, MySQL).

For vendor-specific features such as RETURNING (Postgres, Oracle) or vendor-specific placeholder formats, use the corresponding dialect package.

Example
package main

import (
	"fmt"

	"github.com/entiqon/db/dialect/generic"
)

func main() {
	d := generic.New()
	fmt.Println(d.Name())
}
Output:
generic
Example (Options)
package main

import (
	"fmt"

	"github.com/entiqon/db/dialect/generic"
)

func main() {
	d := generic.New()
	opts := d.Options()
	fmt.Printf("Name=%s, Placeholder=%s\n", opts.Name, opts.PlaceholderStyle)
}
Output:
Name=generic, Placeholder=?
Example (PaginationSyntax)
package main

import (
	"fmt"

	"github.com/entiqon/db/dialect/generic"
)

func main() {
	d := generic.New()
	fmt.Println(d.PaginationSyntax(10, 0))
	fmt.Println(d.PaginationSyntax(10, 20))
	fmt.Println(d.PaginationSyntax(0, 0))
}
Output:
 LIMIT 10
 LIMIT 10 OFFSET 20
Example (Placeholder)
package main

import (
	"fmt"

	"github.com/entiqon/db/dialect/generic"
)

func main() {
	d := generic.New()
	fmt.Println(d.Placeholder(1))
	fmt.Println(d.Placeholder(99))
}
Output:
?
?
Example (QuoteIdentifier)
package main

import (
	"fmt"

	"github.com/entiqon/db/dialect/generic"
)

func main() {
	d := generic.New()
	fmt.Println(d.QuoteIdentifier("users"))
	fmt.Println(d.QuoteIdentifier("UserData"))
	fmt.Println(d.QuoteIdentifier("order items"))
}
Output:
users
"UserData"
"order items"
Example (QuoteLiteral)
package main

import (
	"fmt"
	"time"

	"github.com/entiqon/db/dialect/generic"
)

func main() {
	d := generic.New()
	fmt.Println(d.QuoteLiteral("O'Reilly"))
	fmt.Println(d.QuoteLiteral(true))
	fmt.Println(d.QuoteLiteral(42))
	fmt.Println(d.QuoteLiteral(time.Date(2025, 9, 19, 3, 30, 0, 0, time.UTC)))
}
Output:
'O''Reilly'
TRUE
42
'2025-09-19 03:30:00'

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New() dialect.SQLDialect

New returns a new ANSI-compliant generic dialect. The returned value implements the dialect.SQLDialect interface.

Example:

d := generic.New()
sql := fmt.Sprintf("SELECT %s FROM %s%s",
    d.QuoteIdentifier("id"),
    d.QuoteIdentifier("users"),
    d.PaginationSyntax(10, 0))

Produces:

SELECT "id" FROM "users" LIMIT 10

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL