MySQLでViewが存在しないときだけ作成するには

問題

Viewが存在しないときだけ、Viewを作成するようなSQLを書きたいときがあります。

しかし、MySQLではCREATE VIEW IF NOT EXISTSの構文は直接サポートされていません。

解決策

CREATE VIEW IF NOT EXISTSの代わりにCREATE OR REPLACE VIEWを使用します。

この方法は、指定された名前のViewがすでに存在する場合はそれを置き換え、存在しない場合は新しく作成します。

CREATE OR REPLACE VIEW test.v AS SELECT * FROM t;

このステートメントは次のように動作します:

  • test.vという名前のViewがすでに存在する場合:
    • そのビューを削除し、新しい定義でViewを再作成します。
  • test.vという名前のViewが存在しない場合:
    • 新しいViewを作成します。

この方法の利点は、Viewが既に存在するかどうかに関わらず、常にViewが最新の定義になることを保証できる点です。

ただし、大規模なデータセットや複雑なクエリを含むビューでは、パフォーマンスに影響を与える可能性があります。
アプリケーション側でビューの存在確認を行い、必要に応じてCREATE VIEWやALTER VIEWを実行するという方法もあります。

ユニットテストでGuzzleを使うときにモックを使う方法

Guzzleは、外部のAPIとの通信によく使われます。しかし、ユニットテストの際には外部のAPIと実際に通信を行いたくない場合が多いです。

このような状況でモックを利用して、Guzzleを使ったコードのテストを行う方法を紹介します。

モックを使ったテストコードの例

以下のPHPコードは、Guzzleを使用してHTTPリクエストをモックする方法を示しています。

use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;

// 期待されるJSONレスポンスボディを定義
$json = [
    'data' => [
        'id' => 1,
        'name' => 'test',
    ]
];
// モックレスポンスを作成
$mock = new MockHandler([new Response(200, [], json_encode($json))]);
// モックを含むハンドラースタックを作成し、クライアントに渡す
$client = new Client(['handler' => HandlerStack::create($mock)]);

// モックを使ってHTTPリクエストを行う
$response = $client->get('http://example.com');

// ステータスコードを検証
$this->assertEquals(200, $response->getStatusCode());
// レスポンスボディが期待するJSONデータであることを検証
$body = json_decode((string) $response->getBody(), true);
$this->assertEquals($json, $body);

解説

GuzzleHttp\Clientのカスタマイズ

GuzzleHttp\Clientのコンストラクタにoptions引数を渡すことで、カスタムハンドラーを設定できます。

この例では、モック用のハンドラーを設定しています。

// モックを含むハンドラースタックを作成し、クライアントに渡す
$client = new Client(['handler' => HandlerStack::create($mock)]);

モックの作成

GuzzleHttp\Handler\MockHandlerを使ってHTTPレスポンスをモックします。

このクラスのインスタンスを作成し、コンストラクタにGuzzleHttp\Psr7\Responseオブジェクトの配列を渡します。

// モックレスポンスを作成
$mock = new MockHandler([new Response(200, [], json_encode($json))]);

レスポンスの構築

GuzzleHttp\Psr7\Responseクラスのインスタンスは、HTTPレスポンスを模倣します。

コンストラクタには、ステータスコード、ヘッダー、ボディを順番に渡します。

// 期待されるJSONレスポンスボディを定義
$json = [
    'data' => [
        'id' => 1,
        'name' => 'test',
    ]
];
// モックレスポンスを作成
$mock = new MockHandler([new Response(200, [], json_encode($json))]);

これで、Guzzleを使用したユニットテストでモックを利用する方法の解説は終わりです。

モックを活用することで、実際に外部のAPIと通信することなく、コードのテストを行うことができます。

Laravel(PHP)からSlackにメッセージを送信する

SlackのWebhook URLを取得する

(1) Incoming Webhookのページを開きます。

(2) メッセージを送信するチャンネルを選択して、「Incoming Webhookインテグレーションの追加」ボタンをクリックします。

(3) Webhook URLをコピーします。

(4)「設定を保存する」ボタンをクリックします。

Laravelの設定

セキュリティのため、.envファイルにWebhook URLを設定します。

この値は公開されるべきではないため、注意して管理してください。

# Slack Webhook URL
SLACK_WEBHOOK_URL=<コピーしたWebhook URLを貼り付ける>
# Slackの投稿者の名前
SLACK_USERNAME=webhookbot
# Slackの投稿者のアイコン
SLACK_ICON_EMOJI=:ghost:

Laravelプロジェクトの config ディレクトリ内に slack.php ファイルを作成し、以下の内容を貼り付けます。

<?php
// config/slack.php
return [
    'webhook_url' => env('SLACK_WEBHOOK_URL'),
    'username' => env('SLACK_USERNAME'),
    'icon_emoji' => env('SLACK_ICON_EMOJI'),
];

Slackにメッセージを送信するクラスを作成する

Slackにメッセージを送信するクラスを作成します。

<?php
declare(strict_types=1);

// app/Services/SlackService.php
namespace App\Services;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;

class SlackService
{
    public static function post(string $message): bool
    {
        $client = new Client();

        $webhookUrl = config('slack.webhook_url');
        $username = config('slack.username');
        $iconEmoji = config('slack.icon_emoji');

        try {
            $client->request(
                'POST',
                $webhookUrl,
                [
                    'headers' => [
                        'Content-Type' => 'application/json',
                    ],
                    'body' => json_encode([
                        'username' => $username,
                        'text' => $message,
                        'icon_emoji' => $iconEmoji,
                    ]),
                ]);
            return true;
        } catch (GuzzleException $e) {
            Log::error('Slack Post Failed: '.$e->getMessage());
            Log::error('Failed message: '.$message);
            Log::error($e->getTraceAsString());
            return false;
        }
    }
}

Slackにメッセージを送信する

SlackServiceを使用して、メッセージを送信します。

例として、コントローラーから以下のように呼び出すことができます。

use App\Services\SlackService;

// コントローラーのメソッド内で
SlackService::post('Hello, Slack!');

Amazon Fireタブレットのウェイクワードを変更する方法

Amazon Fireタブレットで「アレクサ、10分後にアラーム」と呼びかけると、2台のFireタブレットが同時に応答してしまうことがあります。このような状況を避けるために、ウェイクワード(呼びかけの名前)を変更する方法を紹介します。

変更手順

  1. Fireタブレットで「設定」アプリを開きます。
  2. 一覧から「Alexa」を選択します。
  3. 「ハンズフリーモード」を探し、それを選択します。
  4. 「ハンズフリーモード」をオンにします(もしまだオフになっている場合)。
  5. 「ウェイクワード」のオプションを選択し、希望のウェイクワードを選びます。

現在、ウェイクワードは「Alexa」または「Amazon」のどちらかを選ぶことができます。
これにより、同じ環境内に複数のFireタブレットがある場合でも、特定のデバイスだけに反応させることが可能です。