module SdbDal

require File.dirname(__FILE__) +"/memory_storage.rb"

class MemoryRepository
  attr_accessor :use_cache #this here just so interface matches sdb repo
      attr_accessor :storage
   
  def initialize(
      sdb_domain= nil,
      clob_bucket= nil,
      aws_key_id= nil,
      aws_secret_key= nil,
      memcache_servers = nil ,
      dummy=nil
    )
    @records={}
    @storage=MemoryStorage.new
  end
  def clear_session_cache
    
  end
  def clear
     @records={}
    @storage=MemoryStorage.new
  end
  def save(table_name, primary_key, attributes)
    key=make_cache_key(table_name,primary_key);
    record=@records[key]
    if !record 
      record={}
      @records[key]=record
        
    end
    
    attributes.each do |description,value|
      if description.is_clob
        @storage.put("",make_clob_key(table_name,primary_key,description.name),value)
      else
        record[description.name]=value
      end
    end
    record["metadata%table_name"]=table_name
    record["metadata%primary_key"]=primary_key
  end
  def query_ids(table_name,attribute_descriptions,options)
    primary_key=nil
    attribute_descriptions.each do |name,desc|
      if desc.is_primary_key
        primary_key= name.to_sym 
        break
      end
      
    end
    objects=query(table_name,attribute_descriptions,options)
    result=[]
    objects.each do | o|
      result<<o[primary_key]
    end
    result
  end
  
  def query(table_name,attribute_descriptions,options)
      
    if options[:query]
      raise 'query not supported yet'
    end
    
    result=[]
    @records.each do |record_key,record|
      ok=true
      if record["metadata%table_name"]!=table_name
        ok=false
      else
        if options.has_key?(:params)
             
          options[:params].each do |param_key,param_value|

            if param_value==:NOT_NULL 
              if record[param_key]==nil
                ok=false
                break
              end
            elsif param_value==:NULL 
               if record[param_key]!=nil
                ok=false
                break
              end         
            elsif param_value.respond_to?(:matches?)

              if !param_value.matches?(record[param_key])
                ok=false
                break
              end
            elsif !record[param_key] && !param_value
              #ok 
              break
            elsif record[param_key]!=param_value
              ok=false
              break
            end
          end
        end
        if options.has_key?(:conditions)
             
          options[:conditions].each do |condition|

            if !condition.matches?(record)
              ok=false
              break
            end
          end
        end
      end
      if ok
        result<<record
      end
          
    end
    
    if options and options[:order_by]
      result.sort! do |a,b|
        a_value=a[options[:order_by]]
        b_value=b[options[:order_by]]
        if options[:order] && options[:order]!=:ascending
          if b_value
            b_value <=> a_value
          else
            -1
          end
        else
          if a_value
            a_value <=> b_value
          else
            -1
          end
        end
      end
    end
    if options[:limit] and result.length>options[:limit]
      result=result[0..options[:limit]-1]
    end
    return result
  end
  def find_one(table_name, primary_key,attribute_descriptions)#, non_clob_attribute_names, clob_attribute_names)
    return @records[make_cache_key(table_name,primary_key)]
  end
  def get_clob(table_name,primary_key,clob_name)
    return @storage.get("",make_clob_key(table_name,primary_key,clob_name))
        
  end
  def destroy(table_name, primary_key)
    key=make_cache_key(table_name,primary_key);
    
    if @records.has_key?(key)
      @records.delete(key)
    end
  end
  
  private
  def make_cache_key(table_name,primary_key)
    return "cached_objects/#{table_name}/#{CGI.escape(primary_key.to_s)}"
  end
  def make_clob_key(table_name,primary_key,clob_name)
    return "clobs/#{table_name}/#{CGI.escape(primary_key)}/#{clob_name}"
  end
end
end