Files
orm-cj/src/db/DatasourceFactory.cj
T
xrain afa6096ed2 feat: orm-cj 仓颉版 EF Core 风格 ORM 初始版本
- 基于数据模型(POCO + 注解)的映射与增删改查:DbContext/DbSet/ChangeTracker/QueryBuilder
- ISqlDialect 方言接口 + PostgreSQL/openGauss 实现,零外部依赖
- @DbContext 宏:纯声明 DbSet 类自动展开为完整 DbContext 子类
- 迁移:Migration/Migrator/ModelSnapshot(快照 JSON)/MiniJson,从模型生成迁移
- 迁移 CLI:add/rm/update/downgrade/list/help,应用内嵌一行 db.cli(args) 接入
- DbContext 便捷方法:databaseExists/hasPendingMigrations/migrate
- 57 个单元测试全部通过
2026-08-19 09:14:01 +08:00

115 lines
4.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (c) 2025 SimcuTeam. All rights reserved.
* 连接串 → Datasource 工厂:把"驱动与配置构建"收敛到 orm-cj,应用侧只需传连接字符串。
*
* 支持两种连接串格式:
* 1. URL 格式(推荐):postgres://user:pass@host:port/db?sslmode=disableopengauss:// 亦可)
* 2. ADO.NET 风格:Host=..;Port=..;Database=..;Username=..;Password=..(自动转 URL
*
* 驱动通过 std.database.sql.DriverManager 查找:应用只需引入并链接驱动包
* (如 opengauss-driver,其模块加载时自动注册 "postgres"/"opengauss"),
* orm-cj 本身不依赖任何具体驱动实现。
*/
package simcu::orm.db
import std.database.sql.*
/**
* 连接串 → Datasource 工厂(对齐 .NET NpgsqlDataSource.Create / EF Core UseNpgsql(connStr))。
*/
public class DatasourceFactory {
/// 默认驱动名(ADO 风格连接串无 scheme 时使用)
public static let DEFAULT_DRIVER = "postgres"
/**
* 由连接字符串创建 Datasource。驱动名自动推断:
* URL 格式按 schemepostgres/postgresql/pgsql/pg → postgresopengauss → opengauss);
* ADO 风格默认 postgres。
*/
public static func create(connStr: String): Datasource {
build(detectDriver(connStr, DEFAULT_DRIVER), toUrl(connStr))
}
/**
* 由连接字符串创建 Datasource,可显式指定驱动名(如 "pgsql"/"postgres"/"opengauss")。
* 显式驱动名优先于连接串内 scheme。
*/
public static func create(connStr: String, driverName: String): Datasource {
build(normalizeDriverName(driverName), toUrl(connStr))
}
private static func build(name: String, url: String): Datasource {
let driver = DriverManager.getDriver(name) ??
throw Exception(
"simorm: 未注册数据库驱动 '${name}'。请确认应用已引入并链接对应驱动包" +
"(如 opengauss-driver,其加载时自动注册 postgres/opengauss")
driver.open(url)
}
/**
* 从连接串推断驱动注册名。
*/
public static func detectDriver(connStr: String, defaultDriver: String): String {
if (connStr.contains("://")) {
let i = connStr.indexOf("://").getOrThrow()
let scheme = connStr[0..i].toAsciiLower()
match (scheme) {
case "postgresql" | "pgsql" | "pg" => "postgres"
case _ => scheme
}
} else {
normalizeDriverName(defaultDriver)
}
}
/**
* 驱动名别名归一化到 DriverManager 注册名。
*/
public static func normalizeDriverName(name: String): String {
match (name.trimAscii().toAsciiLower()) {
case "pgsql" | "pg" | "postgresql" => "postgres"
case _ => name.trimAscii()
}
}
/**
* 统一为驱动可解析的 URL 格式。
* ADO.NET 风格(.NET Npgsql 连接串)示例:
* Host=192.168.0.2;Port=5432;Database=lemon-lurmix;Username=postgres;Password=Love@1314
* → postgres://postgres:Love@1314@192.168.0.2:5432/lemon-lurmix?sslmode=disable
* 已是 URL(含 "://")则原样返回。
*/
public static func toUrl(connStr: String): String {
if (connStr.contains("://")) {
return connStr
}
var host = ""
var port = "5432"
var database = ""
var username = ""
var password = ""
for (part in connStr.split(";")) {
let seg = part.trimAscii()
if (seg.isEmpty()) {
continue
}
match (seg.indexOf("=")) {
case Some(i) =>
let key = seg[0..i].trimAscii().toAsciiLower()
let value = seg[i + 1..].trimAscii()
match (key) {
case "host" => host = value
case "port" => port = value
case "database" => database = value
case "username" | "user id" | "uid" => username = value
case "password" | "pwd" => password = value
case _ => ()
}
case None => ()
}
}
return "${DEFAULT_DRIVER}://${username}:${password}@${host}:${port}/${database}?sslmode=disable"
}
}