Class: Medea::JasonListProperty

Inherits:
JasonDeferredQuery show all
Defined in:
lib/medea/jasonlistproperty.rb

Instance Attribute Summary collapse

Attributes inherited from JasonDeferredQuery

#contents, #filters, #result_format, #state, #time_limit, #type

Instance Method Summary collapse

Methods inherited from JasonDeferredQuery

#[], #add_data_filter, #count, #each, #first, #include?, #last, #limit, #limit=, #top

Constructor Details

#initialize(parent, list_name, list_class, list_type) ⇒ JasonListProperty

Returns a new instance of JasonListProperty.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/medea/jasonlistproperty.rb', line 8

def initialize parent, list_name, list_class, list_type
  super :class => list_class,
        :format => :search,
        :filters => {
            :VERSION0 => nil,
            :FILTER => {:HTTP_X_LIST => list_name,
                        :HTTP_X_ACTION => :POST}}

  self.filters[:FILTER][:HTTP_X_CLASS] = list_class.name if list_type == :value
  @list_name = list_name
  @parent = parent
  @state = :prefetch
  @contents = []
  @list_type = list_type
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/medea/jasonlistproperty.rb', line 24

def method_missing name, *args, &block
  #is this a list property on the base class?
  lists = @type.class_variable_defined?(:@@opts) ? (@type.class_variable_get :@@opts)[:lists] : nil
  if lists && lists.has_key?(name)
    #if so, we'll just return a new ListProperty with my query as the parent
    new_list_class, new_list_type = lists[name]
    base_query = self.clone
    base_query.result_format = :keylist
    JasonListProperty.new base_query, name.to_sym, new_list_class, new_list_type
  else
    #no method, let JasonDeferredQuery handle it
    super
  end
end

Instance Attribute Details

#list_nameObject

Returns the value of attribute list_name.



6
7
8
# File 'lib/medea/jasonlistproperty.rb', line 6

def list_name
  @list_name
end

#list_typeObject

Returns the value of attribute list_type.



6
7
8
# File 'lib/medea/jasonlistproperty.rb', line 6

def list_type
  @list_type
end

#parentObject

Returns the value of attribute parent.



6
7
8
# File 'lib/medea/jasonlistproperty.rb', line 6

def parent
  @parent
end

Instance Method Details

#add!(member, save = true) ⇒ Object

Raises:

  • (RuntimeError)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/medea/jasonlistproperty.rb', line 39

def add! member, save=true
  raise RuntimeError, "You can only add an item if you are accessing this list from an object." unless @parent.is_a? JasonObject
  raise ArgumentError, "You can only add #{@type.name} items to this collection!" unless member.is_a? @type
  
  if @list_type == :value
    member.jason_parent = @parent
    member.jason_parent_list = @list_name
  elsif @list_type == :reference

    url = "#{JasonDB::db_auth_url}#{@parent.class.name}/#{@parent.jason_key}/#{@list_name}/#{member.jason_key}"
    post_headers = {
          :content_type => 'application/json',
          "X-KEY" => member.jason_key,
          "X-PARENT" => @parent.jason_key,
          "X-LIST" => @list_name.to_s
    }
    content = {
        "_id" => member.jason_key,
        "_parent" => @parent.jason_key
    }
    #puts "   = " + url
    #puts "   = #{post_headers}"
    response = RestClient.post url, content.to_json, post_headers

    if response.code == 201
        #save successful!
        #store the new eTag for this object
        #puts response.raw_headers
        #@__jason_etag = response.headers[:location] + ":" + response.headers[:content_md5]
    else
        raise "POST failed! Could not save membership"
    end
  else
    #parent is a JasonObject, but this list is something other than :value or :reference??
    raise "Invalid list type or trying to add an item to a subquery list!"
  end

  if member.jason_state == :new
    #we want to save it? probably...
    member.save! if save
  end

  @state = :prefetch
end

#execute_queryObject



113
114
115
116
117
# File 'lib/medea/jasonlistproperty.rb', line 113

def execute_query
  #call super, but don't use the content to populate if this is a reference list
  content = @list_type == :reference ? false : true
  super content
end

#remove!(member, cascade = false) ⇒ Object

Raises:

  • (RuntimeError)


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/medea/jasonlistproperty.rb', line 84

def remove! member, cascade=false
  raise RuntimeError, "You can only remove an item if you are accessing this list from an object." unless @parent.is_a? JasonObject
  raise ArgumentError, "You can only remove #{@type.name} items from this collection!" unless member.is_a? @type
  raise ArgumentError, "This item (#{member.jason_key}) doesn't exist in the list you're trying to remove it from!" unless self.include? member
  
  if @list_type == :value
    member.jason_parent = nil
    member.jason_parent_list = nil
    member.delete! if cascade
  elsif @list_type == :reference

    #send DELETE to JasonDB::db_auth_url/a_class.name/
    url = "#{JasonDB::db_auth_url}#{@parent.class.name}/#{@parent.jason_key}/#{@list_name}/#{member.jason_key}"

    response = RestClient.delete url

    if response.code == 201
        #delete successful!
    else
        raise "DELETE failed! Could not remove membership"
    end
  else
    #parent is a JasonObject, but this list is something other than :value or :reference??
    raise "Invalid list type or trying to remove an item from a subquery list!"
  end

  @state = :prefetch
end

#to_urlObject



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/medea/jasonlistproperty.rb', line 120

def to_url
  url = "#{JasonDB::db_auth_url}@#{@time_limit}.#{@result_format}?"
  params = ["VERSION0"]
  params << "FILTER=HTTP_X_LIST:#{@list_name.to_s}"

  if @parent.is_a? JasonObject
    params << "FILTER=HTTP_X_PARENT:#{@parent.jason_key}"
  else # @parent.is_a? JasonListProperty ##(or DeferredQuery?)
    #we can get the insecure url here, because it will be resolved and executed at JasonDB - on a secure subnet.

    #puts "   = Fetching subquery stupidly. (#{@parent.to_url})"
    @parent.result_format = :keylist
    subquery = (RestClient.get @parent.to_url).strip
    #puts "   =   Result: #{subquery}"
    params << "FILTER={HTTP_X_PARENT:#{subquery}}"
  end

  url << URI.escape(params.join("&"), Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
end