oracleからメールを送る

こんな感じで。重い処理の最後にメール送信するようにしとくとか。

declare
  type ADDRESSES IS TABLE OF VARCHAR2(40);
  procedure SendMail(mail_from    in varchar2,
                     mail_to      in ADDRESSES,
                     mail_subject in varchar2,
                     mail_text    in varchar2) is
    smtp  utl_smtp.connection;
    MAIL_SERVER     constant varchar2(40)   := 'MAIL_SERVER';     -- メールサーバ名、または、IP
    SMTP_PORT       constant binary_integer := 25;
    CRLF            constant varchar2(4)    := UTL_TCP.CRLF;
    TAB             constant varchar2(2)    := chr(9);
    MIME_CHARSET    constant varchar2(250)  := 'ISO-2022-JP';
    CONV_CHARSET    constant varchar2(250)  := 'ISO2022-JP';
    SUBJECT_LENGTH  constant number         := 14; -- Subjectは14文字ずつ区切って送信

    len number;
    pos number;
  begin
  
    /* メール送信 */
    smtp := utl_smtp.open_connection(MAIL_SERVER, 25);
    utl_smtp.helo(smtp, MAIL_SERVER);
    utl_smtp.mail(smtp, mail_from);
  
    for idx in mail_to.FIRST .. mail_to.LAST loop
      utl_smtp.rcpt(smtp, mail_to(idx));
    end loop;
    utl_smtp.open_data(smtp);
  
    utl_smtp.write_data(smtp, 'To:');
    for idx in mail_to.FIRST .. mail_to.LAST loop
      utl_smtp.write_data(smtp, mail_to(idx));
      utl_smtp.write_data(smtp, ', ');
      utl_smtp.write_data(smtp, CRLF);
      utl_smtp.write_data(smtp, TAB);
    end loop;
    utl_smtp.write_data(smtp, CRLF);
  
    utl_smtp.write_data(smtp, 'From:' || mail_from || CRLF);
    utl_smtp.write_data(smtp, 'Subject:');
    -- Subjectはある程度区切って送信しないと文字化けする
    pos := 1;
    len := length(mail_subject);
    while (pos <= len) loop
      if (pos > 1) then 
        utl_smtp.write_data(smtp, CRLF||TAB);
      end if;
      utl_smtp.write_data(smtp, '=?'||MIME_CHARSET||'?B?');
      utl_smtp.write_raw_data(smtp,
        utl_encode.base64_encode(
          utl_raw.cast_to_raw(convert(substr(mail_subject, pos, SUBJECT_LENGTH), CONV_CHARSET))
        )
      );
      utl_smtp.write_data(smtp, '?=');
      pos := pos + SUBJECT_LENGTH;
    end loop;
    utl_smtp.write_data(smtp, CRLF);
    utl_smtp.write_data(smtp, 'MIME-Version: 1.0' || CRLF);
    utl_smtp.write_data(smtp, 'Content-Type: text/plain;' || CRLF);
    utl_smtp.write_data(smtp, TAB || 'charset: ' || MIME_CHARSET || CRLF);
    utl_smtp.write_data(smtp, 'Content-Transfer-Encoding: base64' || CRLF);
    utl_smtp.write_data(smtp, CRLF);
    utl_smtp.write_raw_data(smtp,
      utl_encode.BASE64_ENCODE(
        utl_raw.cast_to_raw(mail_text)
      ));
    utl_smtp.close_data(smtp);
    utl_smtp.quit(smtp);
  
  end SendMail;
begin
  SendMail('sender', ADDRESSES('mail@example.com'), 'Subject', 'Hello,World.');
end;
/

msys2でgithubへpushできない

最近は、自宅も職場もmsys2+Git for Windowsで安定している。
githubにプロジェクトを作っていざpushしようとすると、

bash: /dev/tty: No such device or address
error: failed to execute prompt script (exit code 1)
fatal: could not read Username for 'https://github.com': Invalid argument

 のようなエラーが発生した。

試しに、Git for Windows付属のGitBashで試すと

Username for 'https://github.com':  

 のようにプロンプトが表示され、問題なくpushできた。

……しかしどうしてもzshを使いたい。
msys2の何かが問題なわけだがエラーメッセージをググっても要領を得ない。
ttyという単語から、ダメもとで

winpty git push origin master

 のようにしてみるとうまくいった。

チェックアウトしてあるすべてのブランチをプル

# チェックアウトしてあるすべてのブランチをプル
function gp() {
    current=$(git rev-parse --abbrev-ref HEAD)
    for b in $(git for-each-ref refs/heads --format='%(refname:short)')
    do
        git branch -vv | grep "${b}.*behind" > /dev/null
        if [ "$?" -eq 0 ]
        then
            git checkout $b&&git pull
        fi
    done
    git checkout -q $current
}

zshでredmineのチケットタイトルを取得する

function get-redmine-subject() {
    echo $(curl -s -X GET http://[redmineのアドレス]/issues/$1.xml | sed -n -e 's/.*<subject>\(.*\)<\/subject>.*/\1/p')
}

のような関数を.zshrcに作成する。

% get-redmine-subject 1234

とすると、チケット番号1234番のタイトルが取得できる。

MSYS2 + Git for Windows

・両方とも普通にインストールする
・MSYS2ではGitのインストールを行わない
・MSYS2でgitをwinpty経由で起動するようにエイリアス設定する
alias git="winpty git"

これでgit logでlessに渡らないこともないし結構快適。
git statusもそれなりに早い

↑のエイリアスはダメ。
grep なんかへパイプで渡すと妙なことになる。

alias wgit="winpty git"

としておいて、ログは

wgit log

で見るのが現状の最善かも。

SeaMonkeyでCtrl+Qに「他のタブを閉じる」を割り当てる

WebメールのUIが嫌いなのと、ブラウジング→メーラ起動をスムーズに行いたいのでSeaMonkeyを使っている。
以前はOperaを使っていたが、M2が切り離されてしまい用をなさないのでVivaldi待ち。

で、新規インストールのたびに
SeaMonkeyでCtrl+Qに「他のタブを閉じる」を割り当てたい』
と思うのだが、やり方を忘れがちなのでいい加減メモっとく。

KeyConfigの旧バージョンをインストール

http://mozilla.dorando.at/keyconfig.xpi から古いKeyConfigアドオンを入手してインストールする。
KeyConfigの最新版はSeaMonkeyに対応してないので古いのが必要。
特に問題なさそうなので古くても気にしない。

ショートカットを設定する

 アドオンの設定画面を開いて、まず終了に割り当てられているCtrl+Qを無効にする。
次に、「新しいキーを追加」ボタンをクリックして下記のコードを貼り付ける。

var browser = getBrowser(); browser.removeAllTabsBut(browser.mCurrentTab);

 追加したキーにCtrl+Qを割り当てて完了。

msys2を使ってみる

仕事でgitを使い始めてしばらくたった。
windowsのハブられっぷりを感じつつもいい感じになじんできた。
SourceTreeやGitExtentionsを併用しているけども、コマンドラインで済むと簡単だなーと感じ始めた。
10数年前にCygwinを使ったときは遅くて投げたけど、最近はどうなんだろう。。。
ということで調べたところmsys2が良さそうだったので導入してみた。

インストール

msys2のページ(MSYS2 installer)からインストーラをダウンロードして実行するだけ。
非常に簡単。

更新

pacman*1 というパッケージマネージャが標準で付属しているが普通に使うと
「forkできません」みたいなメッセージを吐いてコケる。
インストーラをダウンロードしたページに書いてあるが、まず

update-core

のようにしてシステムのパッケージ情報を更新する。
終了したらいったんmsys2を終了させてから再起動する。
再起動したら、

pacman -Su

としてパッケージの更新を行う。

必要なものをインストールする

適当に必要なパッケージをインストールする。

pacman -S zsh winpty tmux mingw-w64-i686-emacs

とかする。それっぽいパッケージを探すときには

pacman -Ss emacs

とすると「mingw-w64-i686-emacs」というパッケージ名であることがわかったりする。

パッケージ追加したら起動時にエラーがでる

zshの最新版を入れると、起動時に forkが~~ unable to remap とエラーがでる。 適当にググったところ、ashを起動してrebaseallすると良いらしい。 msys2のインストールディレクトリ以下 usr\bin\ash.exe を起動して

/usr/bin/rebaseall

と実行する。

msys2のインストールディレクトリ直下に autorebase.bat があるのでそれを実行してもよい。

起動時のシェルをbashからzshに変更する

msys2のインストールディレクトリ直下に msys2_shell.bat とか mingw32_shell.bat とか mingw64_shell.bat があるので、 普段使ってるやつを書き換える。 ラベル:startmintty が定義されているあたりでminttyを起動しているので、引数に渡しているbashzshに変える。

Git for Windowsの代わりに使ってみる

ファイルの検索、定型的な置換処理等 おおむね良好。 1つきになるのはGit for Windowsに比べて git status が異様に遅いこと。 fscacheではどうにもならないくらい遅い。 msys2でインストールしたgitをアンインストールしてもGit for Windowsのgitは使えるのでそれでごまかそうかな。。。 perlとかいろいろ別途入れなきゃみたいだけども。

 

 msys2のGitは使わないほうが幸せ

MSYS2 + Git for Windows - foohogehoge's blog

*1:個人的にはapt-getよりも好き