write ahead log

ロールフォワード用

Laravelでテストする時にパスワードの更新を確認する

パスワードのハッシュを確認するメソッドを毎回忘れる.

// Hashファサードがいるよね
use Illuminate\Support\Facades\Hash;

// 普通の項目は以下でテストできる
$this->assertDatabaseHas('users', [
    'name' => '更新した名前',
    'email' => '更新したメールアドレス',
]);

// パスワードの確認はHash::checkを使う
$registed_user = User::where('email', '更新したメールアドレス')->first();
$this->assertTrue(Hash::check('期待されるパスワード', $registed_user->password));

Laravel Duskでテストする時に毎回ログアウトしたい

なんか毎回ググってる気がするからメモっとく.

場合によっちゃDuskTestCase.phpに入れてもいいかもしれない.

public function setUp(): void
{
    parent::setUp();

    // 毎回ログアウトするためクッキーを消す
    foreach (static::$browsers as $browser) {
        $browser->driver->manage()->deleteAllCookies();
    }
}

CentOS7にLaravel6 + Postgresを構築する時にやった設定メモ

忘れるし.

vagrantで構築する時の.

ユーザはvagrantで.

provisioning.shとか作れって話だけど.

ロケールがvagrantのboxにないのでlibcを入れなおす

sudo yum reinstall -y glibc glibc-common

ロケールとタイムゾーンの設定

sudo localectl set-locale LANG=ja_JP.utf8
sudo timedatectl set-timezone Asia/Tokyo

SELinuxを無効化

有効のままの設定方法知りたい.

SELinuxはポリシーでいつもハマる.わからん.

sudo sed -i".org" -e "s/^SELINUX=enforcing$/SELINUX=disabled/g" /etc/selinux/config

VMを再起動する.

パッケージのアップデート

sudo yum -y update

Gitのインストール

sudo yum -y install git

unzipのインストール

sudo yum -y install unzip

Node.jsのインストール

適当にその時のLTSを使う.

curl -sL https://rpm.nodesource.com/setup_12.x > node_setup.sh
chmod +x node_setup.sh
sudo ./node_setup.sh
sudo yum -y install nodejs

PostgreSQLのインストール

sudo yum -y install postgresql-server
sudo postgresql-setup initdb
sudo systemctl enable postgresql.service
sudo systemctl start postgresql.service
sudo vi /var/lib/pgsql/data/pg_hba.conf

以下のように変更.

# IPv4 local connections:
#host    all             all             127.0.0.1/32            ident
host    all             all             127.0.0.1/32            password
host    all             all             all                       password # ローカル開発環境だしこれでいいでしょ

他ホストから接続を許可する.

sudo vi /var/lib/pgsql/data/postgresql.conf
listen_addresses = '*'

再起動する.

sudo systemctl restart postgresql.service

Apacheのインストール

sudo yum -y install httpd
sudo systemctl enable httpd
sudo systemctl start httpd

PHPのインストール

remiレポで入れた.

sudo yum install epel-release -y
sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
sudo yum install --enablerepo=remi,remi-php74 -y php php-cli php-common php-bcmath php-ctype php-json php-mbstring php-openssl php-pdo php-tokenizer php-xml php-pdo_pgsql composer

データベースの作成/設定

postgresユーザの有効化.

sudo passwd postgres

ロールを作成.

su - postgres
psql
> CREATE ROLE app WITH LOGIN PASSWORD 'app';
> CREATE ROLE app_test WITH LOGIN PASSWORD 'app_test';

データベースを作成.

> CREATE DATABASE app OWNER = app TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'ja_JP.UTF-8' LC_CTYPE = 'ja_JP.UTF-8';
> GRANT ALL ON DATABASE app TO app;
> CREATE DATABASE app_test OWNER = app_test TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'ja_JP.UTF-8' LC_CTYPE = 'ja_JP.UTF-8';
> GRANT ALL ON DATABASE app_test TO app_test;

アプリケーションの設定/配備

アプリケーションファイルの配備

cd ~
git clone [URL] app

シンボリックリンクの作成

sudo mkdir /var/www/app
sudo ln -s /home/vagrant/app/public /var/www/app/public

パーミッション関連の設定

# homeの権限を変更
sudo chmod 750 /home/vagrant

# apacheグループに追加
sudo usermod -a -G apache vagrant

# ファイルとディレクトリをapacheグループに変更
sudo chown vagrant:apache /home/vagrant
sudo chown -R vagrant:apache ~/app

# 念のためパーミッションをきれいにしておく
sudo find ~/app -type f -exec chmod 644 {} \;
sudo find ~/app -type d -exec chmod 755 {} \;
sudo chgrp -R apache ~/app/storage ~/app/bootstrap/cache
sudo chmod -R ug+rwx ~/app/storage ~/app/bootstrap/cache

# SGIDの設定
# 新規作成のファイルとディレクトリは現在のディレクトリグループ(apache)に固定
find ~/app -type d -exec chmod g+s {} \;
find ~/app/bootstrap/cache -type d -exec chmod g+s {} \;

# storageとbootstrap/cacheで作成されるファイル、ディレクトリ
# にはグループへ全てのパーミッションを与える
sudo setfacl -R -d -m g::rwx ~/app/storage
sudo setfacl -R -d -m g::rwx ~/app/bootstrap/cache

依存ライブラリのインストール

cd ~/app
composer install
npm install

Laravelの初期設定

.envと.env.testingを作成する. その後以下の初期化コマンド実行.

cd ~/app
php artisan key:generate
php artisan key:generate --env=testing
php artisan storage:link

jsの初期設定

npm run dev

データベースのマイグレーション

php artisan migrate --seed

httpdの設定ファイルの変更

/etc/httpd/conf/httpd.conf へ以下を追記

# 以下を変更
#DocumentRoot "/var/www/html"
DocumentRoot "/var/www/app/public"

# 以下を追記
<Directory "/var/www/app/public/">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride all
    Order allow,deny
    Allow from all
</Directory>

httpdを再起動

sudo systemctl restart httpd

supervisorのインストール

sudo yum install -y supervisor

設定ファイルを作成

キュー使わないならいらんけど.

sudo vi /etc/supervisor.d/laravel.ini

こんな感じでそれっぽく.

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)01d
command=php /home/vagrant/app/artisan queue:work --sleep=3 --daemon
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/home/vagrant/app/storage/laravel_worker.log
stderr_logfile=/home/vagrant/app/storage/laravel_error.log

cronの設定

スケジュール使わないならいらんけど.

crontab -e 

* * * * * cd /home/vagrant/app/ && php artisan schedule:run >> /dev/null 2>&1

Laravel6系でmigrationのchangeを使おうとしたらエラーが出た

こんなエラーが出た.

Symfony\Component\Debug\Exception\FatalThrowableError  : Class 'Doctrine\DBAL\Driver\PDOMySql\Driver' not found

doctrine/dbalを入れれば良いという情報はたくさん見つかるのだが, Laravel6だとうまく動かなかった.

どうもdoctrine/dbalのメジャーバージョンは3.*で, Laravel6はこれに対応していないらしい.

というわけでバージョン指定して入れれば解決した.

$ composer require doctrine/dbal:2.*

pg_dumpでオブジェクトを削除(Drop)するSQLを一緒に出力したい

こんな感じで「-c」オプションを使えばよいらしい.(--cleanの別名っぽい)

「--if-exists」を使うとその名の通り「if exists」を付けてくれてより良い感じ.

pg_dump -c --if-exists db名 > dump.sql

PowershellでmdbファイルをExcelにするスクリプトを書いた

仕事で使いそうだったので.

出来ればこんなの使いたくない.

#######################################################################
# 概要
#   mdbファイルを開いてテーブルの内容をExcelへ出力する
# 書式
#   export-mdb.ps1 [mdbファイルへの相対パス] [mdbファイルパスワード]
#######################################################################

Param($filename, $password)

# 指定テーブルを指定シートへエクスポートする
function ExportTable {
    param (
        $con,
        $sheet,
        $tableName
    )
    $rs = New-Object -ComObject "ADODB.Recordset"

    $sql = "SELECT * FROM ${tableName}"
    $rs.Open($sql, $con, 3, 3)

    # テーブル名
    $col_idx = 1
    $row_idx = 1
    foreach ($f in $rs.Fields) {
        $sheet.Cells.Item($row_idx, $col_idx) = $f.name
        $col_idx += 1
    }
    $row_idx += 1

    # データ内容
    $rs.MoveFirst()
    while ($rs.EOF -eq $false) {
        $col_idx = 1
        foreach ($f in $rs.Fields) {
            $sheet.Cells.Item($row_idx, $col_idx) = $rs.Fields.Item($f.Name).Value
            $col_idx += 1
        }
        $rs.MoveNext()
        $row_idx += 1
    }

    $rs.Close()
}

# MDBファイルのファイルパスを組み立てる
$filepath = join-path $PSScriptRoot $filename
$excel_filepath = join-path $PSScriptRoot "exported.xlsx"

$connection_string = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source = ${filepath};"

# パスワード指定の場合にはパスワードをConnectionStringへ加える
if($password -ne '') {
    $connection_string += "Jet OLEDB:Database Password = ${password};"
}

# Excelを開いてブックを作る
$excel = New-Object -ComObject Excel.Application
$excel.visible = $false
$excel.DisplayAlerts = $false
$book = $excel.Workbooks.Add()

# mdbを開く
$catalog = New-Object -ComObject "ADOX.Catalog"
$con = New-Object -ComObject "ADODB.Connection"
$con.Open($connection_string)
$catalog.ActiveConnection = $con

try {
    foreach($tbl in $catalog.Tables) {
        # テーブルのみ出力
        if($tbl.type -eq "table") {
            # シートを加える
            $sheet = $book.Worksheets.Add()
            $sheet.name = $tbl.name
            ExportTable $con $sheet $tbl.name
        }
    }
    $book.SaveAs($excel_filepath)
} finally {
    $con.Close()
    $excel.Quit()
    $excel = $null
}

Powershellでmdbファイルを開いてテーブルの一覧を得る

2020年にもなってMDBファイルを触ることになるとは思わなかった.

PowerShellは便利だ.

使うときにはこの辺のコンポーネントが必要だと思う.

Microsoft Access Database Engine 2016 Redistributable

#######################################################################
# 概要
#   mdbファイルを開いてテーブルの一覧を出力する
# 書式
#   table-list.ps1 [mdbファイルへの相対パス] [mdbファイルパスワード]
#######################################################################

Param($filename, $password)

# MDBファイルのファイルパスを組み立てる
$filepath = join-path $PSScriptRoot $filename

$connection_string = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source = ${filepath};"

# パスワード指定の場合にはパスワードをConnectionStringへ加える
if($password -ne '') {
    $connection_string += "Jet OLEDB:Database Password = ${password};"
}

$catalog = New-Object -ComObject "ADOX.Catalog"
$conn = New-Object -ComObject "ADODB.Connection"

$conn.Open($connection_string)
$catalog.ActiveConnection = $conn

foreach($tbl in $catalog.Tables) {
    #Write-Output $tbl
    #テーブル名だけほしい時はこっち
    Write-Output $tbl.name
}

$conn.Close()