Last active
April 25, 2025 05:36
-
-
Save MichalSkoula/b0df289804f0c216200732624468a765 to your computer and use it in GitHub Desktop.
AI prompt in SQL command generating the queries with Anthropic Claude
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** AI prompt in SQL command generating the queries with Anthropic Claude | |
* Beware that this sends your whole database structure (not data) to Anthropic Claude. | |
* Forked from https://github.com/vrana/adminer/blob/master/plugins/sql-gemini.php | |
* @link https://www.anthropic.com/claude | |
* @link https://www.adminer.org/plugins/#use | |
* @author Michal Škoula, https://skoula.cz | |
* @author Jakub Vrana, https://www.vrana.cz/ | |
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 | |
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) | |
*/ | |
class AdminerSqlClaude extends Adminer\Plugin { | |
private $apiKey; | |
private $model; | |
/** | |
* @param string $apiKey Your Claude API key. Get your API key at: https://console.anthropic.com/ | |
* @param string $model Available models: https://docs.anthropic.com/en/docs/about-claude/models/all-models#model-comparison-table | |
*/ | |
function __construct(string $apiKey, string $model = "claude-3-5-haiku-20241022") { | |
$this->apiKey = $apiKey; | |
$this->model = $model; | |
} | |
function headers() { | |
if (isset($_POST["claude"]) && !isset($_POST["query"])) { | |
$prompt = "I have a " . Adminer\get_driver(Adminer\DRIVER) . " database with this structure:\n\n"; | |
foreach (Adminer\tables_list() as $table => $type) { | |
$prompt .= Adminer\create_sql($table, false, "CREATE") . ";\n\n"; | |
} | |
$prompt .= "Prefer returning relevant columns including primary key.\n\n"; | |
$prompt .= "Give me this SQL query in plain text (pretty formatted) and nothing else:\n\n$_POST[claude]\n\n"; | |
$prompt .= "Do not wrap the SQL in markdown code blocks. Just return the raw SQL."; | |
$context = stream_context_create(array("http" => array( | |
"method" => "POST", | |
"header" => array( | |
"User-Agent: AdminerSqlClaude/" . Adminer\VERSION, | |
"Content-Type: application/json", | |
"x-api-key: $this->apiKey", | |
"anthropic-version: 2023-06-01" | |
), | |
"content" => json_encode([ | |
"model" => $this->model, | |
"max_tokens" => 1024, | |
"messages" => [ | |
["role" => "user", "content" => $prompt] | |
] | |
]), | |
"ignore_errors" => true, | |
))); | |
$response = json_decode(file_get_contents("https://api.anthropic.com/v1/messages", false, $context)); | |
if (isset($response->error)) { | |
echo "-- " . $response->error->message; | |
} else { | |
$text = $response->content[0]->text; | |
// Strip markdown code blocks | |
$text = preg_replace('/```sql\s*|\s*```/s', '', $text); | |
// Also remove any /* */ style comments that might be in the text | |
$text = preg_replace('~/\*.*?\*/~s', '', $text); | |
echo trim($text); | |
} | |
exit; | |
} | |
} | |
function sqlPrintAfter() { | |
echo "<p><textarea name='claude' rows='5' cols='50' placeholder='" . $this->lang('Ask Claude') . "'>" . Adminer\h($_POST["claude"] ?? '') . "</textarea>\n"; | |
?> | |
<p><input type='button' value='Claude'> | |
<script <?php echo Adminer\nonce(); ?>> | |
const claudeText = qsl('textarea'); | |
const claudeButton = qsl('input'); | |
function setSqlareaValue(value) { | |
const sqlarea = qs('textarea.sqlarea'); | |
sqlarea.value = value; | |
sqlarea.onchange && sqlarea.onchange(); | |
} | |
claudeButton.onclick = () => { | |
setSqlareaValue('-- <?php echo $this->lang('Just a sec...'); ?>'); | |
ajax( | |
'', | |
req => setSqlareaValue(req.responseText), | |
'claude=' + encodeURIComponent(claudeText.value) | |
); | |
}; | |
claudeText.onfocus = event => { | |
alterClass(findDefaultSubmit(claudeText), 'default'); | |
alterClass(claudeButton, 'default', true); | |
event.stopImmediatePropagation(); | |
}; | |
claudeText.onblur = () => { | |
alterClass(claudeButton, 'default'); | |
}; | |
claudeText.onkeydown = event => { | |
if (isCtrl(event) && (event.keyCode == 13 || event.keyCode == 10)) { | |
claudeButton.onclick(); | |
event.stopPropagation(); | |
} | |
}; | |
</script> | |
<?php | |
} | |
// use the phrases from https://www.anthropic.com/ | |
protected $translations = array( | |
'cs' => array( | |
'' => 'Generování SQL příkazů pomocí umělé inteligence Anthropic Claude', | |
'Ask Claude' => 'Zeptat se Claude', | |
'Just a sec...' => 'Chviličku...', | |
), | |
'pl' => array( | |
'Ask Claude' => 'Zapytaj Claude', | |
'Just a sec...' => 'Chwileczkę...', | |
), | |
'de' => array( | |
'' => 'KI-Eingabeaufforderung im SQL-Befehl zur Erstellung der Abfragen mit Anthropic Claude', | |
'Ask Claude' => 'Claude fragen', | |
'Just a sec...' => 'Einen Moment...', | |
), | |
'ja' => array( | |
'' => 'Anthropic Claude AI を用いて SQL 文を生成', | |
'Ask Claude' => 'Claude に聞く', | |
'Just a sec...' => 'しばらくお待ち下さい...', | |
), | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment