FUMIの開発日記

ソフトウェア開発のメモ的なブログです

macのmysqlがmysql8.0になってたので、mysql5.7に戻したときのメモ

brew upgradeをしたら、気づかないうちにmysql 8.0になっていました。 ローカルのmysql serverに接続できなくなったので、mysql 5.7に戻したときのメモです。 前提として、msyql 5.7がもともと動いていて、brew upgradeをしたことで、mysql 8.0がインストールされたものとします。 念の為、/usr/loca/var/mysql以下のバックアップを忘れないようにします。

まず、mysqlのバージョンチェック。 8.0系が表示されることを確認

$mysql --version

mysql 8.0をアンインストール

$brew uninstall mysql

symlinkの状況を確認

$brew doctor

mysql5.7のsymlinkを再設定

$brew link mysql

mysqlのバージョンを確認

$mysql --version

mysql5.7になっていれば完了

お疲れ様でした。

gitlab + plantuml server を ssl で運用する

gitlab ce (omnibus) でplantumlを有効にするためにやったこと。

環境 Ubuntu 16.04 (gitlab ce) , Ubuntu 16.04 (plantuml)

はじめに、plantuml-serverをインストールする。 今回は以下のドキュメントに従ってplantuml-serverをインストールした。

docs.gitlab.com

openjdk-7-jdkubuntu 16.04だとダウンロードできないので、ppaを追加しておく。

askubuntu.com

sslはnginxのreverse proxy と certbotで構築する。

nginxをインストールする。

virtualhostとreverse proxyを設定する。以下のようなvirtualhostを/etc/nginx/sites-available/defaultに書き込む(別ファイルにしても良い)。

server {
         listen 80;
         listen [::]:80;

        server_name uml.example.com;

        location / {
                proxy_pass http://127.0.0.1:8080/;
                proxy_pass_request_headers on;
                proxy_set_header        Host  $http_host;
                proxy_set_header        X-Real-IP  $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto $scheme;
        }

}

ここで, 127.0.0.1:8080は、/etc/tomcat7/server.xml に記載されているポートとなっている。

続いて、certbotをインストールする。 インストール方法は公式ドキュメントに従ってインストールする。

certbot.eff.org

https://uml.example.com/plantumlにアクセスして、httpsとなっていればOK。

最後に、gitlab側でplantumlの設定を行う。

前述のgitlab - plantumlのドキュメントに従って、gitlab のadminパネルからplantumlを有効にして、 urlをhttps://uml.example.com/plantuml/とすれば完了。

wikiなどでplantumlが直接画像で表示されるようになる。

※gitlab ce (omnibus)と同じサーバーにplantuml-serverの設置を試みたが、nginxの設定がうまく行かず、断念した。 なので、今回はgitlab ce と plantuml-serverは別のサーバーとしている。

video.jsのVolumeControlをiOSで表示する

iOSでインライン動画自動再生をしたときにミュート解除ができないのは不便なので、 iOSでもボリュームコントロールを表示できるか試行錯誤してみた。

playerの再生開始イベントでshow()を呼ぶと表示できるみたい。

環境

  • video.js (6.8.0)
  • iOS 11

Code

<video id="video_player" class="video-js vjs-default-skin" controls preload playsinline muted>
    <source src="" type="application/x-mpegURL">
</video>
/* ... */
<script>
var player = videojs('video_player');
player.ready(function() {
    player.on('play', function() {
            player.controlBar.volumePanel.show();
            player.controlBar.volumePanel.volumeControl.show();
            player.controlBar.volumePanel.muteToggle.show();
    });
});
</script>

AndroidとiOSのダウンロード数(ユニット数)取得を自動化する

2018.03時点での方法

  • iOS -> iTunesConnectAnalyticsを使う
  • Android → gsutilを使う

github.com

iOSのダウンロード数を取得する方法として Reporter を使うことが推奨されているようだけど、 試してみたらTimeZoneが変更できないようなので3rdPartyのiTunesConnectAnalyticsを利用することにした。 Androidのダウンロード数は直接APIにリクエストをおくるのではなく、gsutilを使ってGoogleCloudStrage上に保存されたCSVをダウンロードする。 gsutilからダウンロードしてきたcsvファイルはutf-16エンコードされているので注意。

Laravel 5.4 + jwt-auth 1.0 でFirebase のprivatekeyを使ってjwt認証をする

AndroidアプリとAPIを作っていて、Firebaseのカスタム認証を使おうとしています。 APIはLaravel5.4で実装しているけど、FirebaseのAdrminSDKはPHPに対応していないので独自実装が必要です。 Firebaseカスタムトークン認証をするためには、Firebaseから秘密鍵をダウンロードして、サーバに登録します。 今回、サーバに秘密鍵を登録するところで躓いたので、そのときの知見をメモしておきます。

※まだfirebase認証をAndroid側で実装していないので、カスタムトークン認証が正常に動作することは確認できておりません。

開発環境としては、ubuntu 16.04、php 7.1、MySQL5.7 フレームワークはLaravel 5.4 JWT認証ライブラリとして、jwt-auth 1.0を使います。 WebサーバはLaravelの開発サーバを用いています。

まずは、Firebaseから公開鍵(json)をダウンロードします。 jsonの中のprivate_keyが秘密鍵になっているので、コピーします。 秘密鍵を作成します。

$ touch private-key.pem

作成した鍵をvimで開いて、改行コードを改行に変換します。

:%s/\\n/\r/g

秘密鍵のパーミションを600にします。

$ chmod 600 private-key.pem

秘密鍵から公開鍵を作成します。

$ openssl rsa -pubout < private-key.pem > public-key.pem

以上で鍵ファイルの準備は完了です。

今回、公開鍵と秘密鍵はlaravelのアプリケーションルート配下に置きました。

次にconfig/jwt.phpを編集します。

return [
...
'keys' => [
...
    //'public' => env('JWT_PUBLIC_KEY'),
    'public' => "file://".base_path("public-key"),

    //'private' => env('JWT_PRIVATE_KEY'),
    'private' => "file://".base_path("private-key.pem"),
...
],
...
//'algo' => env('JWT_ALGO', 'HS256'),
'algo' => env('JWT_ALGO', 'RS256'),
...
];

以上で、秘密鍵を使ってjwtトークンが生成されます。

JWTAuthクラスでトークンを生成するときにclaimsが設定可能なようです。

例えば認証のハンドラを用意して、認証が成功した時にuidをclaimsに含めたい場合は以下のような実装になります。

$claims = ['uid' => $user->uid];
return $token = JWTAuth::claims($claims)->fromUser($user);

MySQL5.7のONLY_FULL_GROUP_BYをOFFせずに重複レコードを除外する方法

目的:

ONLY_FULL_GROUP_BYをOFFにせずに、重複レコードを除外してレコードを取得する。

一行まとめ:

group byしないcolumnをselectに含めるには、MAX()もしくはMIN()を使う。

MySQLのバージョンを5.6から5.7に変更して、既存のソースをテストしていたら、 ONLY_FULL_GROUP_BYがONになっていることが原因のエラーが発生。

同様の問題について、ぐぐったら結構ヒットしたんだけど、my.cnfでONLY_FULL_GROUP_BYをOFFにすればOK的なこと書いてあるのがほとんど。

今後のことも考えて、ONLY_FULL_GROUP_BYをOFFにせずに、既存コードと同様に動くようにソースコードを修正してみます。

例として、以下のようなテーブルを考えます。

テーブル名 hoge
id : int primary autoincrement
name : varchar(255) 

MySQL5.7において以下のようなクエリーを発行すると、

SELECT id FROM hoge GROUP BY name;

こんなエラーが返って来ます。

SELECT list is not in GROUP BY clause and contains nonaggregated column 'hoge.id' which is not functionally dependent on columns in GROUP BY clause;

で、こちらが修正後のクエリー

SELECT (MAX(id)) AS `id` FROM hoge GROUP BY name;

ここでポイントはMAX(id)。

ONLY_FULL_GROUP_BYがONになっていると、 MySQLはGroupByしていないカラム(今回はID)をSelectするときに、 どのIDを取得したらよいかMySQLがわからないためエラーとなっています(たぶん)。

重複時にどの値を使うかをMySQLに伝えてあげればいいので、状況に応じて、MAX()やMIN()を使い分ければ良いと思います。

あとはこれをサブクエリに使うなり、PHPの配列に入れてWhere INするなりすれば既存のコードを置き換えられます。

お疲れ様でした。

Intellij IdeaでCakePHP3のUnitTestを行う。

普段使っているIntellij IdeaでもCake3のUnitテストできないものかと調べたら、 設定がいろいろと大変そうだなーと一旦断念。

改めてググったら、StackOverflowでよさ気な回答を発見。

stackoverflow.com

試したら無事にUnitテストができたのでメモ。

Languages & Frameworks > PHPを選択。

CLI InterpreterPHPの実行ファイルを指定。

Applyを押して、OKで一旦Settingsを閉じる。

再度Settingsを開き、 Languages & Frameworks > PHP > Test Frameworksを選択。

+ボタンを押してLocalを選択。

PHPUnit LibraryでUse Composer autoloaderを選択。

pathをvendor/autoloader.phpに設定。

Test runnerのDefault configuration file にチェック。

pathをアプリケーションルートディレクトリのphpunit.xml.distに設定。

applyを押して設定完了。