Adminer Editorでデータ更新依頼を自動化できないか検討


## 概要
データの修正依頼を受けてDB運用者が依頼に沿ってデータ修正するのではなく、直接依頼者がデータ修正できるようにできないかという想像から始まった。
phpmyadminやAdminerなどは機能豊富で生のSQLを叩けるのでなかなかハードルが高いし、だからといっていちいちツールを開発するのは大変。

そこで、いろいろ調べてみるとAdmin Editorというツールを見つけた。

https://www.adminer.org/en/editor/

Adminer Editorは非開発者でもわかりやすいようなUIを提供するデータ修正ツールで、Adminer同様多数のDBMSに対応している。
Adminerの機能制限版といった感じ？テーブルの作成やスキーマの修正などの機能を提供せずデータの追加、修正、削除のみを実施することができる。
そのため、アプリを立ち上げて依頼者にURLを提供すれば安全に修正できるようにならないか？という発想です。

公式サイトによると以下の制約があるようです。

* SQLは直接実行できない
* データベースは1つしか選べない

このページではAdminer EditorをDockerで試してみます。

## 環境構築
ローカルのDocker上でMySQL、Adminer Editorを構築する。

### 実行環境
AdminerはDockerイメージが公式で提供されているがAdminer Editorはなさそうだったので作成した。

mysqlのクライアントをインストールする。

```dockerfile:Dockerfile
FROM php:apache

RUN docker-php-ext-install pdo_mysql mysqli
```

それで、docker-compose.yamlでadminerをマウントするだけ。

```yaml:docker-compose.yml
version: '3.1'

services:

  db:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password

  adminer:
    build:
      context: .
    restart: always
    ports:
      - 80:80
    volumes:
      - ./adminer:/var/www/html
```

### ソース

editor.phpの1ファイルでソースは完結しているので公式ページからダウンロードして配置する。ただし、各種設定が必要なためindex.phpを新規作成して設定する。

https://www.adminer.org/en/editor/

設定方法は以下のページに記載されている。基本クラスのAdminerをオーバーライドして関数を書くことで各種設定ができる。
設定ファイル等ではないのでとっつきにくいがいろいろできるとも言える？

https://www.adminer.org/en/extension/

```
 tree ./adminer
./adminer
├── editor.php
├── index.php
```

```php:index.php
<?php
function adminer_object()
{
  class AdminerSoftware extends Adminer
  {

    // 画面表示されるタイトル
    function name()
    {
      return 'tool';
    }

    // DB設定
    function credentials()
    {
      return array('db', 'root', 'password');
    }

    // 使用するデータベース
    function database()
    {
      return 'world';
    }

    // 認証方法、trueを返すと何も入力しなくても認証が通る。
    function login($login, $password)
    {
      return true;
    }
  }


  return new AdminerSoftware();
}

include './editor.php';
```

## 確認
確認のためMySQLにMySQL公式で提供されているworld databaseをインポートした。

https://dev.mysql.com/doc/index-other.html

localhost/adminer にアクセスしログイン画面が表示された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359375/75adcd6f-72bc-4e19-78d4-29c686bc267e.png)

なんでも認証を通しているのでログイン成功。予め設定したDBのテーブルのみが表示されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359375/c3f252a0-5adf-59e6-8f09-2e59d3b56dcf.png)

テーブル一覧が表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359375/0e338fcf-1a33-5438-e285-e3545c31047c.png)

画面下部にはCSVインポート、エクスポートなどもある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359375/a3bb1a9e-86ce-655c-19b2-f192ac7dfc08.png)

編集をクリックするとデータ変更できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359375/1de7c3fc-3127-f770-d0f3-afb0dfafc033.png)

データ修正しかできないのが良い感じ。

## さらにカスタマイズしてみる

関数を書き換えるのでハードルが高いが以下のカスタムを試してみた。

* 不要なテーブルを表示しない
* 不要なカラムを表示しない

tableNameとfieldNameをオーバーライドする。

```php
    function tableName($tableStatus)
    {
      // countryテーブルを非表示
      $ignored_list = [
        'country',
      ];
      if (in_array($tableStatus["Name"], $ignored_list, true)) {
        return '';
      }
      return h($tableStatus["Name"]);
    }

    function fieldName($field, $order = 0)
    {
      // ID列を非表示
      $ignored_list = [
        'ID'
      ];
      if (in_array($field["field"], $ignored_list, true)) {
        return '';
      }
      return '<span title="' . h($field["full_type"]) . '">' . h($field["field"]) . '</span>';
    }
```

countryテーブルが消えた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359375/96f69ad4-429e-f1d7-298e-c8841ec9e573.png)

IDカラムが消えた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359375/53a8b0e0-1e7d-aa2c-a275-f1d0536fa68c.png)

編集画面からも消えている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359375/7934a577-c1a9-a3bc-d203-3978f36b5299.png)

これでIDや論理削除、作成日時などの列があれば非表示にできる。

## 感想

汎用的な修正ツールとして活用できそうだが、
実用を考えると操作ログがアクセスログくらいしかないことや認証周りの機能が少ないので解決する必要があるという感想を持った。