/*
* utils.cj - 工具函数模块
*
* 提供 ORM 模块通用的工具函数。
*/
package tybb2026::tycj_orm
import std.collection.*
// ============================================================================
// 字符串工具函数
// ============================================================================
/**
* 连接字符串列表
* @param list 字符串列表
* @param separator 分隔符
* @return 连接后的字符串
*/
public func joinStrings(list: ArrayList<String>, separator: String): String {
if (list.isEmpty()) {
return ""
}
let sb = StringBuilder()
for (i in 0..list.size) {
if (i > 0) {
sb.append(separator)
}
sb.append(list[i])
}
sb.toString()
}
/**
* 将字符串转换为大写
* @param s 输入字符串
* @return 大写字符串
*/
public func toUpperCaseString(s: String): String {
let sb = StringBuilder()
for (i in 0..s.size) {
let c = s[i]
if (c >= 97u8 && c <= 122u8) { // a-z
sb.append(String.fromUtf8([c - 32u8]))
} else {
sb.append(String.fromUtf8([c]))
}
}
sb.toString()
}
/**
* 将字符串转换为小写
* @param s 输入字符串
* @return 小写字符串
*/
public func toLowerCaseString(s: String): String {
let sb = StringBuilder()
for (i in 0..s.size) {
let c = s[i]
if (c >= 65u8 && c <= 90u8) { // A-Z
sb.append(String.fromUtf8([c + 32u8]))
} else {
sb.append(String.fromUtf8([c]))
}
}
sb.toString()
}
/**
* 检查字符串是否以指定前缀开头(忽略大小写)
* @param s 输入字符串
* @param prefix 前缀
* @return 是否以此前缀开头
*/
public func startsWithIgnoreCase(s: String, prefix: String): Bool {
if (prefix.size > s.size) {
return false
}
let sUpper = toUpperCaseString(s)
let prefixUpper = toUpperCaseString(prefix)
sUpper.startsWith(prefixUpper)
}
/**
* 检查字符串是否包含子串(忽略大小写)
* @param s 输入字符串
* @param sub 子串
* @return 是否包含
*/
public func containsIgnoreCase(s: String, sub: String): Bool {
let sUpper = toUpperCaseString(s)
let subUpper = toUpperCaseString(sub)
sUpper.contains(subUpper)
}
// ============================================================================
// 集合工具函数
// ============================================================================
/**
* 将列表分批处理
* @param list 原始列表
* @param batchSize 每批大小
* @return 分批后的列表
*/
public func batchList<T>(list: ArrayList<T>, batchSize: Int64): ArrayList<ArrayList<T>> {
let result = ArrayList<ArrayList<T>>()
var currentBatch = ArrayList<T>()
for (item in list) {
currentBatch.add(item)
if (currentBatch.size >= batchSize) {
result.add(currentBatch)
currentBatch = ArrayList<T>()
}
}
if (!currentBatch.isEmpty()) {
result.add(currentBatch)
}
result
}
// ============================================================================
// 验证工具函数
// ============================================================================
/**
* 检查字符串是否为有效的标识符(表名、列名)
* @param identifier 标识符
* @return 是否有效
*/
public func isValidIdentifier(identifier: String): Bool {
if (identifier.isEmpty()) {
return false
}
// 检查首字符
let first = identifier[0]
if (!((first >= 65u8 && first <= 90u8) || // A-Z
(first >= 97u8 && first <= 122u8) || // a-z
(first == 95u8))) { // _
return false
}
// 检查其余字符
for (i in 1..identifier.size) {
let c = identifier[i]
if (!((c >= 65u8 && c <= 90u8) || // A-Z
(c >= 97u8 && c <= 122u8) || // a-z
(c >= 48u8 && c <= 57u8) || // 0-9
(c == 95u8))) { // _
return false
}
}
true
}
/**
* 转义 SQL 标识符中的特殊字符
* @param identifier 标识符
* @return 转义后的标识符
*/
public func escapeIdentifier(identifier: String): String {
// 移除可能导致 SQL 注入的字符
var result = ""
for (i in 0..identifier.size) {
let c = identifier[i]
// 只允许字母、数字、下划线
if ((c >= 65u8 && c <= 90u8) || // A-Z
(c >= 97u8 && c <= 122u8) || // a-z
(c >= 48u8 && c <= 57u8) || // 0-9
(c == 95u8)) { // _
result = result + String.fromUtf8([c])
}
}
result
}