hotdog 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 017715f50e986cf3c0f61cb4834859c296ddf6f7
4
- data.tar.gz: 137f2e8504b9c9908635b8dfe7db6d2b1541be9b
3
+ metadata.gz: 551436c6cb264d187db243f60da58a14f38cb820
4
+ data.tar.gz: f68bd1dd186fa326af8541b9ea3ae4ae95075d44
5
5
  SHA512:
6
- metadata.gz: 3b406633a8f174b328dca17c976b4585d6e187f8cefc2dfe7c19ca094f2469faf292a1335d8aaea75f8e440c7d24f1878782710ac9b4c8456cea65466ced87cc
7
- data.tar.gz: a1f2843dd806045110b64c915c8fda049f1a228654e8fc1282f5aa057280e129ecd5da06ca88a80db37b0f35c3c3054ec6e57338fb20d0e9ca176169fb17811c
6
+ metadata.gz: f85d09c3f08d2cce6fec0d9d73654e86b2ac6fa8abaa6b2682047f8b4daeeedb6985dc7a0f4613bee2076caf43ecf8e0df129f45023d986b14b306ee971a2a38
7
+ data.tar.gz: 2e983f2f1508ea69872aa58758ee2a7cfca55e3dcbcba2b612f26e8b543fb8b87a0b849b0d5ef198fb4919c1622c5f2f90bdeb38d73f0ea5ead1e23ad987c11c
@@ -242,16 +242,24 @@ module Hotdog
242
242
  case @op
243
243
  when :AND
244
244
  left_values = @left.evaluate(environment)
245
+ environment.logger.debug("lhs: #{left_values.length} value(s)")
245
246
  if left_values.empty?
246
247
  []
247
248
  else
248
249
  right_values = @right.evaluate(environment)
249
- (left_values & right_values)
250
+ environment.logger.debug("rhs: #{right_values.length} value(s)")
251
+ (left_values & right_values).tap do |values|
252
+ environment.logger.debug("lhs AND rhs: #{values.length} value(s)")
253
+ end
250
254
  end
251
255
  when :OR
252
256
  left_values = @left.evaluate(environment)
257
+ environment.logger.debug("lhs: #{left_values.length} value(s)")
253
258
  right_values = @right.evaluate(environment)
254
- (left_values | right_values).uniq
259
+ environment.logger.debug("rhs: #{right_values.length} value(s)")
260
+ (left_values | right_values).uniq.tap do |values|
261
+ environment.logger.debug("lhs OR rhs: #{values.length} value(s)")
262
+ end
255
263
  else
256
264
  []
257
265
  end
@@ -288,11 +296,23 @@ module Hotdog
288
296
  def evaluate(environment, options={})
289
297
  case @op
290
298
  when :NOT
291
- values = @expression.evaluate(environment)
299
+ values = @expression.evaluate(environment).sort
300
+ environment.logger.debug("expr: #{values.length} value(s)")
292
301
  if values.empty?
293
- environment.execute("SELECT DISTINCT host_id FROM hosts_tags").map { |row| row.first }
302
+ environment.execute("SELECT id FROM hosts").map { |row| row.first }.tap do |values|
303
+ environment.logger.debug("NOT expr: #{values.length} value(s)")
304
+ end
294
305
  else
295
- environment.execute("SELECT DISTINCT host_id FROM hosts_tags WHERE host_id NOT IN (%s)" % values.map { "?" }.join(", "), values).map { |row| row.first }
306
+ # workaround for "too many terms in compound SELECT"
307
+ min, max = environment.execute("SELECT MIN(id), MAX(id) FROM hosts ORDER BY id LIMIT 1").first.to_a
308
+ slice = 200
309
+ (min / slice).upto(max / slice).map { |i|
310
+ range = (slice*i)...(slice*(i+1))
311
+ selected = values.select { |n| range === n }
312
+ environment.execute("SELECT id FROM hosts WHERE ? <= id AND id < ? AND id NOT IN (%s)" % selected.map { "?" }.join(", "), [range.first, range.last] + selected).map { |row| row.first }
313
+ }.reduce(:+).tap do |values|
314
+ environment.logger.debug("NOT expr: #{values.length} value(s)")
315
+ end
296
316
  end
297
317
  else
298
318
  []
@@ -11,6 +11,7 @@ module Hotdog
11
11
  PERSISTENT_DB = "persistent.db"
12
12
  MASK_DATABASE = 0xffff0000
13
13
  MASK_QUERY = 0x0000ffff
14
+ MAX_TERMS = 200
14
15
 
15
16
  def initialize(application)
16
17
  @application = application
@@ -82,7 +83,11 @@ module Hotdog
82
83
  if fields == fields_without_host
83
84
  host_names = {}
84
85
  else
85
- host_names = Hash[execute("SELECT id, name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }]
86
+ host_names = Hash[
87
+ host_ids.each_slice(MAX_TERMS).map { |host_ids|
88
+ execute("SELECT id, name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }
89
+ }.reduce(:+)
90
+ ]
86
91
  end
87
92
  q1 = []
88
93
  q1 << "SELECT tags.name, GROUP_CONCAT(tags.value, ',') FROM hosts_tags"
@@ -91,7 +96,11 @@ module Hotdog
91
96
  q1 << "WHERE hosts_tags.host_id = ? AND tags.name IN (%s)"
92
97
  q1 << "GROUP BY tags.name;"
93
98
  result = host_ids.map { |host_id|
94
- tag_values = Hash[execute(q1.join(" ") % fields_without_host.map { "?" }.join(", "), [host_id] + fields_without_host).map { |row| row.to_a }]
99
+ tag_values = Hash[
100
+ fields_without_host.each_slice(MAX_TERMS).map { |fields_without_host|
101
+ execute(q1.join(" ") % fields_without_host.map { "?" }.join(", "), [host_id] + fields_without_host).map { |row| row.to_a }
102
+ }.reduce(:+)
103
+ ]
95
104
  fields.map { |tag_name|
96
105
  if tag_name == "host"
97
106
  host_names.fetch(host_id, "")
@@ -111,15 +120,23 @@ module Hotdog
111
120
  fields = [
112
121
  @options[:primary_tag],
113
122
  "host",
114
- ] + execute(q1.join(" ") % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.first }.reject { |tag_name|
115
- tag_name == @options[:primary_tag]
116
- }
123
+ ] + host_ids.each_slice(MAX_TERMS).map { |host_ids|
124
+ execute(q1.join(" ") % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.first }.reject { |tag_name|
125
+ tag_name == @options[:primary_tag]
126
+ }
127
+ }.reduce(:+)
117
128
  else
118
129
  fields = [
119
130
  "host",
120
- ] + execute(q1.join(" ") % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.first }
131
+ ] + host_ids.each_slice(MAX_TERMS).map { |host_ids|
132
+ execute(q1.join(" ") % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.first }
133
+ }.reduce(:+)
121
134
  end
122
- host_names = Hash[execute("SELECT id, name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }]
135
+ host_names = Hash[
136
+ host_ids.each_slice(MAX_TERMS).map { |host_ids|
137
+ execute("SELECT id, name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }
138
+ }.reduce(:+)
139
+ ]
123
140
  q2 = []
124
141
  q2 << "SELECT tags.name, GROUP_CONCAT(tags.value, ',') FROM hosts_tags"
125
142
  q2 << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
@@ -127,7 +144,11 @@ module Hotdog
127
144
  q2 << "GROUP BY tags.name;"
128
145
  fields_without_host = fields.reject { |tag_name| tag_name == "host" }
129
146
  result = host_ids.map { |host_id|
130
- tag_values = Hash[execute(q2.join(" ") % fields_without_host.map { "?" }.join(", "), [host_id] + fields_without_host).map { |row| row.to_a }]
147
+ tag_values = Hash[
148
+ fields_without_host.each_slice(MAX_TERMS).map { |fields_without_host|
149
+ execute(q2.join(" ") % fields_without_host.map { "?" }.join(", "), [host_id] + fields_without_host).map { |row| row.to_a }
150
+ }.reduce(:+)
151
+ ]
131
152
  fields.map { |tag_name|
132
153
  if tag_name == "host"
133
154
  host_names.fetch(host_id, "")
@@ -145,11 +166,15 @@ module Hotdog
145
166
  q1 << "INNER JOIN hosts ON hosts_tags.host_id = hosts.id"
146
167
  q1 << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
147
168
  q1 << "WHERE hosts_tags.host_id IN (%s) AND tags.name = ?;"
148
- result = execute(q1.join(" ") % host_ids.map { "?" }.join(", "), host_ids + [@options[:primary_tag]]).map { |row| row.to_a }
169
+ result = host_ids.each_slice(MAX_TERMS).map { |host_ids|
170
+ execute(q1.join(" ") % host_ids.map { "?" }.join(", "), host_ids + [@options[:primary_tag]]).map { |row| row.to_a }
171
+ }.reduce(:+)
149
172
  [result, fields]
150
173
  else
151
174
  fields = ["host"]
152
- result = execute("SELECT name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }
175
+ result = host_ids.each_slice(MAX_TERMS).map { |host_ids|
176
+ execute("SELECT name FROM hosts WHERE id IN (%s)" % host_ids.map { "?" }.join(", "), host_ids).map { |row| row.to_a }
177
+ }.reduce(:+)
153
178
  [result, fields]
154
179
  end
155
180
  end
@@ -195,24 +220,26 @@ module Hotdog
195
220
 
196
221
  all_tags = get_all_tags()
197
222
 
198
- known_tags = all_tags.keys.map { |tag| split_tag(tag) }.uniq
199
- unless known_tags.empty?
200
- prepare(memory_db, "INSERT OR IGNORE INTO tags (name, value) VALUES %s" % known_tags.map { "(?, ?)" }.join(", ")).execute(known_tags)
201
- end
223
+ memory_db.transaction do
224
+ known_tags = all_tags.keys.map { |tag| split_tag(tag) }.uniq
225
+ known_tags.each_slice(MAX_TERMS) do |known_tags|
226
+ prepare(memory_db, "INSERT OR IGNORE INTO tags (name, value) VALUES %s" % known_tags.map { "(?, ?)" }.join(", ")).execute(known_tags)
227
+ end
202
228
 
203
- known_hosts = all_tags.values.reduce(:+).uniq
204
- unless known_hosts.empty?
205
- prepare(memory_db, "INSERT OR IGNORE INTO hosts (name) VALUES %s" % known_hosts.map { "(?)" }.join(", ")).execute(known_hosts)
206
- end
229
+ known_hosts = all_tags.values.reduce(:+).uniq
230
+ known_hosts.each_slice(MAX_TERMS) do |known_hosts|
231
+ prepare(memory_db, "INSERT OR IGNORE INTO hosts (name) VALUES %s" % known_hosts.map { "(?)" }.join(", ")).execute(known_hosts)
232
+ end
207
233
 
208
- all_tags.each do |tag, hosts|
209
- q = []
210
- q << "INSERT OR REPLACE INTO hosts_tags (host_id, tag_id)"
211
- q << "SELECT host.id, tag.id FROM"
212
- q << "( SELECT id FROM hosts WHERE name IN (%s) ) AS host,"
213
- q << "( SELECT id FROM tags WHERE name = ? AND value = ? LIMIT 1 ) AS tag;"
214
- unless hosts.empty?
215
- prepare(memory_db, q.join(" ") % hosts.map { "?" }.join(", ")).execute(hosts + split_tag(tag))
234
+ all_tags.each do |tag, hosts|
235
+ q = []
236
+ q << "INSERT OR REPLACE INTO hosts_tags (host_id, tag_id)"
237
+ q << "SELECT host.id, tag.id FROM"
238
+ q << "( SELECT id FROM hosts WHERE name IN (%s) ) AS host,"
239
+ q << "( SELECT id FROM tags WHERE name = ? AND value = ? LIMIT 1 ) AS tag;"
240
+ hosts.each_slice(MAX_TERMS) do |hosts|
241
+ prepare(memory_db, q.join(" ") % hosts.map { "?" }.join(", ")).execute(hosts + split_tag(tag))
242
+ end
216
243
  end
217
244
  end
218
245
 
@@ -265,13 +292,19 @@ module Hotdog
265
292
  create_table_hosts_tags(dst)
266
293
 
267
294
  hosts = prepare(src, "SELECT id, name FROM hosts").execute().to_a
268
- prepare(dst, "INSERT INTO hosts (id, name) VALUES %s" % hosts.map { "(?, ?)" }.join(", ")).execute(hosts) unless hosts.empty?
295
+ hosts.each_slice(MAX_TERMS) do |hosts|
296
+ prepare(dst, "INSERT INTO hosts (id, name) VALUES %s" % hosts.map { "(?, ?)" }.join(", ")).execute(hosts)
297
+ end
269
298
 
270
299
  tags = prepare(src, "SELECT id, name, value FROM tags").execute().to_a
271
- prepare(dst, "INSERT INTO tags (id, name, value) VALUES %s" % tags.map { "(?, ?, ?)" }.join(", ")).execute(tags) unless tags.empty?
300
+ tags.each_slice(MAX_TERMS) do |tags|
301
+ prepare(dst, "INSERT INTO tags (id, name, value) VALUES %s" % tags.map { "(?, ?, ?)" }.join(", ")).execute(tags)
302
+ end
272
303
 
273
304
  hosts_tags = prepare(src, "SELECT host_id, tag_id FROM hosts_tags").to_a
274
- prepare(dst, "INSERT INTO hosts_tags (host_id, tag_id) VALUES %s" % hosts_tags.map { "(?, ?)" }.join(", ")).execute(hosts_tags) unless hosts_tags.empty?
305
+ hosts_tags.each_slice(MAX_TERMS) do |hosts_tags|
306
+ prepare(dst, "INSERT INTO hosts_tags (host_id, tag_id) VALUES %s" % hosts_tags.map { "(?, ?)" }.join(", ")).execute(hosts_tags)
307
+ end
275
308
 
276
309
  create_index_hosts(dst)
277
310
  create_index_tags(dst)
@@ -1,3 +1,3 @@
1
1
  module Hotdog
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hotdog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yamashita Yuu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-04 00:00:00.000000000 Z
11
+ date: 2015-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler