1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
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
sorted.close
raise
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
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[0] = ""
order = :descending
elsif key_name.start_with?("+")
key_name[0] = ""
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
|