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.)
142 143 144 145 146 147 148 149 |
# File 'lib/mongoscript/multiquery.rb', line 142 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.
56 57 58 59 60 61 62 63 64 65 |
# File 'lib/mongoscript/multiquery.rb', line 56 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.
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 103 104 105 106 |
# File 'lib/mongoscript/multiquery.rb', line 77 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.
157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/mongoscript/multiquery.rb', line 157 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).
118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/mongoscript/multiquery.rb', line 118 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 |