Slick の lifted embedding で FOR UPDATE する
mechairoi/slick-for-update-sample · GitHub
Slcik の lifted embedding で 無理やり FOR UPDATE
できようにするサンプル
slick-for-update-sample/Driver.scala at master · mechairoi/slick-for-update-sample · GitHub
みたいに PostgresDriver を継承した MyPostgresDriver を作って,
import MyPostgresDriver.simple._ class CoffeesForUpdate(tag: Tag) extends Coffees(tag) with ForUpdateTable val coffeesForUpdate = TableQuery[CoffeesForUpdate]
val q = for { c <- coffeesForUpdate if c.price < 9.0 s <- suppliers if s.id === c.supID } yield (c.name, s.name) q.list
のように書くと
select x2."COF_NAME", x3."SUP_NAME" from "COFFEES" x2, "SUPPLIERS" x3 where (x2."PRICE" < 9.0) and (x3."SUP_ID" = x2."SUP_ID") for update of x2
みたいにちゃんとFOR UPDATE
するクエリが吐かれる。
FOR UPDATE
は DBMS によって文法が結構違うのでリポジトリのは PostgreSQL でしか使えない。
Docker を使って Haskell を Heroku の cedar stack 用にコンパイルする
Heroku で Haskell を動かす方法は http://daimatz.hateblo.jp/entry/2013/02/09/164531 のように buildpack を使うとデプロイ時に Heroku のホストでビルドできて便利です。しかしビルド時間が15分までで Yesod などを使っていると間に合わず、手元で Ubuntu 10.04 向けのバイナリを作って push などする必要があります。Ubuntu 10.04 で開発してる人はもうあまりいないと思いますので、最近流行っている Docker を使って cedar stack 向けにビルドできるようにしてみました。
ビルドに使う Docker image は cedar 用のものに ghc と cabal-install をインストールして作りました。
サンプルプロジェクトは
- https://github.com/mechairoi/docker-heroku-cedar-ghc-demo
- http://docker-heroku-cedar-ghc.herokuapp.com/
にあります。デプロイするには READMEに書いてある通り、docker
とか heroku
コマンドをインストールして、リポジトリをクローンして
git clone https://github.com/mechairoi/docker-heroku-cedar-ghc.git
Heroku の アプリケーションを作って、
heroku create --stack=cedar
ビルドしてpush すれば
make build git checkout -b deploy git add -f dist/build/heroku-haskell/heroku-haskell git commit -m "build" git push heroku deploy:master
デプロイできると思います。Yesod でも deploy/Procfile に従って package.json などを配置して Makefile を修正すれば動くはずです。
make build の中身は
sudo docker run -v ${PWD}:/workspace -t mechairoi/heroku-cedar-ghc /bin/bash -xc 'cd /workspace/ \ && cabal --sandbox-config-file=./heroku.cabal.sandbox.config sandbox --sandbox=/workspace/.heroku-cabal-sandbox init \ && cabal --sandbox-config-file=./heroku.cabal.sandbox.config install --dependencies-only \ && cabal --sandbox-config-file=./heroku.cabal.sandbox.config configure \ && cabal --sandbox-config-file=./heroku.cabal.sandbox.config build --builddir=./dist-heroku \ && strip --strip-unneeded ./dist-heroku/build/heroku-haskell/heroku-haskell'
のようになっていて、Docker のホスト側をマウントして cabal sandbox を作ってるので2回目からはパッケージのダウンロードもなくビルドできます。Vagrant と違って起動も早いし Docker 便利ですね。
kyoto.js #5 で Emacs から WebSocket で Google Chrome を操作する拡張について発表しました。 #kyotojs
先日開催された Kyoto.js #5 で LT をしてきました.
crxel
Emacs から Google Chrome を操作する crxel というライブラリを作っているので発表しました. 今回の発表ではこのライブラリを使ったデモとして
- Emacs から Google Chrome のタブを Anything で切り替える anything-chrome-tabs.el と,
- Emacs のカーソル下のシンボルをバックグラウンドで google 検索する google-eldoc.el
を紹介しました. google-eldoc.el は全く役に立たないのですが, Emacs の操作にフックして Google Chrome を操作できると何か便利なことができそうな気がしています.
Motivation
Emacs には既に swank-js という Emacs から javascript の repl などが使えて javascript を使ったページを便利に開発できるものがあります. これは node.js で立てた WebSocket サーバに, ページ中の javascript から接続しておいて, Emacs から node.js のプロセスに送信した文字列をページ内で eval
することで実現しています.
今回作った crxel もほぼ同じ仕組みで, javscript の コードはほとんど swank-js から流用させてもらっています. crxel は Emacs で直接 WebSocket サーバを立てている点と, Emacs から Google Chrome を操作することを目的にしている点が swank-js と異なっています.
Anychrome って Google Chrome 拡張を作っています
id:hitode909 さんに手伝ってもらいました。ありがとうございます。
概要
こちらをインストールすると追加されるかわいいトマトのアイコンを押すと、開いてるタブと履歴からインクリメンタルに選んでアクティブにしたり開いたりできます。
今はタブと履歴から選ぶしかできませんがそれなりに便利なので公開します。(上のようにタブをたくさん開く人には特に)いずれ anything.el のように同じインタフェースでブックマークや Web 上のリソースなど色々な候補から選んで操作できるようにしたいです。
ChromeMigemo に対応していて一緒にインストールするとタブを探すときに migemo が使えます。
使い方
キーボードでしか操作できません。
C-n, ↓ | 下の候補 |
C-p, ↑ | 上の候補 |
C-m, RET | 一つ目のアクションを実行 |
C-i, TAB | アクションを選択 |
C-g | キャンセル |
C-x | マーク |
さらに
トマトのアイコンをマウスで毎回クリックするのは困難ですのでキーボードから直接(むりやり)起動する方法を用意しています。拡張機能のオプションページに表示される HTML か AppleScript をファイルに保存して、実行する(開く)だけで Anychrome を起動できます。 Mac なら Spark で AppleScript の実行をショートカットに割り当てるとどこからでも呼び出すことができて便利です。
gdbでEmacs Lisp のスタックトレースを表示する
Emacs"で"デバッグする方法はいっぱい出てくるのに、Emacs"を"デバッグする方法が http://www.emacswiki.org/emacs/DebugEmacs くらいしかみつけられないです...
とりあえずgdb で elispのスタックトレースをみたいので GDBで実行中のスクリプト言語のスタックフレームをダンプしてみる試み - muddy brown thang を参考に 書いてみました。
関数(struct Lisp_Function)以外に対応してないとか, アーキテクチャ(OSX)にとても依存している気がします。
あとハッシュを計算するのが面倒なのでシンボルテーブルを引くのが欲しいです。
実行結果は以下
bt だと C の関数ばっかりでよくわからない! のが
(gdb) bt #0 0x00007fff84a210b6 in __kill () #1 0x00007fff84ac19f6 in abort () #2 0x00000001001429d9 in die (msg=<value temporarily unavailable, due to optimizations>, file=<value temporarily unavailable, due to optimizations>, line=<value temporarily unavailable, due to optimizations>) at alloc.c:6279 #3 0x0000000100068541 in temp_output_buffer_show (buf=4762380197) at window.c:3787 #4 0x00000001001b764a in Fbyte_code (bytestr=<value temporarily unavailable, due to optimizations>, vector=<value temporarily unavailable, due to optimizations>, maxdepth=<value temporarily unavailable, due to optimizations>) at bytecode.c:888 #5 0x00000001001649b7 in funcall_lambda (fun=4737389829, nargs=1, arg_vector=0x7fff5fbfc8c8) at eval.c:3220 #6 0x0000000100164cef in Ffuncall (nargs=<value temporarily unavailable, due to optimizations>, args=<value temporarily unavailable, due to optimizations>) at eval.c:3088 #7 0x00000001001b8687 in Fbyte_code (bytestr=<value temporarily unavailable, due to optimizations>, vector=<value temporarily unavailable, due to optimizations>, maxdepth=<value temporarily unavailable, due to optimizations>) at bytecode.c:680 #8 0x00000001001649b7 in funcall_lambda (fun=4737395093, nargs=2, arg_vector=0x7fff5fbfcaa8) at eval.c:3220 #9 0x0000000100164cef in Ffuncall (nargs=<value temporarily unavailable, due to optimizations>, args=<value temporarily unavailable, due to optimizations>) at eval.c:3088 #10 0x00000001001b8687 in Fbyte_code (bytestr=<value temporarily unavailable, due to optimizations>, vector=<value temporarily unavailable, due to optimizations>, maxdepth=<value temporarily unavailable, due to optimizations>) at bytecode.c:680 #11 0x00000001001649b7 in funcall_lambda (fun=4737392117, nargs=2, arg_vector=0x7fff5fbfcc88) at eval.c:3220 #12 0x0000000100164cef in Ffuncall (nargs=<value temporarily unavailable, due to optimizations>, args=<value temporarily unavailable, due to optimizations>) at eval.c:3088 #13 0x00000001001b8687 in Fbyte_code (bytestr=<value temporarily unavailable, due to optimizations>, vector=<value temporarily unavailable, due to optimizations>, maxdepth=<value temporarily unavailable, due to optimizations>) at bytecode.c:680 #14 0x00000001001640fd in Feval (form=<value temporarily unavailable, due to optimizations>) at eval.c:2356 #15 0x0000000100163050 in internal_catch (tag=<value temporarily unavailable, due to optimizations>, func=0x100163940 <Feval>, arg=4748685078) at eval.c:1228 #16 0x00000001001b771d in Fbyte_code (bytestr=<value temporarily unavailable, due to optimizations>, vector=<value temporarily unavailable, due to optimizations>, maxdepth=<value temporarily unavailable, due to optimizations>) at bytecode.c:855 #17 0x00000001001649b7 in funcall_lambda (fun=4737350181, nargs=1, arg_vector=0x7fff5fbfd188) at eval.c:3220 #18 0x0000000100164cef in Ffuncall (nargs=<value temporarily unavailable, due to optimizations>, args=<value temporarily unavailable, due to optimizations>) at eval.c:3088 #19 0x00000001001611e1 in Fcall_interactively (function=4321459514, record_flag=4320133130, keys=4309662936) at callint.c:869 #20 0x0000000100165033 in Ffuncall (nargs=<value temporarily unavailable, due to optimizations>, args=<value temporarily unavailable, due to optimizations>) at eval.c:3037 #21 0x0000000100165386 in call3 (fn=<value temporarily unavailable, due to optimizations>, arg1=<value temporarily unavailable, due to optimizations>, arg2=<value temporarily unavailable, due to optimizations>, arg3=<value temporarily unavailable, due to optimizations>) at eval.c:2857 #22 0x00000001000e83d6 in command_loop_1 () at keyboard.c:1930 #23 0x0000000100162f47 in internal_condition_case (bfun=0x1000e7c60 <command_loop_1>, handlers=4320204266, hfun=0x1000dce90 <cmd_error>) at eval.c:1492 #24 0x00000001000dc18e in command_loop_2 () at keyboard.c:1379 #25 0x0000000100163050 in internal_catch (tag=<value temporarily unavailable, due to optimizations>, func=0x1000dc150 <command_loop_2>, arg=4320133130) at eval.c:1228 #26 0x00000001000dcc68 in command_loop () at keyboard.c:1354 #27 0x00000001000dd10f in recursive_edit_1 () at keyboard.c:963 #28 0x00000001000dd308 in Frecursive_edit () at keyboard.c:1025 #29 0x00000001000cf021 in main (argc=1, argv=0x7fff5fbfda18) at emacs.c:1858
これだとわかる!!1
(gdb) dump_emacs_bt $7 = { size = 26, size_byte = 26, intervals = 0x0, data = 0x115a56870 "pcomplete-show-completions" } $8 = { size = 14, size_byte = 14, intervals = 0x0, data = 0x115a55668 "pcomplete-stub" } $9 = { size = 21, size_byte = 21, intervals = 0x0, data = 0x115a558b0 "pcomplete-do-complete" } $10 = { size = 9, size_byte = -1, intervals = 0x0, data = 0x1002c63e8 "byte-code" } $11 = { size = 9, size_byte = 9, intervals = 0x0, data = 0x100638d74 "pcomplete" } $12 = { size = 18, size_byte = -1, intervals = 0x0, data = 0x1002b6b15 "call-interactively" } (gdb)
emacs で git blame して summary も表示する (mo-git-blame.el)
みんな大好きな git blame をいい感じに表示します。author より summary の方が有益なのでそれも表示します。こんな感じになります。
以下導入方法
https://github.com/voins/mo-git-blame/blob/master/mo-git-blame.el から mo-git-blame.el をいれます
M-x auto-install-from-url https://raw.github.com/voins/mo-git-blame/master/mo-git-blame.el
でもなんでもお好きなように。
設定ファイルを書きます。
そのままだとよく無限ループで Emacs ごと固まるので next-line を forward-line に書き換えて上書きしています。あと表示のフォーマットを変更。
(追記)8文字より短いauthor がいるとうまく表示できてなかったので修正しました.
gudでソースコードを表示してるwindowを常にセンタリング
カーソルがwindowの下の方にいってしまうと次の行が見にくくて辛いので
perldb-ui.elでしか試してないです.