# Web::Persistent::Store::DBI
# Copyright(c) 2004 MoonWolf <moonwolf@moonwolf.com>
require 'dbi'
require 'web/escape'

module Web
  class Persistent
    module Store
      class DBI
        def initialize(persistent_id, options={})
          @persistent_id = persistent_id
          @uri  = options[:dbi]      || 'dbi:Pg:Sample'
          @user = options[:dbi_user] || 'nora'
          @pass = options[:dbi_pass] || 'nora'
        end
        
        def key_limit
          64
        end
        
        def data_limit
          960 # 1024 - 64(key)
        end
        
        def open
          @dbh = ::DBI.connect(@uri,@user,@pass)
        end

        def close
          @dbh.disconnect
          @dbh = nil
        end
        
        def [](key)
          value = nil
          @dbh.transaction {|dbh|
            row = dbh.select_one('select value from sessions where session_id=? and key=?', @persistent_id, key)
            if row
              value = Web::unescape(row[0])
            else
              value = nil
            end
          }
          value
        end

        def []=(key,value)
          v = Web::escape(value)
          @dbh.transaction {|dbh|
            sth = dbh.execute('update sessions set value=?, last_modified=? where session_id=? and key=?', v, Time.now.utc, @persistent_id, key)
            if sth.rows==0
              row = dbh.execute('insert into sessions values(?,?,?,?)', @persistent_id, key, v, Time.now.utc)
            end
          }
        end
        
        def has_key?(key)
          value = nil
          @dbh.transaction {|dbh|
            row = dbh.select_one('select key from sessions where session_id=? and key=?', @persistent_id, key)
            if row
              value = true
            else
              value = false
            end
          }
          value
        end

        def delete(key)
          @dbh.transaction {|dbh|
            sth = dbh.execute('delete from sessions where session_id=? and key=?', @persistent_id, key)
          }
        end

        def keys
          rows = nil
          @dbh.transaction {|dbh|
            rows = dbh.select_all('select key from sessions where session_id=? order by key',@persistent_id)
          }
          rows.map {|row| row[0] }
        end
        
      end # DBI
    end # Store
  end # Persistent
end # Web
