狛ログ

2019年12月26日木曜日

C#でExecuteScalarメソッドを使うときの注意点。

12月 26, 2019

オフィス狛 技術部のHammarです。

C#のSQL実行メソッドに「ExecuteScalar」というのがあります。
これはクエリを実行し、そのクエリが返す結果セットの最初の行にある最初の列を返してくれます。
このメソッドを使って、ちょっとハマってしまったことについて書こうと思います。

例えば、テーブルの主キーとなるidが自動インクリメントになっているテーブルに、INSERTすると同時に登録したidを取得したい時などがあると思います。
今回試した環境はSQLServerだったので、INSERT実行時に
SELECT SCOPE_IDENTITY();
を使えばそれが可能なのですが、INSERT文が別テーブルからの「INSERT SELECT」の場合、SELECTの結果が条件によっては取得できない場合があります。
そのときの結果の挙動で自分が想定した結果ではなかったので、ちょっと戸惑いました。

まず、上記の「INSERT SELECT」と「SELECT SCOPE_IDENTITY」を使って「ExecuteScalar」を実行するサンプルコードとして

SqlConnection Connection = new SqlConnection();
SqlCommand cmd = new SqlCommand("INSERT INTO users(...) SELECT ...; SELECT SCOPE_IDENTITY();", Connection);
decimal id = (decimal)cmd.ExecuteScalar();

上記は、別テーブルから取得した情報を登録し、登録した時のidを取得するというような処理になります。

で、基本SELECTでデータが取得できる前提であれば問題ないんですが、このSELECTでデータが取得できない場合、
「指定されたキャストは有効ではありません。」
というエラーが発生してしまいます。

恐らくこのエラーは、「SELECTでデータ取得できない」→「INSERTするデータなし」→「SELECT SCOPE_IDENTITYでid取得できない」
ということなので、返り値としてはNullが返ってくると思います。
なので、結果decimalにキャストできなくてエラー発生していると思ったので、以下のように、Nullが入ってくることを許容すればいいと思い、返り値にNullable型を使って

SqlConnection Connection = new SqlConnection();
SqlCommand cmd = new SqlCommand("INSERT INTO users(...) SELECT ...; SELECT SCOPE_IDENTITY();", Connection);
decimal? id = (decimal?)cmd.ExecuteScalar();
if (id.HasValue)
{
    string insertId = id.ToString();
}

という感じにしました。
返り値の型decimalに?を付けてNull許容(Nullable)とすれば、仮にNullが返っても問題ないのかなと。
その後で、Nullの場合の判定を加えてやれば処理的にうまくいくかなと思いましたが、やはり同じく「指定されたキャストは有効ではありません。」のエラーが発生しました。

よくよく考えてみると、そもそもここでdecimal型にキャストして、基本的に値が返ってくる前提のような作りがよくないのと、SELECT時データが取得できない場合は、返り値が「Null」ではなくて、「DBNull」という別物だということを知りました。

ということで、返り値の型をobject型に変更し、下記のように変更しました。

SqlConnection Connection = new SqlConnection();
SqlCommand cmd = new SqlCommand("INSERT INTO users(...) SELECT ...; SELECT SCOPE_IDENTITY();", Connection);
object id = cmd.ExecuteScalar();
if (!DBNull.Value.Equals(id))
{
    string insertId = id.ToString();
}

これでデータが取得できた時だけ、登録時のidを取得できるようになりました。

もしかしたらこういったケースはあまりないかもしれませんが、「ExecuteScalar」メソッドを使って「INSERT SELECT」するときには、ご参考にしてみてください。

2019年12月18日水曜日

zshでプロンプトをコマンドの実行結果によって変更する方法。

12月 18, 2019

オフィス狛 技術部のmmm(むー)です。

TL; DR

zsh(oh-my-zsh)をインストールして、下記のようにプロンプト(➜ 😶/ ➜ 🙃🙃🙃)をコマンドの実行結果によって変更する設定を説明します。さよなら、bash。
※特に意味はありませんが、あえて良い点をあげるとローカルとリモートの区別が簡単につきます。
【環境】
MacOS Mojava
バージョン 10.14.5

【ターミナルアプリ】
iTerm2
https://www.iterm2.com/
※これは好みの問題なので、Macのデフォルトのターミナルでも問題ありません。

1. Homebrewのインストール

Homebrewをインストールします。
(HomebrewとはMac専用のパッケージマネージャーで、インストールしておくと便利です。)
➜ 😶/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

インストールできていることの確認
➜ 😶brew -v
Homebrew 2.2.1
Homebrew/homebrew-core (git revision 0105; last commit 2019-12-10)

参考)Homebrew
https://brew.sh/index_ja

2.zshのインストール

zshをインストールします。
➜ 😶brew install zsh zsh-completions

インストールできていることの確認
➜ 😶zsh --version
zsh --version
zsh 5.7.1 (x86_64-apple-darwin18.2.0)

3.oh-my-zshのインストール

oh-my-zshとは、zshのフレームワークです。
➜ 😶sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

参考)of-my-zsh
https://github.com/ohmyzsh/ohmyzsh

oh-my-zshにはたくさんのカラーテーマが用意されています。
テーマ等修正したい場合、~/.zshrcを修正すると適用されます。
robbyrussellはデフォルトのテーマで私はデフォルトのままにしています。
➜ 😶vi ~/.zshrc

~省略~
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
ZSH_THEME="robbyrussell" #ここを変更する
~省略~

参考)oh-my-zshカラーテーマ一覧
https://github.com/ohmyzsh/ohmyzsh/wiki/Themes

4.プロンプトの修正

現在使用しているzshのテーマを確認。
先ほど変更したものは変更したものに、変更していない人はrobbyrussellが表示されます。
➜ 😶echo $ZSH_THEME
 robbyrussell

自分が使用しているカラーテーマの対象のファイルを修正します。
※変更後は適用を反映するため、ターミナルを起動しなおしましょう。
➜ 😶vi ~/.oh-my-zsh/themes/robbyrussell.zsh-theme

 PROMPT="%(?:%{$fg_bold[green]%}➜ 😶:%{$fg_bold[red]%}➜ 🙃🙃🙃 )"  #ここが基本のプロンプト
 PROMPT+=' %{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)'
 
 ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}"
 ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
 ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗"
 ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"

🍭~/.oh-my-zsh/themes/robbyrussell.zsh-themeファイルの設定の補足
※ここは読まなくても、設定は完了しています。

%(?:%{$fg_bold[green]%}➜ 😶:%{$fg_bold[red]%}➜ 🙃🙃🙃 )」の部分ですが
 %(?:true:false)なので、下記のようになります。

成功した場合「%{$fg_bold[green]%}➜ 😶
echo $?の結果が0 (直前の処理が成功)

失敗した場合「%{$fg_bold[red]%}➜ 🙃🙃🙃
false:echo $?の結果が0以外 (直前の処理が失敗)

$?で終了ステータス(直前のコマンド実行結果)を取得することができます。
0が成功。1は失敗の意味です。
(コマンドによっては、上記ルールに適していないものもあります。例えば、diffは差分がない場合0、差分が有れば1、失敗すると2です...)
# 直前の処理が成功
➜ 😶ls test.txt
test.txt
➜ 😶echo $?
0

# 直前の処理が失敗
➜ 😶ls a
ls: a: No such file or directory
➜ 🙃🙃🙃echo $?
1

残りの箇所ですが、文字の色を変更しています。
 %{$fg_bold[green]%}:文字の色を緑に
 %{$fg_bold[red]%}:文字の色を赤に

最後の補足が長くなってしまいましたが、以上となります。
オリジナルのプロンプトをぜひ作成してみてください。

2019年12月16日月曜日

Angular で作られたプロジェクトをPWAにしてみよう。(後編)正しくPWA化されているか確認する

12月 16, 2019

オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。

前編(Angular 7 から 8 へのアップデート)中編(PWA化の実施)の続きです。
今回は、PWA化したプロジェクトが、正しくPWA化されているか確認しましょう。

(1)前提条件

・ビルドはproduction設定の「ng build --prod」で行う。
・サイトへの接続はHTTPSであること。

最初のproduction設定については、後でいくらでも変更は出来るのですが、デフォルトだと「serviceWorker」がproductionの場合のみ有効になるので必須となります。
2番目の「HTTPS」ですが、チェックツールの「Chrome デベロッパーツールのAudits」がHTTPS接続でないと、そもそも使えないので、これも致し方ないです。

(2)PWAかどうかチェックする

さて、早速チェックしていきます。Chromeで対象のサイトを表示し、デベロッパーツールを起動します。(右クリックから「検証」を選ぶと早いです。)
デベロッパーツールが起動したら、Auditsと言うタブがあるので、そのタブを選択します。


続いて、Auditsの設定を行います。


今回は、PWAのチェックだけ実施したいので、他のチェックは外します。

それでは実行してみましょう!


???
チェック出来てない・・・。
あ、なるほど。
このプロジェクトは、AWSのEC2に配置し、ALB(ロードバランサ)でバランシングしているのですが、
ロードバランサ側でhttp接続は処理しないようになっていました。
と言う事で、設定を変更し、HTTPはHTTPSにリダイレクトするようにしました。

気を取り直して、もう一度、チェック実行してみます。


とりあえず、「?」マークはなくなりましたね。
後は、
Does not have a <meta name="viewport"> tag with width or initial-scaleNo viewport meta tag found
Add a viewport meta tag to optimize your app for mobile screens.
ですね。
こちらは、エラー内容の通り、metaタグ(viewport)が無い事で発生しています。

そして、もう一つ
Does not provide a valid apple-touch-icon
For ideal appearance on iOS when users add to the home screen, define an apple-touch-icon. It must point to a non-transparent 192px (or 180px) square PNG.
こちらはiPhone・iPadのホーム画面用アイコンapple-touch-iconnの指定がありませんよ、と言う事で発生しています。

いずれも、「index.html」に記述する事で解決しそうです。
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="manifest" href="manifest.webmanifest">
  <meta name="theme-color" content="#1976d2">
  <meta name=”viewport” content=”width=device-width,initial-scale=1.0,minimum-scale=1.0″><!-- ←追加 -->
  <link rel="apple-touch-icon" href="assets/icons/icon-192x192.png"><!-- ←追加 -->

Angular CLIで、ここまでやってくれると嬉しいですけどね。

という事で、再度、チェック実行してみます。


無事にPWAにチェックマーク✅が付きました!

と言う事で、三回に渡って、Angular で作られたプロジェクトをPWAにしてみました。
途中でAngularアップデートをやっていたので、時間が掛かってしまいましたが、
PWA化自体は非常にお手軽に出来たので、かなり良い感じだと思います。

では、より良いAngularライフを!


Angular で作られたプロジェクトをPWAにしてみよう。(中編)PWA化の実施

12月 16, 2019

オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。

前編(Angular 7 から 8 へのアップデート)の続きです。
今回は、実際にPWA化を行って行きます。
既にPWA化作業が終わっていて、正しくPWA化されているかを確認したい方は、
後編(正しくPWA化されているか確認する)をご覧ください。

では、早速PWA化を行って行きましょう。

(1)PWAパッケージの追加

前編で、Angular8にアップデートしたプロジェクトを使用します。
そのプロジェクトにPWAパッケージを追加します。

追加のコマンドは「ng add @angular/pwa」です。
$ng add @angular/pwa
+ @angular/pwa@0.803.5
added 5 packages from 2 contributors and audited 22482 packages in 22.952s
Installed packages for tooling via npm.
Could not read file (/src/@app/app.module.ts).
エラーになりました。「app.module.ts」が読めないと言っていますね・・・。

「app.module.ts」をimportしているのは、確か「main.ts」なので、そちらを見てみましょう。
import { AppModule } from '@app/app.module';
「@app」になっているのが駄目なのでしょうね。
(でも、元々これはAngular CLIが勝手に作ったような・・・)

とりあえず、
import { AppModule } from './app/app.module';
に修正しました。

では、再度、「ng add @angular/pwa」を実行します。
$ng add @angular/pwa
CREATE ngsw-config.json (620 bytes)
CREATE src/manifest.webmanifest (1119 bytes)
CREATE src/assets/icons/icon-128x128.png (1253 bytes)
CREATE src/assets/icons/icon-144x144.png (1394 bytes)
CREATE src/assets/icons/icon-152x152.png (1427 bytes)
CREATE src/assets/icons/icon-192x192.png (1790 bytes)
CREATE src/assets/icons/icon-384x384.png (3557 bytes)
CREATE src/assets/icons/icon-512x512.png (5008 bytes)
CREATE src/assets/icons/icon-72x72.png (792 bytes)
CREATE src/assets/icons/icon-96x96.png (958 bytes)
UPDATE angular.json (5936 bytes)
UPDATE package.json (2638 bytes)
UPDATE src/app/app.module.ts (1597 bytes)
UPDATE src/index.html (542 bytes)
無事に完了したようですね。(*1)
*1)警告が出る場合、「npm audit fix」しておきましょう

では、自動作成・更新されたファイルについて、エラーが出ていないか確認しておきましょう。

私が試したプロジェクトだと、「app.module.ts」がエラーになっていました。
import { environment } from '@environment/environment'; // ←元々

import { ServiceWorkerModule } from '@angular/service-worker'; // ←追加された行
import { environment } from '../environments/environment'; // ←追加された行

元々の表記が「@environment」だったので、別パスと判断して、新たな「environment」を追加したのですかね。
(でも、元々これはAngular CLIが勝手に作ったような・・・(2回目))

まあ、ここは、追加された行を残して、元々の行を削除しようと思います。

(2)App Shellの導入

続いて、App Shellを導入します。
App Shellは、簡単言うと、画面のキャッシュを行う機構の一つです。
詳細は、この辺を参照してください。

Angularに導入するには、以下のコマンドを実行します。
ng generate app-shell --client-project my-app --universal-project server-app
・my-app はクライアントアプリケーションの名前です。
・server-app はユニバーサル (またはサーバー) アプリケーションの名前です。

と言う事で、今回は、以下のコマンドを実行します。
ng generate app-shell --client-project koma-system-pwa --universal-project koma-system-pwa
エラーになりました。
Could not find /src/app/@app/core/containers/app/app.component.ts.
先程までと同じ、「@app」問題ですね。
(でも、元々これはAngular CLIが勝手に作ったような・・・(3回目))

先程と同じように、
import { AppComponent } from '@app/core/containers/app/app.component';
上記を下記のように書き換えます。
import { AppComponent } from './core/containers/app/app.component';
弊社のプロジェクトの場合、ちょっと特殊な場所に「app.component」を配置しているので、それぞれ環境にあったパスに修正してください。

それでは、再度、実行してみます。
$ng generate app-shell --client-project koma-system-pwa --universal-project koma-system-pwa
CREATE src/main.server.ts (220 bytes)
CREATE src/app/app.server.module.ts (590 bytes)
CREATE src/tsconfig.server.json (270 bytes)
CREATE src/app/app-shell/app-shell.component.css (0 bytes)
CREATE src/app/app-shell/app-shell.component.html (24 bytes)
CREATE src/app/app-shell/app-shell.component.spec.ts (643 bytes)
CREATE src/app/app-shell/app-shell.component.ts (280 bytes)
UPDATE package.json (2679 bytes)
UPDATE angular.json (7231 bytes)
UPDATE src/main.ts (469 bytes)
UPDATE src/app/app.module.ts (1650 bytes)
これでPWA化は完了となります。簡単ですね。

後は、自動生成された画像(src/assets/icons)をそれぞれのプロジェクト用で置き換えてください。

では、次回で最後、Chrome デベロッパーツールのAuditsで、正しくPWA化されている事を確認するところまでやって行きます

次回:Angular で作られたプロジェクトをPWAにしてみよう。(後編)正しくPWA化されているか確認する

Angular で作られたプロジェクトをPWAにしてみよう。(前編)Angular 7 から 8 へのアップデート

12月 16, 2019

オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。

すっかりBlogをサボってしまいました。
社内勉強会用の資料作成で、Android&Kotlinにどっぷり浸かっていました。(言い訳)
気を取り直して、今回は久しぶりのAngularです。

弊社、iOSもAndoridもネイティブでゴリゴリ開発しているのですが、実は、プロジェクト的には減少気味です。
やっぱりアプリの申請とか、色々と気にする事が多いのでしょうね。
代わりにSPAのサイトをレスポンシブで作るプロジェクトがかなり増えています。
そんな中、新たな選択肢として、PWAのプロジェクトも増えています。

と言う事で、今回は、「既存のAngularプロジェクトをPWA化する」を備忘録的に記事にします。

【注意】当記事では、事前準備までを説明していて、実際にPWA化までは行っていません。PWA化のみ見たい方は、「Angular で作られたプロジェクトをPWAにしてみよう。(中編)PWA化の実施」をご覧ください
Angular で作られたプロジェクトをPWAにしてみよう。(中編)PWA化の実施

(1)対象のシステム要件

今回やろうとしていることは以下の通りです。
・既存のAngularで作られたSPAサイトをPWA用として新たに作成する。(既存のサイトは残す。つまりコピーしてサイト名変更)
・既存のサイトのAngularバージョンは「7」
・最終的には、Chrome デベロッパーツールのAuditsで、正しくPWA化されている事を確認する。
・その他の機能についてのアップデートは行わない(もっとも少ない対応内容でPWAを実現させる)
では、早速、やって行きましょう!

(2)サイト名(プロジェクト名)変更

まずは、既存のサイト(koma-system-web)をコピーして、名称を「koma-system-pwa」に変更します。
サイトのrootディレクトリ名称変更の他に、以下のファイルにもサイト名が記載されているので、合わせて修正します。
angular.json
app.e2e-spec.ts
package.json

(3)Angular 7 から 8 へのアップデート

Angular 8から、CLIによるPWA作成が簡単に出来るようになっているので、まずはAngularのバージョンアップを行います。
基本的な作業としては、こちらの手順通りになります。


バージョンは(Angular Version)は、7.0から8.0でいきます。
アプリの複雑度(App Complexity)は・・・・Mediumぐらいですかね、とりあえず。
その他の依存関係(Other Dependencies)ですが、今回のプロジェクトは、AngularJSも混在していませんし、 Angular Material、Express、Hapiも使用していないので、チェックは付けません。
(Express、Hapiは、サーバーサイドレンダリングで使用するものですかね、多分)
パッケージ管理(Package Manager)はnpmを使っているので、npmを選択します。

【更新する前に(Before Updating)】

サイトに記載している手順と注意書き通りに作業を進めて行きます。
If you use the legacy HttpModule and the Http service, switch to HttpClientModule and the HttpClient service. HttpClient simplifies the default ergonomics (you don't need to map to JSON anymore) and now supports typed return values and interceptors. Read more on angular.io.
HttpModuleは使えないからHttpClientModuleに変更してね、と言う事ですね。
HttpClientModuleは、確かAngular 4.3 ぐらいから使えるようになった機能です。
Once you and all of your dependencies have updated to RxJS 6, remove rxjs-compat.
rxjs-compatを使っているなら、削除してね、と言う事ですね。
If you use the Angular Service worker, migrate any versionedFiles to the files array. The behavior is the same.
Angular Service workerを使っている場合もマイグレーションを行う必要があるようですが、
今回のプロジェクトでは使用していないので、特に何もしません。

【更新作業(During the Update)】

Update to version 8 of the core framework and CLI by running ng update @angular/cli @angular/core in your terminal
早速実行していきます
無事に実行できたら(*1)、プロジェクト内を確認してみましょう。
*1)ちなみに、私が試したプロジェクトでは、いくつかのプラグインがAngular8に対応していませんでしたので、代替のプラグインを取り込んだりして、何度もやり直しました。
Angular now uses TypeScript 3.4, read more about errors that might arise from improved type checking.
あれ、アップデート後のpackage.jsonを見ると、typescriptが3.5.3にupdateされているけど、良いのかな・・・?
Make sure you are using Node 10 or later.
こちらも念の為確認
$node --version
v10.14.1
うん、大丈夫そう。

【更新後作業(After the Update)】

では、最後に、「ng update」を実行しますが、
その前にちょっと試しに「ng update --all」をやってみました。
すると・・・・
Package "@angular-devkit/build-angular" has an incompatible peer dependency to "typescript" (requires ">=3.1 < 3.6", would install "3.6.3")
Package "@angular/compiler-cli" has an incompatible peer dependency to "typescript" (requires ">=3.4 <3.6", would install "3.6.3").
Package "@angular/core" has an incompatible peer dependency to "zone.js" (requires "~0.9.1", would install "0.10.2").
Incompatible peer dependencies found.
Peer dependency warnings when installing dependencies means that those dependencies might not work correctly together.
You can use the '--force' option to ignore incompatible peer dependencies and instead address these warnings later.
色々出てますが、TypeScriptのバージョンで怒られているものはないですね。
3.5.3は大丈夫なんだ・・・。

と言う事で、地道に「ng update」で更新が必要なものを探ります。
$ ng update
Using package manager: 'npm'
Collecting installed dependencies...
Found 54 dependencies.
    We analyzed your package.json, there are some packages to update:
    
      Name                               Version                  Command to update
     --------------------------------------------------------------------------------
      @ngrx/store                        7.4.0 -> 8.3.0           ng update @ngrx/store

と言う事なので、ひとまず、「ng update @ngrx/store」でngrxだけ上げます。

これで、「ng build」してみると・・・・

An unhandled exception occurred: Could not find the implementation for builder @angular-devkit/build-angular:dev-server
エラーになってしまいました。
と言う事で、「ng update @angular-devkit/build-angular」も実行します。

そして、最後の最後に「npm audit fix」で、脆弱性が発生しているパッケージなどのチェックと修正を同時に行ってしまいます。

これで、「Angular 7 から 8 へのアップデート」は完了です。

と言う事で、すいません、長くなってしまったので、続きは中編に記載します。
(同時に記事公開しますので、許してください)

次回:Angular で作られたプロジェクトをPWAにしてみよう。(中編)PWA化の実施

2019年12月9日月曜日

PHP Conference 2019に行ってきました。

12月 09, 2019

オフィス狛 技術部のmmm(むー)です。
先週のことですが、PHP Conference Japan 2019に行ってきました。
(現在の業務ではPHPは使用しておりませんが…)

・ 公式URL
https://phpcon.php.gr.jp/2019/
・ セッションのタイムテーブル
https://fortee.jp/phpcon-2019/timetable

今年のテーマは 「beyond .*」で、これから先のPHPの未来がさらに飛躍するようにとつけたようです。
今回第20回目を記念して、PHPの像のぬいぐるみが販売されていました。

自由すぎると定評のPHPですが、先月末7.4がリリースされました。
オープイングセッションでは、PHP7.4の新機能の紹介がありまして、型付けプロパティやアロー関数を使用できるようになりました。
次にリリースされるバージョンは8になるようです。
また、5.6も7.1もEOL(End of Life)になったねって話が出てました。あっという間ですね…

カンファレンスに参加する醍醐味は、自分が知らない技術・考え・作者の方の思いを知ることができることだと思います。以下、各セッションの感想になります。

MVCにおける「モデル」とはなにか

天重誠二さん
https://speakerdeck.com/tenjuu99/what-mvc-is

フレームワークの話をするのかと思っていましたが、概念的な話でした。
ドメインモデルについての話を現実世界で使用している伝票システムにたとえて説明をしていたのが面白かったです。
また、誰にとってのデザインかを考えた上で設計するのは大切ですね。
今回の発表でたくさんの参考文献が紹介されていたのですが、その中の一つ「誰のためのデザイン」は私も以前プログラマーでも読んだ方が良いとデザイナーの方に勧められて読みました。
タイトルの通り誰のためにデザイン(設計)するのかということが、実生活を例に紹介されていてとても面白い本でした。他の参考文献も読んでみたいと思います。

思想と理想の果てに -- クリーンアーキテクチャのWEBフレームワークを作ろう

成瀬允宣さん
https://nrslib.com/phpcon-2019-proposal/

クリーンアーキテクチャとはフレームワークに依存しないという前提のもと、環境に依存しないフレームワークを作る説明のセッション。クリーンアーキテクチャを採用すれば、どの処理をそこに書いたか悩むことから解放されます。
この発表を他の会場で行った時、似たようなライブラリがあると参加者の方に聞けたので、アウトプットする人のところに情報が集まってくる(アウトプットしよう)とのことでした。
また、フレームワークは変わらないと思っていても、10年15年やってるとフレームワーク変えることはあり、10年後保守してる人達が辛い思いをするからフレームワーク非依存をおすすめしますといった内容でした。

PHPは何を捨て、どんな力を手に入れてきたのか

うさみけんたさん
https://www.pixiv.net/fanbox/creator/105589/post/691574

PHPを使用していると、PHP5.3を最後にPHP6がスキップされて、次は7になっていることは一目瞭然だと思います。
PHP5.3は、6が開発されるまでの繋ぎで、6でUnicode化等を行うつもりでしたが 開発が止まってしまったのでした…。
現在、他のモダンと言われている言語に追いつくためにPHPは歴史的経緯で残っているレガシーコードを消していこうという動きがあります。
は使用できないよう、PHPから派生したP++を作る…等、今年の夏頃議論が白熱してPHP界隈で炎上していました。
銀河の平和はまだわかりませんが、詳細は調べてみてくださいとのことでした。

PHPUnit: Past, Present and Future

Sebastian Bergmannさん
https://thephp.cc/dates/2019/12/php-conference-japan/phpunit-past-present-future

PHP Unitの開発者の方のセッションです。別のセッションの関係で、途中から聞きました。
Sebastianさんの誕生やプログラミングを始めたこと、PHPが誕生したこと、PHP Unitの開発を始めたこと順を追って各歴史を順番に振り返えるセッションでした。 PHP4では例外処理がなかったため大変だった等の話を聞いて、私にとってはあって当たり前の機能だったので、その時代の話が聞けて面白かったです。
セッション終了後には、エモかったという感想がTwitterにあふれていました。
ちなみに、PHP Unitのロゴは好きなゲーム、宇野デザイナーさんにお願いしたそうです。
英語でしたが、ゆっくり話してくださっていたので聞きやすかったです。

How to Supercharge your PHP Web API

Aurimas Niekisさん
※スライドがアップされていませんでした

私のプログラマーとしてのスキル能力と英語力が足りなくて、内容がわかりませんでした…
セッションが終了した後に、少し対面で話をさせていただいたのですが、Aurimasさんは来年の2月から日本で働き始めるようです。
また、私がNode.jsを今業務で使用していることを伝えると、Node.jsも使っているので質問があればいつでも連絡してねと言ってくださいました。(優しい…)


カンファレンスに参加していると知り合いが少しずつ増えていくので、時々集まる同窓会のようで楽しいです。
来年のPHP Conferenceは2020/10/11に開催されるようですので、都合が合えば参加したいです。


2019年11月30日土曜日

knex.jsで実行したSQL文を確認する。

11月 30, 2019
オフィス狛 技術部のHammarです。

以前の投稿で、knex.jsのtipsをいくつか書いたりNode.jsでknex.jsを使ったSQL書き方Tips、弊社技術部のmmm(むー)が書いたりしていますが(knex.jsでfromに2つ以上のサブクエリを書く方法)、今回はもう1つ「実行したSQL文を確認する」やり方を書きたいと思います。

これ意外とよく使うのに、やり方がぱっとわからなくて、社内でもどうやるのか質問があったりしたので新たにtipsとして追加したいと思います。

もちろん公式サイトにも載ってはいるのですが、日本語対応されていないのでちょっとわかりずらいんですよね。
で、やり方は単純で、SQL実行文に.toSQL()という記述を追加することで確認可能です。

具体的には

■記述例1

knex
  .select('*').from('users')
  .where('id = ?', [1]))
  .toSQL()

上記の結果を出力すると、
bindings: [1],
method: 'select',
sql: 'select * from "users" where id = ?',
options: undefined,
のように出力されて、バインド値と実際のSQL文を確認することができます。

ちなみにpostgresqlはSQL実行文に.toSQL().toNative()と記述することで同様の結果が得られるようです。

■記述例2

knex
  .select('*').from('users')
  .where(knex.raw('id = ?', [1]))
  .toSQL().toNative()

出力結果
bindings: [1],
sql: 'select * from "users" where id = $1',

自分も最初はこのやり方を知らずに、デバッグでステップ実行してどこでSQL作っているのかずーっと奥の方まで追って行って、確認するのに結構苦労してました(苦笑)

以上のように知ってしまえば簡単なんですが、知らないとかなりやりずらいので、ご参考にしてみてください。