chore(dev): 添加本地 MySQL seed 环境
This commit is contained in:
+116
@@ -0,0 +1,116 @@
|
||||
import { reset } from 'drizzle-seed'
|
||||
import { drizzle } from 'drizzle-orm/mysql2'
|
||||
import { datetime, index, int, mysqlTable, tinyint, varchar } from 'drizzle-orm/mysql-core'
|
||||
import mysql from 'mysql2/promise'
|
||||
|
||||
type SeedRow = {
|
||||
userId: number
|
||||
mac: string
|
||||
devModel: string
|
||||
devName: string
|
||||
isLowPower: 'true' | 'false'
|
||||
powerStatus: 0 | 1 | 2
|
||||
power: number
|
||||
createTime: Date
|
||||
remark: string | null
|
||||
}
|
||||
|
||||
const lsBatteryInfo = mysqlTable(
|
||||
'ls_battery_info',
|
||||
{
|
||||
id: int('id').autoincrement().primaryKey(),
|
||||
userId: int('user_id').notNull(),
|
||||
mac: varchar('mac', { length: 50 }).notNull(),
|
||||
devModel: varchar('dev_model', { length: 20 }).notNull(),
|
||||
devName: varchar('dev_name', { length: 50 }).notNull(),
|
||||
isLowPower: varchar('is_low_power', { length: 10 }).notNull(),
|
||||
powerStatus: tinyint('power_status').notNull(),
|
||||
power: tinyint('power').notNull(),
|
||||
createTime: datetime('create_time').notNull(),
|
||||
remark: varchar('remark', { length: 500 }),
|
||||
},
|
||||
(table) => [index('idx_ls_battery_info_mac_time_id').on(table.mac, table.createTime, table.id)],
|
||||
)
|
||||
|
||||
const databaseUrl = process.env.DATABASE_URL
|
||||
|
||||
if (!databaseUrl) {
|
||||
throw new Error('DATABASE_URL is required, for example mysql://battery:battery@localhost:3306/battery_soh')
|
||||
}
|
||||
|
||||
const parsedUrl = new URL(databaseUrl)
|
||||
const safeSeedHosts = new Set(['localhost', '127.0.0.1', '0.0.0.0', 'db', 'mysql'])
|
||||
|
||||
if (!safeSeedHosts.has(parsedUrl.hostname) && process.env.SEED_ALLOW_REMOTE !== 'true') {
|
||||
throw new Error(
|
||||
`Refusing to seed non-local MySQL host "${parsedUrl.hostname}". Set SEED_ALLOW_REMOTE=true only for disposable test databases.`,
|
||||
)
|
||||
}
|
||||
|
||||
const devices = [
|
||||
{ mac: 'RING-A03', model: 'SR-01', name: '样机-A03', basePower: 96, status: 2, remark: 'v3.8.2' },
|
||||
{ mac: 'RING-B11', model: 'SR-01', name: '样机-B11', basePower: 91, status: 1, remark: 'v3.8.2' },
|
||||
{ mac: 'RING-C07', model: 'SR-02', name: '样机-C07', basePower: 88, status: 0, remark: 'v3.8.1' },
|
||||
{ mac: 'RING-D19', model: 'SR-02', name: '样机-D19', basePower: 84, status: 0, remark: 'v3.7.9' },
|
||||
{ mac: 'RING-E21', model: 'SR-03', name: '样机-E21', basePower: 79, status: 1, remark: 'v3.7.9' },
|
||||
{ mac: 'RING-F02', model: 'SR-03', name: '样机-F02', basePower: 73, status: 0, remark: null },
|
||||
{ mac: 'RING-G15', model: 'SR-04', name: '样机-G15', basePower: 93, status: 2, remark: 'v3.9.0' },
|
||||
{ mac: 'RING-H09', model: 'SR-04', name: '样机-H09', basePower: 86, status: 0, remark: 'v3.8.1' },
|
||||
] satisfies Array<{
|
||||
mac: string
|
||||
model: string
|
||||
name: string
|
||||
basePower: number
|
||||
status: 0 | 1 | 2
|
||||
remark: string | null
|
||||
}>
|
||||
|
||||
function createSeedRows(now = new Date()): SeedRow[] {
|
||||
return devices.flatMap((device, deviceIndex) =>
|
||||
Array.from({ length: 8 }, (_, historyIndex) => {
|
||||
const createdAt = new Date(now.getTime() - (historyIndex * 24 + deviceIndex * 2) * 60 * 60 * 1000)
|
||||
const power = Math.max(1, Math.min(100, device.basePower - historyIndex * 2 + (deviceIndex % 3)))
|
||||
|
||||
return {
|
||||
userId: 1001 + (deviceIndex % 3),
|
||||
mac: device.mac,
|
||||
devModel: device.model,
|
||||
devName: device.name,
|
||||
isLowPower: power <= 20 || device.basePower <= 80 ? 'true' : 'false',
|
||||
powerStatus: historyIndex === 0 ? device.status : 0,
|
||||
power,
|
||||
createTime: createdAt,
|
||||
remark: device.remark,
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const connection = await mysql.createConnection({ uri: databaseUrl })
|
||||
const db = drizzle(connection)
|
||||
|
||||
try {
|
||||
await db.execute(`
|
||||
CREATE TABLE IF NOT EXISTS ls_battery_info (
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
user_id int(11) NOT NULL,
|
||||
mac varchar(50) NOT NULL,
|
||||
dev_model varchar(20) NOT NULL,
|
||||
dev_name varchar(50) NOT NULL,
|
||||
is_low_power varchar(10) NOT NULL,
|
||||
power_status tinyint(4) NOT NULL,
|
||||
power tinyint(4) NOT NULL,
|
||||
create_time datetime NOT NULL,
|
||||
remark varchar(500) DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_ls_battery_info_mac_time_id (mac, create_time, id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`)
|
||||
|
||||
await reset(db, { lsBatteryInfo })
|
||||
await db.insert(lsBatteryInfo).values(createSeedRows())
|
||||
|
||||
process.stdout.write(`Seeded ${devices.length} devices into ls_battery_info.\n`)
|
||||
} finally {
|
||||
await connection.end()
|
||||
}
|
||||
Reference in New Issue
Block a user