droonga-engine 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,930 @@
1
+ # Copyright (C) 2013-2014 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 "droonga/plugins/search"
17
+
18
+ class SearchHandlerTest < Test::Unit::TestCase
19
+ def setup
20
+ setup_database
21
+ setup_data
22
+ setup_plugin
23
+ end
24
+
25
+ def teardown
26
+ teardown_plugin
27
+ teardown_database
28
+ end
29
+
30
+ def setup_plugin
31
+ @handler = Droonga::Test::StubHandler.new
32
+ @messenger = Droonga::Test::StubHandlerMessenger.new
33
+ @loop = nil
34
+ @plugin = Droonga::Plugins::Search::Handler.new("droonga",
35
+ @handler.context,
36
+ @messenger,
37
+ @loop)
38
+ end
39
+
40
+ def teardown_plugin
41
+ @handler = nil
42
+ @plugin = nil
43
+ end
44
+
45
+ private
46
+ def search(request, headers={})
47
+ message = Droonga::Test::StubHandlerMessage.new(request, headers)
48
+ results_to_result_set(@plugin.handle(message))
49
+ end
50
+
51
+ def results_to_result_set(results)
52
+ result_set = {}
53
+ results.each do |name, result|
54
+ result_set[name] = normalize_result(result)
55
+ end
56
+ result_set
57
+ end
58
+
59
+ def normalize_result(result)
60
+ result["startTime"] = start_time if result["startTime"]
61
+ result["elapsedTime"] = elapsed_time if result["elapsedTime"]
62
+ result
63
+ end
64
+
65
+ def start_time
66
+ "2013-01-31T14:34:47+09:00"
67
+ end
68
+
69
+ def elapsed_time
70
+ 0.01
71
+ end
72
+
73
+ def assert_search(expected, request)
74
+ assert_equal(expected, search(request))
75
+ end
76
+
77
+ class GeneralTest < self
78
+ def setup_data
79
+ restore(fixture_data("document.grn"))
80
+ end
81
+
82
+ class NoParameterTest < self
83
+ def test_empty
84
+ assert_raise(Droonga::Searcher::NoQuery) do
85
+ search({})
86
+ end
87
+ end
88
+
89
+ def test_nil
90
+ assert_raise(Droonga::Searcher::NoQuery) do
91
+ search(nil)
92
+ end
93
+ end
94
+ end
95
+
96
+ class QueriesTest < self
97
+ def test_empty
98
+ assert_raise(Droonga::Searcher::NoQuery) do
99
+ search({"queries" => {}})
100
+ end
101
+ end
102
+
103
+ def test_nil
104
+ assert_raise(Droonga::Searcher::NoQuery) do
105
+ search({"queries" => nil})
106
+ end
107
+ end
108
+ end
109
+
110
+ class HashQueryTest < self
111
+ def test_string_matchTo
112
+ request = base_request
113
+ request["queries"]["sections-result"]["condition"] = {
114
+ "query" => "Groonga",
115
+ "matchTo" => "title"
116
+ }
117
+ assert_search({
118
+ "sections-result" => {
119
+ "records" => [
120
+ { "title" => "Groonga overview" },
121
+ ],
122
+ },
123
+ },
124
+ request)
125
+ end
126
+
127
+ def test_array_matchTo
128
+ request = base_request
129
+ request["queries"]["sections-result"]["condition"] = {
130
+ "query" => "Groonga",
131
+ "matchTo" => ["title"]
132
+ }
133
+ assert_search({
134
+ "sections-result" => {
135
+ "records" => [
136
+ { "title" => "Groonga overview" },
137
+ ],
138
+ },
139
+ },
140
+ request)
141
+ end
142
+
143
+ def base_request
144
+ {
145
+ "queries" => {
146
+ "sections-result" => {
147
+ "source" => "Sections",
148
+ "output" => {
149
+ "elements" => [
150
+ "records",
151
+ ],
152
+ "format" => "complex",
153
+ "limit" => 1,
154
+ "attributes" => ["title"],
155
+ },
156
+ },
157
+ },
158
+ }
159
+ end
160
+ end
161
+
162
+ class SourceTest < self
163
+ def test_non_existent
164
+ assert_raise(Droonga::Searcher::UnknownSource) do
165
+ search({
166
+ "queries" => {
167
+ "non-existent-result" => {
168
+ "source" => "non-existent",
169
+ },
170
+ },
171
+ })
172
+ end
173
+ end
174
+
175
+ def test_existent
176
+ assert_search({
177
+ "sections-result" => {},
178
+ },
179
+ {
180
+ "queries" => {
181
+ "sections-result" => {
182
+ "source" => "Sections",
183
+ "output" => {},
184
+ },
185
+ },
186
+ })
187
+ end
188
+
189
+ def test_no_source
190
+ assert_raise(Droonga::Searcher::MissingSourceParameter) do
191
+ search({
192
+ "queries" => {
193
+ "no-source-result" => {
194
+ },
195
+ },
196
+ })
197
+ end
198
+ end
199
+ end
200
+
201
+ class OutputTest < self
202
+ def test_count
203
+ assert_search({
204
+ "sections-result" => {
205
+ "count" => 9,
206
+ },
207
+ },
208
+ {
209
+ "queries" => {
210
+ "sections-result" => {
211
+ "source" => "Sections",
212
+ "output" => {
213
+ "elements" => [
214
+ "count",
215
+ ],
216
+ },
217
+ },
218
+ },
219
+ })
220
+ end
221
+
222
+ def test_elapsed_time
223
+ assert_search({
224
+ "sections-result" => {
225
+ "startTime" => start_time,
226
+ "elapsedTime" => elapsed_time,
227
+ },
228
+ },
229
+ {
230
+ "queries" => {
231
+ "sections-result" => {
232
+ "source" => "Sections",
233
+ "output" => {
234
+ "elements" => [
235
+ "startTime",
236
+ "elapsedTime",
237
+ ],
238
+ },
239
+ },
240
+ },
241
+ })
242
+ end
243
+
244
+ def test_attributes_simple
245
+ assert_search({
246
+ "sections-result" => {
247
+ "attributes" => [
248
+ {
249
+ "name" => "key",
250
+ "type" => "ShortText",
251
+ "vector" => false
252
+ },
253
+ {
254
+ "name" => "title",
255
+ "type" => "ShortText",
256
+ "vector" => false
257
+ }
258
+ ]
259
+ },
260
+ },
261
+ {
262
+ "queries" => {
263
+ "sections-result" => {
264
+ "source" => "Sections",
265
+ "output" => {
266
+ "elements" => [
267
+ "attributes"
268
+ ],
269
+ "attributes" => [
270
+ {
271
+ "label" => "key",
272
+ "source" => "_key",
273
+ },
274
+ "title",
275
+ ],
276
+ },
277
+ },
278
+ },
279
+ })
280
+ end
281
+
282
+ def test_attributes_complex
283
+ assert_search({
284
+ "sections-result" => {
285
+ "attributes" => {
286
+ "key" => {
287
+ "type" => "ShortText",
288
+ "vector" => false
289
+ },
290
+ "title" => {
291
+ "type" => "ShortText",
292
+ "vector" => false
293
+ }
294
+ }
295
+ },
296
+ },
297
+ {
298
+ "queries" => {
299
+ "sections-result" => {
300
+ "source" => "Sections",
301
+ "output" => {
302
+ "format" => "complex",
303
+ "elements" => [
304
+ "attributes"
305
+ ],
306
+ "attributes" => [
307
+ {
308
+ "label" => "key",
309
+ "source" => "_key",
310
+ },
311
+ "title",
312
+ ],
313
+ },
314
+ },
315
+ },
316
+ })
317
+ end
318
+
319
+ def test_attributes_expression_simple
320
+ assert_search({
321
+ "sections-result" => {
322
+ "attributes" => [
323
+ {
324
+ "name" => "text", # TODO include some information
325
+ },
326
+ ]
327
+ },
328
+ },
329
+ {
330
+ "queries" => {
331
+ "sections-result" => {
332
+ "source" => "Sections",
333
+ "output" => {
334
+ "elements" => [
335
+ "attributes"
336
+ ],
337
+ "attributes" => [
338
+ {
339
+ "label" => "text",
340
+ "source" => "'hello'",
341
+ },
342
+ ],
343
+ },
344
+ },
345
+ },
346
+ })
347
+ end
348
+
349
+ def test_attributes_expression_complex
350
+ assert_search({
351
+ "sections-result" => {
352
+ "attributes" => {
353
+ "text" => {} # TODO include some information
354
+ },
355
+ },
356
+ },
357
+ {
358
+ "queries" => {
359
+ "sections-result" => {
360
+ "source" => "Sections",
361
+ "output" => {
362
+ "format" => "complex",
363
+ "elements" => [
364
+ "attributes"
365
+ ],
366
+ "attributes" => [
367
+ {
368
+ "label" => "text",
369
+ "source" => "'hello'",
370
+ },
371
+ ],
372
+ },
373
+ },
374
+ },
375
+ })
376
+ end
377
+
378
+ def test_attributes_subrecs_simple
379
+ assert_search({
380
+ "sections-result" => {
381
+ "attributes" => [
382
+ {
383
+ "name" => "key",
384
+ "type" => "ShortText",
385
+ "vector" => false
386
+ },
387
+ {
388
+ "name" => "title",
389
+ "type" => "ShortText",
390
+ "vector" => false
391
+ },
392
+ {
393
+ "name" => "_nsubrecs",
394
+ "type" => "Int32",
395
+ "vector" => false
396
+ },
397
+ {
398
+ "name" => "subrecs",
399
+ "attributes" => [
400
+ {
401
+ "name" => "_key",
402
+ "type" => "ShortText",
403
+ "vector" => false
404
+ },
405
+ {
406
+ "name" => "sectionTitle",
407
+ "type" => "ShortText",
408
+ "vector" => false
409
+ },
410
+ {
411
+ "name" => "documentTitle",
412
+ "type" => "ShortText",
413
+ "vector" => false
414
+ }
415
+ ]
416
+ }
417
+ ]
418
+ },
419
+ },
420
+ {
421
+ "queries" => {
422
+ "sections-result" => {
423
+ "source" => "Sections",
424
+ "groupBy" => {
425
+ "key" => "document",
426
+ "maxNSubRecords" => 1
427
+ },
428
+ "output" => {
429
+ "elements" => [
430
+ "attributes"
431
+ ],
432
+ "attributes" => [
433
+ {
434
+ "label" => "key",
435
+ "source" => "_key",
436
+ },
437
+ "title",
438
+ "_nsubrecs",
439
+ {
440
+ "label" => "subrecs",
441
+ "source" => "_subrecs",
442
+ "attributes" => [
443
+ "_key",
444
+ {
445
+ "label" => "sectionTitle",
446
+ "source" => "title"
447
+ },
448
+ {
449
+ "label" => "documentTitle",
450
+ "source" => "document.title"
451
+ }
452
+ ]
453
+ }
454
+ ],
455
+ },
456
+ },
457
+ },
458
+ })
459
+ end
460
+
461
+ def test_attributes_subrecs_complex
462
+ assert_search({
463
+ "sections-result" => {
464
+ "attributes" => {
465
+ "key" => {
466
+ "type" => "ShortText",
467
+ "vector" => false
468
+ },
469
+ "title" => {
470
+ "type" => "ShortText",
471
+ "vector" => false
472
+ },
473
+ "_nsubrecs" => {
474
+ "type" => "Int32",
475
+ "vector" => false
476
+ },
477
+ "subrecs" => {
478
+ "attributes" => {
479
+ "_key" => {
480
+ "type" => "ShortText",
481
+ "vector" => false
482
+ },
483
+ "sectionTitle" => {
484
+ "type" => "ShortText",
485
+ "vector" => false
486
+ },
487
+ "documentTitle" => {
488
+ "type" => "ShortText",
489
+ "vector" => false
490
+ }
491
+ }
492
+ }
493
+ }
494
+ },
495
+ },
496
+ {
497
+ "queries" => {
498
+ "sections-result" => {
499
+ "source" => "Sections",
500
+ "groupBy" => {
501
+ "key" => "document",
502
+ "maxNSubRecords" => 1
503
+ },
504
+ "output" => {
505
+ "format" => "complex",
506
+ "elements" => [
507
+ "attributes"
508
+ ],
509
+ "attributes" => [
510
+ {
511
+ "label" => "key",
512
+ "source" => "_key",
513
+ },
514
+ "title",
515
+ "_nsubrecs",
516
+ {
517
+ "label" => "subrecs",
518
+ "source" => "_subrecs",
519
+ "attributes" => [
520
+ "_key",
521
+ {
522
+ "label" => "sectionTitle",
523
+ "source" => "title"
524
+ },
525
+ {
526
+ "label" => "documentTitle",
527
+ "source" => "document.title"
528
+ }
529
+ ]
530
+ }
531
+ ],
532
+ },
533
+ },
534
+ },
535
+ })
536
+ end
537
+
538
+ class AttributesTest < self
539
+ def test_source_only
540
+ expected = {
541
+ "sections-result" => {
542
+ "records" => [
543
+ {
544
+ "_key" => "1.1",
545
+ "title" => "Groonga overview",
546
+ },
547
+ {
548
+ "_key" => "1.2",
549
+ "title" => "Full text search and Instant update",
550
+ },
551
+ {
552
+ "_key" => "1.3",
553
+ "title" => "Column store and aggregate query",
554
+ },
555
+ ],
556
+ },
557
+ }
558
+ request = {
559
+ "queries" => {
560
+ "sections-result" => {
561
+ "source" => "Sections",
562
+ "output" => {
563
+ "elements" => [
564
+ "records",
565
+ ],
566
+ "format" => "complex",
567
+ "limit" => 3,
568
+ "attributes" => ["_key", "title"],
569
+ },
570
+ },
571
+ },
572
+ }
573
+ assert_search(expected, request)
574
+ end
575
+
576
+ def test_label
577
+ expected = {
578
+ "sections-result" => {
579
+ "records" => [
580
+ {
581
+ "key" => "1.1",
582
+ "title" => "Groonga overview",
583
+ },
584
+ {
585
+ "key" => "1.2",
586
+ "title" => "Full text search and Instant update",
587
+ },
588
+ {
589
+ "key" => "1.3",
590
+ "title" => "Column store and aggregate query",
591
+ },
592
+ ],
593
+ },
594
+ }
595
+ request = {
596
+ "queries" => {
597
+ "sections-result" => {
598
+ "source" => "Sections",
599
+ "output" => {
600
+ "elements" => [
601
+ "records",
602
+ ],
603
+ "format" => "complex",
604
+ "limit" => 3,
605
+ "attributes" => [
606
+ {
607
+ "label" => "key",
608
+ "source" => "_key",
609
+ },
610
+ "title",
611
+ ],
612
+ },
613
+ },
614
+ },
615
+ }
616
+ assert_search(expected, request)
617
+ end
618
+
619
+ def test_static_value
620
+ expected = {
621
+ "sections-result" => {
622
+ "records" => [
623
+ {
624
+ "single_quote_string" => "string value",
625
+ "double_quote_string" => "string value",
626
+ "integer" => 29,
627
+ "complex_negative_number" => -29.29,
628
+ },
629
+ {
630
+ "single_quote_string" => "string value",
631
+ "double_quote_string" => "string value",
632
+ "integer" => 29,
633
+ "complex_negative_number" => -29.29,
634
+ },
635
+ ],
636
+ },
637
+ }
638
+ request = {
639
+ "queries" => {
640
+ "sections-result" => {
641
+ "source" => "Sections",
642
+ "output" => {
643
+ "elements" => [
644
+ "records",
645
+ ],
646
+ "format" => "complex",
647
+ "limit" => 2,
648
+ "attributes" => [
649
+ {
650
+ "label" => "single_quote_string",
651
+ "source" => "'string value'",
652
+ },
653
+ {
654
+ "label" => "double_quote_string",
655
+ "source" => '"string value"',
656
+ },
657
+ {
658
+ "label" => "integer",
659
+ "source" => "29",
660
+ },
661
+ {
662
+ "label" => "complex_negative_number",
663
+ "source" => "-29.29",
664
+ },
665
+ ],
666
+ },
667
+ },
668
+ },
669
+ }
670
+ assert_search(expected, request)
671
+ end
672
+
673
+ def test_expression
674
+ expected = {
675
+ "sections-result" => {
676
+ "records" => [
677
+ {
678
+ "formatted title" => "<Groonga overview>",
679
+ "title" => "Groonga overview",
680
+ },
681
+ ],
682
+ },
683
+ }
684
+ request = {
685
+ "queries" => {
686
+ "sections-result" => {
687
+ "source" => "Sections",
688
+ "output" => {
689
+ "elements" => [
690
+ "records",
691
+ ],
692
+ "format" => "complex",
693
+ "limit" => 1,
694
+ "attributes" => [
695
+ "title",
696
+ {
697
+ "label" => "formatted title",
698
+ "source" => "'<' + title + '>'",
699
+ },
700
+ ],
701
+ },
702
+ },
703
+ },
704
+ }
705
+ assert_search(expected, request)
706
+ end
707
+
708
+ def test_snippet_html
709
+ expected = {
710
+ "sections-result" => {
711
+ "records" => [
712
+ {
713
+ "title" => "Groonga overview",
714
+ "snippet" => [
715
+ "<span class=\"keyword\">Groonga</span> overview",
716
+ ],
717
+ },
718
+ ],
719
+ },
720
+ }
721
+ request = {
722
+ "queries" => {
723
+ "sections-result" => {
724
+ "source" => "Sections",
725
+ "condition" => {
726
+ "query" => "Groonga",
727
+ "matchTo" => ["title"],
728
+ },
729
+ "output" => {
730
+ "elements" => [
731
+ "records",
732
+ ],
733
+ "format" => "complex",
734
+ "limit" => 1,
735
+ "attributes" => [
736
+ "title",
737
+ {
738
+ "label" => "snippet",
739
+ "source" => "snippet_html(title)",
740
+ },
741
+ ],
742
+ },
743
+ },
744
+ },
745
+ }
746
+ assert_search(expected, request)
747
+ end
748
+ end
749
+
750
+ class FormatTest < self
751
+ def test_complex
752
+ request = {
753
+ "queries" => {
754
+ "sections-result" => {
755
+ "source" => "Sections",
756
+ "output" => {
757
+ "elements" => [
758
+ "records",
759
+ ],
760
+ "format" => "complex",
761
+ "limit" => 3,
762
+ "attributes" => ["_key", "title"],
763
+ },
764
+ },
765
+ },
766
+ }
767
+ assert_search(complex_result, request)
768
+ end
769
+
770
+ def test_simple
771
+ request = {
772
+ "queries" => {
773
+ "sections-result" => {
774
+ "source" => "Sections",
775
+ "output" => {
776
+ "elements" => [
777
+ "records",
778
+ ],
779
+ "format" => "simple",
780
+ "limit" => 3,
781
+ "attributes" => ["_key", "title"],
782
+ },
783
+ },
784
+ },
785
+ }
786
+ assert_search(simple_result, request)
787
+ end
788
+
789
+ def test_default
790
+ request = {
791
+ "queries" => {
792
+ "sections-result" => {
793
+ "source" => "Sections",
794
+ "output" => {
795
+ "elements" => [
796
+ "records",
797
+ ],
798
+ "limit" => 3,
799
+ "attributes" => ["_key", "title"],
800
+ },
801
+ },
802
+ },
803
+ }
804
+ assert_search(simple_result, request)
805
+ end
806
+
807
+ def complex_result
808
+ {
809
+ "sections-result" => {
810
+ "records" => [
811
+ {
812
+ "_key" => "1.1",
813
+ "title" => "Groonga overview",
814
+ },
815
+ {
816
+ "_key" => "1.2",
817
+ "title" => "Full text search and Instant update",
818
+ },
819
+ {
820
+ "_key" => "1.3",
821
+ "title" => "Column store and aggregate query",
822
+ },
823
+ ],
824
+ },
825
+ }
826
+ end
827
+
828
+ def simple_result
829
+ {
830
+ "sections-result" => {
831
+ "records" => [
832
+ ["1.1", "Groonga overview"],
833
+ ["1.2", "Full text search and Instant update"],
834
+ ["1.3", "Column store and aggregate query"],
835
+ ],
836
+ },
837
+ }
838
+ end
839
+ end
840
+ end
841
+ end
842
+
843
+ class ReferenceTest < self
844
+ class Hash
845
+ def setup_data
846
+ restore(fixture_data("reference/hash.grn"))
847
+ end
848
+
849
+ def test_reference_to_hash
850
+ expected = {
851
+ "sections-result" => {
852
+ "records" => [
853
+ {
854
+ "_key" => "1.1",
855
+ "document" => "Groonga",
856
+ },
857
+ {
858
+ "_key" => "1.2",
859
+ "document" => "Groonga",
860
+ },
861
+ {
862
+ "_key" => "1.3",
863
+ "document" => "Groonga",
864
+ },
865
+ ],
866
+ },
867
+ }
868
+ request = {
869
+ "queries" => {
870
+ "sections-result" => {
871
+ "source" => "SectionsForHash",
872
+ "output" => {
873
+ "elements" => [
874
+ "records",
875
+ ],
876
+ "format" => "complex",
877
+ "limit" => 3,
878
+ "attributes" => ["_key", "document"],
879
+ },
880
+ },
881
+ },
882
+ }
883
+ assert_search(expected, request)
884
+ end
885
+ end
886
+
887
+ class Array
888
+ def setup_data
889
+ restore(fixture_data("reference/array.grn"))
890
+ end
891
+
892
+ def test_reference_to_array
893
+ expected = {
894
+ "sections-result" => {
895
+ "records" => [
896
+ {
897
+ "_key" => "1.1",
898
+ "document" => 1,
899
+ },
900
+ {
901
+ "_key" => "1.2",
902
+ "document" => 1,
903
+ },
904
+ {
905
+ "_key" => "1.3",
906
+ "document" => 1,
907
+ },
908
+ ],
909
+ },
910
+ }
911
+ request = {
912
+ "queries" => {
913
+ "sections-result" => {
914
+ "source" => "SectionsForArray",
915
+ "output" => {
916
+ "elements" => [
917
+ "records",
918
+ ],
919
+ "format" => "complex",
920
+ "limit" => 3,
921
+ "attributes" => ["_key", "document"],
922
+ },
923
+ },
924
+ },
925
+ }
926
+ assert_search(expected, request)
927
+ end
928
+ end
929
+ end
930
+ end