/*
* 数据源管理模块
* 提供数据库连接和语句执行的接口定义与 Mock 实现
*/
package tybb2026::tycj_orm
import std.collection.*
import std.convert.*
/*
* 数据库类型枚举
*/
public enum DatabaseType {
| MySql
| PostgreSQL
| Sqlite
| Oracle
| SqlServer
}
/*
* 数据库连接接口
* 封装数据库连接操作
*/
public interface Connection {
/*
* 创建预编译 SQL 语句执行器
* @param sql SQL 语句
* @return 预编译语句执行器
*/
func prepareStatement(sql: String): PreparedStatement
/*
* 提交事务
*/
func commit(): Unit
/*
* 回滚事务
*/
func rollback(): Unit
/*
* 关闭连接
*/
func close(): Unit
}
/*
* SQL 语句执行器接口
*/
public interface Statement {
/*
* 执行任意 SQL 语句
* @param sql SQL 语句
* @return 是否有结果集
*/
func execute(sql: String): Bool
/*
* 执行更新语句
* @param sql SQL 语句
* @return 影响的行数
*/
func executeUpdate(sql: String): Int64
/*
* 关闭执行器
*/
func close(): Unit
}
/*
* 预编译 SQL 语句执行器接口
* 继承自 Statement
*/
public interface PreparedStatement <: Statement {
/*
* 设置字符串参数
* @param index 参数索引(从1开始)
* @param value 参数值
*/
func setString(index: Int64, value: String): Unit
/*
* 设置整数参数
* @param index 参数索引(从1开始)
* @param value 参数值
*/
func setInt(index: Int64, value: Int64): Unit
/*
* 设置浮点数参数
* @param index 参数索引(从1开始)
* @param value 参数值
*/
func setFloat(index: Int64, value: Float64): Unit
/*
* 设置布尔参数
* @param index 参数索引(从1开始)
* @param value 参数值
*/
func setBool(index: Int64, value: Bool): Unit
/*
* 执行更新操作(INSERT/UPDATE/DELETE)
* @return 影响的行数
*/
func executeUpdate(): Int64
/*
* 执行查询操作(SELECT)
* @return 结果集
*/
func executeQuery(): ResultSet
}
/*
* 结果集接口
*/
public interface ResultSet {
/*
* 移动到下一行
* @return 是否有下一行
*/
func next(): Bool
/*
* 根据列名获取字符串值
* @param columnName 列名
* @return 列值
*/
func getString(columnName: String): String
/*
* 根据列名获取整数值
* @param columnName 列名
* @return 列值
*/
func getInt(columnName: String): Int64
/*
* 根据列名获取浮点数值
* @param columnName 列名
* @return 列值
*/
func getFloat(columnName: String): Float64
/*
* 根据列名获取布尔值
* @param columnName 列名
* @return 列值
*/
func getBool(columnName: String): Bool
/*
* 检查列值是否为 NULL
* @param columnName 列名
* @return 是否为 NULL
*/
func isNull(columnName: String): Bool
/*
* 关闭结果集
*/
func close(): Unit
}
/*
* 数据源接口
* 定义数据源的基本操作
*/
public interface DataSource {
/*
* 获取数据库连接
* @return 数据库连接选项
*/
func getConnection(): Option<Connection>
/*
* 关闭数据源
*/
func close(): Unit
}
/*
* 数据库配置类
* 用于配置数据库连接参数
*/
public class DatabaseConfig {
/* 数据库类型 */
public var dbType: DatabaseType
/* 主机地址 */
public var host: String
/* 端口号 */
public var port: Int64
/* 数据库名 */
public var database: String
/* 用户名 */
public var username: String
/* 密码 */
public var password: String
public init() {
this.dbType = DatabaseType.MySql
this.host = "localhost"
this.port = 3306
this.database = ""
this.username = "root"
this.password = ""
}
/*
* 创建 MySQL 配置
* @return 数据库配置
*/
public static func mysql(): DatabaseConfig {
let config = DatabaseConfig()
config.dbType = DatabaseType.MySql
config.port = 3306
return config
}
/*
* 创建 SQLite 配置
* @return 数据库配置
*/
public static func sqlite(): DatabaseConfig {
let config = DatabaseConfig()
config.dbType = DatabaseType.Sqlite
config.port = 0
return config
}
/*
* 构建数据库连接 URL
* @return 连接 URL 字符串
*/
public func buildUrl(): String {
match (dbType) {
case DatabaseType.MySql =>
return "jdbc:mysql://${host}:${port}/${database}"
case DatabaseType.PostgreSQL =>
return "jdbc:postgresql://${host}:${port}/${database}"
case DatabaseType.Sqlite =>
return "jdbc:sqlite:${database}"
case DatabaseType.Oracle =>
return "jdbc:oracle:thin:@${host}:${port}:${database}"
case DatabaseType.SqlServer =>
return "jdbc:sqlserver://${host}:${port};databaseName=${database}"
}
}
}
/*
* Mock 连接实现
* 用于测试和开发阶段,模拟数据库连接行为
*/
public class MockConnection <: Connection {
/* 是否已关闭 */
private var closed: Bool = false
public func prepareStatement(sql: String): PreparedStatement {
return MockPreparedStatement(sql: sql)
}
public func commit(): Unit {
// 模拟提交事务
}
public func rollback(): Unit {
// 模拟回滚事务
}
public func close(): Unit {
closed = true
}
}
/*
* Mock 预编译语句实现
* 用于测试和开发阶段,模拟预编译语句行为
*/
public class MockPreparedStatement <: PreparedStatement {
/* SQL 语句 */
private let sql: String
/* 参数列表 */
private var parameters: ArrayList<String> = ArrayList<String>()
public init(sql!: String = "") {
this.sql = sql
}
public func setString(index: Int64, value: String): Unit {
// 确保参数按索引顺序存储
while (parameters.size < index) {
parameters.add("")
}
parameters[Int64(index - 1)] = value
}
public func setInt(index: Int64, value: Int64): Unit {
while (parameters.size < index) {
parameters.add("")
}
parameters[Int64(index - 1)] = value.toString()
}
public func setFloat(index: Int64, value: Float64): Unit {
while (parameters.size < index) {
parameters.add("")
}
parameters[Int64(index - 1)] = value.toString()
}
public func setBool(index: Int64, value: Bool): Unit {
while (parameters.size < index) {
parameters.add("")
}
parameters[Int64(index - 1)] = if (value) { "1" } else { "0" }
}
public func executeUpdate(): Int64 {
return 1
}
public func executeQuery(): ResultSet {
MockResultSet()
}
public func execute(sql: String): Bool {
return true
}
public func executeUpdate(sql: String): Int64 {
return 1
}
public func close(): Unit {
// 模拟关闭
}
}
/*
* Mock 结果集实现
* 用于测试和开发阶段,模拟结果集行为
*/
public class MockResultSet <: ResultSet {
/* 数据行列表 */
private var data: ArrayList<HashMap<String, String>>
/* 当前行索引 */
private var rowIndex: Int64 = -1
public init(data!: ArrayList<HashMap<String, String>> = ArrayList<HashMap<String, String>>()) {
this.data = data
}
public func next(): Bool {
rowIndex += 1
return rowIndex < data.size
}
public func getString(columnName: String): String {
if (rowIndex >= 0 && rowIndex < data.size) {
let row = data[rowIndex]
match (row.get(columnName)) {
case Some(val) => return val
case None => return ""
}
}
return ""
}
public func getInt(columnName: String): Int64 {
if (rowIndex >= 0 && rowIndex < data.size) {
let row = data[rowIndex]
match (row.get(columnName)) {
case Some(val) =>
safeParseInt(val)
case None => 0
}
} else {
0
}
}
public func getFloat(columnName: String): Float64 {
if (rowIndex >= 0 && rowIndex < data.size) {
let row = data[rowIndex]
match (row.get(columnName)) {
case Some(val) =>
safeParseFloat(val)
case None => 0.0
}
} else {
0.0
}
}
public func getBool(columnName: String): Bool {
if (rowIndex >= 0 && rowIndex < data.size) {
let row = data[rowIndex]
match (row.get(columnName)) {
case Some(val) =>
val == "true" || val == "1"
case None => false
}
} else {
false
}
}
public func isNull(columnName: String): Bool {
if (rowIndex >= 0 && rowIndex < data.size) {
let row = data[rowIndex]
match (row.get(columnName)) {
case Some(val) => val.isEmpty()
case None => true
}
} else {
true
}
}
// 辅助函数:安全解析整数(避免在 lambda/match 中使用 try-catch)
private static func safeParseInt(val: String): Int64 {
try {
return Int64.parse(val)
} catch (_: Exception) {
return 0
}
}
// 辅助函数:安全解析浮点数
private static func safeParseFloat(val: String): Float64 {
try {
return Float64.parse(val)
} catch (_: Exception) {
return 0.0
}
}
public func close(): Unit {
// 模拟关闭
}
}