2017年8月22日火曜日

MySQLで日付から「○月第○週」を求める方法

MySQLで日付から「○月第○週」を求める方法のメモ。

-- テスト用テーブル・データ作成
create table test.weektest (date1 date primary key);

insert into test.weektest values('2017/06/01');
insert into test.weektest values('2017/06/02');
insert into test.weektest values('2017/06/03');
insert into test.weektest values('2017/06/04');
insert into test.weektest values('2017/06/05');
insert into test.weektest values('2017/06/06');
insert into test.weektest values('2017/06/07');
insert into test.weektest values('2017/06/08');
insert into test.weektest values('2017/06/09');
insert into test.weektest values('2017/06/10');
insert into test.weektest values('2017/06/11');
insert into test.weektest values('2017/06/12');
insert into test.weektest values('2017/06/13');
insert into test.weektest values('2017/06/14');
insert into test.weektest values('2017/06/15');
insert into test.weektest values('2017/06/16');
insert into test.weektest values('2017/06/17');
insert into test.weektest values('2017/06/18');
insert into test.weektest values('2017/06/19');
insert into test.weektest values('2017/06/20');
insert into test.weektest values('2017/06/21');
insert into test.weektest values('2017/06/22');
insert into test.weektest values('2017/06/23');
insert into test.weektest values('2017/06/24');
insert into test.weektest values('2017/06/25');
insert into test.weektest values('2017/06/26');
insert into test.weektest values('2017/06/27');
insert into test.weektest values('2017/06/28');
insert into test.weektest values('2017/06/29');
insert into test.weektest values('2017/06/30');
insert into test.weektest values('2017/07/01');
insert into test.weektest values('2017/07/02');
insert into test.weektest values('2017/07/03');
insert into test.weektest values('2017/07/04');
insert into test.weektest values('2017/07/05');
insert into test.weektest values('2017/07/06');
insert into test.weektest values('2017/07/07');
insert into test.weektest values('2017/07/08');
insert into test.weektest values('2017/07/09');
insert into test.weektest values('2017/07/10');
insert into test.weektest values('2017/07/11');
insert into test.weektest values('2017/07/12');
insert into test.weektest values('2017/07/13');
insert into test.weektest values('2017/07/14');
insert into test.weektest values('2017/07/15');
insert into test.weektest values('2017/07/16');
insert into test.weektest values('2017/07/17');
insert into test.weektest values('2017/07/18');
insert into test.weektest values('2017/07/19');
insert into test.weektest values('2017/07/20');
insert into test.weektest values('2017/07/21');
insert into test.weektest values('2017/07/22');
insert into test.weektest values('2017/07/23');
insert into test.weektest values('2017/07/24');
insert into test.weektest values('2017/07/25');
insert into test.weektest values('2017/07/26');
insert into test.weektest values('2017/07/27');
insert into test.weektest values('2017/07/28');
insert into test.weektest values('2017/07/29');
insert into test.weektest values('2017/07/30');
insert into test.weektest values('2017/07/31');
insert into test.weektest values('2017/08/01');
insert into test.weektest values('2017/08/02');
insert into test.weektest values('2017/08/03');
insert into test.weektest values('2017/08/04');
insert into test.weektest values('2017/08/05');
insert into test.weektest values('2017/08/06');
insert into test.weektest values('2017/08/07');
insert into test.weektest values('2017/08/08');
insert into test.weektest values('2017/08/09');
insert into test.weektest values('2017/08/10');

SELECT
date1
,CONCAT(MONTH(ADDDATE(date1, weekday(date1) * -1))
  , '月第'
  , FLOOR((DAYOFMONTH(ADDDATE(date1, weekday(date1) * -1))-1)/7)+1, '週') 
AS WEEK
FROM test.weektest
ORDER BY date1;

↓のような結果が得られる。月曜始まりとして、ある日付の週の月曜日がある月の第○週を返す。

date1 WEEK
2017/06/01 5月第5週
2017/06/02 5月第5週
2017/06/03 5月第5週
2017/06/04 5月第5週
2017/06/05 6月第1週
2017/06/06 6月第1週
2017/06/07 6月第1週
2017/06/08 6月第1週
2017/06/09 6月第1週
2017/06/10 6月第1週
2017/06/11 6月第1週
2017/06/12 6月第2週
2017/06/13 6月第2週
2017/06/14 6月第2週
2017/06/15 6月第2週
2017/06/16 6月第2週
2017/06/17 6月第2週
2017/06/18 6月第2週
2017/06/19 6月第3週
2017/06/20 6月第3週
2017/06/21 6月第3週
2017/06/22 6月第3週
2017/06/23 6月第3週
2017/06/24 6月第3週
2017/06/25 6月第3週
2017/06/26 6月第4週
2017/06/27 6月第4週
2017/06/28 6月第4週
2017/06/29 6月第4週
2017/06/30 6月第4週
2017/07/01 6月第4週
2017/07/02 6月第4週
2017/07/03 7月第1週
2017/07/04 7月第1週
2017/07/05 7月第1週
2017/07/06 7月第1週
2017/07/07 7月第1週
2017/07/08 7月第1週
2017/07/09 7月第1週
2017/07/10 7月第2週
2017/07/11 7月第2週
2017/07/12 7月第2週
2017/07/13 7月第2週
2017/07/14 7月第2週
2017/07/15 7月第2週
2017/07/16 7月第2週
2017/07/17 7月第3週
2017/07/18 7月第3週
2017/07/19 7月第3週
2017/07/20 7月第3週
2017/07/21 7月第3週
2017/07/22 7月第3週
2017/07/23 7月第3週
2017/07/24 7月第4週
2017/07/25 7月第4週
2017/07/26 7月第4週
2017/07/27 7月第4週
2017/07/28 7月第4週
2017/07/29 7月第4週
2017/07/30 7月第4週
2017/07/31 7月第5週
2017/08/01 7月第5週
2017/08/02 7月第5週
2017/08/03 7月第5週
2017/08/04 7月第5週
2017/08/05 7月第5週
2017/08/06 7月第5週
2017/08/07 8月第1週
2017/08/08 8月第1週
2017/08/09 8月第1週
2017/08/10 8月第1週



2017年3月16日木曜日

AIが人に代わる未来は来ない

グーグルの研究本部長が予言「AIが人に代わる未来は来ない」

を読んだ。
人間が認識しておかなければならないのは、こういったモノは人間が使えるツールであって、われわれがやってきたことにとって代わる、完全に代替するものではないということです。


常々思ってたことなのでGoogleの研究本部長が言ってくれてスッキリした。

技術者がAIを進化させて、人々がうまく使いこなせるようになる事は意味があるけど、
お任せってわけにはなかなかいかないでしょう。



まあでも100年後どうなってるかは分からないけどね。



2017年3月1日水曜日

最近読んだものメモ

Spring Boot解説第2回 (IDEの構築とHello World)
http://qiita.com/TEBASAKI/items/a30a7daf11cdb51272fb

Spring Boot 使い方メモ
http://qiita.com/opengl-8080/items/05d9490d6f0544e2351a

Spring MVCのコントローラでの戻り値いろいろ
http://qiita.com/tag1216/items/3680b92cf96eb5a170f0

Spring4勉強会 第三回(Validation)
http://qiita.com/yu_eguchi/items/5a1b2ae46ff803b020bf

Thymeleafチートシート
http://qiita.com/NagaokaKenichi/items/c6d1b76090ef5ef39482

Spring BootでSpring SecurityのCSRF対策を使う
http://qiita.com/nenokido2000/items/22a97a26a5858ddb164f

OkHttp (POST送信)
http://square.github.io/okhttp/

CentOS6.7 + Java 1.8 + Tomcat 8 の環境を作るには
http://qiita.com/hirohiro77/items/893be0dea507925f6322

CentOSでサーバー公開するためのセキュリティ設定メモ
http://qiita.com/narumi_/items/179048afb48f64f45c6e

鍵認証の設定をしてパスワードログインを無効にするまで
http://qiita.com/nama/items/54e8f62bfe835bf24a4c

AWSのApache2.4の初期設定とセキュリティ設定
http://qiita.com/shojimotio/items/41a74f314f3e47c018a5

中規模サイトのApacheチューニング
http://qiita.com/kou/items/acb3dcf1dcb428d7a3ec

2016年11月22日火曜日

Spring Day 2016 参加メモ

先日11/18、Spring Day 2016 に行ってきました。

そろそろと思い、最近 Spring Framework、Spring Boot の情報収集・勉強を始めてた所でした。

このイベントは大規模で、開発元や国内の大手・有力な会社が講演を行うということで、期待大でした。

という事で参加メモ。


1.Application Re-Architecture Technology
 ~ StrutsからSpring MVCへ ~
倉元 貴一/池谷 智行(NTTデータ)

メモ:
 Springの薄くラップしたTERASOLUNAの説明。ガイドラインが目玉。
 二重送信防止機能がある。
 TERASOLUNAはSpring Boot未対応?みたいだが、ガイドラインは読む価値あり。



2.Spring Bootで学ぶ初めてのWEBアプリ開発
てらひで

http://www.slideshare.net/terahide/spring-bootweb-69236132

メモ:
 Bootのチュートリアルを少しデモ。関係ない話が多くて面白くなかった。



3.LINE における Spring Framework の活用
松野 徳大(LINE)



メモ:
 LINEではかなりJava率が高い。Springを多く使っている。
 フレームワーク決めつけない。一つにコミットすると変化に弱い。
 LINE Notifyで使用。
 Redisは良い
 Jetty使ってる。起動速い
 LINEは全部オンプレ
 freemarker使用。タイムリーフと人気を二分
 mybatis優勢。JPA少ない。
 技術的にかなり濃い内容。松野氏は若そうだがすごい技術者だと思う。しゃべりも上手い。
 


3.楽天トラベルとSpring
藤井貴浩/Thomas Ludwig(楽天トラベル)



メモ:
 マイクロサービス推進
 SpringRESTDocsでAPIドキュメント作成
 マイクロだとログ追跡が面倒。MDCを利用。
 Spring Cloud Sleuthを使用
 楽天は堅そうなイメージだったけど結構攻めてる。



4.アメブロの大規模システム刷新とそれを支える Spring
向井 政貴/服部 拓也(サイバーエージェント)


メモ:
 OS、言語、フレームワークの陳腐化が深刻化
 レガシーコードも多く課題山積
 DC移設の際にシステム刷新した。Springを採用。
 SpringFox+SwaggerでAPIドキュメント作成
 とても分かりやすい内容で、面白かった。大規模になってくるとみんなAPI化。
 +Swagger等でAPIドキュメント作るのが常識になっているのが分かった。



5.Spring で実現する SmartNews のニュース配信基盤
井口 貝(SmartNews)


メモ:
 Seasar2からSpring Bootへ移行した。
 マイクロサービス化で個々のコンポーネントに集中。
 SpringFox+SwaggerでAPIドキュメント作成
 高度な周辺エコシステム
 spring boot adminでUIで設定確認、変更ができる
 actuatorでのメトリクス収集
 こちらもマイクロサービス化。今回Springのイベントなんだがマイクロサービスも存在感大だった。



その他、参加してないが以下のセッションも非常に興味深い。


Let's Visualize Your Spring Cloud Applications!
~ElasticsearchとSleuthを使った可視化の実際〜
谷本 心(Acroquest Technology)




Spring Security で作る Web API アクセス制御の最適解
~ Basic認証? APIキー? OAuth 2.0? OpenID Connect? ~
都元ダイスケ(クラスメソッド)





2016年10月4日火曜日

Rails勉強中

Ruby on Rails勉強中。

とりあえずドットインストールにて。
http://dotinstall.com/lessons/basic_rails_v2

Javaと相当文化が違う。

Migrationて、メリットが分からないな。

カラム追加する時とか、普通にALTERすればいいんじゃない。って思う。

でも、色々面白い。

2015年8月24日月曜日

GMail APIを使ってJavaからGMail検索

















GMail APIというのが最近できたらしい。

Java Quickstart
https://developers.google.com/gmail/api/quickstart/java

上記の説明では、gradleを使うようになっている。
gradleプラグインが標準で入っているEclipse 4.5をインストールしておく。もちろんPleiadesを使う。

Eclipseで、新規→その他→Gradle プロジェクト で、プロジェクトを作成する。

Library.javaとLibraryTest.javaが自動で作成されるが削除する。

「Gradle タスク」ビューでbuildを右クリックして「Gradle タスクの実行」をクリックすると、以下のエラーが出た。

--------------------------------------------------------
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> Could not find tools.jar

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
--------------------------------------------------------

プロジェクトルートフォルダに、gradle.propertiesを作成し、以下のようにJDKのパスを設定した。
org.gradle.java.home=C:/Program Files/Java/jdk1.8.0_40


これで上記エラーは出なくなったが、違うエラーになった。
--------------------------------------------------------
C:\eclipse4.5\workspace\GMailAPI\src\main\java\GmailQuickstart.java:16: エラー: シンボルを見つけられません
private static FileDataStoreFactory DATA_STORE_FACTORY;
--------------------------------------------------------

依存性の解決がされていない。
自分でjarダウンロードのタスクを書いて実行しないといけない。


build.gradleに以下を追加する。libsフォルダはルートに作成しておく。
-------------------------------------------------
task copyDependencies(type:Copy) {
    from (configurations.compile)
    into 'libs' //ダウンロード先ディレクトリ
}
-------------------------------------------------

「実行の構成」から、Gradleの実行構成を作り、タスクに「copyDependencies」を入力して実行すると、
libsにjarがダウンロードされる。

その後、Eclipse上で「Javaのビルド・パス」から、libsにダウンロードしたjarをビルド・パスに入れる。

GmailQuickstart.javaのコンパイルエラーがなくなるので、Eclipseから普通に実行する。
以下のメッセージが表示される。

-------------------------------------------------
Please open the following address in your browser:
  https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=xxxxxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=http://localhost:23189/Callback&response_type=code&scope=https://www.googleapis.com/auth/gmail.labels
Attempting to open that address in the default browser now...
-------------------------------------------------

ブラウザで上記URLが自動的に開き、Googleの承認画面が表示されるので、「承認」をクリック。
以下のメッセージが表示された。
Received verification code. You may now close this window...


再度、GmailQuickstartを実行すると、めでたくGMailのラベル一覧が表示された。
※出力結果は割愛

###########################################################

次に、以下のコードでメール(メッセージ)の検索を試みる。
---------------------------------------------------------
Gmail service = getGmailService();
String user = "me";
ListMessagesResponse listResponse = service.users().messages().list(user).setQ("検索ワード").execute();
List<Message> messages = listResponse.getMessages();
if (messages.size() == 0) {
System.out.println("No messages found.");
} else {
System.out.println("messages:");
for (Message message : messages) {
System.out.printf("- %s\n", message);
}
}
---------------------------------------------------------


実行すると、権限がないとのエラーになる。
---------------------------------------------------------
Credentials saved to C:\Users\nob\.credentials\gmail-api-quickstart
Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Insufficient Permission",
    "reason" : "insufficientPermissions"
  } ],
  "message" : "Insufficient Permission"
}
---------------------------------------------------------


↓に着目する。このフォルダを一旦削除して、再実行すると再度ブラウザで承認画面が開く。
Credentials saved to C:\Users\nob\.credentials\gmail-api-quickstart

しかし、相変わらず「メールボックス ラベルの管理」しか表示されない。


GmailQuickstart.javaのここに着目する。
private static final List<String> SCOPES = Arrays.asList(GmailScopes.GMAIL_LABELS);

以下のように、GMAIL_READONLYを追加する。

private static final List<String> SCOPES = Arrays.asList(GmailScopes.GMAIL_LABELS, GmailScopes.GMAIL_READONLY);


再度実行すると、リクエストの許可画面で、「メール メッセージと設定の表示」も表示された。
承認後、再実行すると、検索が実行できた。


しかし、出力結果を見ると、以下のようにidとthreadIdしかゲットできていない。
-------------------------------------------------------
- {"id":"14f5f0xxxxxxxxxx","threadId":"14f5eefxxxxxxxxxx"}
- {"id":"14f5eexxxxxxxxxx","threadId":"14f5eefxxxxxxxxxx"}
-------------------------------------------------------


メールの内容(送信者、受信者、サブジェクト、本文、etc...)をゲットしたい場合は、
idを元に再度getする必要がある。



以下は、検索して日付とサブジェクトと本文の一部(snippetと言う)をゲットする例。
---------------------------------------------------------
Gmail service = getGmailService();
String user = "me";
Long max = 5L; //最大件数
ListMessagesResponse listResponse = service.users().messages().list(user).setQ("検索ワード").setMaxResults(max).execute();
List<Message> messages = listResponse.getMessages();
System.out.println("ヒットした件数: " + messages.size());
for (Message message : messages) {
Message detailMessage = service.users().messages().get(user, message.getId()).execute();
List<MessagePartHeader> headers = detailMessage.getPayload().getHeaders(); //ヘッダー一覧
String date = "";
String subject = "";
for(MessagePartHeader header : headers) {
if ("Date".equals(header.getName())) { //日付
date = header.getValue();
}
else if ("Subject".equals(header.getName())) { //サブジェクト
subject = header.getValue();
}
}
System.out.println(date + "  " + subject);
System.out.println(detailMessage.getSnippet());
System.out.println();
}
---------------------------------------------------------


setQ("検索ワード")の部分は、GMailブラウザ版と同様の検索機能が色々使える。

 送信者を指定する例:   from:送信者の名前またはアドレス
 期間を指定する例:      after:2015/08/15 before:2015/08/25



しかし、、自分でタスク書いてlibsにダウンロードするなら、gradleである必要があったのかな・・・。

ちなみにlibsにダウンロードされたjarの一覧はこちら。

commons-codec-1.3.jar
commons-logging-1.1.1.jar
google-api-client-1.20.0.jar
google-api-services-gmail-v1-rev29-1.20.0.jar
google-http-client-1.20.0.jar
google-http-client-jackson2-1.20.0.jar
google-oauth-client-1.20.0.jar
google-oauth-client-java6-1.20.0.jar
google-oauth-client-jetty-1.20.0.jar
guava-jdk5-13.0.jar
httpclient-4.0.1.jar
httpcore-4.0.1.jar
jackson-core-2.1.3.jar
jetty-6.1.26.jar
jetty-util-6.1.26.jar
jsr305-1.3.9.jar
servlet-api-2.5-20081211.jar


2015年8月21日金曜日

Amazon S3にawscliのs3 syncを使ってファイルバックアップ

【S3事前準備】
1.AWSアカウントを作成する。
2.AWSコンソールにログインし、S3の管理画面を開く。              
3.バケットを作成する。名称は"xxxx-bucket"等任意。
4.右上のユーザー名をクリックし、「認証情報」をクリック。
5.「アクセスキー」を開き、「新しいアクセスキーの作成」から作成し、アクセスキーIDと、シークレットアクセスキーをエディタ等に控える。(後で再確認できない!)

【s3 sync インストール・設定】
1.pythonインストール
     yum install python
2.pipインストール(awscliをインストールするためのもの)
     cd /usr/local/src
     wget https://raw.github.com/pypa/pip/master/contrib/get-pip.py
     python get-pip.py
3.awscliインストール・設定(AWS公式ツール)
     pip install awscli
     aws configure 
         →アクセスキーIDとシークレットアクセスキーを入力する。Default region nameとDefault output formatは未入力でEnter。

【S3へのバックアップ】
1.バックアップコマンド実行
     aws s3 sync バックアップファイルがあるディレクトリ s3://xxxx-bucket/
     →バケットにファイルが送信される。コピー元にフォルダがある場合はそれも同期される。
         既にS3側に同一ファイルが存在する場合は送信されない。
2.ファイル削除コマンド実行
     aws s3 rm  s3://xxxx-bucket/ファイル名
     →S3のファイルを削除する。

http://docs.aws.amazon.com/cli/latest/reference/s3/index.html

s3fsという、S3をファイルシステムにマウントしてくれるサードパーティツールもあるが、安定していないのでおすすめできない