Commit 9f34266c authored by platyhouse's avatar platyhouse

# --edit 옵션 동작 변경 및 ptyMysqlQuery 도구 추가

## 공통 스크립트 가이드라인 변경

### --edit 옵션 동작 수정
- CLAUDE.md, README.md: --edit 옵션이 기존 스크립트 파일 대신 설정 파일(~/.pty[Service]Config.ini)을 편집하도록 변경
- CLAUDE.md: --edit 구현 패턴 코드 예시 업데이트

## ptyMysqlBackup 개선

### 압축 옵션 기본값 변경
- ptyMysqlBackup: --tgz 옵션을 --no-tgz로 변경하여 기본값으로 tgz 압축 사용
- CLAUDE.md: ptyMysqlBackup 옵션 설명 업데이트

### 데이터베이스 연결 개선
- ptyMysqlBackup: '*' 패턴 사용 시 database 설정 없이 연결하도록 수정

## ptyMysqlConfig 라이브러리 개선

- ptyLibrary_PHP/mysql/ptyMysqlConfig.php: connect() 메서드에 $useDatabase 파라미터 추가하여 database 설정 사용 여부 제어 가능

## ptyMysqlInfo 개선

- ptyMysqlInfo: database 설정 없이 서버 전체 정보 조회하도록 수정
- ptyMysqlInfo: null 병합 연산자(??)를 PHP 5.6 호환 isset() 삼항 연산자로 변경

## ptyMysqlRestore 개선

- ptyMysqlRestore: database 설정 없이 연결하여 여러 DB에 복원 가능하도록 수정

## ptyMysqlQuery 신규 추가

- ptyMysqlQuery: MySQL 쿼리 실행 CLI 도구 신규 생성
- 다양한 출력 형식 지원: key:value(기본값), --table, --json, --dump, --csv, --markdown
- --database 옵션으로 INI 설정과 별도로 데이터베이스 지정 가능
- PHP 5.6 호환성 유지 (mb_ord 폴리필 포함)
parent 33844aa5
...@@ -35,7 +35,7 @@ require_once __DIR__ . '/ptyLibrary_PHP/ai/ptyAIConfig.php'; // AI API ...@@ -35,7 +35,7 @@ require_once __DIR__ . '/ptyLibrary_PHP/ai/ptyAIConfig.php'; // AI API
|------|------|:--------:| |------|------|:--------:|
| `--help` | 도움말 출력 | O | | `--help` | 도움말 출력 | O |
| `--verbose` | 상세 로그 출력 | O | | `--verbose` | 상세 로그 출력 | O |
| `--edit` | 스크립트를 에디터로 열기 | O | | `--edit` | 설정 파일을 에디터로 열기 | O |
| `--dry-run` | 실제 실행 없이 대상/결과 미리보기 | O (데이터 변경 스크립트) | | `--dry-run` | 실제 실행 없이 대상/결과 미리보기 | O (데이터 변경 스크립트) |
### 옵션 처리 우선순위 (중요!) ### 옵션 처리 우선순위 (중요!)
...@@ -47,7 +47,7 @@ require_once __DIR__ . '/ptyLibrary_PHP/ai/ptyAIConfig.php'; // AI API ...@@ -47,7 +47,7 @@ require_once __DIR__ . '/ptyLibrary_PHP/ai/ptyAIConfig.php'; // AI API
// 옵션 처리 우선순위 // 옵션 처리 우선순위
// ============================================================ // ============================================================
// 1. --help : 최우선! 인자 검증/연결 없이 즉시 도움말 출력 // 1. --help : 최우선! 인자 검증/연결 없이 즉시 도움말 출력
// 2. --edit : 스크립트 편집 (인자 없이도 동작) // 2. --edit : 설정 파일 편집 (인자 없이도 동작)
// 3. 필수 인자 검증 // 3. 필수 인자 검증
// 4. 서비스 연결 및 비즈니스 로직 // 4. 서비스 연결 및 비즈니스 로직
// ============================================================ // ============================================================
...@@ -59,10 +59,11 @@ if (isset($options['help'])) { ...@@ -59,10 +59,11 @@ if (isset($options['help'])) {
exit(0); exit(0);
} }
// 2. --edit: 스크립트 편집 // 2. --edit: 설정 파일 편집
if (isset($options['edit'])) { if (isset($options['edit'])) {
$editor = getenv('EDITOR') ?: 'vi'; $editor = getenv('EDITOR') ?: 'vi';
passthru("$editor " . escapeshellarg(__FILE__)); $configFile = getenv('HOME') . '/.pty[Service]Config.ini';
passthru("$editor " . escapeshellarg($configFile));
exit(0); exit(0);
} }
...@@ -153,7 +154,7 @@ if (isset($options['help'])) { ...@@ -153,7 +154,7 @@ if (isset($options['help'])) {
echo "옵션:\n"; echo "옵션:\n";
echo " --dry-run 실제 실행 없이 대상 목록만 출력\n"; echo " --dry-run 실제 실행 없이 대상 목록만 출력\n";
echo " --verbose 상세 로그 출력\n"; echo " --verbose 상세 로그 출력\n";
echo " --edit 이 스크립트를 에디터로 열기\n"; echo " --edit 설정 파일을 에디터로 열기\n";
echo " --help 도움말 출력\n"; echo " --help 도움말 출력\n";
echo "\n"; echo "\n";
// 설정 파일 예시 출력 (해당 시) // 설정 파일 예시 출력 (해당 시)
...@@ -162,11 +163,12 @@ if (isset($options['help'])) { ...@@ -162,11 +163,12 @@ if (isset($options['help'])) {
} }
// ============================================================ // ============================================================
// 2. --edit: 스크립트 편집 // 2. --edit: 설정 파일 편집
// ============================================================ // ============================================================
if (isset($options['edit'])) { if (isset($options['edit'])) {
$editor = getenv('EDITOR') ?: 'vi'; $editor = getenv('EDITOR') ?: 'vi';
passthru("$editor " . escapeshellarg(__FILE__)); $configFile = getenv('HOME') . '/.pty[Service]Config.ini';
passthru("$editor " . escapeshellarg($configFile));
exit(0); exit(0);
} }
...@@ -243,10 +245,11 @@ if ($dryRun) { ...@@ -243,10 +245,11 @@ if ($dryRun) {
### --edit 구현 패턴 ### --edit 구현 패턴
```php ```php
// 도움말 처리보다 먼저 위치 (인자 없이도 동작해야 함) // 도움말 처리 이후에 위치 (인자 없이도 동작해야 함)
if (isset($options['edit'])) { if (isset($options['edit'])) {
$editor = getenv('EDITOR') ?: 'vi'; $editor = getenv('EDITOR') ?: 'vi';
passthru("$editor " . escapeshellarg(__FILE__)); $configFile = getenv('HOME') . '/.pty[Service]Config.ini'; // 서비스별 설정 파일
passthru("$editor " . escapeshellarg($configFile));
exit(0); exit(0);
} }
``` ```
...@@ -819,7 +822,7 @@ mysqldump를 사용하여 테이블을 백업합니다. ...@@ -819,7 +822,7 @@ mysqldump를 사용하여 테이블을 백업합니다.
./ptyMysqlBackup mydb users --output=/backup # 지정 경로에 저장 ./ptyMysqlBackup mydb users --output=/backup # 지정 경로에 저장
./ptyMysqlBackup '*' '*' --dry-run # 백업 대상만 미리보기 ./ptyMysqlBackup '*' '*' --dry-run # 백업 대상만 미리보기
./ptyMysqlBackup '*' '*' --ignore-x=false # x_ 접두사 포함 전체 백업 ./ptyMysqlBackup '*' '*' --ignore-x=false # x_ 접두사 포함 전체 백업
./ptyMysqlBackup mydb users --tgz # mydb.users.tgz 생성 (압축) ./ptyMysqlBackup mydb users --no-tgz # mydb.users.sql 생성 (압축 안 함)
``` ```
**옵션:** **옵션:**
...@@ -829,13 +832,13 @@ mysqldump를 사용하여 테이블을 백업합니다. ...@@ -829,13 +832,13 @@ mysqldump를 사용하여 테이블을 백업합니다.
| `--mysql=섹션명` | INI 파일 섹션 | `default` | | `--mysql=섹션명` | INI 파일 섹션 | `default` |
| `--output=경로` | 출력 디렉토리 | `.` | | `--output=경로` | 출력 디렉토리 | `.` |
| `--ignore-x=true\|false` | x_ 접두사 DB/테이블 무시 | `true` | | `--ignore-x=true\|false` | x_ 접두사 DB/테이블 무시 | `true` |
| `--tgz` | 백업 후 .tgz로 압축 (원본 .sql 삭제) | - | | `--no-tgz` | .tgz 압축 안 함 | 압축 사용 |
| `--dry-run` | 실제 백업 없이 대상 목록만 출력 | - | | `--dry-run` | 실제 백업 없이 대상 목록만 출력 | - |
| `--verbose` | 상세 로그 출력 | - | | `--verbose` | 상세 로그 출력 | - |
| `--edit` | 스크립트를 에디터로 열기 | - | | `--edit` | 스크립트를 에디터로 열기 | - |
**백업 파일:** **백업 파일:**
- 파일명 형식: `{database}.{table}.sql` 또는 `{database}.{table}.tgz` (--tgz 사용 시) - 파일명 형식: `{database}.{table}.tgz` (기본값) 또는 `{database}.{table}.sql` (--no-tgz 사용 시)
- 파일 헤더에 백업 시간, 실행 명령어 포함 - 파일 헤더에 백업 시간, 실행 명령어 포함
- `x_` 접두사 DB/테이블은 기본 스킵 (`--ignore-x=false`로 포함 가능) - `x_` 접두사 DB/테이블은 기본 스킵 (`--ignore-x=false`로 포함 가능)
......
...@@ -221,7 +221,7 @@ ptyCronBuild 'ptyRun "php /path/to/script.php" --max-run-time=10' --daily-10min ...@@ -221,7 +221,7 @@ ptyCronBuild 'ptyRun "php /path/to/script.php" --max-run-time=10' --daily-10min
|------|------| |------|------|
| `--help` | 도움말 출력 | | `--help` | 도움말 출력 |
| `--verbose` | 상세 로그 출력 | | `--verbose` | 상세 로그 출력 |
| `--edit` | 스크립트를 에디터로 열기 | | `--edit` | 설정 파일을 에디터로 열기 |
| `--dry-run` | 실제 실행 없이 미리보기 (데이터 변경 스크립트) | | `--dry-run` | 실제 실행 없이 미리보기 (데이터 변경 스크립트) |
서비스별 섹션 지정: 서비스별 섹션 지정:
......
...@@ -87,10 +87,11 @@ class ptyMysqlConfig ...@@ -87,10 +87,11 @@ class ptyMysqlConfig
* mysqli 연결 생성 * mysqli 연결 생성
* *
* @param string $section INI 파일 섹션명 (기본값: default) * @param string $section INI 파일 섹션명 (기본값: default)
* @param bool $useDatabase database 설정 사용 여부 (기본값: true)
* @return array [connection => mysqli, config => array] * @return array [connection => mysqli, config => array]
* @throws \Exception 연결 실패 시 * @throws \Exception 연결 실패 시
*/ */
public static function connect($section = 'default') public static function connect($section = 'default', $useDatabase = true)
{ {
$config = self::load($section); $config = self::load($section);
...@@ -98,7 +99,7 @@ class ptyMysqlConfig ...@@ -98,7 +99,7 @@ class ptyMysqlConfig
$config['host'], $config['host'],
$config['username'], $config['username'],
$config['password'], $config['password'],
$config['database'] $useDatabase ? $config['database'] : null
); );
if (!$connection) { if (!$connection) {
......
...@@ -24,7 +24,7 @@ $verbose = isset($options['verbose']); ...@@ -24,7 +24,7 @@ $verbose = isset($options['verbose']);
$outputDir = isset($options['output']) ? $options['output'] : '.'; $outputDir = isset($options['output']) ? $options['output'] : '.';
$ignoreX = (isset($options['ignore-x']) ? $options['ignore-x'] : 'true') !== 'false'; // 기본값: true $ignoreX = (isset($options['ignore-x']) ? $options['ignore-x'] : 'true') !== 'false'; // 기본값: true
$dryRun = isset($options['dry-run']); $dryRun = isset($options['dry-run']);
$useTgz = isset($options['tgz']); $useTgz = !isset($options['no-tgz']); // 기본값: tgz 압축 사용
// --edit 옵션: 스크립트 편집 // --edit 옵션: 스크립트 편집
if (isset($options['edit'])) { if (isset($options['edit'])) {
...@@ -46,7 +46,7 @@ if (count($positionalArgs) < 2 || isset($options['help'])) { ...@@ -46,7 +46,7 @@ if (count($positionalArgs) < 2 || isset($options['help'])) {
echo " --mysql=섹션명 INI 파일 섹션 (기본값: default)\n"; echo " --mysql=섹션명 INI 파일 섹션 (기본값: default)\n";
echo " --output=경로 출력 디렉토리 (기본값: 현재 디렉토리)\n"; echo " --output=경로 출력 디렉토리 (기본값: 현재 디렉토리)\n";
echo " --ignore-x=true|false x_ 접두사 DB/테이블 무시 (기본값: true)\n"; echo " --ignore-x=true|false x_ 접두사 DB/테이블 무시 (기본값: true)\n";
echo " --tgz 백업 후 .tgz로 압축 (원본 .sql 삭제)\n"; echo " --no-tgz .tgz 압축 안 함 (기본값: 압축)\n";
echo " --dry-run 실제 백업 없이 대상 목록만 출력\n"; echo " --dry-run 실제 백업 없이 대상 목록만 출력\n";
echo " --verbose 상세 로그 출력\n"; echo " --verbose 상세 로그 출력\n";
echo " --edit 이 스크립트를 에디터로 열기\n"; echo " --edit 이 스크립트를 에디터로 열기\n";
...@@ -59,7 +59,7 @@ if (count($positionalArgs) < 2 || isset($options['help'])) { ...@@ -59,7 +59,7 @@ if (count($positionalArgs) < 2 || isset($options['help'])) {
echo " {$argv[0]} mydb users --output=/backup # /backup/mydb.users.sql 생성\n"; echo " {$argv[0]} mydb users --output=/backup # /backup/mydb.users.sql 생성\n";
echo " {$argv[0]} mydb users --mysql=production # production 섹션 사용\n"; echo " {$argv[0]} mydb users --mysql=production # production 섹션 사용\n";
echo " {$argv[0]} '*' '*' --ignore-x=false # x_ 접두사 포함 전체 백업\n"; echo " {$argv[0]} '*' '*' --ignore-x=false # x_ 접두사 포함 전체 백업\n";
echo " {$argv[0]} mydb users --tgz # mydb.users.tgz 생성 (압축)\n"; echo " {$argv[0]} mydb users --no-tgz # mydb.users.sql 생성 (압축 안 함)\n";
echo "\n"; echo "\n";
echo "기본 mysqldump 옵션:\n"; echo "기본 mysqldump 옵션:\n";
echo " --default-character-set=utf8mb4\n"; echo " --default-character-set=utf8mb4\n";
...@@ -204,8 +204,9 @@ function formatBytes($bytes) { ...@@ -204,8 +204,9 @@ function formatBytes($bytes) {
} }
try { try {
// MySQL 연결 // MySQL 연결 (* 패턴일 경우 database 설정 무시)
$conn = ptyMysqlConfig::connect($mysqlSection); $useDatabase = ($dbPattern !== '*');
$conn = ptyMysqlConfig::connect($mysqlSection, $useDatabase);
$connection = $conn['connection']; $connection = $conn['connection'];
$config = $conn['config']; $config = $conn['config'];
......
...@@ -18,7 +18,7 @@ require_once __DIR__ . '/ptyLibrary_PHP/mysql/ptyMysqlConfig.php'; ...@@ -18,7 +18,7 @@ require_once __DIR__ . '/ptyLibrary_PHP/mysql/ptyMysqlConfig.php';
$parsed = ptyCliOptionParser::parse($argv); $parsed = ptyCliOptionParser::parse($argv);
$positionalArgs = $parsed['positional']; $positionalArgs = $parsed['positional'];
$options = $parsed['options']; $options = $parsed['options'];
$mysqlSection = $options['mysql'] ?? 'default'; $mysqlSection = isset($options['mysql']) ? $options['mysql'] : 'default';
// 도움말 // 도움말
if (isset($options['help'])) { if (isset($options['help'])) {
...@@ -83,8 +83,8 @@ function formatUptime($seconds) { ...@@ -83,8 +83,8 @@ function formatUptime($seconds) {
} }
try { try {
// MySQL 연결 // MySQL 연결 (database 설정 무시 - 서버 전체 정보 조회)
$conn = ptyMysqlConfig::connect($mysqlSection); $conn = ptyMysqlConfig::connect($mysqlSection, false);
$connection = $conn['connection']; $connection = $conn['connection'];
$config = $conn['config']; $config = $conn['config'];
...@@ -256,9 +256,9 @@ try { ...@@ -256,9 +256,9 @@ try {
$userCount = 0; $userCount = 0;
while ($row = mysqli_fetch_assoc($result)) { while ($row = mysqli_fetch_assoc($result)) {
$userCount++; $userCount++;
$locked = $row['account_locked'] ?? 'N'; $locked = isset($row['account_locked']) ? $row['account_locked'] : 'N';
$expired = $row['password_expired'] ?? 'N'; $expired = isset($row['password_expired']) ? $row['password_expired'] : 'N';
$hasPw = $row['has_password'] ?? '-'; $hasPw = isset($row['has_password']) ? $row['has_password'] : '-';
$lockedColor = ($locked === 'Y') ? $RED : $GREEN; $lockedColor = ($locked === 'Y') ? $RED : $GREEN;
$expiredColor = ($expired === 'Y') ? $RED : $GREEN; $expiredColor = ($expired === 'Y') ? $RED : $GREEN;
...@@ -293,10 +293,10 @@ try { ...@@ -293,10 +293,10 @@ try {
while ($row = mysqli_fetch_assoc($result)) { while ($row = mysqli_fetch_assoc($result)) {
$processCount++; $processCount++;
$host = substr($row['Host'], 0, 20); $host = substr($row['Host'], 0, 20);
$db = $row['db'] ?? '-'; $db = isset($row['db']) ? $row['db'] : '-';
$state = $row['State'] ?? '-'; $state = isset($row['State']) ? $row['State'] : '-';
$command = $row['Command'] ?? '-'; $command = isset($row['Command']) ? $row['Command'] : '-';
$info = $row['Info'] ?? null; $info = isset($row['Info']) ? $row['Info'] : null;
printf(" %-7s %-12s %-20s %-12s %-6s %-10s %-20s\n", printf(" %-7s %-12s %-20s %-12s %-6s %-10s %-20s\n",
$row['Id'], $row['Id'],
...@@ -388,7 +388,7 @@ try { ...@@ -388,7 +388,7 @@ try {
$result = mysqli_query($connection, "SHOW VARIABLES WHERE Variable_name IN ('" . implode("','", array_keys($moreVars)) . "')"); $result = mysqli_query($connection, "SHOW VARIABLES WHERE Variable_name IN ('" . implode("','", array_keys($moreVars)) . "')");
while ($row = mysqli_fetch_assoc($result)) { while ($row = mysqli_fetch_assoc($result)) {
$varName = $row['Variable_name']; $varName = $row['Variable_name'];
$label = $moreVars[$varName] ?? $varName; $label = isset($moreVars[$varName]) ? $moreVars[$varName] : $varName;
$value = $row['Value']; $value = $row['Value'];
// 바이트 값 포맷팅 // 바이트 값 포맷팅
......
This diff is collapsed.
...@@ -234,8 +234,8 @@ function restoreFile($host, $user, $password, $dbName, $tableName, $sqlFile, $ve ...@@ -234,8 +234,8 @@ function restoreFile($host, $user, $password, $dbName, $tableName, $sqlFile, $ve
} }
try { try {
// MySQL 연결 (DB 목록 조회용) // MySQL 연결 (database 설정 무시 - 여러 DB에 복원 가능)
$conn = ptyMysqlConfig::connect($mysqlSection); $conn = ptyMysqlConfig::connect($mysqlSection, false);
$connection = $conn['connection']; $connection = $conn['connection'];
$config = $conn['config']; $config = $conn['config'];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment