IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

cabalでローカルにあるライブラリを使う

課題

  • ローカルに自作ライブラリのソースコードがある。
    • ライブラリ側の変更はない仮定(安定している仮定)。
  • そのライブラリを使うプログラムをローカルで作りたい。
  • ライブラリのソースコードディレクトリは別にするが、cabalプロジェクトを作る。
    • ライブラリ側はlibraryディレクトリ配下、プログラムはsrc配下のようにする。
  • ライブラリ側のコードも一緒にコンパイルされるので、ビルドに時間がかかる。 ⇨ なんとかしたい

解決策

  • ライブラリ単独でcabalプロジェクトにして、それをプログラム側のcabalプロジェクトにインストールする。

やり方

  • ライブラリ用のcabalプロジェクトを作成する。
> cabal sandbox init
などなど
name:                mylibrary
version:             0.1.0.0
省略

library
  exposed-modules: Foo.Bar.X
                 , Foo.Bar.Y
                 , Foo.Bar.Z
                 , などなど
 
  • ライブラリモジュールを作成する(ビルドする)。
> cabal build
  • 上記のライブラリを利用するcabalプロジェクトを作成する。まずは、ライブラリを意識せずにプロジェクトを作成する。
> cabal sandbox init
いろいろ
  • ライブラリプロジェクトを取り込む。
> cabal sandbox add-source ライブラリがあるパス(のcabalファイルの親ディレクトリのパス)
  • cabalファイルの依存関係の指定をする。
executable myprogram
  main-is:             Main.hs
  other-extensions:    BangPatterns, DeriveDataTypeable, DeriveGeneric, FlexibleInstances, MultiParamTypeClasses
  build-depends:       base >=4.9 && <4.10
   その他いろいろ
                     , mylibrary <-- ここにライブラリ名を追加
> cabal install

作業ログ

haskell

How to split a string in Haskell? - Stack Overflow

Vim

VimとWindows コピーの違い - World Wide Wonderful

MySQLのSample Databaseの設定

sample data

https://dev.mysql.com/doc/index-other.html

word_x-db

Download and unzip

shell> wget http://downloads.mysql.com/docs/world_x-db.zip
shell> unzip world_x-db.zip 

Read instruction

shell> less world_x-db/README.txt 

Connect to MySQL:

shell> mysql -u root -p

Load the file:

mysql> SOURCE /tmp/world_x-db/world_x.sql;

sakila-db

Download and unzip

shell> wget http://downloads.mysql.com/docs/sakila-db.zip
shell> unzip sakila-db.zip

Connect to MySQL:

shell> mysql -u root -p

Load the file:

mysql> SOURCE example-databases/sakila-db/sakila-schema.sql
mysql> SSOURCE example-databases/sakila-db/sakila-data.sql

Reference

https://dev.mysql.com/doc/sakila/en/sakila-installation.html

menagerie-db

download and unzip

shell> wget http://downloads.mysql.com/docs/menagerie-db.zip
shell> unzip menagerie-db.zip 

Connect to MySQL and make tables

shell> mysql -u root -p
mysql> SOURCE example-databases/menagerie-db/cr_pet_tbl.sql
mysql> SOURCE example-databases/menagerie-db/cr_event_tbl.sql

Disconnect mysql, cd and load data

shell> cd example-databases/menagerie-db
shell> mysql menagerie --local_infile=1 -u root -p < load_pet_tbl.sql
shell> mysqlimport --local menagerie event.txt

Reference

https://dev.mysql.com/doc/refman/5.6/en/load-data-local.htm://dev.mysql.com/doc/refman/5.6/en/load-data-local.html

ysql-connector-java-6.0.6のサンプル実行

$javac -cp .:mysql-connector-java-6.0.6-bin.jar DevApiSample.java

$java -cp .:mysql-connector-java-6.0.6-bin.jar:lib/protobuf-java-2.6.0.jar DevApiSample
Connected!
Default schema is: Schema(foo)
Currently reading Effi Briest on page 42
Currently reading Effi Briest on page 42
Number of books in collection: 0

作業ログ

haskell

Haskell 文字列変換入門 - Qiita

Example of streaming data from the database using Persistent and Conduit libraries in Haskell

Smart Data with Conduits — Monday Morning Haskell

作業ログ

VIM

vim-plugin NERDTree で開発効率をアップする! - Qiita

Vim split line command - Stack Overflow

haskell

ストリーム処理ライブラリはなぜ必要なのか // Speaker Deck

MySQL

Streaming MySQL Results Using Java 8 Streams and Spring Data JPA

RealWorld Example を触ってみる

Haskell Servant RealWorld Example App

リポジトリの場所

Haskell Servant RealWorld Example App

インストー

サイトの手順の通り

データベース

>sqlite3 /tmp/haskell-servant-test.db <  {your_path}/haskell-servant-realworld-example-app/scripts/schema.sql 

処理

登録

xxx$ curl --verbose -H "Content-Type: application/json" -X POST -d '{"user" : {"email":"aaa@a.com", "username":"aaa", "password": "aaa"} }' http://127.0.0.1:8081/api/users
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> POST /api/users HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 70
>
* upload completely sent off: 70 out of 70 bytes
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:32:50 GMT
< Server: Warp/3.2.11.2
< Content-Type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"user":{"bio":null,"email":"aaa@a.com","image":null,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI","username":"aaa"}}

認証

成功

xxx$ curl --verbose -H "Content-Type: application/json" -X POST -d '{"user" : {"email":"aaa@a.com", "username":"aaa", "password": "aaa"} }' http://127.0.0.1:8081/api/users/login
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> POST /api/users/login HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 70
>
* upload completely sent off: 70 out of 70 bytes
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:39:33 GMT
< Server: Warp/3.2.11.2
< Content-Type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"user":{"bio":null,"email":"aaa@a.com","image":null,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI","username":"aaa"}}

失敗

xxx$ curl --verbose -H "Content-Type: application/json" -X POST -d '{"user" : {"email":"aaa@a.com", "username":"aaa", "password": "xxx"} }' http://127.0.0.1:8081/api/users/login
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> POST /api/users/login HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 70
>
* upload completely sent off: 70 out of 70 bytes
< HTTP/1.1 401 Unauthorized
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:39:42 GMT
< Server: Warp/3.2.11.2
<
* Connection #0 to host 127.0.0.1 left intact
Incorrect login or password

ユーザ取得

成功

xxx$ curl --verbose -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI"  http://127.0.0.1:8081/api/user
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET /api/user HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:28:27 GMT
< Server: Warp/3.2.11.2
< Content-Type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"user":{"bio":null,"email":"aaa@a.com","image":null,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI","username":"aaa"}}

失敗

xxx$ curl --verbose -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuX"  http://127.0.0.1:8081/api/user
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET /api/user HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuX
>
< HTTP/1.1 401 Unauthorized
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:37:18 GMT
< Server: Warp/3.2.11.2
<
* Connection #0 to host 127.0.0.1 left intact
Wrong 'Authorization' token

プロファイル取得

成功

xxx$ curl --verbose -H "Authorization: yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI" -X GET  http://127.0.0.1:8081/api/profiles/aaa
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET /api/profiles/aaa HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:41:39 GMT
< Server: Warp/3.2.11.2
< Content-Type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"profile":{"bio":null,"image":null,"username":"aaa","following":false}}

失敗

xxx$ curl --verbose -H "Authorization: yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI" -X GET  http://127.0.0.1:8081/api/profiles/xxx
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET /api/profiles/xxx HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:42:11 GMT
< Server: Warp/3.2.11.2
< Content-Type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"profile":null}
xxx$

記事作成

xxx$ curl --verbose -H "Content-Type: application/json" -H "Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI" -X POST -d '{"article": {"title" : "aaa_title_1", "description" : "aaa_description_1", "body" : "aaa_body_1", "tag" : "aaa_tag_1"} }' http://127.0.0.1:8081/api/articles
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> POST /api/articles HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type: application/json
> Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6eyJ1c2VyIjoiYWFhIn19.2_OPvQfqSdJfqftP-4ovSzv6zLFcyaMHPK6XdV1NuuI
> Content-Length: 120
>
* upload completely sent off: 120 out of 120 bytes
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:47:30 GMT
< Server: Warp/3.2.11.2
< Content-Type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"article":{"createdAt":"2017-06-03T02:47:30Z","slug":"aaa_title_1","body":"aaa_body_1","favorited":0,"tagList":null,"favoritesCount":0,"author":{"bio":null,"image":null,"username":"aaa","following":false},"updatedAt":"2017-06-03T02:47:30Z","title":"aaa_title_1","description":"aaa_description_1"}}
xxx$

記事一覧

xxx$ curl --verbose -X GET  http://127.0.0.1:8081/api/articles
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET /api/articles HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:50:09 GMT
< Server: Warp/3.2.11.2
< Content-Type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"articlesCount":1,"articles":[{"createdAt":"2017-06-03T02:47:30Z","slug":"aaa_title_1","body":"aaa_body_1","favorited":0,"tagList":null,"favoritesCount":0,"author":{"bio":null,"image":null,"username":"aaa","following":false},"updatedAt":"2017-06-03T02:47:30Z","title":"aaa_title_1","description":"aaa_description_1"}]}

記事取得

成功

root)blender:servant03 ogawanaoto$ curl --verbose -X GET  http://127.0.0.1:8081/api/articles/aaa_title_1
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET /api/articles/aaa_title_1 HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:54:31 GMT
< Server: Warp/3.2.11.2
< Content-Type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"article":{"createdAt":"2017-06-03T02:47:30Z","slug":"aaa_title_1","body":"aaa_body_1","favorited":0,"tagList":null,"favoritesCount":0,"author":{"bio":null,"image":null,"username":"aaa","following":false},"updatedAt":"2017-06-03T02:47:30Z","title":"aaa_title_1","description":"aaa_description_1"}}

失敗

xxx$ curl --verbose -X GET  http://127.0.0.1:8081/api/articles/aaa_title_x
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8081 (#0)
> GET /api/articles/aaa_title_x HTTP/1.1
> Host: 127.0.0.1:8081
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Sat, 03 Jun 2017 02:54:35 GMT
< Server: Warp/3.2.11.2
< Content-Type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"article":null}