feat(database): add MySQL database support (#201)

This commit is contained in:
521141
2025-07-17 19:44:01 +08:00
committed by GitHub
parent 0ee5ef316f
commit bb5fad47cb
6 changed files with 194 additions and 26 deletions
+50 -10
View File
@@ -3,28 +3,68 @@ import type { NewsItem } from "@shared/types"
import type { Database } from "db0"
import type { CacheInfo, CacheRow } from "../types"
// 改进的数据库类型检测函数
function isMySQLDatabase(): boolean {
const hasMySQLConfig = process.env.MYSQL_HOST &&
process.env.MYSQL_USER &&
process.env.MYSQL_PASSWORD &&
process.env.MYSQL_DATABASE
if (hasMySQLConfig) {
console.log('🔍 检测到 MySQL 配置,使用 MySQL 数据库')
return true
} else {
console.log('🔍 未检测到 MySQL 配置,使用 SQLite 数据库')
return false
}
}
export class Cache {
private db
private isMySQL: boolean
constructor(db: Database) {
this.db = db
this.isMySQL = isMySQLDatabase()
}
async init() {
await this.db.prepare(`
CREATE TABLE IF NOT EXISTS cache (
id TEXT PRIMARY KEY,
updated INTEGER,
data TEXT
);
`).run()
if (this.isMySQL) {
// MySQL syntax
await this.db.prepare(`
CREATE TABLE IF NOT EXISTS cache (
id VARCHAR(255) PRIMARY KEY,
updated BIGINT,
data TEXT
);
`).run()
} else {
// SQLite syntax
await this.db.prepare(`
CREATE TABLE IF NOT EXISTS cache (
id TEXT PRIMARY KEY,
updated INTEGER,
data TEXT
);
`).run()
}
logger.success(`init cache table`)
}
async set(key: string, value: NewsItem[]) {
const now = Date.now()
await this.db.prepare(
`INSERT OR REPLACE INTO cache (id, data, updated) VALUES (?, ?, ?)`,
).run(key, JSON.stringify(value), now)
if (this.isMySQL) {
// MySQL syntax - use ON DUPLICATE KEY UPDATE
await this.db.prepare(
`INSERT INTO cache (id, data, updated) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE data = VALUES(data), updated = VALUES(updated)`,
).run(key, JSON.stringify(value), now)
} else {
// SQLite syntax - use INSERT OR REPLACE
await this.db.prepare(
`INSERT OR REPLACE INTO cache (id, data, updated) VALUES (?, ?, ?)`,
).run(key, JSON.stringify(value), now)
}
logger.success(`set ${key} cache`)
}
+46 -15
View File
@@ -1,3 +1,4 @@
import process from "node:process"
import type { Database } from "db0"
import type { UserInfo } from "#/types"
@@ -8,28 +9,58 @@ export class UserTable {
}
async init() {
await this.db.prepare(`
CREATE TABLE IF NOT EXISTS user (
id TEXT PRIMARY KEY,
email TEXT,
data TEXT,
type TEXT,
created INTEGER,
updated INTEGER
);
`).run()
await this.db.prepare(`
CREATE INDEX IF NOT EXISTS idx_user_id ON user(id);
`).run()
// Check if we're using MySQL by looking for MySQL environment variables
const isMySQL = process.env.MYSQL_HOST && process.env.MYSQL_USER && process.env.MYSQL_PASSWORD && process.env.MYSQL_DATABASE
if (isMySQL) {
// MySQL syntax
await this.db.prepare(`
CREATE TABLE IF NOT EXISTS user (
id VARCHAR(255) PRIMARY KEY,
email VARCHAR(255),
data TEXT,
type VARCHAR(50),
created BIGINT,
updated BIGINT
);
`).run()
await this.db.prepare(`
CREATE INDEX IF NOT EXISTS idx_user_id ON user(id);
`).run()
} else {
// SQLite syntax
await this.db.prepare(`
CREATE TABLE IF NOT EXISTS user (
id TEXT PRIMARY KEY,
email TEXT,
data TEXT,
type TEXT,
created INTEGER,
updated INTEGER
);
`).run()
await this.db.prepare(`
CREATE INDEX IF NOT EXISTS idx_user_id ON user(id);
`).run()
}
logger.success(`init user table`)
}
async addUser(id: string, email: string, type: "github") {
const u = await this.getUser(id)
const now = Date.now()
const isMySQL = process.env.MYSQL_HOST && process.env.MYSQL_USER && process.env.MYSQL_PASSWORD && process.env.MYSQL_DATABASE
if (!u) {
await this.db.prepare(`INSERT INTO user (id, email, data, type, created, updated) VALUES (?, ?, ?, ?, ?, ?)`)
.run(id, email, "", type, now, now)
if (isMySQL) {
// MySQL syntax - use ON DUPLICATE KEY UPDATE
await this.db.prepare(`INSERT INTO user (id, email, data, type, created, updated) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE email = VALUES(email), updated = VALUES(updated)`)
.run(id, email, "", type, now, now)
} else {
// SQLite syntax
await this.db.prepare(`INSERT INTO user (id, email, data, type, created, updated) VALUES (?, ?, ?, ?, ?, ?)`)
.run(id, email, "", type, now, now)
}
logger.success(`add user ${id}`)
} else if (u.email !== email && u.type !== type) {
await this.db.prepare(`UPDATE user SET email = ?, updated = ? WHERE id = ?`).run(email, now, id)