class NoSE::Query
A representation of a query in the workload
Attributes
limit[R]
order[R]
select[R]
Public Class Methods
new(params, text, group: nil, label: nil)
click to toggle source
Calls superclass method
NoSE::Statement::new
# File lib/nose/statements/query.rb, line 10 def initialize(params, text, group: nil, label: nil) super params, text, group: group, label: label populate_conditions params @select = params[:select] @order = params[:order] || [] fail InvalidStatementException, 'can\'t order by IDs' \ if @order.any? { |f| f.is_a? Fields::IDField } if join_order.first != @key_path.entities.first @key_path = @key_path.reverse end fail InvalidStatementException, 'must have an equality predicate' \ if @conditions.empty? || @conditions.values.all?(&:is_range) @limit = params[:limit] end
parse(tree, params, text, group: nil, label: nil)
click to toggle source
Build a new query from a provided parse tree @return [Query]
# File lib/nose/statements/query.rb, line 32 def self.parse(tree, params, text, group: nil, label: nil) conditions_from_tree tree, params fields_from_tree tree, params order_from_tree tree, params params[:limit] = tree[:limit].to_i if tree[:limit] new params, text, group: group, label: label end
Private Class Methods
fields_from_tree(tree, params)
click to toggle source
Extract fields to be selected from a parse tree @return [Set<Field>]
# File lib/nose/statements/query.rb, line 92 def self.fields_from_tree(tree, params) params[:select] = tree[:select].flat_map do |field| if field.last == '*' # Find the entity along the path entity = params[:key_path].entities[tree[:path].index(field.first)] entity.fields.values else field = add_field_with_prefix tree[:path], field, params fail InvalidStatementException, 'Foreign keys cannot be selected' \ if field.is_a? Fields::ForeignKeyField field end end.to_set end
order_from_tree(tree, params)
click to toggle source
Extract ordering fields from a parse tree @return [Array<Field>]
# File lib/nose/statements/query.rb, line 112 def self.order_from_tree(tree, params) return params[:order] = [] if tree[:order].nil? params[:order] = tree[:order][:fields].each_slice(2).map do |field| field = field.first if field.first.is_a?(Array) add_field_with_prefix tree[:path], field, params end end
Public Instance Methods
==(other)
click to toggle source
# File lib/nose/statements/query.rb, line 58 def ==(other) other.is_a?(Query) && @graph == other.graph && @select == other.select && @conditions == other.conditions && @order == other.order && @limit == other.limit && @comment == other.comment end
Also aliased as: eql?
all_fields()
click to toggle source
All fields referenced anywhere in the query @return [Set<Fields::Field>]
# File lib/nose/statements/query.rb, line 86 def all_fields (@select + @conditions.each_value.map(&:field) + @order).to_set end
hash()
click to toggle source
# File lib/nose/statements/query.rb, line 69 def hash @hash ||= [@graph, @select, @conditions, @order, @limit, @comment].hash end
join_order()
click to toggle source
The order entities should be joined according to the query graph @return [Array<Entity>]
# File lib/nose/statements/query.rb, line 75 def join_order @graph.join_order(@eq_fields) end
read_only?()
click to toggle source
Specifies that queries don't modify data
# File lib/nose/statements/query.rb, line 80 def read_only? true end
unparse()
click to toggle source
Produce the SQL text corresponding to this query @return [String]
# File lib/nose/statements/query.rb, line 43 def unparse field_namer = -> (f) { field_path f } query = 'SELECT ' + @select.map(&field_namer).join(', ') query << " FROM #{from_path @graph.longest_path}" query << where_clause(field_namer) query << ' ORDER BY ' << @order.map(&field_namer).join(', ') \ unless @order.empty? query << " LIMIT #{@limit}" unless @limit.nil? query << " -- #{@comment}" unless @comment.nil? query end
Private Instance Methods
field_path(field)
click to toggle source
# File lib/nose/statements/query.rb, line 124 def field_path(field) path = @graph.path_between @graph.longest_path.entities.first, field.parent path = path.drop_while { |k| @graph.longest_path.include? k } << path[-1] path = KeyPath.new(path) unless path.is_a?(KeyPath) from_path path, @graph.longest_path, field end