Module: MongoScript::Multiquery::ClassMethods
- Defined in:
- lib/mongoscript/multiquery.rb
Instance Method Summary collapse
-
#mongoize_queries(queries) ⇒ Object
Prepare normalized queries for use in Mongo.
-
#multiquery(queries) ⇒ Object
Runs multiple find queries at once, returning the results keyed to the original query names.
-
#normalize_queries(queries) ⇒ Object
Standardize a set of queries into a form we can use.
-
#process_results(results, queries) ⇒ Object
If any results failed, create appropriate QueryFailedError objects.
-
#validate_queries!(queries) ⇒ Object
Validate that all the queries are well formed.
Instance Method Details
#mongoize_queries(queries) ⇒ Object
Prepare normalized queries for use in Mongo. Currently, this involves deleting parameters that can’t be turned into BSON. (We can’t act directly on the normalized queries, since they contain data used later to rehydrate models.)
138 139 140 141 142 143 144 145 |
# File 'lib/mongoscript/multiquery.rb', line 138 def mongoize_queries(queries) # delete any information not needed by/compatible with Mongoid execution mongoized_queries = queries.dup mongoized_queries.each_pair do |name, details| # have to dup the query details to avoid changing the original hashes mongoized_queries[name] = details.dup.tap {|t| t.delete(:klass) } end end |
#multiquery(queries) ⇒ Object
Runs multiple find queries at once, returning the results keyed to the original query names. If a query produces an error, its result will be a QueryFailedError object with the appropriate details; other queries will be unaffected.
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/mongoscript/multiquery.rb', line 52 def multiquery(queries) # don't do anything if we don't get any queries return {} if queries == {} # resolve all the queries = normalize_queries(queries) validate_queries!(queries) results = MongoScript.execute_readonly_routine("multiquery", mongoize_queries(queries)) process_results(results, queries) end |
#normalize_queries(queries) ⇒ Object
Standardize a set of queries into a form we can use. Specifically, ensure each query has a database collection and an ORM class, and resolve any ORM criteria into hashes.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/mongoscript/multiquery.rb', line 73 def normalize_queries(queries) # need to also ensure we have details[:klass] queries.inject({}) do |normalized_queries, data| name, details = data if details.is_a?(Hash) # duplicate the details so we don't make changes to the original query data details = details.dup.with_indifferent_access # if no collection is specified, assume it's the same as the name details[:collection] ||= name # ensure that we know which class the collection maps to # so we can rehydrate the resulting data unless details[:klass] expected_class_name = details[:collection].to_s.singularize.titlecase # if the class doesn't exist, this'll be false (and we'll raise an error later) details[:klass] = Object.const_defined?(expected_class_name) && Object.const_get(expected_class_name) end elsif processable_into_parameters?(details) # process Mongo ORM selectors into JS-compatible hashes details = MongoScript.build_multiquery_parameters(details) else raise ArgumentError, "Invalid selector type provided to multiquery for #{name}, expected hash or Mongoid::Criteria, got #{data.class}" end normalized_queries[name] = details normalized_queries.with_indifferent_access end end |
#process_results(results, queries) ⇒ Object
If any results failed, create appropriate QueryFailedError objects.
153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/mongoscript/multiquery.rb', line 153 def process_results(results, queries) processed_results = {} results.each_pair do |name, response| processed_results[name] = if response.is_a?(Hash) && response["error"] QueryFailedError.new(name, queries[name], response) elsif response # turn all the individual responses into real objects response.map {|data| MongoScript.rehydrate(queries[name][:klass], data)} end end processed_results end |
#validate_queries!(queries) ⇒ Object
Validate that all the queries are well formed. We could do this when building them, but doing it afterward allows us to present a single, comprehensive error message (in case multiple queries have problems).
114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/mongoscript/multiquery.rb', line 114 def validate_queries!(queries) errors = {:collection => [], :klass => []} queries.each_pair do |name, details| errors[:collection] << name unless details[:collection] errors[:klass] << name unless details[:klass] end error_text = "" error_text += "Missing collection details: #{errors[:collection].join(", ")}." if errors[:collection].length > 0 error_text += "Missing Ruby class details: #{errors[:klass].join(", ")}." if errors[:klass].length > 0 if error_text.length > 0 raise ArgumentError, "Unable to execute multiquery. #{error_text}" end true end |