droonga-engine 1.0.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.
Files changed (341) hide show
  1. data/.dir-locals.el +3 -0
  2. data/.gitignore +6 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +7 -0
  5. data/Gemfile +66 -0
  6. data/LICENSE.txt +14 -0
  7. data/README.md +17 -0
  8. data/Rakefile +64 -0
  9. data/benchmark/benchmark.rb +123 -0
  10. data/benchmark/utils.rb +246 -0
  11. data/benchmark/watch/benchmark-notify.rb +143 -0
  12. data/benchmark/watch/benchmark-notify.sh +20 -0
  13. data/benchmark/watch/benchmark-publish.rb +120 -0
  14. data/benchmark/watch/benchmark-scan.rb +213 -0
  15. data/bin/droonga-catalog-generate +103 -0
  16. data/bin/droonga-engine +20 -0
  17. data/bin/droonga-engine-service +20 -0
  18. data/doc/text/news.md +106 -0
  19. data/droonga-engine.gemspec +52 -0
  20. data/lib/droonga/adapter.rb +48 -0
  21. data/lib/droonga/adapter_runner.rb +104 -0
  22. data/lib/droonga/catalog/base.rb +41 -0
  23. data/lib/droonga/catalog/collection_volume.rb +106 -0
  24. data/lib/droonga/catalog/dataset.rb +69 -0
  25. data/lib/droonga/catalog/errors.rb +113 -0
  26. data/lib/droonga/catalog/schema.rb +186 -0
  27. data/lib/droonga/catalog/single_volume.rb +28 -0
  28. data/lib/droonga/catalog/slice.rb +41 -0
  29. data/lib/droonga/catalog/version1.rb +427 -0
  30. data/lib/droonga/catalog/version2.rb +96 -0
  31. data/lib/droonga/catalog/version2_validator.rb +63 -0
  32. data/lib/droonga/catalog/volume.rb +33 -0
  33. data/lib/droonga/catalog/volume_collection.rb +56 -0
  34. data/lib/droonga/catalog_generator.rb +156 -0
  35. data/lib/droonga/catalog_loader.rb +56 -0
  36. data/lib/droonga/catalog_observer.rb +83 -0
  37. data/lib/droonga/collector.rb +38 -0
  38. data/lib/droonga/collector_message.rb +71 -0
  39. data/lib/droonga/collector_runner.rb +64 -0
  40. data/lib/droonga/collectors/and.rb +26 -0
  41. data/lib/droonga/collectors/or.rb +26 -0
  42. data/lib/droonga/collectors/sum.rb +26 -0
  43. data/lib/droonga/collectors.rb +18 -0
  44. data/lib/droonga/dispatcher.rb +326 -0
  45. data/lib/droonga/distributed_command_planner.rb +179 -0
  46. data/lib/droonga/distributor.rb +87 -0
  47. data/lib/droonga/engine/command/droonga_engine.rb +441 -0
  48. data/lib/droonga/engine/version.rb +20 -0
  49. data/lib/droonga/engine.rb +80 -0
  50. data/lib/droonga/engine_state.rb +79 -0
  51. data/lib/droonga/error.rb +73 -0
  52. data/lib/droonga/error_messages.rb +33 -0
  53. data/lib/droonga/event_loop.rb +46 -0
  54. data/lib/droonga/farm.rb +58 -0
  55. data/lib/droonga/fluent_message_receiver.rb +191 -0
  56. data/lib/droonga/fluent_message_sender.rb +140 -0
  57. data/lib/droonga/forwarder.rb +119 -0
  58. data/lib/droonga/handler.rb +49 -0
  59. data/lib/droonga/handler_message.rb +61 -0
  60. data/lib/droonga/handler_messenger.rb +119 -0
  61. data/lib/droonga/handler_runner.rb +125 -0
  62. data/lib/droonga/input_message.rb +51 -0
  63. data/lib/droonga/job_protocol.rb +20 -0
  64. data/lib/droonga/job_pusher.rb +179 -0
  65. data/lib/droonga/job_receiver.rb +70 -0
  66. data/lib/droonga/loggable.rb +29 -0
  67. data/lib/droonga/logger.rb +142 -0
  68. data/lib/droonga/message_matcher.rb +109 -0
  69. data/lib/droonga/output_message.rb +55 -0
  70. data/lib/droonga/planner.rb +47 -0
  71. data/lib/droonga/pluggable.rb +31 -0
  72. data/lib/droonga/plugin/metadata/adapter_input_message.rb +39 -0
  73. data/lib/droonga/plugin/metadata/adapter_output_message.rb +39 -0
  74. data/lib/droonga/plugin/metadata/collector_message.rb +39 -0
  75. data/lib/droonga/plugin/metadata/handler_action.rb +39 -0
  76. data/lib/droonga/plugin/metadata/input_message.rb +54 -0
  77. data/lib/droonga/plugin.rb +43 -0
  78. data/lib/droonga/plugin_loader.rb +63 -0
  79. data/lib/droonga/plugin_registry.rb +66 -0
  80. data/lib/droonga/plugins/basic.rb +54 -0
  81. data/lib/droonga/plugins/crud.rb +145 -0
  82. data/lib/droonga/plugins/dump.rb +97 -0
  83. data/lib/droonga/plugins/error.rb +51 -0
  84. data/lib/droonga/plugins/groonga/column_create.rb +123 -0
  85. data/lib/droonga/plugins/groonga/column_list.rb +124 -0
  86. data/lib/droonga/plugins/groonga/column_remove.rb +65 -0
  87. data/lib/droonga/plugins/groonga/column_rename.rb +67 -0
  88. data/lib/droonga/plugins/groonga/delete.rb +117 -0
  89. data/lib/droonga/plugins/groonga/generic_command.rb +105 -0
  90. data/lib/droonga/plugins/groonga/generic_response.rb +43 -0
  91. data/lib/droonga/plugins/groonga/select.rb +236 -0
  92. data/lib/droonga/plugins/groonga/table_create.rb +111 -0
  93. data/lib/droonga/plugins/groonga/table_list.rb +120 -0
  94. data/lib/droonga/plugins/groonga/table_remove.rb +57 -0
  95. data/lib/droonga/plugins/groonga.rb +37 -0
  96. data/lib/droonga/plugins/search/distributed_search_planner.rb +407 -0
  97. data/lib/droonga/plugins/search.rb +146 -0
  98. data/lib/droonga/plugins/watch.rb +178 -0
  99. data/lib/droonga/processor.rb +63 -0
  100. data/lib/droonga/reducer.rb +169 -0
  101. data/lib/droonga/replier.rb +49 -0
  102. data/lib/droonga/schema_applier.rb +167 -0
  103. data/lib/droonga/searcher/mecab_filter.rb +67 -0
  104. data/lib/droonga/searcher.rb +733 -0
  105. data/lib/droonga/server.rb +45 -0
  106. data/lib/droonga/session.rb +99 -0
  107. data/lib/droonga/single_step.rb +68 -0
  108. data/lib/droonga/single_step_definition.rb +54 -0
  109. data/lib/droonga/slice.rb +122 -0
  110. data/lib/droonga/status_code.rb +25 -0
  111. data/lib/droonga/step_runner.rb +64 -0
  112. data/lib/droonga/sweeper.rb +42 -0
  113. data/lib/droonga/test/stub_handler.rb +37 -0
  114. data/lib/droonga/test/stub_handler_message.rb +35 -0
  115. data/lib/droonga/test/stub_handler_messenger.rb +34 -0
  116. data/lib/droonga/test/stub_planner.rb +31 -0
  117. data/lib/droonga/test.rb +21 -0
  118. data/lib/droonga/watch_schema.rb +92 -0
  119. data/lib/droonga/watcher.rb +257 -0
  120. data/lib/droonga/worker.rb +61 -0
  121. data/sample/cluster/catalog.json +42 -0
  122. data/sample/mecab_filter/data.grn +7 -0
  123. data/sample/mecab_filter/ddl.grn +7 -0
  124. data/sample/mecab_filter/search_with_mecab_filter.json +21 -0
  125. data/sample/mecab_filter/search_without_mecab_filter.json +21 -0
  126. data/test/command/config/default/catalog.json +85 -0
  127. data/test/command/config/default/fluentd.conf +11 -0
  128. data/test/command/config/version1/catalog.json +68 -0
  129. data/test/command/config/version1/fluentd.conf +11 -0
  130. data/test/command/fixture/documents.jsons +208 -0
  131. data/test/command/fixture/event.jsons +41 -0
  132. data/test/command/fixture/user-table-array.jsons +38 -0
  133. data/test/command/fixture/user-table.jsons +47 -0
  134. data/test/command/run-test.rb +34 -0
  135. data/test/command/suite/add/dimension/column.catalog.json +28 -0
  136. data/test/command/suite/add/dimension/column.expected +41 -0
  137. data/test/command/suite/add/dimension/column.test +51 -0
  138. data/test/command/suite/add/dimension/integer.catalog.json +19 -0
  139. data/test/command/suite/add/dimension/integer.expected +41 -0
  140. data/test/command/suite/add/dimension/integer.test +51 -0
  141. data/test/command/suite/add/error/invalid-integer.expected +46 -0
  142. data/test/command/suite/add/error/invalid-integer.test +12 -0
  143. data/test/command/suite/add/error/invalid-time.expected +46 -0
  144. data/test/command/suite/add/error/invalid-time.test +12 -0
  145. data/test/command/suite/add/error/missing-key.expected +25 -0
  146. data/test/command/suite/add/error/missing-key.test +16 -0
  147. data/test/command/suite/add/error/missing-table.expected +25 -0
  148. data/test/command/suite/add/error/missing-table.test +16 -0
  149. data/test/command/suite/add/error/unknown-column.expected +46 -0
  150. data/test/command/suite/add/error/unknown-column.test +12 -0
  151. data/test/command/suite/add/error/unknown-table.expected +25 -0
  152. data/test/command/suite/add/error/unknown-table.test +17 -0
  153. data/test/command/suite/add/minimum.expected +6 -0
  154. data/test/command/suite/add/minimum.test +11 -0
  155. data/test/command/suite/add/with-values.expected +6 -0
  156. data/test/command/suite/add/with-values.test +17 -0
  157. data/test/command/suite/add/without-key.expected +6 -0
  158. data/test/command/suite/add/without-key.test +16 -0
  159. data/test/command/suite/groonga/column_create/scalar.expected +26 -0
  160. data/test/command/suite/groonga/column_create/scalar.test +17 -0
  161. data/test/command/suite/groonga/column_create/unknown-table.expected +14 -0
  162. data/test/command/suite/groonga/column_create/unknown-table.test +7 -0
  163. data/test/command/suite/groonga/column_create/vector.expected +26 -0
  164. data/test/command/suite/groonga/column_create/vector.test +18 -0
  165. data/test/command/suite/groonga/column_list/success.expected +86 -0
  166. data/test/command/suite/groonga/column_list/success.test +24 -0
  167. data/test/command/suite/groonga/column_list/unknown-table.expected +13 -0
  168. data/test/command/suite/groonga/column_list/unknown-table.test +7 -0
  169. data/test/command/suite/groonga/column_remove/success.expected +39 -0
  170. data/test/command/suite/groonga/column_remove/success.test +25 -0
  171. data/test/command/suite/groonga/column_remove/unknown-column.expected +27 -0
  172. data/test/command/suite/groonga/column_remove/unknown-column.test +16 -0
  173. data/test/command/suite/groonga/column_remove/unknown-table.expected +14 -0
  174. data/test/command/suite/groonga/column_remove/unknown-table.test +7 -0
  175. data/test/command/suite/groonga/column_rename/success.expected +39 -0
  176. data/test/command/suite/groonga/column_rename/success.test +26 -0
  177. data/test/command/suite/groonga/column_rename/unknown-column.expected +27 -0
  178. data/test/command/suite/groonga/column_rename/unknown-column.test +16 -0
  179. data/test/command/suite/groonga/column_rename/unknown-table.expected +14 -0
  180. data/test/command/suite/groonga/column_rename/unknown-table.test +7 -0
  181. data/test/command/suite/groonga/delete/duplicated-identifiers.expected +27 -0
  182. data/test/command/suite/groonga/delete/duplicated-identifiers.test +17 -0
  183. data/test/command/suite/groonga/delete/filter.expected +19 -0
  184. data/test/command/suite/groonga/delete/filter.test +19 -0
  185. data/test/command/suite/groonga/delete/invalid-filter.expected +14 -0
  186. data/test/command/suite/groonga/delete/invalid-filter.test +9 -0
  187. data/test/command/suite/groonga/delete/no-identifier.expected +27 -0
  188. data/test/command/suite/groonga/delete/no-identifier.test +15 -0
  189. data/test/command/suite/groonga/delete/success.expected +19 -0
  190. data/test/command/suite/groonga/delete/success.test +19 -0
  191. data/test/command/suite/groonga/delete/unknown-table.expected +14 -0
  192. data/test/command/suite/groonga/delete/unknown-table.test +7 -0
  193. data/test/command/suite/groonga/select/minimum.expected +22 -0
  194. data/test/command/suite/groonga/select/minimum.test +8 -0
  195. data/test/command/suite/groonga/table_create/array.expected +14 -0
  196. data/test/command/suite/groonga/table_create/array.test +8 -0
  197. data/test/command/suite/groonga/table_create/hash.expected +13 -0
  198. data/test/command/suite/groonga/table_create/hash.test +8 -0
  199. data/test/command/suite/groonga/table_list/success.expected +71 -0
  200. data/test/command/suite/groonga/table_list/success.test +15 -0
  201. data/test/command/suite/groonga/table_remove/success.expected +13 -0
  202. data/test/command/suite/groonga/table_remove/success.test +8 -0
  203. data/test/command/suite/groonga/table_remove/unknown-table.expected +14 -0
  204. data/test/command/suite/groonga/table_remove/unknown-table.test +7 -0
  205. data/test/command/suite/message/error/missing-dataset.expected +9 -0
  206. data/test/command/suite/message/error/missing-dataset.test +5 -0
  207. data/test/command/suite/message/error/unknown-dataset.expected +9 -0
  208. data/test/command/suite/message/error/unknown-dataset.test +6 -0
  209. data/test/command/suite/message/error/unknown-type.expected +9 -0
  210. data/test/command/suite/message/error/unknown-type.test +6 -0
  211. data/test/command/suite/search/adjusters/multiple.catalog.json +38 -0
  212. data/test/command/suite/search/adjusters/multiple.expected +19 -0
  213. data/test/command/suite/search/adjusters/multiple.test +75 -0
  214. data/test/command/suite/search/adjusters/one.catalog.json +38 -0
  215. data/test/command/suite/search/adjusters/one.expected +19 -0
  216. data/test/command/suite/search/adjusters/one.test +66 -0
  217. data/test/command/suite/search/attributes/array.expected +21 -0
  218. data/test/command/suite/search/attributes/array.test +28 -0
  219. data/test/command/suite/search/attributes/hash.expected +30 -0
  220. data/test/command/suite/search/attributes/hash.test +36 -0
  221. data/test/command/suite/search/complex.expected +48 -0
  222. data/test/command/suite/search/complex.test +23 -0
  223. data/test/command/suite/search/condition/nested.expected +15 -0
  224. data/test/command/suite/search/condition/nested.test +27 -0
  225. data/test/command/suite/search/condition/query/nonexistent_column.catalog.json +37 -0
  226. data/test/command/suite/search/condition/query/nonexistent_column.expected +48 -0
  227. data/test/command/suite/search/condition/query/nonexistent_column.test +33 -0
  228. data/test/command/suite/search/condition/query/syntax_error.catalog.json +36 -0
  229. data/test/command/suite/search/condition/query/syntax_error.expected +48 -0
  230. data/test/command/suite/search/condition/query/syntax_error.test +33 -0
  231. data/test/command/suite/search/condition/query.expected +24 -0
  232. data/test/command/suite/search/condition/query.test +23 -0
  233. data/test/command/suite/search/condition/script.expected +24 -0
  234. data/test/command/suite/search/condition/script.test +26 -0
  235. data/test/command/suite/search/error/cyclic-source.expected +14 -0
  236. data/test/command/suite/search/error/cyclic-source.test +12 -0
  237. data/test/command/suite/search/error/deeply-cyclic-source.expected +17 -0
  238. data/test/command/suite/search/error/deeply-cyclic-source.test +15 -0
  239. data/test/command/suite/search/error/missing-source-parameter.expected +13 -0
  240. data/test/command/suite/search/error/missing-source-parameter.test +11 -0
  241. data/test/command/suite/search/error/no-query.expected +9 -0
  242. data/test/command/suite/search/error/no-query.test +7 -0
  243. data/test/command/suite/search/error/unknown-source.expected +52 -0
  244. data/test/command/suite/search/error/unknown-source.test +12 -0
  245. data/test/command/suite/search/group/count.expected +10 -0
  246. data/test/command/suite/search/group/count.test +18 -0
  247. data/test/command/suite/search/group/limit.expected +15 -0
  248. data/test/command/suite/search/group/limit.test +20 -0
  249. data/test/command/suite/search/group/string.expected +32 -0
  250. data/test/command/suite/search/group/string.test +40 -0
  251. data/test/command/suite/search/group/subrecord/with-sort.catalog.json +33 -0
  252. data/test/command/suite/search/group/subrecord/with-sort.expected +30 -0
  253. data/test/command/suite/search/group/subrecord/with-sort.test +81 -0
  254. data/test/command/suite/search/multiple/chained.expected +41 -0
  255. data/test/command/suite/search/multiple/chained.test +39 -0
  256. data/test/command/suite/search/multiple/parallel.expected +35 -0
  257. data/test/command/suite/search/multiple/parallel.test +35 -0
  258. data/test/command/suite/search/output/attributes/invalid.catalog.json +13 -0
  259. data/test/command/suite/search/output/attributes/invalid.expected +44 -0
  260. data/test/command/suite/search/output/attributes/invalid.test +28 -0
  261. data/test/command/suite/search/range/only-output.expected +24 -0
  262. data/test/command/suite/search/range/only-output.test +23 -0
  263. data/test/command/suite/search/range/only-sort.expected +24 -0
  264. data/test/command/suite/search/range/only-sort.test +26 -0
  265. data/test/command/suite/search/range/sort-and-output.expected +21 -0
  266. data/test/command/suite/search/range/sort-and-output.test +27 -0
  267. data/test/command/suite/search/range/too-large-output-offset.expected +12 -0
  268. data/test/command/suite/search/range/too-large-output-offset.test +23 -0
  269. data/test/command/suite/search/range/too-large-sort-offset.expected +12 -0
  270. data/test/command/suite/search/range/too-large-sort-offset.test +26 -0
  271. data/test/command/suite/search/response/elapsed_time.catalog.json +13 -0
  272. data/test/command/suite/search/response/elapsed_time.expected +11 -0
  273. data/test/command/suite/search/response/elapsed_time.test +26 -0
  274. data/test/command/suite/search/response/records/value/time.expected +20 -0
  275. data/test/command/suite/search/response/records/value/time.test +22 -0
  276. data/test/command/suite/search/simple.expected +48 -0
  277. data/test/command/suite/search/simple.test +22 -0
  278. data/test/command/suite/search/sort/default-offset-limit.expected +39 -0
  279. data/test/command/suite/search/sort/default-offset-limit.test +24 -0
  280. data/test/command/suite/search/sort/invisible-column.expected +24 -0
  281. data/test/command/suite/search/sort/invisible-column.test +26 -0
  282. data/test/command/suite/watch/subscribe.expected +6 -0
  283. data/test/command/suite/watch/subscribe.test +9 -0
  284. data/test/command/suite/watch/unsubscribe.expected +6 -0
  285. data/test/command/suite/watch/unsubscribe.test +9 -0
  286. data/test/performance/run-test.rb +56 -0
  287. data/test/performance/watch/catalog.json +33 -0
  288. data/test/performance/watch/feed.json +9 -0
  289. data/test/performance/watch/fluentd.conf +11 -0
  290. data/test/performance/watch/subscribe.json +3 -0
  291. data/test/unit/catalog/test_collection_volume.rb +103 -0
  292. data/test/unit/catalog/test_dataset.rb +104 -0
  293. data/test/unit/catalog/test_schema.rb +226 -0
  294. data/test/unit/catalog/test_single_volume.rb +31 -0
  295. data/test/unit/catalog/test_slice.rb +92 -0
  296. data/test/unit/catalog/test_version1.rb +361 -0
  297. data/test/unit/catalog/test_version2.rb +124 -0
  298. data/test/unit/catalog/test_version2_validator.rb +66 -0
  299. data/test/unit/catalog/test_volume_collection.rb +50 -0
  300. data/test/unit/fixtures/array.grn +18 -0
  301. data/test/unit/fixtures/catalog/version1.json +40 -0
  302. data/test/unit/fixtures/catalog/version2.json +62 -0
  303. data/test/unit/fixtures/document.grn +34 -0
  304. data/test/unit/fixtures/reference/array.grn +11 -0
  305. data/test/unit/fixtures/reference/hash.grn +7 -0
  306. data/test/unit/helper/distributed_search_planner_helper.rb +83 -0
  307. data/test/unit/helper/fixture.rb +28 -0
  308. data/test/unit/helper/plugin_helper.rb +38 -0
  309. data/test/unit/helper/sandbox.rb +86 -0
  310. data/test/unit/helper/stub_worker.rb +27 -0
  311. data/test/unit/helper/watch_helper.rb +23 -0
  312. data/test/unit/helper.rb +28 -0
  313. data/test/unit/plugins/crud/test_add.rb +190 -0
  314. data/test/unit/plugins/groonga/select/test_adapter_input.rb +510 -0
  315. data/test/unit/plugins/groonga/select/test_adapter_output.rb +201 -0
  316. data/test/unit/plugins/groonga/test_column_create.rb +171 -0
  317. data/test/unit/plugins/groonga/test_column_list.rb +170 -0
  318. data/test/unit/plugins/groonga/test_column_remove.rb +98 -0
  319. data/test/unit/plugins/groonga/test_column_rename.rb +105 -0
  320. data/test/unit/plugins/groonga/test_delete.rb +127 -0
  321. data/test/unit/plugins/groonga/test_table_create.rb +147 -0
  322. data/test/unit/plugins/groonga/test_table_list.rb +184 -0
  323. data/test/unit/plugins/groonga/test_table_remove.rb +61 -0
  324. data/test/unit/plugins/search/planner/test_basic.rb +120 -0
  325. data/test/unit/plugins/search/planner/test_group_by.rb +573 -0
  326. data/test/unit/plugins/search/planner/test_output.rb +388 -0
  327. data/test/unit/plugins/search/planner/test_sort_by.rb +938 -0
  328. data/test/unit/plugins/search/test_collector.rb +806 -0
  329. data/test/unit/plugins/search/test_handler.rb +930 -0
  330. data/test/unit/plugins/search/test_planner.rb +174 -0
  331. data/test/unit/plugins/test_basic.rb +510 -0
  332. data/test/unit/plugins/test_groonga.rb +70 -0
  333. data/test/unit/plugins/test_watch.rb +211 -0
  334. data/test/unit/run-test.rb +56 -0
  335. data/test/unit/test_catalog_generator.rb +93 -0
  336. data/test/unit/test_message_matcher.rb +160 -0
  337. data/test/unit/test_schema_applier.rb +59 -0
  338. data/test/unit/test_sweeper.rb +95 -0
  339. data/test/unit/test_watch_schema.rb +57 -0
  340. data/test/unit/test_watcher.rb +336 -0
  341. metadata +759 -0
@@ -0,0 +1,95 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 Droonga Project
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ require "droonga/watcher"
19
+ require "droonga/sweeper"
20
+
21
+ class SweeperTest < Test::Unit::TestCase
22
+ include WatchHelper
23
+
24
+ def setup
25
+ setup_database
26
+ setup_schema
27
+ @context = Groonga::Context.default
28
+ @watcher = Droonga::Watcher.new(@context)
29
+ @sweeper = Droonga::Sweeper.new(@context)
30
+ end
31
+
32
+ def teardown
33
+ @watcher = nil
34
+ @sweeper = nil
35
+ teardown_database
36
+ end
37
+
38
+ private
39
+ def subscriber_table
40
+ @context["Subscriber"]
41
+ end
42
+
43
+ def existing_subscribers
44
+ subscriber_table.select.collect(&:_key)
45
+ end
46
+
47
+ public
48
+ class SweepSubscribersTest < self
49
+ NINE_MINUTES_IN_SECONDS = 9 * 60
50
+ TEN_MINUTES_IN_SECONDS = 10 * 60
51
+ ELEVEN_MINUTES_IN_SECONDS = 11 * 60
52
+
53
+ def setup
54
+ super
55
+ @now = Time.now
56
+ setup_expired_subscribers
57
+ end
58
+
59
+ def test_single_term
60
+ @sweeper.sweep_expired_subscribers(:now => @now)
61
+ assert_equal(
62
+ ["subscriber1", "subscriber2"],
63
+ existing_subscribers
64
+ )
65
+ end
66
+
67
+ private
68
+ def setup_expired_subscribers
69
+ request1 = {
70
+ :route => "localhost:23003/output",
71
+ :condition => "たいやき",
72
+ :query => "たいやき".to_json,
73
+ :subscriber => "subscriber1",
74
+ }
75
+ @watcher.subscribe(request1)
76
+ request2 = {
77
+ :route => "localhost:23003/output",
78
+ :condition => "たいやき",
79
+ :query => "たいやき".to_json,
80
+ :subscriber => "subscriber2",
81
+ }
82
+ @watcher.subscribe(request2)
83
+ request3 = {
84
+ :route => "localhost:23003/output",
85
+ :condition => "たいやき",
86
+ :query => "たいやき".to_json,
87
+ :subscriber => "subscriber3",
88
+ }
89
+ @watcher.subscribe(request3)
90
+ subscriber_table["subscriber1"].last_modified = @now - NINE_MINUTES_IN_SECONDS
91
+ subscriber_table["subscriber2"].last_modified = @now - TEN_MINUTES_IN_SECONDS
92
+ subscriber_table["subscriber3"].last_modified = @now - ELEVEN_MINUTES_IN_SECONDS
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,57 @@
1
+ # Copyright (C) 2013 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ require "helper"
17
+
18
+ require "droonga/watch_schema"
19
+
20
+ class WatchSchemaTest < Test::Unit::TestCase
21
+ def setup
22
+ @database_path = @temporary_directory + "droonga/watch/db"
23
+ @context = Groonga::Context.default
24
+ FileUtils.mkdir_p(File.dirname(@database_path))
25
+ @context.create_database(@database_path.to_s)
26
+ end
27
+
28
+ def test_ensure_created
29
+ schema = Droonga::WatchSchema.new(@context)
30
+ schema.ensure_created
31
+
32
+ dumped_commands = nil
33
+ @context.open_database(@database_path.to_s) do |database|
34
+ dumped_commands = Groonga::DatabaseDumper.dump(:context => @context,
35
+ :database => database)
36
+ end
37
+ assert_equal(<<-SCHEMA, dumped_commands)
38
+ table_create Keyword TABLE_PAT_KEY --key_type ShortText --normalizer NormalizerAuto
39
+
40
+ table_create Query TABLE_HASH_KEY --key_type ShortText
41
+
42
+ table_create Route TABLE_HASH_KEY --key_type ShortText
43
+
44
+ table_create Subscriber TABLE_HASH_KEY --key_type ShortText
45
+ column_create Subscriber last_modified COLUMN_SCALAR Time
46
+
47
+ column_create Query keywords COLUMN_VECTOR Keyword
48
+
49
+ column_create Subscriber route COLUMN_SCALAR Route
50
+ column_create Subscriber subscriptions COLUMN_VECTOR Query
51
+
52
+ column_create Keyword queries COLUMN_INDEX Query keywords
53
+
54
+ column_create Query subscribers COLUMN_INDEX Subscriber subscriptions
55
+ SCHEMA
56
+ end
57
+ end
@@ -0,0 +1,336 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 Droonga Project
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ require "droonga/watcher"
19
+
20
+ class WatcherTest < Test::Unit::TestCase
21
+ include WatchHelper
22
+
23
+ def setup
24
+ setup_database
25
+ setup_schema
26
+ setup_watcher
27
+ end
28
+
29
+ def teardown
30
+ teardown_watcher
31
+ teardown_database
32
+ end
33
+
34
+ private
35
+ def setup_watcher
36
+ @context = Groonga::Context.default
37
+ @watcher = Droonga::Watcher.new(@context)
38
+ end
39
+
40
+ def teardown_watcher
41
+ @watcher = nil
42
+ end
43
+
44
+ def subscriber_table
45
+ @context["Subscriber"]
46
+ end
47
+
48
+ def query_table
49
+ @context["Query"]
50
+ end
51
+
52
+ def keyword_table
53
+ @context["Keyword"]
54
+ end
55
+
56
+ def existing_subscribers
57
+ subscriber_table.select.collect(&:_key)
58
+ end
59
+
60
+ def existing_queries
61
+ query_table.select.collect(&:_key)
62
+ end
63
+
64
+ def existing_keywords
65
+ keyword_table.select.collect(&:_key)
66
+ end
67
+
68
+ def existing_records
69
+ {
70
+ :subscribers => existing_subscribers,
71
+ :queries => existing_queries,
72
+ :keywords => existing_keywords,
73
+ }
74
+ end
75
+
76
+ def normalize_subscriber(subscriber)
77
+ return nil if subscriber.nil?
78
+ {
79
+ :_key => subscriber._key,
80
+ :subscriptions => subscriber.subscriptions.collect(&:_key),
81
+ :route => subscriber.route._key,
82
+ }
83
+ end
84
+
85
+ def normalize_queries(queries)
86
+ return nil if queries.nil?
87
+ queries.collect do |query|
88
+ normalize_query(query)
89
+ end
90
+ end
91
+
92
+ def normalize_query(query)
93
+ return nil if query.nil?
94
+ {
95
+ :_key => query._key,
96
+ :keywords => query.keywords.collect(&:_key),
97
+ }
98
+ end
99
+
100
+ public
101
+ class SubscribeTest < self
102
+ def test_single_term
103
+ request = {
104
+ :route => "localhost:23003/output",
105
+ :condition => "たいやき",
106
+ :query => "たいやき".to_json,
107
+ :subscriber => "localhost",
108
+ }
109
+ @watcher.subscribe(request)
110
+
111
+ assert_equal(
112
+ {:subscribers => ["localhost"],
113
+ :queries => ["たいやき".to_json],
114
+ :keywords => ["たいやき"]},
115
+ existing_records
116
+ )
117
+ assert_equal(
118
+ {:_key => "localhost",
119
+ :subscriptions => ["たいやき".to_json],
120
+ :route => "localhost:23003/output"},
121
+ normalize_subscriber(subscriber_table.first)
122
+ )
123
+ assert_equal(
124
+ [{:_key => "たいやき".to_json, :keywords => ["たいやき"]}],
125
+ normalize_queries(subscriber_table.first.subscriptions)
126
+ )
127
+ end
128
+
129
+ =begin
130
+ # this test will be activated when condition with multiple tabs is supproted.
131
+ def test_multiple_terms
132
+ request = {
133
+ :route => "localhost:23003/output",
134
+ :condition => "たいやき たこやき",
135
+ :query => "たいやき たこやき".to_json,
136
+ :subscriber => "localhost",
137
+ }
138
+ @watcher.subscribe(request)
139
+
140
+ assert_equal(["localhost"], existing_subscribers)
141
+ assert_equal(
142
+ {:_key => "localhost",
143
+ :subscriptions => ["たいやき たこやき".to_json],
144
+ :route => "localhost:23003/output"},
145
+ normalize_subscriber(subscriber_table.first)
146
+ )
147
+ assert_equal(["たいやき たこやき".to_json], existing_queries)
148
+ assert_equal(["たいやき", "たこやき"], existing_keywords)
149
+ end
150
+ =end
151
+
152
+ def test_same_condition_multiple_times
153
+ request = {
154
+ :route => "localhost:23003/output",
155
+ :condition => "たいやき",
156
+ :query => "たいやき".to_json,
157
+ :subscriber => "localhost",
158
+ }
159
+ @watcher.subscribe(request)
160
+ @watcher.subscribe(request)
161
+ assert_equal(
162
+ {:subscribers => ["localhost"],
163
+ :queries => ["たいやき".to_json],
164
+ :keywords => ["たいやき"]},
165
+ existing_records
166
+ )
167
+ end
168
+
169
+ def test_different_conditions
170
+ request1 = {
171
+ :route => "localhost:23003/output",
172
+ :condition => "たいやき",
173
+ :query => "たいやき".to_json,
174
+ :subscriber => "localhost",
175
+ }
176
+ @watcher.subscribe(request1)
177
+ request2 = {
178
+ :route => "localhost:23003/output",
179
+ :condition => "たこやき",
180
+ :query => "たこやき".to_json,
181
+ :subscriber => "localhost",
182
+ }
183
+ @watcher.subscribe(request2)
184
+ assert_equal(
185
+ {:subscribers => ["localhost"],
186
+ :queries => ["たいやき".to_json, "たこやき".to_json],
187
+ :keywords => ["たいやき", "たこやき"]},
188
+ existing_records
189
+ )
190
+ assert_equal(
191
+ {:_key => "localhost",
192
+ :subscriptions => ["たいやき".to_json, "たこやき".to_json],
193
+ :route => "localhost:23003/output"},
194
+ normalize_subscriber(subscriber_table.first)
195
+ )
196
+ end
197
+
198
+ def test_multiple_subscribers
199
+ request = {
200
+ :route => "localhost:23003/output",
201
+ :condition => "たいやき",
202
+ :query => "たいやき".to_json,
203
+ :subscriber => "subscriber1",
204
+ }
205
+ @watcher.subscribe(request)
206
+ request = {
207
+ :route => "localhost:23003/output",
208
+ :condition => "たこやき",
209
+ :query => "たこやき".to_json,
210
+ :subscriber => "subscriber2",
211
+ }
212
+ @watcher.subscribe(request)
213
+ assert_equal(
214
+ {:subscribers => ["subscriber1", "subscriber2"],
215
+ :queries => ["たいやき".to_json, "たこやき".to_json],
216
+ :keywords => ["たいやき", "たこやき"]},
217
+ existing_records
218
+ )
219
+ assert_equal([["たいやき".to_json],
220
+ ["たこやき".to_json]],
221
+ [subscriber_table["subscriber1"].subscriptions.collect(&:_key),
222
+ subscriber_table["subscriber2"].subscriptions.collect(&:_key)])
223
+ end
224
+ end
225
+
226
+ class UnsubscribeTest < self
227
+ def setup
228
+ super
229
+ setup_subscriptions
230
+ end
231
+
232
+ def test_with_query_multiple_times
233
+ @watcher.unsubscribe(
234
+ :route => "localhost:23003/output",
235
+ :query => "たいやき".to_json,
236
+ :subscriber => "subscriber1",
237
+ )
238
+ assert_equal(
239
+ {:subscribers => ["subscriber1", "subscriber2"],
240
+ :queries => ["たいやき".to_json, "たこやき".to_json],
241
+ :keywords => ["たいやき", "たこやき"]},
242
+ existing_records
243
+ )
244
+
245
+ @watcher.unsubscribe(
246
+ :route => "localhost:23003/output",
247
+ :query => "たこやき".to_json,
248
+ :subscriber => "subscriber1",
249
+ )
250
+ assert_equal(
251
+ {:subscribers => ["subscriber2"],
252
+ :queries => ["たいやき".to_json, "たこやき".to_json],
253
+ :keywords => ["たいやき", "たこやき"]},
254
+ existing_records
255
+ )
256
+ end
257
+
258
+ def test_with_query_watched_by_multiple_subscribers
259
+ @watcher.unsubscribe(
260
+ :route => "localhost:23003/output",
261
+ :query => "たいやき".to_json,
262
+ :subscriber => "subscriber1",
263
+ )
264
+ assert_equal(
265
+ {:subscribers => ["subscriber1", "subscriber2"],
266
+ :queries => ["たいやき".to_json, "たこやき".to_json],
267
+ :keywords => ["たいやき", "たこやき"]},
268
+ existing_records
269
+ )
270
+
271
+ @watcher.unsubscribe(
272
+ :route => "localhost:23003/output",
273
+ :query => "たいやき".to_json,
274
+ :subscriber => "subscriber2",
275
+ )
276
+ assert_equal(
277
+ {:subscribers => ["subscriber1", "subscriber2"],
278
+ :queries => ["たこやき".to_json],
279
+ :keywords => ["たこやき"]},
280
+ existing_records
281
+ )
282
+ end
283
+
284
+ def test_without_query
285
+ request = {
286
+ :route => "localhost:23003/output",
287
+ :subscriber => "subscriber1",
288
+ }
289
+ @watcher.unsubscribe(request)
290
+ assert_equal(
291
+ {:subscribers => ["subscriber2"],
292
+ :queries => ["たいやき".to_json, "たこやき".to_json],
293
+ :keywords => ["たいやき", "たこやき"]},
294
+ existing_records
295
+ )
296
+ end
297
+
298
+ private
299
+ def setup_subscriptions
300
+ request1_1 = {
301
+ :route => "localhost:23003/output",
302
+ :condition => "たいやき",
303
+ :query => "たいやき".to_json,
304
+ :subscriber => "subscriber1",
305
+ }
306
+ @watcher.subscribe(request1_1)
307
+ request1_2 = {
308
+ :route => "localhost:23003/output",
309
+ :condition => "たこやき",
310
+ :query => "たこやき".to_json,
311
+ :subscriber => "subscriber1",
312
+ }
313
+ @watcher.subscribe(request1_2)
314
+ request2_1 = {
315
+ :route => "localhost:23003/output",
316
+ :condition => "たいやき",
317
+ :query => "たいやき".to_json,
318
+ :subscriber => "subscriber2",
319
+ }
320
+ @watcher.subscribe(request2_1)
321
+ request2_2 = {
322
+ :route => "localhost:23003/output",
323
+ :condition => "たこやき",
324
+ :query => "たこやき".to_json,
325
+ :subscriber => "subscriber2",
326
+ }
327
+ @watcher.subscribe(request2_2)
328
+ assert_equal(
329
+ {:subscribers => ["subscriber1", "subscriber2"],
330
+ :queries => ["たいやき".to_json, "たこやき".to_json],
331
+ :keywords => ["たいやき", "たこやき"]},
332
+ existing_records
333
+ )
334
+ end
335
+ end
336
+ end