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, #execute_query, #include?

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
# File 'lib/medea/jasonlistproperty.rb', line 8

def initialize parent, list_name, list_class, list_type
  @type = list_class
  @list_name = list_name
  @list_type = list_type
  @parent = parent
  @result_format = :search
  @time_limit = 0
  @state = :prefetch
  @contents = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/medea/jasonlistproperty.rb', line 19

def method_missing name, *args, &block
  #is this a list property on the base class?
  if (@type.class_variable_defined? :@@lists) && (@type.class_variable_get(:@@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 = @type.class_variable_get(:@@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)


33
34
35
36
37
38
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
# File 'lib/medea/jasonlistproperty.rb', line 33

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

    #post to JasonDB::db_auth_url/a_class.name/
    url = "#{JasonDB::db_auth_url}#{@type.name}/#{@parent.jason_key}/#{@list_name}/#{member.jason_key}"
    post_headers = {
          :content_type => 'application/json',
          "X-CLASS" => @list_name.to_s,
          "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

#remove!(member) ⇒ Object

Raises:

  • (RuntimeError)


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

def remove! member
  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.save!
  elsif @list_type == :reference

    #send DELETE to JasonDB::db_auth_url/a_class.name/
    url = "#{JasonDB::db_auth_url}#{@type.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



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/medea/jasonlistproperty.rb', line 109

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

  params << "FILTER=HTTP_X_CLASS:#{@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.

    #subquery = "<%@LANGUAGE=\"URL\" #{@parent.to_url}%>"
    #puts "   = Fetching subquery stupidly. (#{@parent.to_url})"

    subquery = (RestClient.get @parent.to_url).strip
    #puts "   =   Result: #{subquery}"
    params << URI.escape("FILTER={HTTP_X_PARENT:#{subquery}}", Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
  end

  url << params.join("&")
end