はい!今やってます!

Work Pertly, Live Idly

GormのPreloadでorder by構文を使いたくなったとき

GormでPreloadの中でorder by 呼びたくなった場合、以下のような書き方(Preloadの中に記述)をすると、 Preloadの中身をよしなにorder byしてくれる。 Preloadの条件式(where)との併用も可能。

err := tx.
    Limit(limit).
    Offset(offset).
    Where("status = ?", TASK_STATUS_HOGE).
    Preload("ChildTasks", "status = ?", CHILD_TASK_STATUS_HOGE, func(db *gorm.DB) *gorm.DB {
        return db.Order("child_tasks.sort_order ASC")
    }).
    Find(&tasks).Error

この時実行されるSQLはこんな感じ。

api_1    | (/go/src/api/domain/repository/task_repository.go:29)
api_1    | [2019-11-15 12:02:12]  [3.84ms]  SELECT * FROM `tasks`  WHERE (status = 1) LIMIT 10 OFFSET 0
api_1    | [10 rows affected or returned ]
api_1    |
api_1    | (/go/src/api/domain/repository/task_repository.go:29)
api_1    | [2019-11-15 12:02:12]  [2.66ms]  SELECT * FROM `child_tasks`  WHERE (`task_id` IN (2,3,6,7,8,1,4,5,9,10)) AND (status = 1) ORDER BY child_tasks.sort_order ASC
api_1    | [18 rows affected or returned ]

たまに公式のドキュメントでも載ってないのがある。

シェルの引数あれこれ

シェルで引数を取得したい場合は

$1:1つ目の引数

という感じで取得できるが、

$0:実行時のコマンド名
$#:引数の数
$@:実行時に指定された全パラメーター

というような指定も可能。

というのは割と常識なんだけど、

$BASH_SOURCE:実行時のコマンド名

という方法で$0と同等のことをすることができる。

ただ厄介なのが、shellの実行方式や実行するshellによって結果が変わる。

具体的には

source ./shell_name

とすると$0には-bash

zsh test

とすると$BASH_SOURCEには空文字が入ってくる

結論どうするのが良いかというと$0を使いたいときは

${BASH_SOURCE:-$0}

とするか

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  <処理>
fi

とするのがよい

パイプラインの左側でエラーが発生したら処理を止めたい

bash-eのオプション

#!/bin/bash 
set -eu

をつけたとしても、パイプラインの左側のコマンドにエラーがある場合に処理が停止しない。

pipefailのオプション

set -euo pipefail

を設定してやると

この場合は"hoge"が出力されるが

#!/bin/bash
set -eu

false | true
echo "hoge"

この場合は"hoge"が出力されない

#!/bin/bash
set -euo pipefail

false | true
echo "hoge"