]> git.joonet.de Git - adminer.git/commitdiff
New plugin: AI prompt in SQL command creating the queries with Google Gemini
authorJakub Vrana <jakub@vrana.cz>
Sun, 23 Mar 2025 06:34:33 +0000 (07:34 +0100)
committerJakub Vrana <jakub@vrana.cz>
Sun, 23 Mar 2025 07:02:48 +0000 (08:02 +0100)
CHANGELOG.md
adminer/include/adminer.inc.php
adminer/include/plugins.inc.php
adminer/sql.inc.php
plugins/sql-gemini.php [new file with mode: 0644]

index d05467e48352c216fcda3e3f83c981afb89a73f9..887efb75dc4e5fdcb1a5ecdfb260b22aad8cfaf6 100644 (file)
@@ -16,6 +16,7 @@
 - Plugins: autoload plugins from adminer-plugins/
 - Plugins: configure plugins with adminer-plugins.php
 - Plugins: Display loaded plugins in server overview
+- New plugin: AI prompt in SQL command generating the queries with Google Gemini
 - New plugin: IMAP driver created for fun
 - New plugin: Display links to tables referencing current row
 - New plugin: Allow switching light and dark mode (bug #926)
index 728ce5038071afd150e420b6683ad96a1d269616..fdd8050760e82f7bcf0cc4ee81663acc2e1104fc 100644 (file)
@@ -263,6 +263,11 @@ class Adminer {
                return shorten_utf8(trim($query), 1000);
        }
 
+       /** Print HTML code just before the Execute button in SQL command
+       */
+       function sqlPrintAfter() {
+       }
+
        /** Description of a row in a table
        * @param string
        * @return string SQL expression, empty string for no description
index 2a6eca6a18585c288b366e224ce957e59dc627bf..b72626ece91a836157300e3bb5f05d95dedd7913 100644 (file)
@@ -245,6 +245,11 @@ class Plugins extends Adminer {
                return $this->applyPlugin(__FUNCTION__, $args);
        }
 
+       function sqlPrintAfter() {
+               $args = func_get_args();
+               return $this->applyPlugin(__FUNCTION__, $args);
+       }
+
        function rowDescription($table) {
                $args = func_get_args();
                return $this->applyPlugin(__FUNCTION__, $args);
index 64ef96b6fc6d611bb50f9a28fefa0d1bc108cc0d..02db018a7d3921fba308c5362a1f6ecc51a8bf65 100644 (file)
@@ -235,7 +235,9 @@ if (!isset($_GET["import"])) {
        echo "<p>";
        textarea("query", $q, 20);
        echo script(($_POST ? "" : "qs('textarea').focus();\n") . "qs('#form').onsubmit = partial(sqlSubmit, qs('#form'), '" . js_escape(remove_from_uri("sql|limit|error_stops|only_errors|history")) . "');");
-       echo "<p>$execute\n";
+       echo "<p>";
+       $adminer->sqlPrintAfter();
+       echo "$execute\n";
        echo lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n";
 
 } else {
diff --git a/plugins/sql-gemini.php b/plugins/sql-gemini.php
new file mode 100644 (file)
index 0000000..9a507d6
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+
+/** AI prompt in SQL command generating the queries with Google Gemini
+* Beware that this sends your whole database structure (not data) to Google Gemini.
+* @link https://www.adminer.org/static/plugins/sql-gemini.gif
+* @link https://gemini.google.com/
+* @link https://www.adminer.org/plugins/#use
+* @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 AdminerSqlGemini {
+       private $apiKey;
+       private $model;
+
+       /**
+       * @param string Get API key at: https://aistudio.google.com/apikey
+       * @param string Available models: https://ai.google.dev/gemini-api/docs/models#available-models
+       */
+       function __construct($apiKey, $model = "gemini-2.0-flash") {
+               $this->apiKey = $apiKey;
+               $this->model = $model;
+       }
+
+       function headers() {
+               if ($_POST["gemini"] && !isset($_POST["query"])) {
+                       $prompt = "I have a database with this structure:\n\n";
+                       foreach (Adminer\tables_list() as $table => $type) {
+                               $prompt .= Adminer\create_sql($table, false, "CREATE") . ";\n\n";
+                       }
+                       $prompt .= "Give me this SQL query and nothing else:\n\n$_POST[gemini]";
+                       //~ echo $prompt; exit;
+                       $context = stream_context_create(array("http" => array(
+                               "method" => "POST",
+                               "header" => array("User-Agent: AdminerSqlGemini", "Content-Type: application/json"),
+                               "content" => '{"contents": [{"parts":[{"text": ' . json_encode($prompt) . '}]}]}',
+                       )));
+                       $response = json_decode(file_get_contents("https://generativelanguage.googleapis.com/v1beta/models/$this->model:generateContent?key=$this->apiKey", false, $context));
+                       $text = $response->candidates[0]->content->parts[0]->text;
+                       echo preg_replace('~```sql\n(.*\n)```~s', '\1', $text) . "\n";
+                       exit;
+               }
+       }
+
+       function sqlPrintAfter() {
+               echo "<p><textarea name='gemini' rows='5' cols='50' title='AI prompt'>" . Adminer\h($_POST["gemini"]) . "</textarea>\n";
+               echo "<p><input type='button' value='Gemini'>" . Adminer\script("qsl('input').onclick = function () { ajax(
+                       '',
+                       req => {
+                               qs('textarea.sqlarea').value = req.responseText;
+                               const sqlarea = qs('pre.sqlarea');
+                               sqlarea.textContent = req.responseText;
+                               sqlarea.oninput(); // syntax highlighting
+                       },
+                       'gemini=' + encodeURIComponent(this.form['gemini'].value)
+               ); }");
+       }
+}