flexera-public / right_aws

RightScale Amazon Web Services Ruby Gems
MIT License
451 stars 175 forks source link

SimpleDB Query Expressions Don't Support IN() Statements #138

Open pr1001 opened 12 years ago

pr1001 commented 12 years ago

When doing a SimpleDB query with IN() only the first value is used. This is the case both in query_expression_from_hash and query_expression_from_array:

> conn.query_expression_from_hash(:userId =>  user_ids)
 => "userId='12342a1c090c-d84f-4dec-acc0-2e5debf5b48f'" 
> conn.query_expression_from_array(["userId IN(?)", user_ids])
 => "userId IN('12342a1c090c-d84f-4dec-acc0-2e5debf5b48f')" 
> user_ids
 => ["1234", "2a1c090c-d84f-4dec-acc0-2e5debf5b48f"] 

This is because both methods user escape():

 > conn.escape(user_ids)
 => "'12342a1c090c-d84f-4dec-acc0-2e5debf5b48f'"

which just converts the given value to a string:

def escape(value)
  %Q{'#{value.to_s.gsub(/(['\\])/){ "\\#{$1}" }}'} if value
end

This can be fixed by converting the value passed to escape() to an array, iterating over the items, and then joining them:

def escape(value)
  values = value.to_a
  values.map{|v| %Q{'#{v.to_s.gsub(/(['\\])/){ "\\#{$1}" }}'}}.join(', ') if not values.empty?
end

This is gives logical results:

> escape(nil)
 => nil 
> escape([])
 => nil 
> escape(user_ids)
 => "'1234', '2a1c090c-d84f-4dec-acc0-2e5debf5b48f'" 
> escape(['1234'])
 => "'1234'" 
> escape('1234')
 => "'1234'"