feat: add MySQL import wizard component and backend service for database restoration
This commit is contained in:
@@ -1 +0,0 @@
|
||||
32612
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user