setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "--- [복구 마이그레이션 시작] 노트북 자산 관리 시스템 v2.1 ---\n\n"; // 2. 백업 생성 $backupPath = $dbPath . '.bak_' . date('Ymd_His'); if (!copy($dbPath, $backupPath)) { throw new Exception("데이터베이스 백업 생성 실패"); } echo "🛡️ 데이터 안전: 작업 전 원본 백업이 생성되었습니다. ($backupPath)\n"; // 3. 스키마 확장 (신규 규격 컬럼 추가) $newColumns = [ 'disposal_recipient' => 'TEXT', 'disposal_date' => 'TEXT', 'real_user' => 'TEXT', 'disposal_user_id' => 'INTEGER' ]; foreach ($newColumns as $col => $type) { try { $db->exec("ALTER TABLE laptop_assets ADD COLUMN $col $type"); echo "✅ 컬럼 보정 성공: $col\n"; } catch (PDOException $e) { if (strpos($e->getMessage(), 'duplicate column name') !== false) { echo "ℹ️ 이미 존재함: $col (스키마 유지)\n"; } else { throw $e; } } } // 4. 데이터 정합성 - STOCK 자산 '업무용' 명칭 통합 $stmtStock = $db->prepare(" UPDATE laptop_assets SET assigned_user_name = '업무용(TEMP_44666b)', current_user_id = NULL WHERE status = 'stock' AND (assigned_user_name != '업무용(TEMP_44666b)' OR assigned_user_name IS NULL) "); $stmtStock->execute(); $affectedStock = $stmtStock->rowCount(); echo "✅ 데이터 정합성: STOCK 자산 $affectedStock 건의 입력을 '업무용'으로 통일했습니다.\n"; // 5. 데이터 정합성 - 매각 대상자 ID 복구 (직원 DB 대조) $allDisposed = $db->query(" SELECT id, disposal_recipient FROM laptop_assets WHERE status = 'disposed' AND disposal_recipient IS NOT NULL AND disposal_user_id IS NULL ")->fetchAll(PDO::FETCH_ASSOC); $idRestored = 0; $userFinder = $db->prepare("SELECT id FROM users WHERE name = ? LIMIT 1"); $idUpdater = $db->prepare("UPDATE laptop_assets SET disposal_user_id = ? WHERE id = ?"); foreach ($allDisposed as $row) { $userFinder->execute([$row['disposal_recipient']]); $uid = $userFinder->fetchColumn(); if ($uid) { $idUpdater->execute([$uid, $row['id']]); $idRestored++; } } echo "✅ 데이터 정합성: DISPOSED 자산 $idRestored 건의 사원 매핑을 완료했습니다.\n\n"; echo "--- [마이그레이션 성공] 복구된 DB가 최신 규격으로 업데이트되었습니다. ---\n"; } catch (Exception $e) { echo "\n❌ [마이그레이션 실패] 오류 내용: " . $e->getMessage() . "\n"; }