Skip to content

Commit 152dc49

Browse files
committed
refactor: remove ai analyze command, keep only ai query
Remove 'ai analyze' subcommand as it was redundant with 'ai query'. The 'ai query' command provides more comprehensive analysis including both base analysis (issues/recommendations) and AI analysis. Changes: - Removed analyze() method from AiCommand - Removed analyze from execute() match statement - Removed analyze from help text and examples - Removed testAiCommandAnalyze and related tests - Updated documentation to remove analyze references - Updated README.md examples to use 'ai query' instead
1 parent 58687f1 commit 152dc49

File tree

4 files changed

+5
-197
lines changed

4 files changed

+5
-197
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ export PDODB_AI_OPENAI_MODEL=gpt-4o-mini # Optional: gpt-4, gpt-3.5-turbo
493493
export PDODB_AI_GOOGLE_MODEL=gemini-2.5-flash # Optional: gemini-2.5-pro, gemini-2.0-flash-001, gemini-flash-latest
494494

495495
# Analyze query
496-
pdodb ai analyze "SELECT * FROM users WHERE email = '[email protected]'" \
496+
pdodb ai query "SELECT * FROM users WHERE email = '[email protected]'" \
497497
--provider=openai \
498498
--table=users
499499
```
@@ -759,7 +759,7 @@ echo "source ~/.pdodb-completion.bash" >> ~/.bashrc
759759
vendor/bin/pdodb ui
760760

761761
# 🤖 AI-powered analysis (requires API keys or Ollama)
762-
vendor/bin/pdodb ai analyze "SELECT * FROM users WHERE email = '[email protected]'" --provider=openai
762+
vendor/bin/pdodb ai query "SELECT * FROM users WHERE email = '[email protected]'" --provider=openai
763763
vendor/bin/pdodb ai query "SELECT * FROM orders" --provider=anthropic --table=orders
764764
vendor/bin/pdodb ai schema --table=users --provider=ollama
765765

documentation/05-advanced-features/23-ai-analysis.md

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -291,25 +291,6 @@ $suggestions = $aiService->suggestOptimizations(
291291

292292
## CLI Commands
293293

294-
### `pdodb ai analyze`
295-
296-
Analyze a SQL query with AI:
297-
298-
```bash
299-
pdodb ai analyze "SELECT * FROM users WHERE email = '[email protected]'" \
300-
--provider=openai \
301-
--table=users \
302-
--format=json
303-
```
304-
305-
Options:
306-
- `--provider=NAME` - AI provider (openai, anthropic, google, microsoft, ollama)
307-
- `--model=NAME` - Model name (provider-specific)
308-
- `--temperature=N` - Temperature (0.0-2.0, default: 0.7)
309-
- `--max-tokens=N` - Maximum tokens (default: 2000)
310-
- `--table=NAME` - Table name for context
311-
- `--format=FORMAT` - Output format (text, json)
312-
313294
### `pdodb ai query`
314295

315296
Analyze query using `explainAiAdvice()` (includes both base and AI analysis):
@@ -366,10 +347,10 @@ The MCP server exposes the following tools:
366347
}
367348
```
368349

369-
2. **`analyze_query`** - Analyze SQL query with AI
350+
2. **`explain_plan`** - Analyze SQL query with EXPLAIN plan and AI
370351
```json
371352
{
372-
"name": "analyze_query",
353+
"name": "explain_plan",
373354
"arguments": {
374355
"sql": "SELECT * FROM users WHERE id = 1",
375356
"table": "users",
@@ -412,7 +393,7 @@ The server also exposes database tables as resources:
412393

413394
The server provides prompt templates:
414395

415-
- `analyze_query` - Template for analyzing SQL queries
396+
- `explain_plan` - Template for analyzing SQL queries with EXPLAIN plan
416397
- `optimize_schema` - Template for schema optimization
417398

418399
## Examples
@@ -498,12 +479,6 @@ echo $result->aiAnalysis;
498479
### Example 4: CLI Usage
499480

500481
```bash
501-
# Analyze query with OpenAI
502-
pdodb ai analyze "SELECT * FROM users WHERE email LIKE '%@gmail.com'" \
503-
--provider=openai \
504-
--table=users \
505-
--format=json
506-
507482
# Get schema optimization suggestions
508483
pdodb ai schema --table=orders --provider=anthropic
509484

src/cli/commands/AiCommand.php

Lines changed: 0 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public function execute(): int
2626
$subcommand = $this->getArgument(0);
2727

2828
return match ($subcommand) {
29-
'analyze' => $this->analyze(),
3029
'query' => $this->query(),
3130
'schema' => $this->schema(),
3231
'optimize' => $this->optimize(),
@@ -35,91 +34,6 @@ public function execute(): int
3534
};
3635
}
3736

38-
/**
39-
* Analyze SQL query with AI.
40-
*/
41-
protected function analyze(): int
42-
{
43-
$sql = $this->getArgument(1);
44-
if ($sql === null || $sql === '') {
45-
return $this->showError('SQL query is required. Usage: pdodb ai analyze "SELECT * FROM users"');
46-
}
47-
48-
$db = $this->getDb();
49-
$provider = $this->getOption('provider');
50-
$format = (string)$this->getOption('format', 'text');
51-
52-
$options = [];
53-
if (($this->getOption('temperature')) !== null) {
54-
$options['temperature'] = (float)$this->getOption('temperature');
55-
}
56-
if (($this->getOption('max-tokens')) !== null) {
57-
$options['max_tokens'] = (int)$this->getOption('max-tokens');
58-
}
59-
if (($this->getOption('model')) !== null) {
60-
$options['model'] = (string)$this->getOption('model');
61-
}
62-
63-
$tableName = $this->getOption('table');
64-
65-
try {
66-
// Get EXPLAIN plan for better AI analysis
67-
static::info('Analyzing query execution plan...');
68-
$connection = $db->connection;
69-
$dialect = $connection->getDialect();
70-
$pdo = $connection->getPdo();
71-
72-
$explainAnalysis = null;
73-
74-
try {
75-
$explainResults = $dialect->executeExplain($pdo, $sql, []);
76-
$queryBuilder = $db->find();
77-
$reflection = new \ReflectionClass($queryBuilder);
78-
$executionEngineProperty = $reflection->getProperty('executionEngine');
79-
$executionEngineProperty->setAccessible(true);
80-
$executionEngine = $executionEngineProperty->getValue($queryBuilder);
81-
$analyzer = new ExplainAnalyzer($dialect, $executionEngine);
82-
$explainAnalysis = $analyzer->analyze($explainResults, $tableName);
83-
} catch (\Throwable $e) {
84-
// If EXPLAIN fails, continue without it (e.g., invalid SQL or unsupported)
85-
static::info('Note: Could not get execution plan: ' . $e->getMessage());
86-
}
87-
88-
static::info('Initializing AI service...');
89-
$aiService = new AiAnalysisService($db);
90-
$actualProvider = $aiService->getProvider($provider);
91-
$model = $actualProvider->getModel();
92-
93-
static::info("Provider: {$actualProvider->getProviderName()}");
94-
static::info("Model: {$model}");
95-
static::loading('Sending request to AI API');
96-
97-
$analysis = $aiService->analyzeQuery($sql, $tableName, $provider, $options, $explainAnalysis);
98-
99-
if (getenv('PHPUNIT') === false) {
100-
echo "\r" . str_repeat(' ', 80) . "\r"; // Clear loading line
101-
}
102-
103-
if ($format === 'json') {
104-
echo json_encode([
105-
'sql' => $sql,
106-
'provider' => $actualProvider->getProviderName(),
107-
'analysis' => $analysis,
108-
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
109-
return 0;
110-
}
111-
112-
echo 'AI Analysis (Provider: ' . $actualProvider->getProviderName() . ")\n";
113-
echo str_repeat('=', 80) . "\n\n";
114-
$formatter = new MarkdownFormatter();
115-
echo $formatter->format($analysis) . "\n";
116-
117-
return 0;
118-
} catch (\Throwable $e) {
119-
return $this->showError('AI analysis failed: ' . $e->getMessage());
120-
}
121-
}
122-
12337
/**
12438
* Analyze query using explainAiAdvice.
12539
*/
@@ -414,7 +328,6 @@ protected function showHelp(): int
414328
echo "============================\n\n";
415329
echo "Usage: pdodb ai <subcommand> [arguments] [options]\n\n";
416330
echo "Subcommands:\n";
417-
echo " analyze <sql> Analyze SQL query with AI\n";
418331
echo " query <sql> Analyze query using explainAiAdvice (includes base analysis)\n";
419332
echo " schema Analyze database schema with AI\n";
420333
echo " optimize Get AI-powered optimization suggestions\n";
@@ -427,7 +340,6 @@ protected function showHelp(): int
427340
echo " --table=NAME Table name for context\n";
428341
echo " --format=FORMAT Output format (text, json)\n\n";
429342
echo "Examples:\n";
430-
echo " pdodb ai analyze \"SELECT * FROM users WHERE id = 1\"\n";
431343
echo " pdodb ai query \"SELECT * FROM users\" --provider=anthropic\n";
432344
echo " pdodb ai schema --table=users --format=json\n";
433345
echo " pdodb ai optimize --provider=openai --temperature=0.5\n\n";

tests/shared/AiCommandCliTests.php

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -129,30 +129,6 @@ public function testAiCommandHelp(): void
129129
}
130130
}
131131

132-
public function testAiCommandAnalyze(): void
133-
{
134-
ob_start();
135-
136-
try {
137-
$exitCode = $this->app->run([
138-
'pdodb',
139-
'ai',
140-
'analyze',
141-
'SELECT * FROM test_users WHERE id = 1',
142-
'--provider=ollama',
143-
'--max-tokens=' . self::OLLAMA_MAX_TOKENS,
144-
'--timeout=' . self::OLLAMA_API_TIMEOUT,
145-
]);
146-
$output = ob_get_clean();
147-
$this->assertEquals(0, $exitCode);
148-
$this->assertStringContainsString('AI Analysis', $output);
149-
} catch (\Throwable $e) {
150-
ob_end_clean();
151-
152-
throw $e;
153-
}
154-
}
155-
156132
public function testAiCommandQuery(): void
157133
{
158134
// Create table in the database that Application will use
@@ -221,61 +197,6 @@ public function testAiCommandSchema(): void
221197
}
222198
}
223199

224-
public function testAiCommandAnalyzeWithJsonFormat(): void
225-
{
226-
ob_start();
227-
228-
try {
229-
$exitCode = $this->app->run([
230-
'pdodb',
231-
'ai',
232-
'analyze',
233-
'SELECT * FROM test_users',
234-
'--provider=ollama',
235-
'--format=json',
236-
'--max-tokens=' . self::OLLAMA_MAX_TOKENS,
237-
'--timeout=' . self::OLLAMA_API_TIMEOUT,
238-
]);
239-
$output = ob_get_clean();
240-
$this->assertEquals(0, $exitCode);
241-
$json = json_decode($output, true);
242-
$this->assertIsArray($json);
243-
$this->assertArrayHasKey('sql', $json);
244-
$this->assertArrayHasKey('provider', $json);
245-
$this->assertArrayHasKey('analysis', $json);
246-
} catch (\Throwable $e) {
247-
ob_end_clean();
248-
249-
throw $e;
250-
}
251-
}
252-
253-
public function testAiCommandWithInvalidProvider(): void
254-
{
255-
ob_start();
256-
257-
try {
258-
$exitCode = $this->app->run([
259-
'pdodb',
260-
'ai',
261-
'analyze',
262-
'SELECT * FROM test_users',
263-
'--provider=invalid',
264-
]);
265-
$output = ob_get_clean();
266-
// Should return error code (non-zero) or throw exception
267-
$this->assertNotEquals(0, $exitCode);
268-
$this->assertStringContainsString('failed', mb_strtolower($output, 'UTF-8'));
269-
} catch (\RuntimeException $e) {
270-
ob_end_clean();
271-
// Exception is also acceptable - it means error was handled
272-
$this->assertStringContainsString('failed', mb_strtolower($e->getMessage(), 'UTF-8'));
273-
} catch (\Throwable $e) {
274-
ob_end_clean();
275-
276-
throw $e;
277-
}
278-
}
279200

280201
public static function tearDownAfterClass(): void
281202
{

0 commit comments

Comments
 (0)