pematon / adminer-plugins

Usefull plugins for Adminer database tool.
MIT License
33 stars 9 forks source link

AdminerLoginServers.php/sqlite: database definition via # not working #10

Open maddes-b opened 3 years ago

maddes-b commented 3 years ago

OS: Ubuntu Server 21.04 Adminer version: adminer-4.7.9-1 (Ubuntu package) Full path of wanted SQLite db: /var/lib/dbconfig-common/sqlite3/roundcube/roundcube

When defining the database name via a # symbol, then connection does not work. When getting rid of the # symbol then everything works fine.

1. Failure /etc/adminer/conf.php:

...
    $plugins = array(
        // specify enabled plugins here
        new AdminerVersionNoverify(), // disable phoning home
        new AdminerLoginServers([
            'sqlite://fakeuser:fakepw@/var/lib/dbconfig-common/sqlite3/roundcube/#roundcube' => 'Roundcube',
            'mysql://localhost' => 'localhost',
        ]),
    );
...

Results internally correctly to:

Array
(
[driver] => sqlite
[username] => root
[password] => $2y$10$RmeNImI7uH9rFn4xCh5uIeXJVw0ZxlRuYU7D2v9oF1DZ/6Uzybr4O
[server] => /var/lib/dbconfig-common/sqlite3/roundcube
[database] => roundcube
)

Connection fails with Invalid database. Server name shown is SQLite 3 » /var/lib/dbconfig-common/sqlite3/roundcube/ » Database: roundcube

2. Working /etc/adminer/conf.php:

...
    $plugins = array(
        // specify enabled plugins here
        new AdminerVersionNoverify(), // disable phoning home
        new AdminerLoginServers([
            'sqlite://fakeuser:fakepw@/var/lib/dbconfig-common/sqlite3/roundcube/roundcube' => 'Roundcube',
            'mysql://localhost' => 'localhost',
        ]),
    );
...

Results internally to:

Array
(
[driver] => sqlite
[username] => root
[password] => $2y$10$gD3kf6rEi6GgmG/hh4ory.ftVpFdpiTWJy4y4/J9KqmPEpeCWHb/G
[server] =>
[database] => /var/lib/dbconfig-common/sqlite3/roundcube/roundcube
)

Connection works. Server name shown is SQLite 3 » Server » Database: /var/lib/dbconfig-common/sqlite3/roundcube/roundcube.

maddes-b commented 3 years ago

Seems that Adminer needs for SQLite the full path in DB. This can be handled in loginForm() locally, and to get a matching server key again for SQLite just remove the # symbol from the internal server key.

The following changes worked for me:

--- AdminerLoginServers.php.org 2021-07-24 23:53:57.427206651 +0000
+++ AdminerLoginServers.php     2021-07-25 01:41:20.000000000 +0000
@@ -183,7 +183,7 @@ class AdminerLoginServers
      */
     private function getServerKey($driver, $server, $database)
     {
-        return $this->isSQLite($driver) ? $server . "#" . $database : $server;
+        return $this->isSQLite($driver) ? $server . $database : $server;
     }

     /**
@@ -288,6 +288,10 @@ class AdminerLoginServers
                     $count = count($this->loginParams);
                     $i = 1;
                     foreach ($this->loginParams as $serverKey => $params) {
+                        if ($this->isSQLite($params["driver"])) {
+                            $params["database"] = $params["server"] . $params["database"];
+                            $params["server"] = "";
+                        }
                         echo json_encode($serverKey) . ": { 'driver': " . json_encode($params["driver"]) .
                             ",  'server': " . json_encode($params["server"]) .
                             ", 'database': " . json_encode($params["database"]) . " }";
maddes-b commented 3 years ago

Mabye this could also be handled just in parseServers() (plural), as the split of path and actual db file is just important for getServerName() - as far as I understand the code:

  1. Handle $name incl. executing getServerName()
  2. If SQLite then concatenate server and database into database and clear server. Similar to what is done in parseServer() (singular). The additional code above for loginForm() should be usable as-is for this too.
  3. Only then determine server key.
  4. No need to change variables in loginForm() anymore.
  5. Still needs getServerKey() change. Could be reduced to return $this->isSQLite($driver) ? $database : $server;
--- AdminerLoginServers.php.org 2021-07-24 23:53:57.427206651 +0000
+++ AdminerLoginServers.php     2021-07-25 02:40:05.000000000 +0000
@@ -126,10 +126,14 @@ class AdminerLoginServers
                 $params = [];
                 $this->parseServer($server, $params);

-                $serverKey = $this->getServerKey($params["driver"], $params["server"], $params["database"]);
                 if (!$name) {
                     $name = $this->getServerName($params);
                 }
+                if ($this->isSQLite($params["driver"])) {
+                    $params["database"] = $params["server"] . $params["database"];
+                    $params["server"] = "";
+                }
+                $serverKey = $this->getServerKey($params["driver"], $params["server"], $params["database"]);

                 $out[$serverKey] = "(" . $this->formatDriver($params["driver"]) . ") " . $name;

@@ -183,7 +187,7 @@ class AdminerLoginServers
      */
     private function getServerKey($driver, $server, $database)
     {
-        return $this->isSQLite($driver) ? $server . "#" . $database : $server;
+        return $this->isSQLite($driver) ? $database : $server;
     }

     /**