Redshiftの文字列はバイト数換算
Amazon RedshiftはPostgreSQL互換ですが、多くの違いがあります。異なる点については公式を始めとして各所にまとまっていますが、タイトルの件についてはあまり記載を見なかったのでメモしときます。
PostgreSQLは文字数
SQLは2つの主要な文字データ型を定義しています。 character varying(n)とcharacter(n)です。 ここでnは正の整数です。 これらのデータ型は2つともn文字長(バイト数ではなく)までの文字列を保存できます。
わざわざ、バイト数ではなく
と強調して書かれています。
create table hoge(c1 varchar(5)); insert into hoge(c1) values('12345'); -- OK insert into hoge(c1) values('あいうえお'); -- OK select * from hoge; insert into hoge(c1) values('あいうえおa'); -- NG
実際にSQLを実行しても文字数換算です。
Redshiftはバイト数
CHAR および VARCHAR のデータ型は、文字単位でなくバイト単位で定義されます。CHAR 列にはシングルバイト文字のみを含めることができます。したがって、CHAR(10) 列には、最大 10 バイト長の文字列を含めることができます。VARCHAR にはマルチバイト文字 (1 文字あたり最大で 4 バイトまで) を含めることができます。例えば、VARCHAR(12) 列には、シングルバイト文字なら 12 個、2 バイト文字なら 6 個、3 バイト文字なら 4 個、4 バイト文字なら 3 個含めることができます。
こちらも、わざわざ文字単位ではなく
と強調して書かれています。
create table hoge(c1 varchar(5)); insert into hoge(c1) values('あいうえお'); -- NG insert into hoge(c1) values('12345'); -- OK select * from hoge;
実際にSQLを実行してもバイト数換算です。ちなみに、日本語は3-4バイトになるので注意が必要です。
insert into hoge(c1) values('あ12'); -- OK insert into hoge(c1) values('あ123'); -- NG insert into hoge(c1) values('𠮷1'); -- OK insert into hoge(c1) values('𠮷12'); -- NG
参考
Spring Bootを使ってWebアプリケーションを作成する(開発環境から)
はじめに
- 某所でお題として与えられ、楽勝!って思ったら完遂できなかったので、ハマった所を解消し、再挑戦した際のメモです。*1
- 最良、最適な方法ではないと思いますので、参考にする場合には自己責任でお願いします。*2
- コードは一部しか記載しませんので、全てを確認したい場合には参考用コミットとしてGitHubへのリンクを記載してますので、こちらを確認してください。
要件とか
- 下記の要件でWebアプリケーションを作成する。
- 少しでも早く作成する。
- 指定されていない事は想定する必要はない。
- 最低限要件を満たした上で1秒でも早く作成する。
環境
アプリケーションの要件
- 問い合わせフォームを作る
- 「 http://xxx.xxx.xxx.xxx 」でアクセスすると問い合わせフォーム画面が表示される。
- ポートは80
- 問い合わせフォーム画面は、「名前」、「Eメール」、「問い合わせ内容」の3つの入力が可能。
- それぞれの入力にそれなりにValidationをかける。
- 送信ボタンを押下すると完了画面が表示される。
- 送信ボタン押下時にDBに入力内容を保存する。
- DBはなんでも良い
- テーブル構成もなんでも良い
リポジトリ
- この記事のコードは以下に置いてあります。
- https://github.com/yamap55/example_minimum_form_for_springboot
- 手順に沿ってコミットも分けていますので、見たい方はどうぞ。
Pleiadesインストール*4
プロジェクト作成
- プロジェクトエクスプローラ上で右クリック → 新規 → プロジェクト
- Spring → Springスタータープロジェクト
- Spring Boot Version : 1.5.3
- Dependencies
- DevTools
- Web
- Thymeleaf
- H2
- JPA
完了
問い合わせ画面を作成
- Controllerを追加
- com.example.demo.DemoApplication.java
- クラス分ける時間が惜しいので、アプリケーションを起動するクラスに追加してしまいます。
- com.example.demo.DemoApplication.java
@RequestMapping("/") public String index(Model model) { return "index"; }
- 画面を作成
- src/main/resources/templates/index.html
- 特に特筆すべき事はないのでコードは割愛。
- アプリケーション起動
- プロジェクト右クリック → 実行 → Spring Boot アプリケーション
ブラウザで確認
完了画面を作成
@RequestMapping("result") public String result(Model model) { // TODO 入力チェック // TODO DBに保存 return "result"; }
- 完了画面に遷移するように問い合わせ画面を変更
- src/main/resources/templates/index.html
- <form role="form" action="#"> + <form role="form" th:action="@{/result}" method="post">
- 画面を作成
- src/main/resources/templates/result.html
- 特に特筆すべき事はないのでコードは割愛。
ブラウザで確認
入力チェックを追加
public class InputForm { @NotEmpty @Size(min = 1, max = 50) private String name; @Size(max = 50) private String email; @NotEmpty @Size(max = 100) private String message; // getter, setterは略 }
- 入力チェックでエラーとなった場合には問い合わせ画面に戻す処理を追加。
- com.example.demo.DemoApplication.java
- public String result(Model model) { - // TODO 入力チェック + public String result(@ModelAttribute("inputForm") @Valid InputForm form, BindingResult bindingResult, Model model) { + if (bindingResult.hasErrors()) { + return index(form, model); + }
- エラーメッセージを表示するように修正。
- src/main/resources/templates/index.html
- <p>名前 : <input type="text" name="name" /></p> + <p>名前 : <input type="text" th:value="*{name}" name="name" /></p> + <p><span + th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span> + </p> <!-- 以下略 -->
ブラウザで確認
DBに保存する
- DB(H2)に入力情報を保存する。
- ブラウザで確認
- ドメインを作成
@Entity @Table(name="message") public class Message { public Message(InputForm form) { // 何か他にいい方法ありそうだけど、コンストラクタでformから入れ替える this.message = form.getMessage(); this.email = form.getEmail(); this.name = form.getName(); } @Id @GeneratedValue private int id; @Column private String name; @Column private String email; @Column private String message; // getter, setterは略 }
public interface MessageRepository extends JpaRepository<Message, Integer> { }
- 保存処理を追加
public class DemoApplication { + @Autowired MessageRepository repository; // 略 - // TODO DBに保存 + repository.save(new Message(form));
ブラウザで確認
プロパティファイルは好きじゃないのでYAMLに変更
src/main/resources/application.properties → src/main/resources/application.yml
DBに保存されている事を確認するためh2コンソールの表示設定を追加
- src/main/resources/application.yml
spring: h2: console: enabled: true datasource: url: jdbc:h2:mem:test
起動するポート番号を変更
- src/main/resources/application.yml
+server: + port: 80
ブラウザで確認
- アプリケーションの再起動が必要かも。
- http://localhost
- http://localhost/h2-console
jarで出力する
- プロジェクト右クリック → 実行 → Maven install
- target配下にjarが出力されていることを確認。
jar単体で起動
- コマンドプロンプト起動。
java -jar demo-0.0.1-SNAPSHOT.jar
- ブラウザで確認
動作環境の整備
- Linuxにログイン
- Javaのインストール
sudo yum install java-1.8.0-openjdk.x86_64
- ↑で作成したjarをLinuxに移動
- ファイアーウォールを止める
sudo service iptables stop
- 起動
java -jar demo-0.0.1-SNAPSHOT.jar
- ブラウザで確認
- http://xxx.xxx.xxx.xxx
- http://xxx.xxx.xxx.xxx/h2-console
- h2コンソールを見たい場合には起動オプションに「
--spring.h2.console.settings.web-allow-others=true
」を追加することで確認可能。
- h2コンソールを見たい場合には起動オプションに「
まとめ
- ハマった部分が解消されたら、特になんてこともなくこなすことができ、凹んでいた気分が少し回復したので良しとする。
- ハマった部分に関しても、落ち着いて挑めば解決できたと思うので、焦ってエラーメッセージや事象を検索するのではなく、外の空気でも吸いに行けばよかったと思った。
- 色々突っ込みどころはあると自分でも思うが、お題がお題なのでこんなものではないだろうか。
- いいお題だと思ったので、今後新しいフレームワークを学ぶ際にはこのお題をこなそうと決めた。
GroovyでJSONをPOSTする
概要
- ↓をGroovyでやりたい。
curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":"abcdef","user":{"name":"tarou","age":20,"email":"example@example.com","result":true}}' https://script.google.com/macros/s/xxxxxxxxx/exec
groovy.json.JsonBuilder
を利用してJSONを作成。groovyx.net.http.HTTPBuilder
を利用してPOSTする。
コード
@Grab("org.codehaus.groovy.modules.http-builder:http-builder:0.7.1") import groovyx.net.http.HTTPBuilder import groovy.json.JsonBuilder import static groovyx.net.http.ContentType.* def json = new JsonBuilder() json { id "abcdef" user { name "tarou" age 20 email "example@example.com" result true } } def postBody = json.toString() assert postBody == $/{"id":"abcdef","user":{"name":"tarou","age":20,"email":"example@example.com","result":true}}/$ /* { "id":"abcdef", "user":{ "name":"tarou", "age":20, "email":"example@example.com", "result":true } } */ def http = new HTTPBuilder("https://script.google.com/macros/s/xxxxxxxxx/") http.post( path: 'exec', body: postBody, contentType: JSON ) { resp -> println "POST Success: ${resp.statusLine}" }
- 昨日の記事「JSONをPOSTしてGoogle SpreadSheetに書き込む」で作成したGASにPOSTしてます。
参考
JSONをPOSTしてGoogle SpreadSheetに書き込む
はじめに
- GAS(Google Apps Script)でPOSTを受け付けて、SpreadSheetに書き込む手順です。
- 認証はありませんので、URLがわかれば誰でもPOSTできてしまうので注意。
- GroovyからSpreadSheetに書き込みたかったが、GData APIを使用するためのライブラリである、gdata-java-clientをGrapeで入れようとしたら、うまく入らなかったのでやめたという経緯があったりします。
仕様
{ "id":"abcdef", "user":{ "name":"tarou", "age":20, "email":"example@example.com", "result":true } }
手順
function doPost(e) { var jsonString = e.postData.getDataAsString(); var data = JSON.parse(jsonString); var id = data.id; var name = data.user.name; var age = data.user.age; var email = data.user.email; var result = data.user.result; // シート取得 var ss = SpreadsheetApp.openById(SpreadsheetApp.getActiveSpreadsheet().getId()); var sheet = ss.getSheetByName("シート1"); // データ入力 sheet.appendRow([id, name, age, email, result]); }
- 保存
- 公開 → ウェブアプリケーションとして公開
- プロジェクトバージョン
- 新規作成
- コミットコメント
- 次のユーザとしてアプリケーションを実行
- 自分
- アプリケーションにアクセスできるユーザー
- 全員(匿名ユーザーを含む)
- ↑に設定することで認証が行われない。
- 「承認が必要です」というダイアログが表示される。
- 許可を確認 → 許可
- 「現在のウェブアプリケーションのURL」をメモ。
- POST(URLは↑で確認したURLに置換してください。)
- GroovyでPOST
- curlでPOST
curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":"abcdef","user":{"name":"tarou","age":20,"email":"example@example.com","result":true}}' https://script.google.com/macros/s/xxxxxxxxx/exec
- 確認
参考
We Are JavaScripters! @6thに参加してきた #WeJS #21cafe
はじめに
4月27日(木)に「We Are JavaScripters! @6th」という勉強会に参加してきた時の自分用メモです。*1
全てLTなので、資料見たほうが早いかと思いますw
概要
「JSの勉強会って、登壇する人がハイレベルな人ばっかりだな〜」 と思ったのがきっかけで作った勉強会、「We Are JavaScripters」! 自分が学んだこと/気づいたこと/面白かったこと/失敗したこと/ハマったこと/挑戦したこと/デバッグテクニック/オススメツール・開発環境/お気に入りのライブラリ/オレオレライブラリ/実はこうだった言語仕様/tips などなど、 お酒を片手に、気軽に発信できる場を目指しています^^/ ※誰でも怖がらずに登壇できる空気を作りたいだけだけなので、もちろん玄人のみなさんも登壇大歓迎です!!
- イベント申込時の主催者アンケートだと、JavaScript初心者が半分くらいだったらしいです。
- 個人的には怪しいと思ってますがw
LT.1:JSの基本的なことをちょっと掘り下げてみる話 prototype編(やっと) @ta__miyan
- JSの基本的なことをちょっと掘り下げてみる話シリーズ Chapter04. 〜 prototype編(やっと..!) 〜
- 発表資料
- 図で理解するJavaScriptのプロトタイプチェーンを参考にしたとのこと。
- protoってES2015まで非標準だった。
- protoはプロトタイプチェーンを辿るためのオブジェクト。
LT.2:Elmの話(仮) @boiyaa
関連ツイート↓
さきほどのElmコードです。https://t.co/oG7z3sCegs
— boiyaa (@YamaHilo) 2017年4月27日
Try Elmでみてみてくださいー https://t.co/j1D1teSPcX #wejs
移植元のJSコードつけ忘れましたhttps://t.co/CjEtpvcn1Q#wejs https://t.co/hHFjRmxcPC
— boiyaa (@YamaHilo) 2017年4月27日
LT.3:==と=== @IganinTea
- ==と===を調べてみた
- 発表資料
- JavaScriptの==の中身を知る
- 発表者による補完資料
- 曖昧な比較と厳密な比較
- 1 == ‘1’
- まとめると「==」を使うなって話。
関連ツイート↓
これをリツイートしろって言われている気がした #wejs https://t.co/FbdMk6EfYq
— zuckey (@zuckey_17) 2017年4月27日
LT.4:そろそろwebpackと真剣に向き合ってみる。 @Nao-bt
- 公式ページ
- 大量のJSを書くと死ぬ。
- 大量のJSのコードをモジュールごとに分ける。
- 言語仕様としてはモジュールをサポートしていない。
- ↓の4個を覚えとけ
- Entry
- アプリの中で最初に読み込むファイル
- Output
- ビルドの結果を出力する設定
- Loaders
- ビルドの際にモジュールのソースコードに適用される変換を指定する。
- testって書かないとエラーとなるのがハマりどころらしい。
- Plugins
- ビルド時の設定を行う。
- ビルドの際にファイルの圧縮だったり、コンパイルエラーを無視?するとか。
LT.5:TypeScriptでDDD~RepositoryとEntity編~ @mrdShinse
- リポジトリ
- TypeSctipt公式
- DDD = ドメイン駆動設計
- LineのBotを作成するのに、Bot作成用のフレームワークを使わず、あえてExpress.jsを使用して開発。
- TypeScriptのGenericsはいい
LT.6:jsのGCについて @brn0227
- Javascript Garbage Collector overview
- 発表資料
- 関数は会議
- Stackはホワイトボード
- 関数単位で割り当てられるので、終了すると自動で廃棄
- Heapは議事録
- プログラムで制御
LT.7:はじめてのReact: ES2015の実用 @Jay
- はじめてのReact
- HelloWorldの代わりになる自分のやったことの発表
- セミコロンレスで書いたらしい。
LT.8:オブジェクトの作成とコンストラクタの話 @chikoski
- An implementation of new operator in JS
- 発表資料
- Gist
- サンプルコード
- newは何をしているのか。
- newを使わないでnewを再現する。
*1:公開が遅れて申し訳ありません。(書いたとばっかり思ってました。。。)
JJUGナイトセミナーに参加してきた(4/24) #JJUG
4/24に開催されたJJUGナイトセミナーに参加してきた際のメモ。(後で追記予定
概要
- 名前
- 【東京】JJUG ナイト・セミナー 「テスティング特集」
- 日時
- 2017-04-24(月)19:00 - 21:00
- 会場
- 募集ページ
- 概要
今回はテスティング特集と称しまして、JUnit他についてその道のプロの方々にお話いただきます!
「Modern unit testing with JUnit 5」
概要
JUnit is the tool of choice when it comes to unit testing in Java. The current version JUnit 4 has been working reliably for many years but despite some advancements it has now reached its limits. JUnit version 5 is a complete rewrite and will be released soon. In the session, we will discuss what is new in JUnit 5 and what needs to be considered when upgrading.
- 発表者
メモ
- JUnit5の説明。英語セッション。
- JUnit4と互換性がとられているらしい。
- そのままで動くとのこと
- パラメーター渡すテストや、DisplayNameはかなり便利そう。
- ParameterizedTest
- 直接値渡す以外に、CSVで渡すこともできる。
- 逆にタグ付けや、繰り返しは使うタイミングは少なそう。
- インターフェイスのテストの箇所はよくわからなかったので後で復習。
- IDEは対応してくれているみたい。
- NetBeansは?ってなってたw後で誰か補足してくれるかな?
- Maven、Gradle共にJUnitチームがプラグインを開発しているらしい。
- Jenkins対応は?ってなってた。XML出力すれば勝手に読んでくれるような気がするけど。。。
- カバレッジという言葉もしゃべっていた気がした。
- 現時点ではM4
- 7月にリリース予定?けど遅れそうなのかな?(笑いが出てた)
「アジャイルテスティング -バグ埋め込みを年間1件にまで減らした戦略-」
概要
アジャイル開発におけるソフトウェアテストへの態度に関する発表です。4年間開発しているチームにおける品質向上の取り組みで、次のスライドの再演になります https://speakerdeck.com/kyonmm/aziyairutesuteingu-bagumai-meip-miwonian-jian-1jian-nimadejian-rasitazhan-lue-number-nagoyatesting
メモ
- バグの数を年1件にした話。
- バグの根源はムリからきている。そのバグをテストで取り除こうとするのはムダ。
- やったこと
- バグの分析
- チームの分析
- 理想像を構築
- チームを帰る情熱と理論を構築、共有
- ↑の普通のことをどう進めるのか。
- ビジョンをはっきり持つ。
- そのためのリスクは許容する。
- なんども伝える。(400ー800位言う
- 基本に立ち返る。
- 失敗しているなら、まずは基本と違うところを基本に戻してから考える。
- 基本に立ち返ると比較しやすい。
- 積極的な暗黙知
- これはちょっと同意できないけど、どうなんだろうか?
- チームメンバーのレベルが高いといけるのか?
- 凄い高品質なドキュメントがあった(作成した)としても、それをうまく使う方法論はない。
- 最小6分、最大1時間の単位でタスクを全て書き出している。
- 12ー18分のタスクが多いらしい。
「pact-jvmではじめるコンシューマー駆動契約」
概要
マイクロサービスアーキテクチャーの普及を始めとする近年の開発トレンドの風潮により、サービスのコンポーネントをテストする上でサービス間の依存関係を考慮することが必要とし、テストの難易度が増してきています。このセッションではサービス相互のインターフェースの仕様と実装の妥当性を検証する方法としてコンシューマー駆動契約にスポットをあて、その実装であるpact-jvmを例にして解説します。
発表者
スライド : pact-jvmではじめるコンシューマー駆動契約
メモ
GrailsアプリケーションをTravis CI、Herokuと連携する
アジェンダ
概要
- タイトルの通りの事をやろうとしたら、結構戸惑ったためメモ。
- 尚、Herokuの設定については公式にドキュメントがあった上、サンプルリポジトリまである事に全部終わってから気づきました。こちらを参照した方が良いかと思います。
- 特に難しいことはしていませんが、誤っている点、もっと簡単な方法等がありましたらコメント、ブコメ、Twitterなどで教えてください。
環境
前準備
- Javaのインストール
- Grailsのインストール
- Herokuアカウント作成
- Heroku CLI(Heroku Command Line Interface)のインストール
- travis CIアカウント作成
- travisのインストール
- rubyが必要。
gem install travis
- Gitのインストール
- 手順は割愛
- GitHubの登録
- 手順は割愛
Grailsのデフォルトアプリを作成
- grailsコマンドでアプリケーションを作成。
grails create-app grails-heroku-example2
- アプリケーションを起動
cd grails-heroku-example2
./grailsw run-app
- http://localhost:8080にアクセス
- 以下のような画面が表示されればOK
Herokuで動作させる
build.gradle
にstageタスクを追記
task stage { dependsOn build }
- Procfileをカレントに作成。
- herokuでアプリケーションを実行するコマンドを記載する。
- 今回の場合、javaコマンドで作成されたwarを起動する。(Scriptとしてwarを起動する方法もあるらしい。)
web: java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/grails-heroku-example2-0.1.war
- Gitで管理する
git init git add . git commit -m "first commit"
- Heroku CLIでログイン
heroku login
- メールアドレスとパスワード入力。
- Heroku上にアプリケーションを作成
heroku create grails-heroku-example2
- アプリ名は省略も可能。
- アプリ名はHeroku全体でユニークである必要があるので注意。
- リモートリポジトリが追加されていることを確認。
git remote -v
heroku https://git.heroku.com/grails-heroku-example2.git (fetch) heroku https://git.heroku.com/grails-heroku-example2.git (push)
- Herokuへデプロイ
git push heroku master
BUILD SUCCESSFUL
的なメッセージが表示されればOK
- 確認
heroku open
- ローカルで実行時と同じ画面が出ればOK
GitHubにpush
git remote add origin git@github.com:yamap55/grails-heroku-example2.git
git push -u origin master
Travis CIと連携
touch .travis.yml
.travis.yml
を設定travis setup heroku
.travis.yml
に設定を追加language: groovy
- ファイルの先頭に追加。
- 設定例
language: groovy deploy: provider: heroku api_key: secure: (略) app: grails-heroku-example2 on: repo: yamap55/grails-heroku-example2
- GitHubにpush
git add . git commit -m "comment" git push origin
- 確認
heroku open
- herokuのログを確認
メモ
- GrailsのwarをScriptとして起動する方法もあるらしい。
参考URL
- Deploying Gradle Apps on Heroku
- Herokuの公式ドキュメント
- Heroku Deployment
- Gravis CIの公式ドキュメント
- Grails入門して、travis-ciとherokuの連携をしたった
- Java1.7のplay2.2でTravis CIからherokuデプロイまでやった
- Gradleでherokuアプリケーションを作成する