Class: Arrest::MemSource
- Inherits:
-
Object
- Object
- Arrest::MemSource
- Defined in:
- lib/arrest/transport/mem_source.rb
Constant Summary collapse
- @@all_objects =
{}
- @@collections =
holds all objects of all types, each having a unique id
{}
- @@edge_matrix =
For every has_many relation
{}
- @@data =
matrix of edges based on node ids for has_many and belongs_to relations
{}
Instance Attribute Summary collapse
-
#data ⇒ Object
Returns the value of attribute data.
Instance Method Summary collapse
- #cheat_collection(url, ids) ⇒ Object
- #collection_json(values) ⇒ Object
- #collections ⇒ Object
- #delete(context, rest_resource) ⇒ Object
- #delete_all(context, resource_path) ⇒ Object
- #edge_count ⇒ Object
- #edge_matrix ⇒ Object
- #get(context, sub, filters = {}) ⇒ Object
- #get_many_other_ids(context, path) ⇒ Object
- #hash_to_query(filters) ⇒ Object
- #identify_and_store_edges(edge_matrix, rest_resource) ⇒ Object
-
#initialize ⇒ MemSource
constructor
A new instance of MemSource.
- #next_id ⇒ Object
- #node_count ⇒ Object
- #objects ⇒ Object
- #parse_for_has_many_relations(resource_path) ⇒ Object
- #post(context, rest_resource) ⇒ Object
- #put(context, rest_resource) ⇒ Object
- #remove_edges(edge_matrix, node_id) ⇒ Object
- #remove_outgoing_edges(edge_matrix, id) ⇒ Object
-
#set_collection(clazz, scope, objects) ⇒ Object
only to stub collection for development.
- #traverse(hash, keys) ⇒ Object
- #wrap(content, count) ⇒ Object
Constructor Details
#initialize ⇒ MemSource
Returns a new instance of MemSource.
44 45 46 47 48 49 50 51 |
# File 'lib/arrest/transport/mem_source.rb', line 44 def initialize @@all_objects = {} # holds all objects of all types, @@collections = {} # maps urls to collections of ids of objects @@random = Random.new(42) @@edge_matrix = {} end |
Instance Attribute Details
#data ⇒ Object
Returns the value of attribute data.
7 8 9 |
# File 'lib/arrest/transport/mem_source.rb', line 7 def data @data end |
Instance Method Details
#cheat_collection(url, ids) ⇒ Object
290 291 292 |
# File 'lib/arrest/transport/mem_source.rb', line 290 def cheat_collection(url, ids) @@collections[url] = ids end |
#collection_json(values) ⇒ Object
158 159 160 161 162 163 |
# File 'lib/arrest/transport/mem_source.rb', line 158 def collection_json values single_jsons = values.map do |v| v.to_jhash.to_json end "[#{single_jsons.join(',')}]" end |
#collections ⇒ Object
24 25 26 |
# File 'lib/arrest/transport/mem_source.rb', line 24 def collections @@collections end |
#delete(context, rest_resource) ⇒ Object
178 179 180 181 182 183 184 185 186 |
# File 'lib/arrest/transport/mem_source.rb', line 178 def delete(context, rest_resource) raise "To change an object it must have an id" unless rest_resource.respond_to?(:id) && rest_resource.id != nil @@all_objects.delete(rest_resource.id) @@collections.each_pair do |k,v| v.reject!{ |id| id == rest_resource.id } end remove_edges(@@edge_matrix, rest_resource.id) rest_resource end |
#delete_all(context, resource_path) ⇒ Object
147 148 149 150 151 152 153 154 155 156 |
# File 'lib/arrest/transport/mem_source.rb', line 147 def delete_all(context, resource_path) id_list = Array.new(@@collections[resource_path] || []) id_list.each do |base_id| @@collections.each_pair do |k,v| v.reject!{ |id| id == base_id } end @@all_objects[base_id].delete remove_edges(@@edge_matrix, base_id) end end |
#edge_count ⇒ Object
36 37 38 |
# File 'lib/arrest/transport/mem_source.rb', line 36 def edge_count @@edge_matrix.values.inject(0){|sum, edges| sum + edges.length } end |
#edge_matrix ⇒ Object
32 33 34 |
# File 'lib/arrest/transport/mem_source.rb', line 32 def edge_matrix @@edge_matrix end |
#get(context, sub, filters = {}) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/arrest/transport/mem_source.rb', line 117 def get(context,sub, filters = {}) Arrest::debug sub + (hash_to_query filters) # filters are ignored by mem impl so far id_list = parse_for_has_many_relations(sub) if id_list.empty? id_list = @@collections[sub] || [] end objects = id_list.map do |id| @@all_objects[id] end wrap collection_json(objects), id_list.length end |
#get_many_other_ids(context, path) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/arrest/transport/mem_source.rb', line 100 def get_many_other_ids(context,path) matcher = /^.+\/([^\/]+)\/([^\/]+)_ids$/.match(path) return [] unless matcher object_id = matcher[1] relation = matcher[2] + 's' if (object_id && relation && @@edge_matrix[object_id]) id_list = [] @@edge_matrix[object_id].each do |edge| if (edge.name.to_s == relation) id_list << edge.id end end end wrap id_list, id_list.length end |
#hash_to_query(filters) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/arrest/transport/mem_source.rb', line 70 def hash_to_query filters ps = [] filters.each_pair do |k,v| ps << "#{k}=v" end if ps.empty? '' else '?' + ps.join('&') end end |
#identify_and_store_edges(edge_matrix, rest_resource) ⇒ Object
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/arrest/transport/mem_source.rb', line 218 def identify_and_store_edges(edge_matrix, rest_resource) from_id = rest_resource.id rest_resource.class.all_fields.each do |attr| if attr.is_a?(Arrest::HasManyAttribute) to_ids = rest_resource.send(attr.name) # -> foo_ids url_part = attr.url_part foreign_key = attr.foreign_key edge_matrix[from_id] ||= Set.new() if to_ids to_ids.each do |to_id| edge_matrix[from_id].add(Edge.new(foreign_key, url_part, to_id, true)) edge_matrix[to_id] ||= Set.new() edge_matrix[to_id].add(Edge.new(foreign_key, url_part, from_id, false)) end end elsif attr.is_a?(Arrest::BelongsToAttribute) to_id = rest_resource.send(attr.name) if to_id foreign_key = attr.foreign_key has_many_clazz = attr.target_class() hm_candidates = has_many_clazz.all_fields.find_all do |field| field.is_a?(Arrest::HasManyAttribute) && field.foreign_key.to_s == foreign_key end return if hm_candidates.empty? has_many_node = hm_candidates.first url_part = has_many_node.url_part edge_matrix[from_id] ||= Set.new() edge_matrix[from_id].add(Edge.new(foreign_key, url_part, to_id, true)) edge_matrix[to_id] ||= Set.new() edge_matrix[to_id].add(Edge.new(foreign_key, url_part, from_id, false)) end end end end |
#next_id ⇒ Object
294 295 296 |
# File 'lib/arrest/transport/mem_source.rb', line 294 def next_id (0...32).map{ ('a'..'z').to_a[@@random.rand(26)] }.join end |
#node_count ⇒ Object
40 41 42 |
# File 'lib/arrest/transport/mem_source.rb', line 40 def node_count @@edge_matrix.length end |
#objects ⇒ Object
20 21 22 |
# File 'lib/arrest/transport/mem_source.rb', line 20 def objects @@all_objects end |
#parse_for_has_many_relations(resource_path) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/arrest/transport/mem_source.rb', line 82 def parse_for_has_many_relations(resource_path) matcher = /^.+\/([^\/]+)\/([^\/]+)$/.match(resource_path) return [] unless matcher object_id = matcher[1] relation = matcher[2] if (object_id && relation && @@edge_matrix[object_id]) result = [] @@edge_matrix[object_id].each do |edge| if (edge.name.to_s == relation) result << edge.id end end return result end [] end |
#post(context, rest_resource) ⇒ Object
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/arrest/transport/mem_source.rb', line 270 def post(context, rest_resource) Arrest::debug "post -> #{rest_resource.class.name} #{rest_resource.to_hash} #{rest_resource.class.all_fields.map(&:name)}" raise "new object must have setter for id" unless rest_resource.respond_to?(:id=) raise "new object must not have id" if rest_resource.respond_to?(:id) && rest_resource.id != nil rest_resource.id = next_id @@all_objects[rest_resource.id] = rest_resource unless @@data[rest_resource.resource_path()] != nil @@data[rest_resource.resource_path()] = {} end Arrest::debug "child path #{rest_resource.resource_path()}" @@data[rest_resource.resource_path()][next_id.to_s] = rest_resource.id if @@collections[rest_resource.resource_path] == nil @@collections[rest_resource.resource_path] = [] end @@collections[rest_resource.resource_path] << rest_resource.id true end |
#put(context, rest_resource) ⇒ Object
255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/arrest/transport/mem_source.rb', line 255 def put(context, rest_resource) raise "To change an object it must have an id" unless rest_resource.respond_to?(:id) && rest_resource.id != nil old = @@all_objects[rest_resource.id] remove_outgoing_edges(@@edge_matrix, old.id) rest_resource.class.all_fields.each do |f| old.send("#{f.name}=", rest_resource.send(f.name)) end true end |
#remove_edges(edge_matrix, node_id) ⇒ Object
208 209 210 211 212 213 214 215 216 |
# File 'lib/arrest/transport/mem_source.rb', line 208 def remove_edges(edge_matrix, node_id) if (edge_matrix[node_id]) edge_matrix[node_id].each do |edge| to_nodes = edge_matrix[edge.id] to_nodes.delete_if{|e| e.id == node_id} end edge_matrix.delete(node_id) end end |
#remove_outgoing_edges(edge_matrix, id) ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/arrest/transport/mem_source.rb', line 188 def remove_outgoing_edges(edge_matrix, id) if (edge_matrix[id]) out_edges = edge_matrix[id].find_all{|edge| edge.tail} in_edges_to_delete = out_edges.map do |out_edge| foreign_edges = edge_matrix[out_edge.id] # the edge set of the foreign node that this node points to has_many_back_edges = foreign_edges.find_all do |for_edge| for_edge.id == id && for_edge.foreign_key == out_edge.foreign_key end [has_many_back_edges.first, out_edge.id] # first element may be nil end in_edges_to_delete.each do |tupel| if tupel[0] edge_matrix[tupel[1]].delete_if{|e| e.id == tupel[0].id && e.foreign_key == tupel[0].foreign_key} end end edge_matrix[id] = Set.new() end end |
#set_collection(clazz, scope, objects) ⇒ Object
only to stub collection for development
56 57 58 59 60 |
# File 'lib/arrest/transport/mem_source.rb', line 56 def set_collection clazz, scope, objects url = clazz.scoped_path scope Arrest::debug "url:#{url}" @@data[url] = objects end |
#traverse(hash, keys) ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/arrest/transport/mem_source.rb', line 165 def traverse hash, keys if keys.empty? return hash end key = keys.first if hash == nil nil else traverse hash[key.to_s],keys.drop(1) end end |
#wrap(content, count) ⇒ Object
62 63 64 65 66 67 68 |
# File 'lib/arrest/transport/mem_source.rb', line 62 def wrap content,count "{ \"queryTime\" : \"0.01866644\", \"resultCount\" : #{count}, \"result\" : #{content} }" end |