feat: implement PHP and MySQL version management services with automated download and cataloging capabilities
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { app } from 'electron'
|
||||
|
||||
export interface MySqlVersion {
|
||||
id: string
|
||||
version: string
|
||||
cycle: string
|
||||
url: string
|
||||
status: 'available' | 'downloading' | 'installed'
|
||||
progress: number
|
||||
description?: string
|
||||
}
|
||||
|
||||
export class MySqlManagerService {
|
||||
private versions: MySqlVersion[] = []
|
||||
private binDir: string
|
||||
private catalogPath: string
|
||||
|
||||
constructor() {
|
||||
this.binDir = path.join(app.getPath('userData'), 'bin')
|
||||
// In development, it's in src/main/resources, but we should handle both
|
||||
this.catalogPath = path.join(app.getAppPath(), 'src/main/resources/mysql_catalog.json')
|
||||
if (!fs.existsSync(this.catalogPath)) {
|
||||
// Fallback for production or different root
|
||||
this.catalogPath = path.join(process.cwd(), 'src/main/resources/mysql_catalog.json')
|
||||
}
|
||||
this.init()
|
||||
}
|
||||
|
||||
private async init() {
|
||||
if (!fs.existsSync(this.binDir)) {
|
||||
fs.mkdirSync(this.binDir, { recursive: true })
|
||||
}
|
||||
}
|
||||
|
||||
async fetchAvailableVersions(): Promise<MySqlVersion[]> {
|
||||
console.log('Loading MySQL versions from local catalog:', this.catalogPath)
|
||||
try {
|
||||
if (!fs.existsSync(this.catalogPath)) {
|
||||
console.error('MySQL Catalog not found at:', this.catalogPath)
|
||||
return this.versions
|
||||
}
|
||||
|
||||
const rawData = fs.readFileSync(this.catalogPath, 'utf8')
|
||||
const catalog = JSON.parse(rawData)
|
||||
const releases = catalog.mysql_release_catalog.releases as any[]
|
||||
|
||||
const dynamicVersions: MySqlVersion[] = releases.map(v => {
|
||||
const version = v.version
|
||||
const cycle = v.series
|
||||
// Pattern: https://downloads.mysql.com/archives/get/p/23/file/mysql-VERSION-winx64.zip
|
||||
const url = `https://downloads.mysql.com/archives/get/p/23/file/mysql-${version}-winx64.zip`
|
||||
|
||||
return {
|
||||
id: `mysql-${version}`,
|
||||
version,
|
||||
cycle,
|
||||
url,
|
||||
status: 'available',
|
||||
progress: 0,
|
||||
description: v.status
|
||||
}
|
||||
})
|
||||
|
||||
this.updateVersionsList(dynamicVersions)
|
||||
return this.versions
|
||||
} catch (e: any) {
|
||||
console.error('Failed to load MySQL catalog:', e.message)
|
||||
return this.versions
|
||||
}
|
||||
}
|
||||
|
||||
private updateVersionsList(newList: MySqlVersion[]) {
|
||||
this.versions = newList.map(dv => {
|
||||
const current = this.versions.find(cv => cv.id === dv.id)
|
||||
if (current && current.status === 'downloading') return current
|
||||
return dv
|
||||
}).sort((a, b) => b.version.localeCompare(a.version, undefined, { numeric: true, sensitivity: 'base' }))
|
||||
|
||||
this.refreshInstalledStatus()
|
||||
}
|
||||
|
||||
private refreshInstalledStatus() {
|
||||
this.versions = this.versions.map(v => {
|
||||
const targetDir = path.join(this.binDir, v.id)
|
||||
const possiblePaths = [
|
||||
path.join(targetDir, 'bin', 'mysqld.exe'),
|
||||
path.join(targetDir, `mysql-${v.version}-winx64`, 'bin', 'mysqld.exe')
|
||||
]
|
||||
|
||||
const isInstalled = possiblePaths.some(p => fs.existsSync(p))
|
||||
|
||||
if (isInstalled) {
|
||||
return { ...v, status: 'installed', progress: 100 }
|
||||
}
|
||||
return v
|
||||
})
|
||||
}
|
||||
|
||||
async getVersions(): Promise<MySqlVersion[]> {
|
||||
if (this.versions.length === 0) {
|
||||
await this.fetchAvailableVersions()
|
||||
} else {
|
||||
this.refreshInstalledStatus()
|
||||
}
|
||||
return this.versions
|
||||
}
|
||||
|
||||
updateProgress(id: string, progress: number, status: MySqlVersion['status'] = 'downloading') {
|
||||
const version = this.versions.find(v => v.id === id)
|
||||
if (version) {
|
||||
version.progress = progress
|
||||
version.status = status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const mySqlManagerService = new MySqlManagerService()
|
||||
Reference in New Issue
Block a user