module Groonga class Table include Enumerable include Indexable def columns context = Context.instance column_ids.collect do |id| context[id] end end def each flags = TableCursorFlags::ASCENDING | TableCursorFlags::BY_ID TableCursor.open(self, :flags => flags) do |cursor| cursor.each do |id| yield(id) end end end def sort(keys, options={}) offset = options[:offset] || 0 limit = options[:limit] || -1 ensure_sort_keys(keys) do |sort_keys| sorted = Array.create("", self) begin sort_raw(sort_keys, offset, limit, sorted) rescue Exception => error sorted.close raise error end sorted end end def group(keys, result) ensure_sort_keys(keys) do |sort_keys| group_raw(sort_keys, result) end end def apply_window_function(output_column, window_function_call, options={}) ensure_sort_keys_accept_nil(options[:sort_keys]) do |sort_keys| ensure_sort_keys_accept_nil(options[:group_keys]) do |group_keys| window_definition = WindowDefinition.new begin window_definition.sort_keys = sort_keys window_definition.group_keys = group_keys apply_window_function_raw(output_column, window_definition, window_function_call) ensure window_definition.close end end end end def select_all expression = Expression.create(self) begin expression.append_constant(true, Operator::PUSH, 1) select(expression) ensure expression.close end end private def ensure_sort_keys_accept_nil(keys, &block) return yield(nil) if keys.nil? ensure_sort_keys(keys, &block) end def ensure_sort_keys(keys) if keys.is_a?(::Array) and keys.all? {|key| key.is_a?(TableSortKey)} return yield(keys) end converted_keys = [] begin keys = [keys] unless keys.is_a?(::Array) sort_keys = keys.collect do |key| ensure_sort_key(key, converted_keys) end yield(sort_keys) ensure converted_keys.each do |converted_key| converted_key.close end end end def ensure_sort_key(key, converted_keys) return key if key.is_a?(TableSortKey) sort_key = TableSortKey.new converted_keys << sort_key key_name = nil order = :ascending offset = 0 if key.is_a?(::Hash) key_name = key[:key] order = key[:order] || order offset = key[:offset] || offset else key_name = key end case key_name when String # Do nothing when Symbol key_name = key_name.to_s else message = "sort key name must be String or Symbol: " + "#{key_name.inspect}: #{key.inspect}" raise ArgumentError, message end if key_name.start_with?("-") key_name = key_name[1..-1] order = :descending elsif key_name.start_with?("+") key_name = key_name[1..-1] end key = find_column(key_name) if key.nil? table_name = name || "(temporary)" message = "unknown key: #{key_name.inspect}: " message << "#{table_name}(#{size})" raise ArgumentError, message end sort_key.key = key if order == :ascending sort_key.flags = Groonga::TableSortFlags::ASCENDING else sort_key.flags = Groonga::TableSortFlags::DESCENDING end sort_key.offset = offset sort_key end end end