refactor: 接口 ISqlDialect 改名 SqlDialect(仓颉惯例,去掉 I 前缀,删除兼容别名,同步 README 与文件名 sql_dialect.cj)

This commit is contained in:
2026-08-25 12:32:30 +08:00
parent 985473b8a7
commit 401e6a9bf2
11 changed files with 39 additions and 42 deletions
+4 -4
View File
@@ -4,7 +4,7 @@
> 仓颉版 ORM:**基于数据模型(POCO + 注解)的映射、增删改查、数据库迁移**。
面向多数据库的方言架构:内置 PostgreSQL(`PostgreSqlDialect`)与 openGauss(`OpenGaussDialect`,继承 PG)方言(对接 [opengauss-driver](../opengauss-driver)),可通过实现 `ISqlDialect` 接口接入 sqlite / mysql 等新数据库。包本身零外部依赖。
面向多数据库的方言架构:内置 PostgreSQL(`PostgreSqlDialect`)与 openGauss(`OpenGaussDialect`,继承 PG)方言(对接 [opengauss-driver](../opengauss-driver)),可通过实现 `SqlDialect` 接口接入 sqlite / mysql 等新数据库。包本身零外部依赖。
---
@@ -279,7 +279,7 @@ orm-cj/
│ ├── model/ # EntityModel(反射映射)、ModelCache(模型缓存)、
│ │ # ColumnNamingPolicy(列命名策略)、ValueReader、ParamBinder、GuidUtil
│ ├── tracking/ # ChangeTracker(操作队列)、EntityState、EntityEntry
│ ├── sql/ # ISqlDialect 接口(独立文件)+ PostgreSqlDialect(PG 实现)+
│ ├── sql/ # SqlDialect 接口(独立文件)+ PostgreSqlDialect(PG 实现)+
│ │ # OpenGaussDialect(继承 PG)、ColumnTypes(列类型)
│ ├── query/ # QueryBuilder<T>(条件/排序/分页)、PagedResult<T>
│ ├── db/ # DbContext(连接 + 提交 + 物化 + 数据库存在性/迁移状态检查)、DbSet<T>
@@ -439,7 +439,7 @@ cjpm test # 纯逻辑单元测试(模型映射/SQL 生成/DDL 生成/QueryB
- 不支持导航属性 / 延迟加载 / 级联删除(这些能力属于 v2+);
- 不支持 LINQ 表达式树,查询以 `filter` 条件方法 + SQL 片段组合;
- `QueryBuilder` 的 SQL 片段形式(`filter(condition, params)`)需自行保证列名合法(会做标识符引号包裹校验外的处理)——推荐优先使用三参属性形式;
- 自增主键回读依赖驱动 `RETURNING` 支持(openGauss/PostgreSQL 原生支持;换方言时由 `ISqlDialect.buildInsert` 决定回读策略)。
- 自增主键回读依赖驱动 `RETURNING` 支持(openGauss/PostgreSQL 原生支持;换方言时由 `SqlDialect.buildInsert` 决定回读策略)。
---
@@ -450,7 +450,7 @@ cjpm test # 纯逻辑单元测试(模型映射/SQL 生成/DDL 生成/QueryB
| 数据库驱动(使用者引入,如 `opengauss` → `../opengauss-driver`) | 实现 `std.database.sql` 的 `Datasource`/`Connection`/`Statement` |
| `stdx`(CANGJIE_STDX_PATH) | 标准扩展库(std.database.sql 接口) |
> orm-cj 包本身零依赖:连接层走 `std.database.sql` 标准接口,SQL/DDL 生成走 `ISqlDialect` 方言接口。新数据库接入 = 实现 `ISqlDialect`(CRUD + 列类型映射 + 差异 DDL 语句)+ 提供对应 `std.database.sql` 驱动。
> orm-cj 包本身零依赖:连接层走 `std.database.sql` 标准接口,SQL/DDL 生成走 `SqlDialect` 方言接口。新数据库接入 = 实现 `SqlDialect`(CRUD + 列类型映射 + 差异 DDL 语句)+ 提供对应 `std.database.sql` 驱动。
---
+1 -1
View File
@@ -20,7 +20,7 @@ public interface CliContext {
/// 应用主数据源
func getDatasource(): Datasource
/// SQL 方言
func getDialect(): ISqlDialect
func getDialect(): SqlDialect
/// 迁移列表(子类 override migrations() 提供)
func getMigrations(): ArrayList<Migration>
/// 应用所有迁移
+8 -8
View File
@@ -94,7 +94,7 @@ public class MigrationCli {
private func dispatch(args: ArrayList<String>, models: () -> ArrayList<EntityModel>,
datasource: () -> Datasource, migrations: () -> ArrayList<Migration>,
dialect: ISqlDialect, seedCtx: ?Any): Int64 {
dialect: SqlDialect, seedCtx: ?Any): Int64 {
if (args.size == 0) {
printHelp()
return 0
@@ -122,7 +122,7 @@ public class MigrationCli {
/// database <子命令>:数据库级操作(不需要迁移注册)
private func cmdDatabase(args: ArrayList<String>, datasource: () -> Datasource,
dialect: ISqlDialect): Int64 {
dialect: SqlDialect): Int64 {
if (args.size < 2) {
println("用法: simcu::orm database <truncate|drop>")
return 1
@@ -137,7 +137,7 @@ public class MigrationCli {
}
/// database truncate:清空所有业务表数据(保留表结构与迁移历史)
private func cmdTruncate(datasource: () -> Datasource, dialect: ISqlDialect): Int64 {
private func cmdTruncate(datasource: () -> Datasource, dialect: SqlDialect): Int64 {
try {
let migrator = Migrator(datasource(), dialect)
let n = migrator.truncateAll()
@@ -151,7 +151,7 @@ public class MigrationCli {
}
/// database drop:删除所有表(含迁移历史),完全清空数据库;之后可 update 重建
private func cmdDrop(datasource: () -> Datasource, dialect: ISqlDialect): Int64 {
private func cmdDrop(datasource: () -> Datasource, dialect: SqlDialect): Int64 {
try {
let migrator = Migrator(datasource(), dialect)
let n = migrator.dropAllTables()
@@ -217,7 +217,7 @@ public class MigrationCli {
/// update:应用所有未执行的迁移
private func cmdUpdate(datasource: () -> Datasource,
migrations: () -> ArrayList<Migration>, dialect: ISqlDialect): Int64 {
migrations: () -> ArrayList<Migration>, dialect: SqlDialect): Int64 {
let list = migrations()
if (list.size == 0) {
println("simcu::orm: 未注册任何迁移(检查 ${_registryPath})")
@@ -231,7 +231,7 @@ public class MigrationCli {
/// downgrade [目标]:回退迁移(执行 down + 删除历史记录;无目标 = 回退最近一个)
private func cmdDowngrade(datasource: () -> Datasource, migrations: () -> ArrayList<Migration>,
dialect: ISqlDialect, args: ArrayList<String>): Int64 {
dialect: SqlDialect, args: ArrayList<String>): Int64 {
let list = migrations()
if (list.size == 0) {
println("simcu::orm: 未注册任何迁移(检查 ${_registryPath})")
@@ -334,7 +334,7 @@ public class MigrationCli {
/// list:显示已应用/待应用迁移(空库/全新库时全部显示为待应用)
private func cmdList(datasource: () -> Datasource, migrations: () -> ArrayList<Migration>,
dialect: ISqlDialect): Int64 {
dialect: SqlDialect): Int64 {
let list = migrations()
if (list.size == 0) {
println("simcu::orm: 未注册任何迁移(检查 ${_registryPath})")
@@ -365,7 +365,7 @@ public class MigrationCli {
/// seed:列出/运行数据填充(@Seed 标注的类,按 seedId 唯一前缀匹配;--all 全部;无参=列出)
private func cmdSeed(datasource: () -> Datasource, migrations: () -> ArrayList<Migration>,
dialect: ISqlDialect, args: ArrayList<String>, seedCtx: ?Any): Int64 {
dialect: SqlDialect, args: ArrayList<String>, seedCtx: ?Any): Int64 {
let list = allSeeds()
if (list.size == 0) {
println("simcu::orm: 未注册任何填充(检查 @Seed 标注的类是否存在,并确认应用已 import 对应包)")
+5 -5
View File
@@ -41,13 +41,13 @@ import simcu::orm.migrations.{Migrator, Migration}
*/
public open class DbContext <: CliContext {
internal let datasource: Datasource
internal let dialect: ISqlDialect
internal let dialect: SqlDialect
internal let tracker = ChangeTracker()
private let _sets = HashMap<String, Any>()
private var _driverName: String
private var _connString: String
public init(datasource: Datasource, dialect: ISqlDialect) {
public init(datasource: Datasource, dialect: SqlDialect) {
this.datasource = datasource
this.dialect = dialect
this._driverName = ""
@@ -59,7 +59,7 @@ public open class DbContext <: CliContext {
}
/// 便捷构造:由连接字符串创建 Datasource(驱动构建收敛在 DatasourceFactory)
public init(connStr: String, dialect: ISqlDialect) {
public init(connStr: String, dialect: SqlDialect) {
this(DatasourceFactory.create(connStr), dialect)
this._driverName = DatasourceFactory.detectDriver(connStr, DatasourceFactory.DEFAULT_DRIVER)
this._connString = connStr
@@ -70,7 +70,7 @@ public open class DbContext <: CliContext {
}
/// 便捷构造:显式指定驱动类型(如 "pgsql")+ 连接字符串
public init(driverName: String, connStr: String, dialect: ISqlDialect) {
public init(driverName: String, connStr: String, dialect: SqlDialect) {
this(DatasourceFactory.create(connStr, driverName), dialect)
this._driverName = DatasourceFactory.normalizeDriverName(driverName)
this._connString = connStr
@@ -200,7 +200,7 @@ public open class DbContext <: CliContext {
}
/// 当前方言(子类/应用可读取)
public func getDialect(): ISqlDialect {
public func getDialect(): SqlDialect {
dialect
}
+6 -6
View File
@@ -275,12 +275,12 @@ public open class Migration {
}
/**
* DDL SQL 工厂:MigrationOperation → SQL(类型映射与差异语法委托给 ISqlDialect)。
* DDL SQL 工厂:MigrationOperation → SQL(类型映射与差异语法委托给 SqlDialect)。
*/
public class DdlFactory {
public init() {}
public func toSql(op: MigrationOperation, dialect: ISqlDialect): String {
public func toSql(op: MigrationOperation, dialect: SqlDialect): String {
match (op.kind) {
case MigrationOperationKind.CreateTable => createTableSql(op, dialect)
case MigrationOperationKind.DropTable => "DROP TABLE IF EXISTS ${dialect.quoteName(op.tableName)}"
@@ -303,7 +303,7 @@ public class DdlFactory {
/// - 有同名列且类型一致 → AddColumn 幂等跳过(空列表);AlterColumn 保留原 SQL(处理非空/长度等变化)
/// - 有同名列但类型不同 → 先 DROP COLUMN 再 ADD COLUMN(重建该字段)
/// existingType 来自 information_schema.data_type;None 表示列不存在。
public func resolveColumnSqls(op: MigrationOperation, dialect: ISqlDialect,
public func resolveColumnSqls(op: MigrationOperation, dialect: SqlDialect,
existingType: ?String): ArrayList<String> {
let result = ArrayList<String>()
let col = op.column.getOrThrow()
@@ -369,7 +369,7 @@ public class DdlFactory {
sb.toString()
}
private func createTableSql(op: MigrationOperation, dialect: ISqlDialect): String {
private func createTableSql(op: MigrationOperation, dialect: SqlDialect): String {
let sb = StringBuilder()
sb.append("CREATE TABLE IF NOT EXISTS ${dialect.quoteName(op.tableName)} (\n")
var first = true
@@ -384,7 +384,7 @@ public class DdlFactory {
sb.toString()
}
private func createIndexSql(op: MigrationOperation, dialect: ISqlDialect): String {
private func createIndexSql(op: MigrationOperation, dialect: SqlDialect): String {
let sb = StringBuilder()
sb.append("CREATE ")
if (op.unique) {
@@ -406,7 +406,7 @@ public class DdlFactory {
sb.toString()
}
private func columnDefSql(col: ColumnDefinition, dialect: ISqlDialect): String {
private func columnDefSql(col: ColumnDefinition, dialect: SqlDialect): String {
let sb = StringBuilder()
sb.append(dialect.quoteName(col.name))
sb.append(" ${dialect.columnTypeSql(col.columnType, col.autoIncrement, col.maxLength)}")
+2 -2
View File
@@ -18,10 +18,10 @@ import simcu::orm.sql.*
*/
public class Migrator {
private let _datasource: Datasource
private let _dialect: ISqlDialect
private let _dialect: SqlDialect
private let _historyTable = "simcu_orm_migrations"
public init(datasource: Datasource, dialect: ISqlDialect) {
public init(datasource: Datasource, dialect: SqlDialect) {
this._datasource = datasource
this._dialect = dialect
}
+2 -2
View File
@@ -48,7 +48,7 @@ public class PagedResult<T> {
*/
public class QueryBuilder<T> {
private let _model: EntityModel
private let _dialect: ISqlDialect
private let _dialect: SqlDialect
private let _executor: (String, ArrayList<Any>) -> ArrayList<T>
private let _counter: (String, ArrayList<Any>) -> Int64
@@ -58,7 +58,7 @@ public class QueryBuilder<T> {
private var _skip: Int64 = 0
private var _take: Int64 = 0
public init(model: EntityModel, dialect: ISqlDialect, executor: (String, ArrayList<Any>) -> ArrayList<T>,
public init(model: EntityModel, dialect: SqlDialect, executor: (String, ArrayList<Any>) -> ArrayList<T>,
counter: (String, ArrayList<Any>) -> Int64) {
this._model = model
this._dialect = dialect
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2025 SimcuTeam. All rights reserved.
* 列类型:与具体数据库无关的抽象,DDL 映射由 ISqlDialect 决定。
* 列类型:与具体数据库无关的抽象,DDL 映射由 SqlDialect 决定。
*/
package simcu::orm.sql
+1 -1
View File
@@ -13,7 +13,7 @@ import std.collection.*
/**
* PostgreSQL 方言。
*/
public open class PostgreSqlDialect <: ISqlDialect {
public open class PostgreSqlDialect <: SqlDialect {
public init() {}
public func quoteName(name: String): String {
@@ -1,9 +1,9 @@
/*
* Copyright (c) 2025 SimcuTeam. All rights reserved.
* SQL 方言接口(I 前缀命名,对齐 EF Core 接口风格):标识符引用、增删改查 SQL 生成、DDL 类型/语句生成。
* SQL 方言接口:标识符引用、增删改查 SQL 生成、DDL 类型/语句生成。
*
* 新数据库接入:实现 ISqlDialect 即可(参考 PostgreSqlDialect / OpenGaussDialect)。
* 内置实现见 PostgreSqlDialect.cj(PostgreSQL)、OpenGaussDialect.cj(openGauss,继承 PG)。
* 新数据库接入:实现 SqlDialect 即可(参考 PostgreSqlDialect / OpenGaussDialect)。
* 内置实现见 postgre_sql_dialect.cj(PostgreSQL)、open_gauss_dialect.cj(openGauss,继承 PG)。
*/
package simcu::orm.sql
@@ -13,7 +13,7 @@ import std.collection.*
/**
* SQL 方言接口。
*/
public interface ISqlDialect {
public interface SqlDialect {
/// 引用标识符(表名/列名)
func quoteName(name: String): String
@@ -51,6 +51,3 @@ public interface ISqlDialect {
/// 探测数据库是否存在的 SELECT(返回带 ? 占位符的语句,库名作为参数值传入避免拼接注入)
func databaseExistsSql(): String
}
/// 兼容别名:旧名称 SqlDialect 仍可用(新代码请使用 ISqlDialect)
public type SqlDialect = ISqlDialect
+5 -5
View File
@@ -301,7 +301,7 @@ class ChangeTrackerTests {
// ---------- OpenGaussDialect SQL 生成 ----------
@Test
class ISqlDialectTests {
class SqlDialectTests {
@TestCase
public func testQuoteInsertUpdateDelete(): Unit {
let d = OpenGaussDialect()
@@ -709,7 +709,7 @@ class MigrationGeneratorTests {
MigrationGenerator()
}
private func upSql(m: Migration, dialect: ISqlDialect): ArrayList<String> {
private func upSql(m: Migration, dialect: SqlDialect): ArrayList<String> {
let builder = MigrationBuilder()
m.up(builder)
let f = DdlFactory()
@@ -720,7 +720,7 @@ class MigrationGeneratorTests {
sqls
}
private func downSql(m: Migration, dialect: ISqlDialect): ArrayList<String> {
private func downSql(m: Migration, dialect: SqlDialect): ArrayList<String> {
let builder = MigrationBuilder()
m.down(builder)
let f = DdlFactory()
@@ -987,7 +987,7 @@ class AppDbContext <: DbContext {
orders = set<Order>()
}
init(ds: Datasource, dialect: ISqlDialect) {
init(ds: Datasource, dialect: SqlDialect) {
super(ds, dialect)
users = set<User>()
orders = set<Order>()
@@ -1044,7 +1044,7 @@ class ModelSnapshotTests {
ms
}
private func upSql(m: Migration, dialect: ISqlDialect): ArrayList<String> {
private func upSql(m: Migration, dialect: SqlDialect): ArrayList<String> {
let builder = MigrationBuilder()
m.up(builder)
let f = DdlFactory()