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.
- data/.dir-locals.el +3 -0
- data/.gitignore +6 -0
- data/.travis.yml +15 -0
- data/.yardopts +7 -0
- data/Gemfile +66 -0
- data/LICENSE.txt +14 -0
- data/README.md +17 -0
- data/Rakefile +64 -0
- data/benchmark/benchmark.rb +123 -0
- data/benchmark/utils.rb +246 -0
- data/benchmark/watch/benchmark-notify.rb +143 -0
- data/benchmark/watch/benchmark-notify.sh +20 -0
- data/benchmark/watch/benchmark-publish.rb +120 -0
- data/benchmark/watch/benchmark-scan.rb +213 -0
- data/bin/droonga-catalog-generate +103 -0
- data/bin/droonga-engine +20 -0
- data/bin/droonga-engine-service +20 -0
- data/doc/text/news.md +106 -0
- data/droonga-engine.gemspec +52 -0
- data/lib/droonga/adapter.rb +48 -0
- data/lib/droonga/adapter_runner.rb +104 -0
- data/lib/droonga/catalog/base.rb +41 -0
- data/lib/droonga/catalog/collection_volume.rb +106 -0
- data/lib/droonga/catalog/dataset.rb +69 -0
- data/lib/droonga/catalog/errors.rb +113 -0
- data/lib/droonga/catalog/schema.rb +186 -0
- data/lib/droonga/catalog/single_volume.rb +28 -0
- data/lib/droonga/catalog/slice.rb +41 -0
- data/lib/droonga/catalog/version1.rb +427 -0
- data/lib/droonga/catalog/version2.rb +96 -0
- data/lib/droonga/catalog/version2_validator.rb +63 -0
- data/lib/droonga/catalog/volume.rb +33 -0
- data/lib/droonga/catalog/volume_collection.rb +56 -0
- data/lib/droonga/catalog_generator.rb +156 -0
- data/lib/droonga/catalog_loader.rb +56 -0
- data/lib/droonga/catalog_observer.rb +83 -0
- data/lib/droonga/collector.rb +38 -0
- data/lib/droonga/collector_message.rb +71 -0
- data/lib/droonga/collector_runner.rb +64 -0
- data/lib/droonga/collectors/and.rb +26 -0
- data/lib/droonga/collectors/or.rb +26 -0
- data/lib/droonga/collectors/sum.rb +26 -0
- data/lib/droonga/collectors.rb +18 -0
- data/lib/droonga/dispatcher.rb +326 -0
- data/lib/droonga/distributed_command_planner.rb +179 -0
- data/lib/droonga/distributor.rb +87 -0
- data/lib/droonga/engine/command/droonga_engine.rb +441 -0
- data/lib/droonga/engine/version.rb +20 -0
- data/lib/droonga/engine.rb +80 -0
- data/lib/droonga/engine_state.rb +79 -0
- data/lib/droonga/error.rb +73 -0
- data/lib/droonga/error_messages.rb +33 -0
- data/lib/droonga/event_loop.rb +46 -0
- data/lib/droonga/farm.rb +58 -0
- data/lib/droonga/fluent_message_receiver.rb +191 -0
- data/lib/droonga/fluent_message_sender.rb +140 -0
- data/lib/droonga/forwarder.rb +119 -0
- data/lib/droonga/handler.rb +49 -0
- data/lib/droonga/handler_message.rb +61 -0
- data/lib/droonga/handler_messenger.rb +119 -0
- data/lib/droonga/handler_runner.rb +125 -0
- data/lib/droonga/input_message.rb +51 -0
- data/lib/droonga/job_protocol.rb +20 -0
- data/lib/droonga/job_pusher.rb +179 -0
- data/lib/droonga/job_receiver.rb +70 -0
- data/lib/droonga/loggable.rb +29 -0
- data/lib/droonga/logger.rb +142 -0
- data/lib/droonga/message_matcher.rb +109 -0
- data/lib/droonga/output_message.rb +55 -0
- data/lib/droonga/planner.rb +47 -0
- data/lib/droonga/pluggable.rb +31 -0
- data/lib/droonga/plugin/metadata/adapter_input_message.rb +39 -0
- data/lib/droonga/plugin/metadata/adapter_output_message.rb +39 -0
- data/lib/droonga/plugin/metadata/collector_message.rb +39 -0
- data/lib/droonga/plugin/metadata/handler_action.rb +39 -0
- data/lib/droonga/plugin/metadata/input_message.rb +54 -0
- data/lib/droonga/plugin.rb +43 -0
- data/lib/droonga/plugin_loader.rb +63 -0
- data/lib/droonga/plugin_registry.rb +66 -0
- data/lib/droonga/plugins/basic.rb +54 -0
- data/lib/droonga/plugins/crud.rb +145 -0
- data/lib/droonga/plugins/dump.rb +97 -0
- data/lib/droonga/plugins/error.rb +51 -0
- data/lib/droonga/plugins/groonga/column_create.rb +123 -0
- data/lib/droonga/plugins/groonga/column_list.rb +124 -0
- data/lib/droonga/plugins/groonga/column_remove.rb +65 -0
- data/lib/droonga/plugins/groonga/column_rename.rb +67 -0
- data/lib/droonga/plugins/groonga/delete.rb +117 -0
- data/lib/droonga/plugins/groonga/generic_command.rb +105 -0
- data/lib/droonga/plugins/groonga/generic_response.rb +43 -0
- data/lib/droonga/plugins/groonga/select.rb +236 -0
- data/lib/droonga/plugins/groonga/table_create.rb +111 -0
- data/lib/droonga/plugins/groonga/table_list.rb +120 -0
- data/lib/droonga/plugins/groonga/table_remove.rb +57 -0
- data/lib/droonga/plugins/groonga.rb +37 -0
- data/lib/droonga/plugins/search/distributed_search_planner.rb +407 -0
- data/lib/droonga/plugins/search.rb +146 -0
- data/lib/droonga/plugins/watch.rb +178 -0
- data/lib/droonga/processor.rb +63 -0
- data/lib/droonga/reducer.rb +169 -0
- data/lib/droonga/replier.rb +49 -0
- data/lib/droonga/schema_applier.rb +167 -0
- data/lib/droonga/searcher/mecab_filter.rb +67 -0
- data/lib/droonga/searcher.rb +733 -0
- data/lib/droonga/server.rb +45 -0
- data/lib/droonga/session.rb +99 -0
- data/lib/droonga/single_step.rb +68 -0
- data/lib/droonga/single_step_definition.rb +54 -0
- data/lib/droonga/slice.rb +122 -0
- data/lib/droonga/status_code.rb +25 -0
- data/lib/droonga/step_runner.rb +64 -0
- data/lib/droonga/sweeper.rb +42 -0
- data/lib/droonga/test/stub_handler.rb +37 -0
- data/lib/droonga/test/stub_handler_message.rb +35 -0
- data/lib/droonga/test/stub_handler_messenger.rb +34 -0
- data/lib/droonga/test/stub_planner.rb +31 -0
- data/lib/droonga/test.rb +21 -0
- data/lib/droonga/watch_schema.rb +92 -0
- data/lib/droonga/watcher.rb +257 -0
- data/lib/droonga/worker.rb +61 -0
- data/sample/cluster/catalog.json +42 -0
- data/sample/mecab_filter/data.grn +7 -0
- data/sample/mecab_filter/ddl.grn +7 -0
- data/sample/mecab_filter/search_with_mecab_filter.json +21 -0
- data/sample/mecab_filter/search_without_mecab_filter.json +21 -0
- data/test/command/config/default/catalog.json +85 -0
- data/test/command/config/default/fluentd.conf +11 -0
- data/test/command/config/version1/catalog.json +68 -0
- data/test/command/config/version1/fluentd.conf +11 -0
- data/test/command/fixture/documents.jsons +208 -0
- data/test/command/fixture/event.jsons +41 -0
- data/test/command/fixture/user-table-array.jsons +38 -0
- data/test/command/fixture/user-table.jsons +47 -0
- data/test/command/run-test.rb +34 -0
- data/test/command/suite/add/dimension/column.catalog.json +28 -0
- data/test/command/suite/add/dimension/column.expected +41 -0
- data/test/command/suite/add/dimension/column.test +51 -0
- data/test/command/suite/add/dimension/integer.catalog.json +19 -0
- data/test/command/suite/add/dimension/integer.expected +41 -0
- data/test/command/suite/add/dimension/integer.test +51 -0
- data/test/command/suite/add/error/invalid-integer.expected +46 -0
- data/test/command/suite/add/error/invalid-integer.test +12 -0
- data/test/command/suite/add/error/invalid-time.expected +46 -0
- data/test/command/suite/add/error/invalid-time.test +12 -0
- data/test/command/suite/add/error/missing-key.expected +25 -0
- data/test/command/suite/add/error/missing-key.test +16 -0
- data/test/command/suite/add/error/missing-table.expected +25 -0
- data/test/command/suite/add/error/missing-table.test +16 -0
- data/test/command/suite/add/error/unknown-column.expected +46 -0
- data/test/command/suite/add/error/unknown-column.test +12 -0
- data/test/command/suite/add/error/unknown-table.expected +25 -0
- data/test/command/suite/add/error/unknown-table.test +17 -0
- data/test/command/suite/add/minimum.expected +6 -0
- data/test/command/suite/add/minimum.test +11 -0
- data/test/command/suite/add/with-values.expected +6 -0
- data/test/command/suite/add/with-values.test +17 -0
- data/test/command/suite/add/without-key.expected +6 -0
- data/test/command/suite/add/without-key.test +16 -0
- data/test/command/suite/groonga/column_create/scalar.expected +26 -0
- data/test/command/suite/groonga/column_create/scalar.test +17 -0
- data/test/command/suite/groonga/column_create/unknown-table.expected +14 -0
- data/test/command/suite/groonga/column_create/unknown-table.test +7 -0
- data/test/command/suite/groonga/column_create/vector.expected +26 -0
- data/test/command/suite/groonga/column_create/vector.test +18 -0
- data/test/command/suite/groonga/column_list/success.expected +86 -0
- data/test/command/suite/groonga/column_list/success.test +24 -0
- data/test/command/suite/groonga/column_list/unknown-table.expected +13 -0
- data/test/command/suite/groonga/column_list/unknown-table.test +7 -0
- data/test/command/suite/groonga/column_remove/success.expected +39 -0
- data/test/command/suite/groonga/column_remove/success.test +25 -0
- data/test/command/suite/groonga/column_remove/unknown-column.expected +27 -0
- data/test/command/suite/groonga/column_remove/unknown-column.test +16 -0
- data/test/command/suite/groonga/column_remove/unknown-table.expected +14 -0
- data/test/command/suite/groonga/column_remove/unknown-table.test +7 -0
- data/test/command/suite/groonga/column_rename/success.expected +39 -0
- data/test/command/suite/groonga/column_rename/success.test +26 -0
- data/test/command/suite/groonga/column_rename/unknown-column.expected +27 -0
- data/test/command/suite/groonga/column_rename/unknown-column.test +16 -0
- data/test/command/suite/groonga/column_rename/unknown-table.expected +14 -0
- data/test/command/suite/groonga/column_rename/unknown-table.test +7 -0
- data/test/command/suite/groonga/delete/duplicated-identifiers.expected +27 -0
- data/test/command/suite/groonga/delete/duplicated-identifiers.test +17 -0
- data/test/command/suite/groonga/delete/filter.expected +19 -0
- data/test/command/suite/groonga/delete/filter.test +19 -0
- data/test/command/suite/groonga/delete/invalid-filter.expected +14 -0
- data/test/command/suite/groonga/delete/invalid-filter.test +9 -0
- data/test/command/suite/groonga/delete/no-identifier.expected +27 -0
- data/test/command/suite/groonga/delete/no-identifier.test +15 -0
- data/test/command/suite/groonga/delete/success.expected +19 -0
- data/test/command/suite/groonga/delete/success.test +19 -0
- data/test/command/suite/groonga/delete/unknown-table.expected +14 -0
- data/test/command/suite/groonga/delete/unknown-table.test +7 -0
- data/test/command/suite/groonga/select/minimum.expected +22 -0
- data/test/command/suite/groonga/select/minimum.test +8 -0
- data/test/command/suite/groonga/table_create/array.expected +14 -0
- data/test/command/suite/groonga/table_create/array.test +8 -0
- data/test/command/suite/groonga/table_create/hash.expected +13 -0
- data/test/command/suite/groonga/table_create/hash.test +8 -0
- data/test/command/suite/groonga/table_list/success.expected +71 -0
- data/test/command/suite/groonga/table_list/success.test +15 -0
- data/test/command/suite/groonga/table_remove/success.expected +13 -0
- data/test/command/suite/groonga/table_remove/success.test +8 -0
- data/test/command/suite/groonga/table_remove/unknown-table.expected +14 -0
- data/test/command/suite/groonga/table_remove/unknown-table.test +7 -0
- data/test/command/suite/message/error/missing-dataset.expected +9 -0
- data/test/command/suite/message/error/missing-dataset.test +5 -0
- data/test/command/suite/message/error/unknown-dataset.expected +9 -0
- data/test/command/suite/message/error/unknown-dataset.test +6 -0
- data/test/command/suite/message/error/unknown-type.expected +9 -0
- data/test/command/suite/message/error/unknown-type.test +6 -0
- data/test/command/suite/search/adjusters/multiple.catalog.json +38 -0
- data/test/command/suite/search/adjusters/multiple.expected +19 -0
- data/test/command/suite/search/adjusters/multiple.test +75 -0
- data/test/command/suite/search/adjusters/one.catalog.json +38 -0
- data/test/command/suite/search/adjusters/one.expected +19 -0
- data/test/command/suite/search/adjusters/one.test +66 -0
- data/test/command/suite/search/attributes/array.expected +21 -0
- data/test/command/suite/search/attributes/array.test +28 -0
- data/test/command/suite/search/attributes/hash.expected +30 -0
- data/test/command/suite/search/attributes/hash.test +36 -0
- data/test/command/suite/search/complex.expected +48 -0
- data/test/command/suite/search/complex.test +23 -0
- data/test/command/suite/search/condition/nested.expected +15 -0
- data/test/command/suite/search/condition/nested.test +27 -0
- data/test/command/suite/search/condition/query/nonexistent_column.catalog.json +37 -0
- data/test/command/suite/search/condition/query/nonexistent_column.expected +48 -0
- data/test/command/suite/search/condition/query/nonexistent_column.test +33 -0
- data/test/command/suite/search/condition/query/syntax_error.catalog.json +36 -0
- data/test/command/suite/search/condition/query/syntax_error.expected +48 -0
- data/test/command/suite/search/condition/query/syntax_error.test +33 -0
- data/test/command/suite/search/condition/query.expected +24 -0
- data/test/command/suite/search/condition/query.test +23 -0
- data/test/command/suite/search/condition/script.expected +24 -0
- data/test/command/suite/search/condition/script.test +26 -0
- data/test/command/suite/search/error/cyclic-source.expected +14 -0
- data/test/command/suite/search/error/cyclic-source.test +12 -0
- data/test/command/suite/search/error/deeply-cyclic-source.expected +17 -0
- data/test/command/suite/search/error/deeply-cyclic-source.test +15 -0
- data/test/command/suite/search/error/missing-source-parameter.expected +13 -0
- data/test/command/suite/search/error/missing-source-parameter.test +11 -0
- data/test/command/suite/search/error/no-query.expected +9 -0
- data/test/command/suite/search/error/no-query.test +7 -0
- data/test/command/suite/search/error/unknown-source.expected +52 -0
- data/test/command/suite/search/error/unknown-source.test +12 -0
- data/test/command/suite/search/group/count.expected +10 -0
- data/test/command/suite/search/group/count.test +18 -0
- data/test/command/suite/search/group/limit.expected +15 -0
- data/test/command/suite/search/group/limit.test +20 -0
- data/test/command/suite/search/group/string.expected +32 -0
- data/test/command/suite/search/group/string.test +40 -0
- data/test/command/suite/search/group/subrecord/with-sort.catalog.json +33 -0
- data/test/command/suite/search/group/subrecord/with-sort.expected +30 -0
- data/test/command/suite/search/group/subrecord/with-sort.test +81 -0
- data/test/command/suite/search/multiple/chained.expected +41 -0
- data/test/command/suite/search/multiple/chained.test +39 -0
- data/test/command/suite/search/multiple/parallel.expected +35 -0
- data/test/command/suite/search/multiple/parallel.test +35 -0
- data/test/command/suite/search/output/attributes/invalid.catalog.json +13 -0
- data/test/command/suite/search/output/attributes/invalid.expected +44 -0
- data/test/command/suite/search/output/attributes/invalid.test +28 -0
- data/test/command/suite/search/range/only-output.expected +24 -0
- data/test/command/suite/search/range/only-output.test +23 -0
- data/test/command/suite/search/range/only-sort.expected +24 -0
- data/test/command/suite/search/range/only-sort.test +26 -0
- data/test/command/suite/search/range/sort-and-output.expected +21 -0
- data/test/command/suite/search/range/sort-and-output.test +27 -0
- data/test/command/suite/search/range/too-large-output-offset.expected +12 -0
- data/test/command/suite/search/range/too-large-output-offset.test +23 -0
- data/test/command/suite/search/range/too-large-sort-offset.expected +12 -0
- data/test/command/suite/search/range/too-large-sort-offset.test +26 -0
- data/test/command/suite/search/response/elapsed_time.catalog.json +13 -0
- data/test/command/suite/search/response/elapsed_time.expected +11 -0
- data/test/command/suite/search/response/elapsed_time.test +26 -0
- data/test/command/suite/search/response/records/value/time.expected +20 -0
- data/test/command/suite/search/response/records/value/time.test +22 -0
- data/test/command/suite/search/simple.expected +48 -0
- data/test/command/suite/search/simple.test +22 -0
- data/test/command/suite/search/sort/default-offset-limit.expected +39 -0
- data/test/command/suite/search/sort/default-offset-limit.test +24 -0
- data/test/command/suite/search/sort/invisible-column.expected +24 -0
- data/test/command/suite/search/sort/invisible-column.test +26 -0
- data/test/command/suite/watch/subscribe.expected +6 -0
- data/test/command/suite/watch/subscribe.test +9 -0
- data/test/command/suite/watch/unsubscribe.expected +6 -0
- data/test/command/suite/watch/unsubscribe.test +9 -0
- data/test/performance/run-test.rb +56 -0
- data/test/performance/watch/catalog.json +33 -0
- data/test/performance/watch/feed.json +9 -0
- data/test/performance/watch/fluentd.conf +11 -0
- data/test/performance/watch/subscribe.json +3 -0
- data/test/unit/catalog/test_collection_volume.rb +103 -0
- data/test/unit/catalog/test_dataset.rb +104 -0
- data/test/unit/catalog/test_schema.rb +226 -0
- data/test/unit/catalog/test_single_volume.rb +31 -0
- data/test/unit/catalog/test_slice.rb +92 -0
- data/test/unit/catalog/test_version1.rb +361 -0
- data/test/unit/catalog/test_version2.rb +124 -0
- data/test/unit/catalog/test_version2_validator.rb +66 -0
- data/test/unit/catalog/test_volume_collection.rb +50 -0
- data/test/unit/fixtures/array.grn +18 -0
- data/test/unit/fixtures/catalog/version1.json +40 -0
- data/test/unit/fixtures/catalog/version2.json +62 -0
- data/test/unit/fixtures/document.grn +34 -0
- data/test/unit/fixtures/reference/array.grn +11 -0
- data/test/unit/fixtures/reference/hash.grn +7 -0
- data/test/unit/helper/distributed_search_planner_helper.rb +83 -0
- data/test/unit/helper/fixture.rb +28 -0
- data/test/unit/helper/plugin_helper.rb +38 -0
- data/test/unit/helper/sandbox.rb +86 -0
- data/test/unit/helper/stub_worker.rb +27 -0
- data/test/unit/helper/watch_helper.rb +23 -0
- data/test/unit/helper.rb +28 -0
- data/test/unit/plugins/crud/test_add.rb +190 -0
- data/test/unit/plugins/groonga/select/test_adapter_input.rb +510 -0
- data/test/unit/plugins/groonga/select/test_adapter_output.rb +201 -0
- data/test/unit/plugins/groonga/test_column_create.rb +171 -0
- data/test/unit/plugins/groonga/test_column_list.rb +170 -0
- data/test/unit/plugins/groonga/test_column_remove.rb +98 -0
- data/test/unit/plugins/groonga/test_column_rename.rb +105 -0
- data/test/unit/plugins/groonga/test_delete.rb +127 -0
- data/test/unit/plugins/groonga/test_table_create.rb +147 -0
- data/test/unit/plugins/groonga/test_table_list.rb +184 -0
- data/test/unit/plugins/groonga/test_table_remove.rb +61 -0
- data/test/unit/plugins/search/planner/test_basic.rb +120 -0
- data/test/unit/plugins/search/planner/test_group_by.rb +573 -0
- data/test/unit/plugins/search/planner/test_output.rb +388 -0
- data/test/unit/plugins/search/planner/test_sort_by.rb +938 -0
- data/test/unit/plugins/search/test_collector.rb +806 -0
- data/test/unit/plugins/search/test_handler.rb +930 -0
- data/test/unit/plugins/search/test_planner.rb +174 -0
- data/test/unit/plugins/test_basic.rb +510 -0
- data/test/unit/plugins/test_groonga.rb +70 -0
- data/test/unit/plugins/test_watch.rb +211 -0
- data/test/unit/run-test.rb +56 -0
- data/test/unit/test_catalog_generator.rb +93 -0
- data/test/unit/test_message_matcher.rb +160 -0
- data/test/unit/test_schema_applier.rb +59 -0
- data/test/unit/test_sweeper.rb +95 -0
- data/test/unit/test_watch_schema.rb +57 -0
- data/test/unit/test_watcher.rb +336 -0
- metadata +759 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Copyright (C) 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 "tsort"
|
|
17
|
+
|
|
18
|
+
module Droonga
|
|
19
|
+
module Catalog
|
|
20
|
+
class Schema
|
|
21
|
+
class ColumnVectorOptions
|
|
22
|
+
def initialize(data)
|
|
23
|
+
@data = data
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def weight
|
|
27
|
+
@data["weight"]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class ColumnIndexOptions
|
|
32
|
+
def initialize(data)
|
|
33
|
+
@data = data
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def section
|
|
37
|
+
@data["section"]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def weight
|
|
41
|
+
@data["weight"]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def position
|
|
45
|
+
@data["position"]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def sources
|
|
49
|
+
@data["sources"]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class Column
|
|
54
|
+
attr_reader :table, :name, :data, :vector_options, :index_options
|
|
55
|
+
def initialize(table, name, data)
|
|
56
|
+
@table = table
|
|
57
|
+
@name = name
|
|
58
|
+
@data = data
|
|
59
|
+
@vector_options = ColumnVectorOptions.new(vector_options_data)
|
|
60
|
+
@index_options = ColumnIndexOptions.new(index_options_data)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def ==(other)
|
|
64
|
+
self.class == other.class and
|
|
65
|
+
name == other.name and
|
|
66
|
+
data == other.data
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def type
|
|
70
|
+
@data["type"] || "Scalar"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def type_symbol
|
|
74
|
+
case type
|
|
75
|
+
when "Scalar"
|
|
76
|
+
:scalar
|
|
77
|
+
when "Vector"
|
|
78
|
+
:vector
|
|
79
|
+
when "Index"
|
|
80
|
+
:index
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def value_type
|
|
85
|
+
@data["valueType"]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def value_type_groonga
|
|
89
|
+
if value_type == "Integer"
|
|
90
|
+
"Int64"
|
|
91
|
+
else
|
|
92
|
+
value_type
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
def vector_options_data
|
|
98
|
+
@data["vectorOptions"] || {}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def index_options_data
|
|
102
|
+
@data["indexOptions"] || {}
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
class Table
|
|
107
|
+
attr_reader :name, :columns, :data
|
|
108
|
+
def initialize(name, data)
|
|
109
|
+
@name = name
|
|
110
|
+
@data = data
|
|
111
|
+
@columns = {}
|
|
112
|
+
|
|
113
|
+
columns_data.each do |column_name, column_data|
|
|
114
|
+
@columns[column_name] = Column.new(name, column_name, column_data)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def ==(other)
|
|
119
|
+
self.class == other.class and
|
|
120
|
+
name == other.name and
|
|
121
|
+
data == other.data
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def type
|
|
125
|
+
@data["type"] || "Hash"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def type_symbol
|
|
129
|
+
case type
|
|
130
|
+
when "Array"
|
|
131
|
+
:array
|
|
132
|
+
when "Hash"
|
|
133
|
+
:hash
|
|
134
|
+
when "PatriciaTrie"
|
|
135
|
+
:patricia_trie
|
|
136
|
+
when "DoubleArrayTrie"
|
|
137
|
+
:double_array_trie
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def key_type
|
|
142
|
+
@data["keyType"]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def key_type_groonga
|
|
146
|
+
case key_type
|
|
147
|
+
when "Integer"
|
|
148
|
+
"Int64"
|
|
149
|
+
when "Float", "Time", "ShortText", "TokyoGeoPoint", "WGS84GeoPoint"
|
|
150
|
+
key_type
|
|
151
|
+
else
|
|
152
|
+
key_type
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def tokenizer
|
|
157
|
+
@data["tokenizer"]
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def normalizer
|
|
161
|
+
@data["normalizer"]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
def columns_data
|
|
166
|
+
@data["columns"] || []
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
attr_reader :tables
|
|
171
|
+
def initialize(dataset_name, data)
|
|
172
|
+
@dataset_name = dataset_name
|
|
173
|
+
@data = data || []
|
|
174
|
+
@tables = {}
|
|
175
|
+
@data.each do |table_name, table_data|
|
|
176
|
+
@tables[table_name] = Table.new(table_name, table_data)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def ==(other)
|
|
181
|
+
self.class == other.class and
|
|
182
|
+
tables == other.tables
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Copyright (C) 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
|
+
module Droonga
|
|
17
|
+
module Catalog
|
|
18
|
+
class SingleVolume
|
|
19
|
+
def initialize(data)
|
|
20
|
+
@data = data
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def address
|
|
24
|
+
@data["address"]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Copyright (C) 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
|
+
module Droonga
|
|
17
|
+
module Catalog
|
|
18
|
+
class Slice
|
|
19
|
+
def initialize(dataset, data)
|
|
20
|
+
@dataset = dataset
|
|
21
|
+
@data = data
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def weight
|
|
25
|
+
@data["weight"] || 1
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def label
|
|
29
|
+
@data["label"]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def boundary
|
|
33
|
+
@data["boundary"]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def volume
|
|
37
|
+
@volume ||= Volume.create(@dataset, @data["volume"])
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,427 @@
|
|
|
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/catalog/base"
|
|
17
|
+
require "droonga/catalog/dataset"
|
|
18
|
+
|
|
19
|
+
module Droonga
|
|
20
|
+
module Catalog
|
|
21
|
+
class Version1 < Base
|
|
22
|
+
def initialize(data, path)
|
|
23
|
+
super
|
|
24
|
+
@errors = []
|
|
25
|
+
|
|
26
|
+
validate
|
|
27
|
+
raise MultiplexError.new(@errors) unless @errors.empty?
|
|
28
|
+
|
|
29
|
+
prepare_data
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def datasets
|
|
33
|
+
@datasets
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def slices(name)
|
|
37
|
+
get_partitions(name)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def get_partitions(name)
|
|
41
|
+
device = @data["farms"][name]["device"]
|
|
42
|
+
pattern = Regexp.new("^#{name}\.")
|
|
43
|
+
results = {}
|
|
44
|
+
@data["datasets"].each do |dataset_name, dataset_data|
|
|
45
|
+
dataset = Dataset.new(dataset_name, dataset_data)
|
|
46
|
+
workers = dataset["workers"]
|
|
47
|
+
plugins = dataset["plugins"]
|
|
48
|
+
dataset["ring"].each do |key, part|
|
|
49
|
+
part["partitions"].each do |range, partitions|
|
|
50
|
+
partitions.each do |partition|
|
|
51
|
+
if partition =~ pattern
|
|
52
|
+
path = File.join([device, $POSTMATCH, "db"])
|
|
53
|
+
path = File.expand_path(path, base_path)
|
|
54
|
+
options = {
|
|
55
|
+
:dataset => dataset_name,
|
|
56
|
+
:database => path,
|
|
57
|
+
:n_workers => workers,
|
|
58
|
+
:plugins => plugins
|
|
59
|
+
}
|
|
60
|
+
results[partition] = options
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
return results
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def get_routes(name, args)
|
|
70
|
+
routes = []
|
|
71
|
+
dataset = dataset(name)
|
|
72
|
+
case args["type"]
|
|
73
|
+
when "broadcast"
|
|
74
|
+
dataset["ring"].each do |key, partition|
|
|
75
|
+
select_range_and_replicas(partition, args, routes)
|
|
76
|
+
end
|
|
77
|
+
when "scatter"
|
|
78
|
+
name = get_partition(dataset, args["record"]["_key"])
|
|
79
|
+
partition = dataset["ring"][name]
|
|
80
|
+
select_range_and_replicas(partition, args, routes)
|
|
81
|
+
end
|
|
82
|
+
return routes
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def get_partition(dataset, key)
|
|
86
|
+
continuum = dataset["continuum"]
|
|
87
|
+
return dataset["ring"].keys[0] unless continuum
|
|
88
|
+
hash = Zlib.crc32(key)
|
|
89
|
+
min = 0
|
|
90
|
+
max = continuum.size - 1
|
|
91
|
+
while (min < max) do
|
|
92
|
+
index = (min + max) / 2
|
|
93
|
+
value, key = continuum[index]
|
|
94
|
+
return key if value == hash
|
|
95
|
+
if value > hash
|
|
96
|
+
max = index
|
|
97
|
+
else
|
|
98
|
+
min = index + 1
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
return continuum[max][1]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def select_range_and_replicas(partition, args, routes)
|
|
105
|
+
date_range = args["date_range"] || 0..-1
|
|
106
|
+
partition["partitions"].sort[date_range].each do |time, replicas|
|
|
107
|
+
case args["replica"]
|
|
108
|
+
when "top"
|
|
109
|
+
routes << replicas[0]
|
|
110
|
+
when "random"
|
|
111
|
+
routes << replicas[rand(replicas.size)]
|
|
112
|
+
when "all"
|
|
113
|
+
routes.concat(replicas)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private
|
|
119
|
+
def prepare_data
|
|
120
|
+
@datasets = {}
|
|
121
|
+
@data["datasets"].each do |name, dataset|
|
|
122
|
+
@datasets[name] = Dataset.new(name, dataset)
|
|
123
|
+
number_of_partitions = dataset["number_of_partitions"]
|
|
124
|
+
next if number_of_partitions < 2
|
|
125
|
+
total_weight = compute_total_weight(dataset)
|
|
126
|
+
continuum = []
|
|
127
|
+
dataset["ring"].each do |key, value|
|
|
128
|
+
points = number_of_partitions * 160 * value["weight"] / total_weight
|
|
129
|
+
points.times do |point|
|
|
130
|
+
hash = Digest::SHA1.hexdigest("#{key}:#{point}")
|
|
131
|
+
continuum << [hash[0..7].to_i(16), key]
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
dataset["continuum"] = continuum.sort do |a, b| a[0] - b[0]; end
|
|
135
|
+
end
|
|
136
|
+
@options = @data["options"] || {}
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def compute_total_weight(dataset)
|
|
140
|
+
dataset["ring"].reduce(0) do |result, zone|
|
|
141
|
+
result + zone[1]["weight"]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def validate
|
|
146
|
+
do_validation do
|
|
147
|
+
validate_effective_date
|
|
148
|
+
end
|
|
149
|
+
do_validation do
|
|
150
|
+
validate_farms
|
|
151
|
+
end
|
|
152
|
+
do_validation do
|
|
153
|
+
validate_zones
|
|
154
|
+
end
|
|
155
|
+
do_validation do
|
|
156
|
+
validate_datasets
|
|
157
|
+
end
|
|
158
|
+
do_validation do
|
|
159
|
+
validate_zone_relations
|
|
160
|
+
end
|
|
161
|
+
do_validation do
|
|
162
|
+
validate_database_relations
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def do_validation(&block)
|
|
167
|
+
begin
|
|
168
|
+
yield
|
|
169
|
+
rescue LegacyValidationError => error
|
|
170
|
+
@errors << error
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def validate_required_parameter(value, name)
|
|
175
|
+
raise MissingRequiredParameter.new(name, @path) unless value
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def validate_parameter_type(expected_types, value, name)
|
|
179
|
+
expected_types = [expected_types] unless expected_types.is_a?(Array)
|
|
180
|
+
|
|
181
|
+
if expected_types.any? do |type|
|
|
182
|
+
value.is_a?(type)
|
|
183
|
+
end
|
|
184
|
+
return
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
raise MismatchedParameterType.new(name,
|
|
188
|
+
expected_types,
|
|
189
|
+
value.class,
|
|
190
|
+
@path)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def validate_valid_datetime(value, name)
|
|
194
|
+
validate_required_parameter(value, name)
|
|
195
|
+
validate_parameter_type(String, value, name)
|
|
196
|
+
begin
|
|
197
|
+
Time.parse(value)
|
|
198
|
+
rescue ArgumentError
|
|
199
|
+
raise InvalidDate.new(name, value, @path)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def validate_positive_numeric_parameter(value, name)
|
|
204
|
+
validate_required_parameter(value, name)
|
|
205
|
+
validate_parameter_type(Numeric, value, name)
|
|
206
|
+
if value < 0
|
|
207
|
+
raise NegativeNumber.new(name, value, @path)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def validate_positive_integer_parameter(value, name)
|
|
212
|
+
validate_required_parameter(value, name)
|
|
213
|
+
validate_parameter_type(Integer, value, name)
|
|
214
|
+
if value < 0
|
|
215
|
+
raise NegativeNumber.new(name, value, @path)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def validate_one_or_larger_integer_parameter(value, name)
|
|
220
|
+
validate_required_parameter(value, name)
|
|
221
|
+
validate_parameter_type(Integer, value, name)
|
|
222
|
+
if value < 1
|
|
223
|
+
raise SmallerThanOne.new(name, value, @path)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def validate_effective_date
|
|
228
|
+
date = @data["effective_date"]
|
|
229
|
+
validate_required_parameter(date, "effective_date")
|
|
230
|
+
validate_valid_datetime(date, "effective_date")
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def validate_farms
|
|
234
|
+
farms = @data["farms"]
|
|
235
|
+
|
|
236
|
+
validate_required_parameter(farms, "farms")
|
|
237
|
+
validate_parameter_type(Hash, farms, "farms")
|
|
238
|
+
|
|
239
|
+
farms.each do |key, value|
|
|
240
|
+
validate_farm(value, "farms.#{key}")
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def validate_farm(farm, name)
|
|
245
|
+
validate_parameter_type(Hash, farm, name)
|
|
246
|
+
|
|
247
|
+
validate_required_parameter(farm["device"], "#{name}.device")
|
|
248
|
+
validate_parameter_type(String, farm["device"], "#{name}.device")
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def validate_zones
|
|
252
|
+
zones = @data["zones"]
|
|
253
|
+
|
|
254
|
+
validate_required_parameter(zones, "zones")
|
|
255
|
+
validate_parameter_type(Array, zones, "zones")
|
|
256
|
+
|
|
257
|
+
validate_zone(zones, "zones")
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def validate_zone(zone, name)
|
|
261
|
+
case zone
|
|
262
|
+
when String
|
|
263
|
+
return
|
|
264
|
+
when Array
|
|
265
|
+
zone.each_with_index do |sub_zone, index|
|
|
266
|
+
validate_zone(sub_zone, "#{name}[#{index}]")
|
|
267
|
+
end
|
|
268
|
+
else
|
|
269
|
+
validate_parameter_type([String, Array], zone, name)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def validate_datasets
|
|
274
|
+
datasets = @data["datasets"]
|
|
275
|
+
|
|
276
|
+
validate_required_parameter(datasets, "datasets")
|
|
277
|
+
validate_parameter_type(Hash, datasets, "datasets")
|
|
278
|
+
|
|
279
|
+
datasets.each do |name, dataset|
|
|
280
|
+
validate_dataset(dataset, "datasets.#{name}")
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def validate_dataset(dataset, name)
|
|
285
|
+
validate_parameter_type(Hash, dataset, name)
|
|
286
|
+
|
|
287
|
+
do_validation do
|
|
288
|
+
validate_one_or_larger_integer_parameter(dataset["number_of_partitions"],
|
|
289
|
+
"#{name}.number_of_partitions")
|
|
290
|
+
end
|
|
291
|
+
do_validation do
|
|
292
|
+
validate_one_or_larger_integer_parameter(dataset["number_of_replicas"],
|
|
293
|
+
"#{name}.number_of_replicas")
|
|
294
|
+
end
|
|
295
|
+
do_validation do
|
|
296
|
+
validate_positive_integer_parameter(dataset["workers"],
|
|
297
|
+
"#{name}.workers")
|
|
298
|
+
end
|
|
299
|
+
do_validation do
|
|
300
|
+
validate_date_range(dataset["date_range"], "#{name}.date_range")
|
|
301
|
+
end
|
|
302
|
+
do_validation do
|
|
303
|
+
validate_partition_key(dataset["partition_key"],
|
|
304
|
+
"#{name}.partition_key")
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
do_validation do
|
|
308
|
+
ring = dataset["ring"]
|
|
309
|
+
validate_required_parameter(ring, "#{name}.ring")
|
|
310
|
+
validate_parameter_type(Hash, ring, "#{name}.ring")
|
|
311
|
+
ring.each do |key, value|
|
|
312
|
+
validate_ring(value, "#{name}.ring.#{key}")
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
do_validation do
|
|
317
|
+
validate_plugins(dataset["plugins"], "#{name}.plugins")
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def validate_date_range(value, name)
|
|
322
|
+
validate_required_parameter(value, name)
|
|
323
|
+
return if value == "infinity"
|
|
324
|
+
raise UnsupportedValue.new(name, value, @path)
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def validate_partition_key(value, name)
|
|
328
|
+
validate_required_parameter(value, name)
|
|
329
|
+
validate_parameter_type(String, value, name)
|
|
330
|
+
return if value == "_key"
|
|
331
|
+
raise UnsupportedValue.new(name, value, @path)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def validate_ring(ring, name)
|
|
335
|
+
validate_parameter_type(Hash, ring, name)
|
|
336
|
+
|
|
337
|
+
do_validation do
|
|
338
|
+
validate_positive_numeric_parameter(ring["weight"], "#{name}.weight")
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
do_validation do
|
|
342
|
+
validate_parameter_type(Hash, ring["partitions"], "#{name}.partitions")
|
|
343
|
+
ring["partitions"].each do |key, value|
|
|
344
|
+
validate_partition(value, "#{name}.partitions.#{key}")
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def validate_partition(partition, name)
|
|
350
|
+
validate_parameter_type(Array, partition, name)
|
|
351
|
+
|
|
352
|
+
partition.each_with_index do |value, index|
|
|
353
|
+
do_validation do
|
|
354
|
+
validate_parameter_type(String, value, "#{name}[#{index}]")
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
def validate_plugins(plugins, name)
|
|
360
|
+
return unless plugins
|
|
361
|
+
validate_required_parameter(plugins, name)
|
|
362
|
+
validate_parameter_type(Array, plugins, "#{name}.plugins")
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def validate_zone_relations
|
|
366
|
+
return unless @data["zones"].is_a?(Array)
|
|
367
|
+
return unless @data["farms"].is_a?(Hash)
|
|
368
|
+
|
|
369
|
+
farms = @data["farms"]
|
|
370
|
+
zones = @data["zones"]
|
|
371
|
+
|
|
372
|
+
all_farms = farms.keys
|
|
373
|
+
all_zones = zones.flatten
|
|
374
|
+
|
|
375
|
+
all_farms.each do |farm|
|
|
376
|
+
unless all_zones.include?(farm)
|
|
377
|
+
raise FarmNotZoned.new(farm, zones, @path)
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
all_zones.each do |zone|
|
|
382
|
+
unless all_farms.include?(zone)
|
|
383
|
+
raise UnknownFarmInZones.new(farm, zones, @path)
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def validate_database_relations
|
|
389
|
+
return unless @data["farms"]
|
|
390
|
+
|
|
391
|
+
farm_names = @data["farms"].keys.collect do |name|
|
|
392
|
+
Regexp.escape(name)
|
|
393
|
+
end
|
|
394
|
+
valid_farms_matcher = Regexp.new("^(#{farm_names.join("|")})\.")
|
|
395
|
+
|
|
396
|
+
@data["datasets"].each do |dataset_name, dataset|
|
|
397
|
+
ring = dataset["ring"]
|
|
398
|
+
next if ring.nil? or !ring.is_a?(Hash)
|
|
399
|
+
ring.each do |ring_key, part|
|
|
400
|
+
partitions_set = part["partitions"]
|
|
401
|
+
next if partitions_set.nil? or !partitions_set.is_a?(Hash)
|
|
402
|
+
partitions_set.each do |range, partitions|
|
|
403
|
+
next unless partitions.is_a?(Array)
|
|
404
|
+
partitions.each_with_index do |partition, index|
|
|
405
|
+
name = "datasets.#{dataset_name}.ring.#{ring_key}." +
|
|
406
|
+
"partitions.#{range}[#{index}]"
|
|
407
|
+
do_validation do
|
|
408
|
+
unless partition =~ valid_farms_matcher
|
|
409
|
+
raise UnknownFarmForPartition.new(name, partition, @path)
|
|
410
|
+
end
|
|
411
|
+
do_validation do
|
|
412
|
+
directory_name = $POSTMATCH
|
|
413
|
+
if directory_name.nil? or directory_name.empty?
|
|
414
|
+
message = "\"#{partition}\" has no database name. " +
|
|
415
|
+
"You mus specify a database name for \"#{name}\"."
|
|
416
|
+
raise LegacyValidationError.new(message, @path)
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
end
|