feat: add MySQL import wizard component and backend service for database restoration

This commit is contained in:
Ümit Tunç
2026-03-30 07:23:24 +03:00
parent 47c322294c
commit b603619286
4 changed files with 35 additions and 14 deletions
-1
View File
@@ -1 +0,0 @@
32612
+4 -4
View File
@@ -424,7 +424,7 @@ export function registerIpcHandlers(): void {
}
})
ipcMain.handle('mysql:import-wizard:check-db', async (_event, { versionId, dbName }) => {
ipcMain.handle('mysql:import-wizard:check-db', async (_event, { versionId, dbName, rootPass }) => {
const versions = await mySqlManagerService.getVersions()
const v = versions.find(v => v.id === versionId)
if (!v) return { exists: false, error: 'MySQL version not found' }
@@ -438,13 +438,13 @@ export function registerIpcHandlers(): void {
host: '127.0.0.1',
port: v.port,
rootUser: 'root',
rootPass: '' // Assuming root has no password by default in this setup
rootPass: rootPass || ''
}, dbName)
return { exists }
})
ipcMain.handle('mysql:import-wizard:start', async (event, { versionId, filePath, dbName, user, pass, overwrite }) => {
ipcMain.handle('mysql:import-wizard:start', async (event, { versionId, filePath, dbName, user, pass, rootPass, overwrite }) => {
const versions = await mySqlManagerService.getVersions()
const v = versions.find(v => v.id === versionId)
if (!v) return { success: false, message: 'MySQL version not found' }
@@ -458,7 +458,7 @@ export function registerIpcHandlers(): void {
host: '127.0.0.1',
port: v.port,
rootUser: 'root',
rootPass: ''
rootPass: rootPass || ''
}
const log = (msg: string) => event.sender.send('mysql:import:log', msg)
+14 -4
View File
@@ -111,15 +111,25 @@ export class MySqlOperationService {
args.push(`--password=${config.rootPass}`)
}
// Using shell true to use redirecting input
const command = `"${mysqlPath}" ${args.join(' ')} < "${sqlFilePath}"`
onProgress?.(`Executing: mysql ${args.join(' ')} < ${path.basename(sqlFilePath)}`)
onProgress?.(`Executing: "${mysqlPath}" ${args.join(' ')} < "${sqlFilePath}"`)
const child = spawn('cmd.exe', ['/c', command], { windowsHide: true })
const child = spawn(mysqlPath, args, { windowsHide: true })
// Pipe the file content to stdin
const fileStream = fs.createReadStream(sqlFilePath)
fileStream.on('error', (err) => {
onProgress?.(`File read error: ${err.message}`)
})
fileStream.pipe(child.stdin)
child.stdout.on('data', (data) => onProgress?.(data.toString()))
child.stderr.on('data', (data) => onProgress?.(data.toString()))
child.on('error', (err) => {
onProgress?.(`Process error: ${err.message}`)
resolve({ success: false, message: `Process error: ${err.message}` })
})
child.on('close', (code) => {
if (code === 0) {
onProgress?.('Import completed successfully.')
@@ -50,7 +50,8 @@ const MySqlImportWizard: React.FC<MySqlImportWizardProps> = ({ open, onClose, my
const [dbConfig, setDbConfig] = useState({
dbName: '',
user: '',
pass: ''
pass: '',
rootPass: ''
})
const [loading, setLoading] = useState(false)
const [logs, setLogs] = useState<string[]>([])
@@ -71,7 +72,8 @@ const MySqlImportWizard: React.FC<MySqlImportWizardProps> = ({ open, onClose, my
setDbConfig({
dbName: `db_${randomStr}`,
user: `user_${randomStr}`,
pass: Math.random().toString(36).substring(2, 12)
pass: Math.random().toString(36).substring(2, 12),
rootPass: ''
})
}
}, [open, mySqlVersions])
@@ -108,14 +110,14 @@ const MySqlImportWizard: React.FC<MySqlImportWizardProps> = ({ open, onClose, my
}
const handleStep3Next = async () => {
if (!dbConfig.dbName || !dbConfig.user || !dbConfig.pass) {
Swal.fire('Hata', 'Lütfen tüm alanları doldurun.', 'error')
if (!dbConfig.dbName || !dbConfig.user) {
Swal.fire('Hata', 'Lütfen veritabanı adı ve kullanıcıyı doldurun.', 'error')
return
}
setLoading(true)
try {
const { exists } = await window.api.checkMySqlDb(selectedVersion, dbConfig.dbName)
const { exists } = await window.api.checkMySqlDb(selectedVersion, dbConfig.dbName, dbConfig.rootPass)
if (exists) {
const result = await Swal.fire({
title: 'Veritabanı Mevcut!',
@@ -151,6 +153,7 @@ const MySqlImportWizard: React.FC<MySqlImportWizardProps> = ({ open, onClose, my
dbName: dbConfig.dbName,
user: dbConfig.user,
pass: dbConfig.pass,
rootPass: dbConfig.rootPass,
overwrite: true // Logic handled by checkMySqlDb before
})
setImportResult(result)
@@ -205,6 +208,15 @@ const MySqlImportWizard: React.FC<MySqlImportWizardProps> = ({ open, onClose, my
))}
</Select>
</FormControl>
<TextField
label="Root Şifresi (Eğer varsa)"
fullWidth
sx={{ mt: 3 }}
value={dbConfig.rootPass}
type="password"
onChange={(e) => setDbConfig({ ...dbConfig, rootPass: e.target.value })}
helperText="MySQL 'root' kullanıcısının mevcut şifresini girin. Boşsa boş bırakın."
/>
</Box>
)
case 2: