OOro

驱动适配器

官方驱动边界、第三方驱动开发、Dialect、Inspector 和 database/sql 包装。

Oro 当前是关系型 SQL ORM。驱动体系面向 database/sql 和 SQL/类 SQL 数据库。

官方驱动做什么

官方驱动包包括三部分:

部分 职责
Driver 打开连接、返回方言、返回结构检查器、错误转换
Dialect 把 Oro AST 编译成具体 SQL
Inspector 读取当前数据库表结构,用于自动同步

官方驱动不主动注册具体 SQL driver:

import (
    "github.com/duxweb/oro/driver/sqlite"
    _ "modernc.org/sqlite"
)

第三方驱动能做什么

第三方可以独立开发 Oracle、SQL Server、ClickHouse、DuckDB、CockroachDB 等 SQL 数据库驱动。

package oracle

func Open(dsn string, options ...Option) oro.Driver {
    return driver{driverName: "oracle", dsn: dsn, owned: true}
}

func Wrap(db *sql.DB, options ...Option) oro.Driver {
    return driver{db: db, owned: false}
}

Driver 接口

type Driver interface {
    Name() string
    Open(ctx context.Context) (*sql.DB, error)
    Dialect() oro.Dialect
    Inspector(db *sql.DB) oro.Inspector
    TranslateError(err error) error
    Owned() bool
}

Dialect 接口

type Dialect interface {
    Name() string
    Capabilities() oro.Capabilities
    QuoteIdent(name string) string
    Placeholder(index int) string
    DataType(column oro.ColumnSpec) (string, error)
    NormalizeType(dbType string) (oro.ColumnType, error)
    Compile(stmt oro.Statement) (oro.CompiledSQL, error)
    CompileSchema(change oro.SchemaChange) ([]oro.CompiledSQL, error)
}

Oro 内部负责链式 API 到 AST;第三方方言负责 AST 到目标 SQL。

Use/Where/Select/Join

Oro Query AST

Dialect.Compile

目标数据库 SQL

database/sql 执行

Inspector 接口

type Inspector interface {
    Tables(ctx context.Context) ([]oro.TableInfo, error)
    Table(ctx context.Context, name string) (*oro.TableSpec, error)
    Indexes(ctx context.Context, table string) ([]oro.IndexSpec, error)
    Constraints(ctx context.Context, table string) ([]oro.ConstraintSpec, error)
}

Sync() 依赖 Inspector。若第三方驱动不支持自动同步,可以返回不支持错误;完整 SQL 驱动建议实现它。

MongoDB 适合吗

不适合直接放进当前 oro.Driver。MongoDB 是文档数据库,不是 database/sql 关系型 SQL 数据库。除非第三方提供非常完整的 SQL 兼容层,否则语义会很别扭。MongoDB 更适合独立 ODM。

错误转换

func (driver) TranslateError(err error) error {
    // 把唯一冲突、约束、死锁、序列化失败转换为 oro.ErrConflict 等
    return err
}

建议至少识别:

  • 唯一冲突:oro.ErrConflict
  • 约束错误:oro.ErrConstraint
  • 死锁:oro.ErrDeadlock
  • 序列化失败:oro.ErrSerializationFailure
编辑此页