[mew-dist 29475] Re: cmew sometimes stores id as blob

Kei Tsuji <[email protected]> Mon, 26 Mar 2012 16:23:44 +0900 (JST)
Newsgroups gmane.mail.mew.general.japanese
Message-ID <[email protected]>
丸山さん、

辻です。情報共有ありがとうございます。

From: Shinichi Maruyama <[email protected]>
Subject: [mew-dist 29474] Re: cmew sometimes stores id as blob
Date: Mon, 26 Mar 2012 13:24:09 +0900

>       sqlite は、場合により型変換を行います。blob と null になる
> データを insert した例が載っています。
>
>       http://www.sqlite.org/datatype3.html
>
>       単純な text が blob になるかどうかは、すぐには見当たりません
> でした。今回の元となった、実際の例で試してみてはいかがでしょうか。

実際の例で試してみたところ、

1. sqlite3コマンドに

   % sqlite3 test.db "insert into mew(id) values ('<E2FF7BADA43AEA42BC4907B26603B75E0CBE5D@SCEXCH02.gracenote.gracenote.com>');"

というように実行してみても、textとしてinsertされました。

2. cmewのinsert近辺の要素を切り出して、test1.rbにて試してみましたが、こちらも
textとしてinsertされました。

3. もう少し変形して、test2.rbにて、実際のメールを指定してみたところ、以下の事実
が判明しました。

  3.1. message-idが途中で改行しているケース

Message-ID:
 <[email protected]>

 => blob

  3.2. 通常の、message-idが途中で改行していないケース

Message-ID: <[email protected]>

 => text

ただし、改行していても、idは、get_idでは、上記のどちらも
"<[email protected]>"となっていて、改行などは含まれていません。

rubyにて、id.classはstringになっているので、何故このような違いが出てしまうのか、
引き続き調べてみます。

-- 
ktsuji
(unnamed) (message/rfc822, 198 B) - not displayed
test1.rb (text/plain, 473 B)
#!/usr/bin/env ruby

require 'sqlite3'

# "insert into mew(id) values ('<0123456789ABCDEF0123456789ABCDEF012345@abcdefgh.abcdefghi.abcdefghi.com>');"
def test_insert
  db = SQLite3::Database.new("test.db")
  db.transaction
  id = "<0123456789ABCDEF0123456789ABCDEF012345@abcdefgh.abcdefghi.abcdefghi.com>"
  add_entry = db.prepare('INSERT INTO mew(id) VALUES(:id);')
  begin
    add_entry.execute('id' => id)
  ensure
    add_entry.close
  end
  db.commit
end

test_insert
test2.rb (text/plain, 1.3 KB)
#!/usr/bin/env ruby

require 'sqlite3'
require 'pp'
require 'logger'


# "insert into mew(id) values ('<0123456789ABCDEF0123456789ABCDEF012345@abcdefgh.abcdefghi.abcdefghi.com>');"
def test_insert(id)
  db = SQLite3::Database.new("test.db")
  db.transaction
  #id = "<0123456789ABCDEF0123456789ABCDEF012345@abcdefgh.abcdefghi.abcdefghi.com>"
  add_entry = db.prepare('INSERT INTO mew(id) VALUES(:id);')
  begin
    $log.info "id: #{id}, id.class: #{id.class}"
    add_entry.execute('id' => id)
  ensure
    add_entry.close
  end
  db.commit
end

def mail_header(path)
  @header = {}
  value = nil
  File.open(path) do |f|
    while l = f.gets.chomp
      next if /^From / =~ l
      break if /^$/ =~ l
      if /^\s+/ !~ l
        (name, value) = l.split(/:\s*/, 2)
        value = '' if value.nil?
        @header[name.downcase] = value
      else
        value << $'
      end
    end
  end
  return @header
end

def check_id(id)
  return nil if id == nil
  if id =~ /\A<[-a-zA-Z0-9!#\$%&\'\*\+\/=\?\^_`{}|~\.@]+>\z/
    return id
  else
    return nil
  end
end

def get_id(msg)
  return check_id(msg['message-id'])
end

$log = Logger.new(STDERR)
begin
  path = ARGV[0]
  $header = mail_header(path)
  pp $header
  id = get_id($header)
  pp "id: '#{id}', class: #{id.class}"
  test_insert(id)
rescue => ex
  $log.fatal ex
end