From f5dabd7acaaaf21019a59a641e090a7dfdaefae5 Mon Sep 17 00:00:00 2001 From: Kentoku SHIBA Date: Tue, 17 Feb 2015 13:34:27 +0900 Subject: [PATCH] Update Mroonga to the latest version on 2015-02-17T13:34:27+0900 --- storage/mroonga/CMakeLists.txt | 120 +- storage/mroonga/Makefile.am | 2 - storage/mroonga/appveyor.yml | 51 + storage/mroonga/configure.ac | 7 +- storage/mroonga/ha_mroonga.cpp | 671 +- storage/mroonga/ha_mroonga.hpp | 10 +- storage/mroonga/lib/mrn_database_manager.cpp | 44 +- storage/mroonga/lib/mrn_database_manager.hpp | 5 +- storage/mroonga/lib/mrn_lock.cpp | 6 +- storage/mroonga/lib/mrn_lock.hpp | 4 +- storage/mroonga/lib/mrn_parameters_parser.cpp | 4 +- storage/mroonga/lib/mrn_path_mapper.cpp | 5 +- storage/mroonga/mrn_err.h | 6 + storage/mroonga/mrn_mysql_compat.h | 11 +- storage/mroonga/mrn_table.cpp | 77 +- storage/mroonga/mrn_table.hpp | 4 +- .../mroonga/check_libgroonga_support_lz4.inc | 20 + .../mroonga/check_libgroonga_support_zlib.inc | 20 + .../mroonga/support_libgroonga_lz4.inc | 22 + .../mroonga/support_libgroonga_zlib.inc | 22 + .../mroonga/unsupport_libgroonga_lz4.inc | 22 + .../mroonga/unsupport_libgroonga_zlib.inc | 22 + .../mysql-test/mroonga/storage/disabled.def | 1 + ...x_unique_multiple_column_duplicated.result | 19 + ...r_table_disable_keys_fulltext_table.result | 27 + ...er_table_enable_keys_fulltext_table.result | 28 + ..._groonga_index_fulltext_other_table.result | 58 +- ...a_index_fulltext_vector_other_table.result | 42 + .../column_groonga_scalar_support_lz4.result | 10 + .../column_groonga_scalar_support_zlib.result | 10 + ...column_groonga_scalar_unsupport_lz4.result | 12 + ...olumn_groonga_scalar_unsupport_zlib.result | 12 + ..._normalizer_fulltext_index_comment.result} | 0 ..._utf8_charset_with_utf8_normalizer.result} | 0 ...able_normalizer_fulltext_index_none.result | 16 + ...rmalizer_primary_key_table_comment.result} | 0 ...ndex_unique_search_after_duplicated.result | 18 + .../r/information_schema_plugins.result | 2 +- ..._on_duplicate_key_update_unique_key.result | 15 +- .../mroonga/storage/r/partition_insert.result | 42 + .../storage/r/replace_without_key.result | 10 + ...lean_mode_syntax_flags_allow_column.result | 18 + ...mode_syntax_flags_allow_leading_not.result | 16 + ...lean_mode_syntax_flags_allow_update.result | 18 + ...lean_mode_syntax_flags_syntax_query.result | 15 + ...ean_mode_syntax_flags_syntax_script.result | 16 + .../mroonga/storage/r/variable_version.result | 2 +- ...dex_unique_multiple_column_duplicated.test | 39 + ...ter_table_disable_keys_fulltext_table.test | 45 + ...lter_table_enable_keys_fulltext_table.test | 46 + ...mn_groonga_index_fulltext_other_table.test | 32 +- ...nga_index_fulltext_vector_other_table.test | 54 + .../t/column_groonga_scalar_support_lz4.test | 37 + .../t/column_groonga_scalar_support_zlib.test | 37 + .../column_groonga_scalar_unsupport_lz4.test | 37 + .../column_groonga_scalar_unsupport_zlib.test | 37 + ...le_normalizer_fulltext_index_comment.test} | 0 ...no_utf8_charset_with_utf8_normalizer.test} | 0 ..._table_normalizer_fulltext_index_none.test | 42 + ...normalizer_primary_key_table_comment.test} | 0 .../index_unique_search_after_duplicated.test | 40 + ...rt_on_duplicate_key_update_unique_key.test | 11 +- .../mroonga/storage/t/partition_insert.test | 49 + .../storage/t/replace_without_key.test | 35 + ...oolean_mode_syntax_flags_allow_column.test | 43 + ...n_mode_syntax_flags_allow_leading_not.test | 41 + ...oolean_mode_syntax_flags_allow_update.test | 43 + ...oolean_mode_syntax_flags_syntax_query.test | 40 + ...olean_mode_syntax_flags_syntax_script.test | 41 + storage/mroonga/packages/Makefile.am | 7 + storage/mroonga/packages/apt/Makefile.am | 67 + storage/mroonga/packages/apt/Vagrantfile | 29 + storage/mroonga/packages/apt/build-deb.sh | 78 + storage/mroonga/packages/apt/env.sh.in | 15 + storage/mroonga/packages/apt/sign-packages.sh | 42 + .../mroonga/packages/apt/sign-repository.sh | 46 + .../mroonga/packages/apt/update-repository.sh | 130 + storage/mroonga/packages/check-utility.sh | 665 + .../debian/apparmor/mysql-server-mroonga | 5 + storage/mroonga/packages/debian/changelog | 391 + storage/mroonga/packages/debian/compat | 1 + storage/mroonga/packages/debian/control.in | 51 + storage/mroonga/packages/debian/copyright | 27 + .../debian/mysql-server-mroonga-doc.install | 1 + .../debian/mysql-server-mroonga.install | 3 + .../debian/mysql-server-mroonga.postinst | 72 + .../debian/mysql-server-mroonga.postrm | 38 + .../debian/mysql-server-mroonga.prerm | 10 + storage/mroonga/packages/debian/rules | 39 + storage/mroonga/packages/rpm/Makefile.am | 2 + .../mroonga/packages/rpm/centos/Makefile.am | 9 + .../rpm/centos/mariadb-mroonga.spec.in | 396 + .../rpm/centos/mysql55-mroonga.spec.in | 218 + .../centos/mysql56-community-mroonga.spec.in | 222 + storage/mroonga/packages/source/Makefile.am | 123 + .../patches/mariadb-10.0.3-windows-build.diff | 9 + storage/mroonga/packages/ubuntu/Makefile.am | 24 + storage/mroonga/packages/ubuntu/upload.rb | 168 + storage/mroonga/packages/windows/Makefile.am | 12 + storage/mroonga/packages/windows/README.md | 20 + .../packages/windows/build-vc2010-msi-32.bat | 8 + .../packages/windows/build-vc2010-msi-64.bat | 8 + .../packages/windows/build-vc2010-zip-32.bat | 8 + .../packages/windows/build-vc2010-zip-64.bat | 8 + .../mroonga/packages/windows/build-vc2010.bat | 4 + .../packages/windows/build-vc2013-msi-32.bat | 8 + .../packages/windows/build-vc2013-msi-64.bat | 8 + .../packages/windows/build-vc2013-zip-32.bat | 8 + .../packages/windows/build-vc2013-zip-64.bat | 8 + .../mroonga/packages/windows/build-vc2013.bat | 4 + storage/mroonga/packages/yum/Makefile.am | 63 + storage/mroonga/packages/yum/Vagrantfile | 50 + storage/mroonga/packages/yum/build-in-vm.sh | 60 + storage/mroonga/packages/yum/build-rpm.sh | 108 + storage/mroonga/packages/yum/env.sh.in | 27 + storage/mroonga/packages/yum/sign-rpm.sh | 52 + .../mroonga/packages/yum/update-repository.sh | 29 + storage/mroonga/plugin_version | 2 +- storage/mroonga/required_groonga_version | 2 +- storage/mroonga/tools/travis/install.sh | 8 +- storage/mroonga/udf/mrn_udf_command.cpp | 8 +- storage/mroonga/udf/mrn_udf_escape.cpp | 4 +- storage/mroonga/udf/mrn_udf_snippet.cpp | 4 +- storage/mroonga/vendor/groonga/CMakeLists.txt | 132 +- storage/mroonga/vendor/groonga/Makefile.am | 1 - storage/mroonga/vendor/groonga/appveyor.yml | 17 + storage/mroonga/vendor/groonga/autogen.sh | 5 + storage/mroonga/vendor/groonga/base_version | 2 +- .../groonga/benchmark/bench-geo-distance.c | 2 +- .../groonga/benchmark/bench-geo-select.c | 2 +- .../groonga/benchmark/bench-range-select.c | 2 +- .../build/ac_macros/check_functions.m4 | 5 + .../groonga/build/ac_macros/check_headers.m4 | 2 + storage/mroonga/vendor/groonga/config.h.cmake | 10 +- storage/mroonga/vendor/groonga/config.sh.in | 1 + storage/mroonga/vendor/groonga/configure.ac | 175 +- .../vendor/groonga/examples/Makefile.am | 1 + .../groonga/examples/dictionary/Makefile.am | 34 + .../examples/dictionary/edict/Makefile.am | 4 + .../examples/dictionary/edict/edict-import.sh | 21 + .../examples/dictionary/edict/edict2grn.rb | 56 + .../examples/dictionary/eijiro/Makefile.am | 4 + .../dictionary/eijiro/eijiro-import.sh | 12 + .../examples/dictionary/eijiro/eijiro2grn.rb | 61 + .../examples/dictionary/gene95/Makefile.am | 4 + .../examples/dictionary/gene95/gene-import.sh | 26 + .../examples/dictionary/gene95/gene2grn.rb | 46 + .../dictionary/html/css/dictionary.css | 3 + .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes .../smoothness/jquery-ui-1.8.12.custom.css | 578 + .../examples/dictionary/html/index.html | 28 + .../examples/dictionary/html/js/dictionary.js | 82 + .../dictionary/html/js/jquery-1.7.2.js | 9404 ++++++++++++ .../html/js/jquery-ui-1.8.18.custom.js | 11802 ++++++++++++++++ .../html/js/jquery-ui-1.8.18.custom.min.js | 356 + .../groonga/examples/dictionary/init-db.sh | 10 + .../examples/dictionary/jmdict/Makefile.am | 3 + .../examples/dictionary/jmdict/jmdict.rb | 42 + .../groonga/examples/dictionary/readme.txt | 71 + .../vendor/groonga/groonga-httpd-conf.sh.in | 4 +- .../vendor/groonga/include/CMakeLists.txt | 8 +- .../mroonga/vendor/groonga/include/groonga.h | 2093 +-- .../groonga/include/groonga/Makefile.am | 11 +- .../vendor/groonga/include/groonga/command.h | 79 + .../vendor/groonga/include/groonga/expr.h | 108 + .../vendor/groonga/include/groonga/groonga.h | 1994 +++ .../vendor/groonga/include/groonga/ii.h | 46 + .../vendor/groonga/include/groonga/nfkc.h | 6 +- .../vendor/groonga/include/groonga/obj.h | 37 + .../vendor/groonga/include/groonga/output.h | 108 + .../vendor/groonga/include/groonga/plugin.h | 29 +- .../include/groonga/request_canceler.h | 39 + .../vendor/groonga/include/groonga/scorer.h | 88 + .../vendor/groonga/include/groonga/token.h | 136 + .../groonga/include/groonga/token_filter.h | 10 +- .../groonga/include/groonga/tokenizer.h | 113 +- .../groonga/{lib => include/groonga}/util.h | 34 +- .../mroonga/vendor/groonga/lib/CMakeLists.txt | 59 +- .../mroonga/vendor/groonga/lib/Makefile.am | 33 +- storage/mroonga/vendor/groonga/lib/com.c | 138 +- storage/mroonga/vendor/groonga/lib/command.c | 194 + storage/mroonga/vendor/groonga/lib/ctx.c | 257 +- .../mroonga/vendor/groonga/lib/ctx_impl_mrb.c | 155 +- storage/mroonga/vendor/groonga/lib/dat.cpp | 27 +- .../vendor/groonga/lib/dat/Makefile.am | 3 +- .../mroonga/vendor/groonga/lib/dat/dat.hpp | 12 - .../vendor/groonga/lib/dat/file-impl.cpp | 12 +- storage/mroonga/vendor/groonga/lib/db.c | 2183 ++- storage/mroonga/vendor/groonga/lib/error.c | 31 +- storage/mroonga/vendor/groonga/lib/expr.c | 1645 +-- storage/mroonga/vendor/groonga/lib/geo.c | 42 +- .../groonga/lib/{groonga_in.h => grn.h} | 363 +- .../vendor/groonga/lib/{com.h => grn_com.h} | 14 +- .../vendor/groonga/lib/{ctx.h => grn_ctx.h} | 134 +- .../lib/{ctx_impl.h => grn_ctx_impl.h} | 19 +- .../{ctx_impl_mrb.h => grn_ctx_impl_mrb.h} | 4 +- .../vendor/groonga/lib/{dat.h => grn_dat.h} | 22 +- .../vendor/groonga/lib/{db.h => grn_db.h} | 61 +- .../lib/{ecmascript.c => grn_ecmascript.c} | 300 +- .../lib/{ecmascript.h => grn_ecmascript.h} | 0 ...{ecmascript.lemon => grn_ecmascript.lemon} | 0 .../groonga/lib/{error.h => grn_error.h} | 8 +- .../vendor/groonga/lib/{expr.h => grn_expr.h} | 6 +- .../vendor/groonga/lib/{geo.h => grn_geo.h} | 10 +- .../vendor/groonga/lib/{hash.h => grn_hash.h} | 9 +- .../vendor/groonga/lib/{ii.h => grn_ii.h} | 25 +- .../vendor/groonga/lib/{io.h => grn_io.h} | 38 +- .../vendor/groonga/lib/{mrb.h => grn_mrb.h} | 7 +- .../lib/{normalizer_in.h => grn_normalizer.h} | 20 +- .../groonga/lib/{output.h => grn_output.h} | 38 +- .../vendor/groonga/lib/{pat.h => grn_pat.h} | 9 +- .../groonga/lib/{plugin_in.h => grn_plugin.h} | 21 +- .../vendor/groonga/lib/{proc.h => grn_proc.h} | 4 +- .../vendor/groonga/lib/grn_request_canceler.h | 31 + storage/mroonga/vendor/groonga/lib/grn_rset.h | 115 + .../mroonga/vendor/groonga/lib/grn_scorer.h | 49 + .../mroonga/vendor/groonga/lib/grn_scorers.h | 33 + .../vendor/groonga/lib/{snip.h => grn_snip.h} | 10 +- .../groonga/lib/{store.h => grn_store.h} | 19 +- .../vendor/groonga/lib/{str.h => grn_str.h} | 9 +- .../groonga/lib/{string_in.h => grn_string.h} | 16 +- .../lib/{token.h => grn_token_cursor.h} | 53 +- .../vendor/groonga/lib/grn_tokenizers.h | 38 + storage/mroonga/vendor/groonga/lib/grn_util.h | 36 + storage/mroonga/vendor/groonga/lib/hash.c | 8 +- storage/mroonga/vendor/groonga/lib/ii.c | 721 +- storage/mroonga/vendor/groonga/lib/io.c | 835 +- storage/mroonga/vendor/groonga/lib/mrb.c | 94 +- .../vendor/groonga/lib/mrb/mrb_accessor.c | 4 +- .../vendor/groonga/lib/mrb/mrb_accessor.h | 4 +- .../vendor/groonga/lib/mrb/mrb_array.c | 60 + .../vendor/groonga/lib/mrb/mrb_array.h | 34 + .../mroonga/vendor/groonga/lib/mrb/mrb_bulk.c | 117 +- .../mroonga/vendor/groonga/lib/mrb/mrb_bulk.h | 11 +- .../vendor/groonga/lib/mrb/mrb_column.c | 39 +- .../vendor/groonga/lib/mrb/mrb_column.h | 2 +- .../vendor/groonga/lib/mrb/mrb_command.c | 180 + .../vendor/groonga/lib/mrb/mrb_command.h | 36 + .../groonga/lib/mrb/mrb_command_input.c | 122 + .../groonga/lib/mrb/mrb_command_input.h | 34 + .../vendor/groonga/lib/mrb/mrb_converter.c | 104 +- .../vendor/groonga/lib/mrb/mrb_converter.h | 9 +- .../mroonga/vendor/groonga/lib/mrb/mrb_ctx.c | 43 +- .../mroonga/vendor/groonga/lib/mrb/mrb_ctx.h | 4 +- .../vendor/groonga/lib/mrb/mrb_database.c | 124 + .../vendor/groonga/lib/mrb/mrb_database.h | 34 + .../groonga/lib/mrb/mrb_double_array_trie.c | 60 + .../groonga/lib/mrb/mrb_double_array_trie.h | 34 + .../vendor/groonga/lib/mrb/mrb_error.c | 161 +- .../vendor/groonga/lib/mrb/mrb_error.h | 2 +- .../mroonga/vendor/groonga/lib/mrb/mrb_expr.c | 256 +- .../mroonga/vendor/groonga/lib/mrb/mrb_expr.h | 4 +- .../groonga/lib/mrb/mrb_fixed_size_column.c | 2 +- .../groonga/lib/mrb/mrb_fixed_size_column.h | 2 +- .../vendor/groonga/lib/mrb/mrb_hash_table.c | 60 + .../vendor/groonga/lib/mrb/mrb_hash_table.h | 34 + .../mroonga/vendor/groonga/lib/mrb/mrb_id.c | 7 +- .../mroonga/vendor/groonga/lib/mrb/mrb_id.h | 2 +- .../vendor/groonga/lib/mrb/mrb_index_column.c | 2 +- .../vendor/groonga/lib/mrb/mrb_index_column.h | 2 +- .../vendor/groonga/lib/mrb/mrb_index_cursor.c | 128 + .../vendor/groonga/lib/mrb/mrb_index_cursor.h | 34 + .../vendor/groonga/lib/mrb/mrb_logger.c | 4 +- .../vendor/groonga/lib/mrb/mrb_logger.h | 2 +- .../lib/mrb/{mrb_obj.c => mrb_object.c} | 67 +- .../vendor/groonga/lib/mrb/mrb_object.h | 34 + .../vendor/groonga/lib/mrb/mrb_operator.c | 2 +- .../vendor/groonga/lib/mrb/mrb_operator.h | 2 +- .../groonga/lib/mrb/mrb_patricia_trie.c | 59 + .../groonga/lib/mrb/mrb_patricia_trie.h | 34 + .../vendor/groonga/lib/mrb/mrb_procedure.c | 14 +- .../vendor/groonga/lib/mrb/mrb_procedure.h | 2 +- .../vendor/groonga/lib/mrb/mrb_table.c | 226 + .../vendor/groonga/lib/mrb/mrb_table.h | 34 + .../vendor/groonga/lib/mrb/mrb_table_cursor.c | 211 + .../vendor/groonga/lib/mrb/mrb_table_cursor.h | 34 + .../groonga/lib/mrb/mrb_table_cursor_flags.c | 60 + .../groonga/lib/mrb/mrb_table_cursor_flags.h | 34 + .../mroonga/vendor/groonga/lib/mrb/mrb_type.c | 60 + .../groonga/lib/mrb/{mrb_obj.h => mrb_type.h} | 12 +- .../lib/mrb/mrb_variable_size_column.c | 2 +- .../lib/mrb/mrb_variable_size_column.h | 2 +- .../mroonga/vendor/groonga/lib/mrb/mrb_void.c | 4 +- .../mroonga/vendor/groonga/lib/mrb/mrb_void.h | 2 +- .../vendor/groonga/lib/mrb/mrb_writer.c | 223 + .../vendor/groonga/lib/mrb/mrb_writer.h | 34 + .../vendor/groonga/lib/mrb/scripts/command.rb | 35 + .../lib/mrb/scripts/command_line/grndb.rb | 169 + .../vendor/groonga/lib/mrb/scripts/context.rb | 39 +- .../groonga/lib/mrb/scripts/context/rc.rb | 242 +- .../groonga/lib/mrb/scripts/database.rb | 39 + .../vendor/groonga/lib/mrb/scripts/error.rb | 16 + .../groonga/lib/mrb/scripts/index_cursor.rb | 18 + .../lib/mrb/scripts/initialize/post.rb | 14 + .../groonga/lib/mrb/scripts/initialize/pre.rb | 1 + .../vendor/groonga/lib/mrb/scripts/logger.rb | 6 +- .../groonga/lib/mrb/scripts/plugin_loader.rb | 14 + .../vendor/groonga/lib/mrb/scripts/require.rb | 68 + .../groonga/lib/mrb/scripts/scan_info.rb | 3 + .../lib/mrb/scripts/scan_info_builder.rb | 28 +- .../groonga/lib/mrb/scripts/scan_info_data.rb | 67 +- .../vendor/groonga/lib/mrb/scripts/sources.am | 13 +- .../groonga/lib/mrb/scripts/table_cursor.rb | 26 + .../vendor/groonga/lib/mrb/scripts/writer.rb | 21 + .../mroonga/vendor/groonga/lib/mrb/sources.am | 32 +- storage/mroonga/vendor/groonga/lib/nfkc.c | 5 +- .../mroonga/vendor/groonga/lib/normalizer.c | 4 +- storage/mroonga/vendor/groonga/lib/obj.c | 106 + storage/mroonga/vendor/groonga/lib/operator.c | 596 + storage/mroonga/vendor/groonga/lib/output.c | 202 +- storage/mroonga/vendor/groonga/lib/pat.c | 16 +- storage/mroonga/vendor/groonga/lib/plugin.c | 393 +- storage/mroonga/vendor/groonga/lib/proc.c | 2055 ++- .../vendor/groonga/lib/request_canceler.c | 123 + storage/mroonga/vendor/groonga/lib/rset.c | 324 + storage/mroonga/vendor/groonga/lib/scorer.c | 134 + storage/mroonga/vendor/groonga/lib/scorers.c | 57 + storage/mroonga/vendor/groonga/lib/snip.c | 6 +- storage/mroonga/vendor/groonga/lib/sources.am | 65 +- storage/mroonga/vendor/groonga/lib/store.c | 174 +- storage/mroonga/vendor/groonga/lib/str.c | 26 +- storage/mroonga/vendor/groonga/lib/string.c | 10 +- .../mroonga/vendor/groonga/lib/token_cursor.c | 357 + .../mroonga/vendor/groonga/lib/token_filter.c | 4 +- .../mroonga/vendor/groonga/lib/tokenizer.c | 37 +- .../groonga/lib/{token.c => tokenizers.c} | 393 +- storage/mroonga/vendor/groonga/lib/util.c | 191 +- storage/mroonga/vendor/groonga/nginx_version | 2 +- .../vendor/groonga/plugins/CMakeLists.txt | 9 +- .../vendor/groonga/plugins/Makefile.am | 10 +- .../plugins/query_expanders/CMakeLists.txt | 4 +- .../groonga/plugins/query_expanders/tsv.c | 10 +- .../groonga/plugins/ruby/CMakeLists.txt | 8 +- .../vendor/groonga/plugins/ruby/ruby_plugin.h | 10 +- .../vendor/groonga/plugins/ruby_scripts.am | 2 + .../vendor/groonga/plugins/sharding.rb | 3 + .../groonga/plugins/sharding/CMakeLists.txt | 22 + .../groonga/plugins/sharding/Makefile.am | 9 + .../groonga/plugins/sharding/logical_count.rb | 160 + .../plugins/sharding/logical_enumerator.rb | 170 + .../plugins/sharding/logical_range_filter.rb | 186 + .../groonga/plugins/sharding/sources.am | 4 + .../groonga/plugins/suggest/CMakeLists.txt | 4 +- .../vendor/groonga/plugins/suggest/suggest.c | 47 +- .../groonga/plugins/table/CMakeLists.txt | 4 +- .../vendor/groonga/plugins/table/table.c | 8 +- .../plugins/token_filters/CMakeLists.txt | 17 +- .../groonga/plugins/token_filters/Makefile.am | 8 + .../groonga/plugins/token_filters/stem.c | 275 + .../plugins/token_filters/stem_sources.am | 2 + .../groonga/plugins/token_filters/stop_word.c | 4 +- .../groonga/plugins/tokenizers/CMakeLists.txt | 8 +- .../vendor/groonga/plugins/tokenizers/mecab.c | 24 +- .../mroonga/vendor/groonga/src/CMakeLists.txt | 12 +- .../mroonga/vendor/groonga/src/Makefile.am | 19 +- storage/mroonga/vendor/groonga/src/grndb.c | 137 + .../vendor/groonga/src/grndb_sources.am | 2 + storage/mroonga/vendor/groonga/src/grnslap.c | 8 +- storage/mroonga/vendor/groonga/src/groonga.c | 519 +- .../vendor/groonga/src/groonga_benchmark.c | 41 +- .../vendor/groonga/src/groonga_mruby.c | 84 + .../groonga/src/groonga_mruby_sources.am | 2 + .../nginx-module/ngx_http_groonga_module.c | 269 +- .../vendor/groonga/src/suggest/CMakeLists.txt | 16 +- .../suggest/groonga_suggest_create_dataset.c | 2 +- .../src/suggest/groonga_suggest_httpd.c | 2 +- .../src/suggest/groonga_suggest_learner.c | 2 +- .../groonga/tools/travis-before-script.sh | 56 +- .../vendor/groonga/tools/travis-install.sh | 31 + .../vendor/groonga/tools/travis-script.sh | 24 +- .../mroonga/vendor/groonga/vendor/Makefile.am | 1 + .../groonga/vendor/mruby/CMakeLists.txt | 2 + .../vendor/groonga/vendor/mruby/Makefile.am | 32 +- .../groonga/vendor/mruby/build_config.rb | 3 + .../vendor/groonga/vendor/onigmo/Makefile.am | 11 +- .../plugins/groonga-normalizer-mysql/AUTHORS | 1 - .../groonga-normalizer-mysql/CMakeLists.txt | 23 +- .../groonga-normalizer-mysql/ChangeLog | 0 .../plugins/groonga-normalizer-mysql/INSTALL | 1 - .../plugins/groonga-normalizer-mysql/NEWS | 1 - .../plugins/groonga-normalizer-mysql/README | 1 - .../groonga-normalizer-mysql/README.md | 18 +- .../groonga-normalizer-mysql/configure.ac | 34 +- .../doc/text/Makefile.am | 5 +- .../groonga-normalizer-mysql/doc/text/news.md | 12 + .../normalizers/CMakeLists.txt | 18 +- .../normalizers/mysql.c | 10 +- .../packages/apt/Vagrantfile | 5 +- .../packages/apt/build-deb.sh | 2 +- .../packages/debian/changelog | 12 + .../packages/debian/control | 20 +- .../packages/debian/copyright | 98 +- .../packages/debian/rules | 2 + .../packages/debian/watch | 2 + .../centos/groonga-normalizer-mysql.spec.in | 7 +- .../fedora/groonga-normalizer-mysql.spec.in | 7 +- .../packages/ubuntu/Makefile.am | 2 +- .../packages/yum/Makefile.am | 1 - .../packages/yum/Vagrantfile | 8 +- .../plugins/groonga-normalizer-mysql/version | 2 +- storage/mroonga/version | 2 +- storage/mroonga/version_in_hex | 2 +- storage/mroonga/version_major | 2 +- storage/mroonga/version_micro | 2 +- 416 files changed, 46200 insertions(+), 7060 deletions(-) create mode 100644 storage/mroonga/appveyor.yml create mode 100644 storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_lz4.inc create mode 100644 storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zlib.inc create mode 100644 storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_lz4.inc create mode 100644 storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zlib.inc create mode 100644 storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_lz4.inc create mode 100644 storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zlib.inc create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_unique_multiple_column_duplicated.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/alter_table_disable_keys_fulltext_table.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/alter_table_enable_keys_fulltext_table.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_vector_other_table.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_lz4.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_zlib.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_lz4.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_zlib.result rename storage/mroonga/mysql-test/mroonga/storage/r/{create_table_normalizer_fulltext_index.result => create_table_normalizer_fulltext_index_comment.result} (100%) rename storage/mroonga/mysql-test/mroonga/storage/r/{create_table_normalizer_no_utf8_charset_with_utf8_normalizer.result => create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.result} (100%) create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_none.result rename storage/mroonga/mysql-test/mroonga/storage/r/{create_table_normalizer_table_comment.result => create_table_normalizer_primary_key_table_comment.result} (100%) create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/index_unique_search_after_duplicated.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/partition_insert.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_column.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_leading_not.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_update.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_syntax_query.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_syntax_script.result create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_multiple_column_duplicated.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_table.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_table.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_vector_other_table.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_lz4.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zlib.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_lz4.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zlib.test rename storage/mroonga/mysql-test/mroonga/storage/t/{create_table_normalizer_fulltext_index.test => create_table_normalizer_fulltext_index_comment.test} (100%) rename storage/mroonga/mysql-test/mroonga/storage/t/{create_table_normalizer_no_utf8_charset_with_utf8_normalizer.test => create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.test} (100%) create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_none.test rename storage/mroonga/mysql-test/mroonga/storage/t/{create_table_normalizer_table_comment.test => create_table_normalizer_primary_key_table_comment.test} (100%) create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/index_unique_search_after_duplicated.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/partition_insert.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_column.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_leading_not.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_update.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_query.test create mode 100644 storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_script.test create mode 100644 storage/mroonga/packages/Makefile.am create mode 100644 storage/mroonga/packages/apt/Makefile.am create mode 100644 storage/mroonga/packages/apt/Vagrantfile create mode 100755 storage/mroonga/packages/apt/build-deb.sh create mode 100644 storage/mroonga/packages/apt/env.sh.in create mode 100755 storage/mroonga/packages/apt/sign-packages.sh create mode 100755 storage/mroonga/packages/apt/sign-repository.sh create mode 100755 storage/mroonga/packages/apt/update-repository.sh create mode 100755 storage/mroonga/packages/check-utility.sh create mode 100644 storage/mroonga/packages/debian/apparmor/mysql-server-mroonga create mode 100644 storage/mroonga/packages/debian/changelog create mode 100644 storage/mroonga/packages/debian/compat create mode 100644 storage/mroonga/packages/debian/control.in create mode 100644 storage/mroonga/packages/debian/copyright create mode 100644 storage/mroonga/packages/debian/mysql-server-mroonga-doc.install create mode 100644 storage/mroonga/packages/debian/mysql-server-mroonga.install create mode 100755 storage/mroonga/packages/debian/mysql-server-mroonga.postinst create mode 100755 storage/mroonga/packages/debian/mysql-server-mroonga.postrm create mode 100755 storage/mroonga/packages/debian/mysql-server-mroonga.prerm create mode 100755 storage/mroonga/packages/debian/rules create mode 100644 storage/mroonga/packages/rpm/Makefile.am create mode 100644 storage/mroonga/packages/rpm/centos/Makefile.am create mode 100644 storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in create mode 100644 storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in create mode 100644 storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in create mode 100644 storage/mroonga/packages/source/Makefile.am create mode 100644 storage/mroonga/packages/source/patches/mariadb-10.0.3-windows-build.diff create mode 100644 storage/mroonga/packages/ubuntu/Makefile.am create mode 100755 storage/mroonga/packages/ubuntu/upload.rb create mode 100644 storage/mroonga/packages/windows/Makefile.am create mode 100644 storage/mroonga/packages/windows/README.md create mode 100644 storage/mroonga/packages/windows/build-vc2010-msi-32.bat create mode 100644 storage/mroonga/packages/windows/build-vc2010-msi-64.bat create mode 100644 storage/mroonga/packages/windows/build-vc2010-zip-32.bat create mode 100644 storage/mroonga/packages/windows/build-vc2010-zip-64.bat create mode 100644 storage/mroonga/packages/windows/build-vc2010.bat create mode 100644 storage/mroonga/packages/windows/build-vc2013-msi-32.bat create mode 100644 storage/mroonga/packages/windows/build-vc2013-msi-64.bat create mode 100644 storage/mroonga/packages/windows/build-vc2013-zip-32.bat create mode 100644 storage/mroonga/packages/windows/build-vc2013-zip-64.bat create mode 100644 storage/mroonga/packages/windows/build-vc2013.bat create mode 100644 storage/mroonga/packages/yum/Makefile.am create mode 100644 storage/mroonga/packages/yum/Vagrantfile create mode 100755 storage/mroonga/packages/yum/build-in-vm.sh create mode 100755 storage/mroonga/packages/yum/build-rpm.sh create mode 100644 storage/mroonga/packages/yum/env.sh.in create mode 100755 storage/mroonga/packages/yum/sign-rpm.sh create mode 100755 storage/mroonga/packages/yum/update-repository.sh create mode 100644 storage/mroonga/vendor/groonga/appveyor.yml create mode 100644 storage/mroonga/vendor/groonga/examples/Makefile.am create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/Makefile.am create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/edict/Makefile.am create mode 100755 storage/mroonga/vendor/groonga/examples/dictionary/edict/edict-import.sh create mode 100755 storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/eijiro/Makefile.am create mode 100755 storage/mroonga/vendor/groonga/examples/dictionary/eijiro/eijiro-import.sh create mode 100755 storage/mroonga/vendor/groonga/examples/dictionary/eijiro/eijiro2grn.rb create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/gene95/Makefile.am create mode 100755 storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene-import.sh create mode 100755 storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/dictionary.css create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_222222_256x240.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_2e83ff_256x240.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_454545_256x240.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_888888_256x240.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_cd0a0a_256x240.png create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/jquery-ui-1.8.12.custom.css create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/index.html create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/js/dictionary.js create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-1.7.2.js create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-ui-1.8.18.custom.js create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-ui-1.8.18.custom.min.js create mode 100755 storage/mroonga/vendor/groonga/examples/dictionary/init-db.sh create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/jmdict/Makefile.am create mode 100755 storage/mroonga/vendor/groonga/examples/dictionary/jmdict/jmdict.rb create mode 100644 storage/mroonga/vendor/groonga/examples/dictionary/readme.txt create mode 100644 storage/mroonga/vendor/groonga/include/groonga/command.h create mode 100644 storage/mroonga/vendor/groonga/include/groonga/expr.h create mode 100644 storage/mroonga/vendor/groonga/include/groonga/groonga.h create mode 100644 storage/mroonga/vendor/groonga/include/groonga/ii.h create mode 100644 storage/mroonga/vendor/groonga/include/groonga/obj.h create mode 100644 storage/mroonga/vendor/groonga/include/groonga/output.h create mode 100644 storage/mroonga/vendor/groonga/include/groonga/request_canceler.h create mode 100644 storage/mroonga/vendor/groonga/include/groonga/scorer.h create mode 100644 storage/mroonga/vendor/groonga/include/groonga/token.h rename storage/mroonga/vendor/groonga/{lib => include/groonga}/util.h (59%) create mode 100644 storage/mroonga/vendor/groonga/lib/command.c rename storage/mroonga/vendor/groonga/lib/{groonga_in.h => grn.h} (73%) rename storage/mroonga/vendor/groonga/lib/{com.h => grn_com.h} (97%) rename storage/mroonga/vendor/groonga/lib/{ctx.h => grn_ctx.h} (85%) rename storage/mroonga/vendor/groonga/lib/{ctx_impl.h => grn_ctx_impl.h} (92%) rename storage/mroonga/vendor/groonga/lib/{ctx_impl_mrb.h => grn_ctx_impl_mrb.h} (95%) rename storage/mroonga/vendor/groonga/lib/{dat.h => grn_dat.h} (78%) rename storage/mroonga/vendor/groonga/lib/{db.h => grn_db.h} (94%) rename storage/mroonga/vendor/groonga/lib/{ecmascript.c => grn_ecmascript.c} (95%) rename storage/mroonga/vendor/groonga/lib/{ecmascript.h => grn_ecmascript.h} (100%) rename storage/mroonga/vendor/groonga/lib/{ecmascript.lemon => grn_ecmascript.lemon} (100%) rename storage/mroonga/vendor/groonga/lib/{error.h => grn_error.h} (88%) rename storage/mroonga/vendor/groonga/lib/{expr.h => grn_expr.h} (94%) rename storage/mroonga/vendor/groonga/lib/{geo.h => grn_geo.h} (98%) rename storage/mroonga/vendor/groonga/lib/{hash.h => grn_hash.h} (98%) rename storage/mroonga/vendor/groonga/lib/{ii.h => grn_ii.h} (93%) rename storage/mroonga/vendor/groonga/lib/{io.h => grn_io.h} (93%) rename storage/mroonga/vendor/groonga/lib/{mrb.h => grn_mrb.h} (89%) rename storage/mroonga/vendor/groonga/lib/{normalizer_in.h => grn_normalizer.h} (80%) rename storage/mroonga/vendor/groonga/lib/{output.h => grn_output.h} (74%) rename storage/mroonga/vendor/groonga/lib/{pat.h => grn_pat.h} (96%) rename storage/mroonga/vendor/groonga/lib/{plugin_in.h => grn_plugin.h} (84%) rename storage/mroonga/vendor/groonga/lib/{proc.h => grn_proc.h} (93%) create mode 100644 storage/mroonga/vendor/groonga/lib/grn_request_canceler.h create mode 100644 storage/mroonga/vendor/groonga/lib/grn_rset.h create mode 100644 storage/mroonga/vendor/groonga/lib/grn_scorer.h create mode 100644 storage/mroonga/vendor/groonga/lib/grn_scorers.h rename storage/mroonga/vendor/groonga/lib/{snip.h => grn_snip.h} (96%) rename storage/mroonga/vendor/groonga/lib/{store.h => grn_store.h} (94%) rename storage/mroonga/vendor/groonga/lib/{str.h => grn_str.h} (96%) rename storage/mroonga/vendor/groonga/lib/{string_in.h => grn_string.h} (89%) rename storage/mroonga/vendor/groonga/lib/{token.h => grn_token_cursor.h} (66%) create mode 100644 storage/mroonga/vendor/groonga/lib/grn_tokenizers.h create mode 100644 storage/mroonga/vendor/groonga/lib/grn_util.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_array.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_array.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_command.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_command.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_command_input.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_database.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_database.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_double_array_trie.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_hash_table.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_index_cursor.h rename storage/mroonga/vendor/groonga/lib/mrb/{mrb_obj.c => mrb_object.c} (70%) create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_object.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_patricia_trie.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_table.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_table.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_table_cursor_flags.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_type.c rename storage/mroonga/vendor/groonga/lib/mrb/{mrb_obj.h => mrb_type.h} (82%) create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.c create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/mrb_writer.h create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/command.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/command_line/grndb.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/database.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/error.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/index_cursor.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/post.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/initialize/pre.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/plugin_loader.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/require.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/table_cursor.rb create mode 100644 storage/mroonga/vendor/groonga/lib/mrb/scripts/writer.rb create mode 100644 storage/mroonga/vendor/groonga/lib/obj.c create mode 100644 storage/mroonga/vendor/groonga/lib/operator.c create mode 100644 storage/mroonga/vendor/groonga/lib/request_canceler.c create mode 100644 storage/mroonga/vendor/groonga/lib/rset.c create mode 100644 storage/mroonga/vendor/groonga/lib/scorer.c create mode 100644 storage/mroonga/vendor/groonga/lib/scorers.c create mode 100644 storage/mroonga/vendor/groonga/lib/token_cursor.c rename storage/mroonga/vendor/groonga/lib/{token.c => tokenizers.c} (57%) create mode 100644 storage/mroonga/vendor/groonga/plugins/ruby_scripts.am create mode 100644 storage/mroonga/vendor/groonga/plugins/sharding.rb create mode 100644 storage/mroonga/vendor/groonga/plugins/sharding/CMakeLists.txt create mode 100644 storage/mroonga/vendor/groonga/plugins/sharding/Makefile.am create mode 100644 storage/mroonga/vendor/groonga/plugins/sharding/logical_count.rb create mode 100644 storage/mroonga/vendor/groonga/plugins/sharding/logical_enumerator.rb create mode 100644 storage/mroonga/vendor/groonga/plugins/sharding/logical_range_filter.rb create mode 100644 storage/mroonga/vendor/groonga/plugins/sharding/sources.am create mode 100644 storage/mroonga/vendor/groonga/plugins/token_filters/stem.c create mode 100644 storage/mroonga/vendor/groonga/plugins/token_filters/stem_sources.am create mode 100644 storage/mroonga/vendor/groonga/src/grndb.c create mode 100644 storage/mroonga/vendor/groonga/src/grndb_sources.am create mode 100644 storage/mroonga/vendor/groonga/src/groonga_mruby.c create mode 100644 storage/mroonga/vendor/groonga/src/groonga_mruby_sources.am create mode 100755 storage/mroonga/vendor/groonga/tools/travis-install.sh delete mode 100644 storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/AUTHORS delete mode 100644 storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/ChangeLog delete mode 100644 storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/INSTALL delete mode 100644 storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/NEWS delete mode 100644 storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/README create mode 100644 storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/doc/text/news.md create mode 100644 storage/mroonga/vendor/groonga/vendor/plugins/groonga-normalizer-mysql/packages/debian/watch diff --git a/storage/mroonga/CMakeLists.txt b/storage/mroonga/CMakeLists.txt index faad871fa95..ff72953bfac 100644 --- a/storage/mroonga/CMakeLists.txt +++ b/storage/mroonga/CMakeLists.txt @@ -1,6 +1,6 @@ # -*- indent-tabs-mode: nil -*- # -# Copyright(C) 2012-2014 Kouhei Sutou +# Copyright(C) 2012-2015 Kouhei Sutou # Copyright(C) 2013 Kentoku SHIBA # # This library is free software; you can redistribute it and/or @@ -75,6 +75,28 @@ file(READ ${MRN_SOURCE_DIR}/version_in_hex MRN_VERSION_IN_HEX) file(READ ${MRN_SOURCE_DIR}/plugin_version MRN_PLUGIN_VERSION) if(MRN_GROONGA_BUNDLED) + option(MRN_GROONGA_EMBED + "Embed libgroonga" + ON) + if(MRN_GROONGA_EMBED) + set(GRN_EMBED ON) + endif() + + set(MRN_BUNDLED_GROONGA_NORMALIZER_MYSQL_DIR + "${MRN_BUNDLED_GROONGA_DIR}/vendor/plugins/groonga-normalizer-mysql") + option(MRN_GROONGA_NORMALIZER_MYSQL_EMBED + "Embed groonga-normalizer-mysql Groonga plugin" + ON) + if(EXISTS ${MRN_BUNDLED_GROONGA_NORMALIZER_MYSQL_DIR}) + set(GROONGA_NORMALIZER_MYSQL_FOUND ON) + else() + set(GROONGA_NORMALIZER_MYSQL_FOUND OFF) + set(MRN_GROONGA_NORMALIZER_MYSQL_EMBED OFF) + endif() + if(MRN_GROONGA_NORMALIZER_MYSQL_EMBED) + set(GROONGA_NORMALIZER_MYSQL_EMBED ON) + endif() + add_subdirectory("${MRN_BUNDLED_GROONGA_RELATIVE_DIR}") else() file(READ ${MRN_SOURCE_DIR}/required_groonga_version REQUIRED_GROONGA_VERSION) @@ -98,15 +120,21 @@ set(MRN_C_COMPILE_FLAGS "") set(MRN_CXX_COMPILE_FLAGS "") macro(mrn_check_cflag flag) - check_c_compiler_flag(${flag} "HAVE_C_${flag}") - if(HAVE_C_${flag}) + string(REGEX REPLACE "[-=]" "_" temporary_variable_name ${flag}) + string(TOUPPER "${temporary_variable_name}" temporary_variable_name) + set(temporary_variable_name "CFLAG${temporary_variable_name}") + check_c_compiler_flag(${flag} ${temporary_variable_name}) + if(${temporary_variable_name}) set(MRN_C_COMPILE_FLAGS "${MRN_C_COMPILE_FLAGS} ${flag}") endif() endmacro() macro(mrn_check_cxxflag flag) - check_cxx_compiler_flag(${flag} "HAVE_CXX_${flag}") - if(HAVE_CXX_${flag}) + string(REGEX REPLACE "[-=]" "_" temporary_variable_name ${flag}) + string(TOUPPER "${temporary_variable_name}" temporary_variable_name) + set(temporary_variable_name "CXXFLAG${temporary_variable_name}") + check_cxx_compiler_flag(${flag} ${temporary_variable_name}) + if(${temporary_variable_name}) set(MRN_CXX_COMPILE_FLAGS "${MRN_CXX_COMPILE_FLAGS} ${flag}") endif() endmacro() @@ -122,7 +150,7 @@ else() set(MRN_RELATIVE_DIR_PREFIX "") endif() -read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am MROONGA_SOURCES) +read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am MRN_SOURCES) read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/lib/libmrn_no_mysql_sources.am LIBMRN_NO_MYSQL_SOURCES) string(REGEX REPLACE "([^;]+)" "${MRN_RELATIVE_DIR_PREFIX}lib/\\1" @@ -157,11 +185,18 @@ else() set(MYSQL_REGEX_INCLUDE_DIR "${MYSQL_SOURCE_DIR}/regex") endif() +if(EXISTS "${MYSQL_SOURCE_DIR}/extra/rapidjson") + set(MYSQL_RAPIDJSON_INCLUDE_DIR "${MYSQL_SOURCE_DIR}/extra/rapidjson/include") +else() + set(MYSQL_RAPIDJSON_INCLUDE_DIR) +endif() + set(MYSQL_INCLUDE_DIRS "${MYSQL_BUILD_DIR}/include" "${MYSQL_SOURCE_DIR}/sql" "${MYSQL_SOURCE_DIR}/include" "${MYSQL_REGEX_INCLUDE_DIR}" + "${MYSQL_RAPIDJSON_INCLUDE_DIR}" "${MYSQL_SOURCE_DIR}") if(MRN_BUNDLED) @@ -190,6 +225,12 @@ else() set_mysql_config_value("--version" MYSQL_VERSION) endif() +if(${MYSQL_VERSION} VERSION_LESS "5.5.0") + message(FATAL_ERROR + "Mroonga doesn't support MySQL < 5.5.0: <${MYSQL_VERSION}>") + return() +endif() + if(${MYSQL_VERSION} VERSION_GREATER "10.0.0" AND ${MYSQL_VERSION} VERSION_LESS "10.0.9") message(FATAL_ERROR @@ -201,10 +242,14 @@ if(MRN_GROONGA_BUNDLED) set(GROONGA_INCLUDE_DIRS "${MRN_BUNDLED_GROONGA_DIR}/include") set(GROONGA_LIBRARY_DIRS "${MRN_BUNDLED_GROONGA_DIR}/lib") set(GROONGA_LIBRARIES "libgroonga") - if(EXISTS "${MRN_BUNDLED_GROONGA_DIR}/vendor/plugins/groonga-normalizer-mysql") - set(GROONGA_NORMALIZER_MYSQL_FOUND TRUE) - else() - set(GROONGA_NORMALIZER_MYSQL_FOUND FALSE) + + set(MRN_LIBRARY_DIRS ${GROONGA_LIBRARY_DIRS}) + set(MRN_LIBRARIES ${GROONGA_LIBRARIES}) + if(MRN_GROONGA_NORMALIZER_MYSQL_EMBED) + set(MRN_LIBRARY_DIRS + ${MRN_LIBRARY_DIRS} + "${MRN_BUNDLED_GROONGA_NORMALIZER_MYSQL_DIR}/normalizers") + set(MRN_LIBRARIES ${MRN_LIBRARIES} mysql_normalizer) endif() else() include(FindPkgConfig) @@ -213,12 +258,6 @@ else() "groonga-normalizer-mysql >= ${REQUIRED_GROONGA_NORMALIZER_MYSQL_VERSION}") endif() -if(GROONGA_NORMALIZER_MYSQL_FOUND AND MRN_GROONGA_BUNDLED) - read_file_list(${MRN_BUNDLED_GROONGA_DIR}/vendor/plugins/groonga-normalizer-mysql/normalizers/mysql_sources.am MRN_GRN_NORMALIZER_MYSQL_SOURCES) - string(REGEX REPLACE "([^;]+)" "${MRN_BUNDLED_GROONGA_DIR}/vendor/plugins/groonga-normalizer-mysql/normalizers/\\1" - MRN_GRN_NORMALIZER_MYSQL_SOURCES "${MRN_GRN_NORMALIZER_MYSQL_SOURCES}") -endif() - include_directories( "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}" @@ -235,28 +274,22 @@ else() "${MYSQL_SERVICES_LIB_DIR}") endif() link_directories( - ${GROONGA_LIBRARY_DIRS} + ${MRN_LIBRARY_DIRS} ${MYSQL_LIBRARY_DIRS}) +set(MRN_ALL_SOURCES + ${MRN_SOURCES} + ${MRN_UDF_SOURCES} + ${LIBMRN_NO_MYSQL_SOURCES} + ${LIBMRN_NEED_MYSQL_SOURCES}) + if(MRN_BUNDLED) - if(GROONGA_NORMALIZER_MYSQL_FOUND AND MRN_GROONGA_BUNDLED) - mysql_add_plugin(mroonga - "${MROONGA_SOURCES};${MRN_UDF_SOURCES};${MRN_GRN_NORMALIZER_MYSQL_SOURCES};${LIBMRN_NEED_MYSQL_SOURCES};${LIBMRN_NO_MYSQL_SOURCES}" - STORAGE_ENGINE MODULE_ONLY - LINK_LIBRARIES ${GROONGA_LIBRARIES}) - else() - mysql_add_plugin(mroonga - "${MROONGA_SOURCES};${MRN_UDF_SOURCES};${LIBMRN_NEED_MYSQL_SOURCES};${LIBMRN_NO_MYSQL_SOURCES}" - STORAGE_ENGINE MODULE_ONLY - LINK_LIBRARIES ${GROONGA_LIBRARIES}) - endif() - else() + mysql_add_plugin(mroonga + ${MRN_ALL_SOURCES} + STORAGE_ENGINE MODULE_ONLY + LINK_LIBRARIES ${MRN_LIBRARIES}) else() - add_library(mroonga MODULE - ${MROONGA_SOURCES} - ${MRN_UDF_SOURCES} - ${LIBMRN_NO_MYSQL_SOURCES} - ${LIBMRN_NEED_MYSQL_SOURCES}) + add_library(mroonga MODULE ${MRN_ALL_SOURCES}) set(MYSQL_LIBRARIES "mysqlservices") target_link_libraries(mroonga ${GROONGA_LIBRARIES} ${MYSQL_LIBRARIES}) @@ -303,14 +336,14 @@ else() mrn_check_cxxflag("-fno-rtti") mrn_check_cxxflag("-felide-constructors") endif() - set_source_files_properties(${MROONGA_SOURCES} PROPERTIES + set_source_files_properties(${MRN_SOURCES} PROPERTIES COMPILE_FLAGS "${MYSQL_CFLAGS} ${MRN_CXX_COMPILE_FLAGS}") set_source_files_properties(${LIBMRN_NEED_MYSQL_SOURCES} PROPERTIES COMPILE_FLAGS "${MYSQL_CFLAGS} ${MRN_CXX_COMPILE_FLAGS}") set_source_files_properties(${MRN_UDF_SOURCES} PROPERTIES - COMPILE_FLAGS "${MRN_C_COMPILE_FLAGS}") + COMPILE_FLAGS "${MRN_CXX_COMPILE_FLAGS}") set_source_files_properties(${LIBMRN_NO_MYSQL_SOURCES} PROPERTIES - COMPILE_FLAGS "${MRN_C_COMPILE_FLAGS}") + COMPILE_FLAGS "${MRN_CXX_COMPILE_FLAGS}") set_property(TARGET mroonga APPEND PROPERTY COMPILE_DEFINITIONS "MYSQL_DYNAMIC_PLUGIN") set_target_properties(mroonga PROPERTIES @@ -321,19 +354,20 @@ else() endif() if(GROONGA_NORMALIZER_MYSQL_FOUND) - set(WITH_GROONGA_NORMALIZER_MYSQL 1) - ADD_DEFINITIONS(-DWITH_GROONGA_NORMALIZER_MYSQL=1) - if(MRN_GROONGA_BUNDLED) - ADD_DEFINITIONS(-DGROONGA_NORMALIZER_MYSQL_PLUGIN_IS_BUNDLED_STATIC=1) + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "WITH_GROONGA_NORMALIZER_MYSQL=1") + if(MRN_GROONGA_NORMALIZER_MYSQL_EMBED) + set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "MRN_GROONGA_NORMALIZER_MYSQL_EMBED") else() - set(GROONGA_NORMALIZER_MYSQL_PLUGIN_NAME \"normalizers/mysql\") set_property(TARGET mroonga APPEND PROPERTY COMPILE_DEFINITIONS "GROONGA_NORMALIZER_MYSQL_PLUGIN_NAME=\"normalizers/mysql\"") endif() endif() set(MRN_DEFAULT_PARSER "TokenBigram" CACHE STRING "The default fulltext parser") -ADD_DEFINITIONS(-DMRN_PARSER_DEFAULT="${MRN_DEFAULT_PARSER}") +set_property(TARGET mroonga APPEND PROPERTY + COMPILE_DEFINITIONS "MRN_PARSER_DEFAULT=\"${MRN_DEFAULT_PARSER}\"") configure_file( "${PROJECT_SOURCE_DIR}/mrn_version.h.in" diff --git a/storage/mroonga/Makefile.am b/storage/mroonga/Makefile.am index 32fc88ad061..733347eb2c2 100644 --- a/storage/mroonga/Makefile.am +++ b/storage/mroonga/Makefile.am @@ -67,8 +67,6 @@ update-latest-release: misc misc/update-latest-release.rb \ $(PACKAGE) $(OLD_RELEASE) $(OLD_RELEASE_DATE) \ $(VERSION) $(NEW_RELEASE_DATE) \ - packages/rpm/fedora/mysql-mroonga.spec.in \ - packages/rpm/fedora/mariadb-mroonga.spec.in \ packages/rpm/centos/mariadb-mroonga.spec.in \ packages/rpm/centos/mysql55-mroonga.spec.in \ packages/rpm/centos/mysql56-community-mroonga.spec.in \ diff --git a/storage/mroonga/appveyor.yml b/storage/mroonga/appveyor.yml new file mode 100644 index 00000000000..a048d7d02e1 --- /dev/null +++ b/storage/mroonga/appveyor.yml @@ -0,0 +1,51 @@ +version: "{build}" +clone_depth: 10 +install: + - cd .. + - choco install curl 7zip.commandline + - curl -O http://mirror.jmu.edu/pub/mariadb/mariadb-10.0.16/source/mariadb-10.0.16.tar.gz + - 7z x mariadb-10.0.16.tar.gz + - 7z x mariadb-10.0.16.tar > nul + - cd mariadb-10.0.16 + - rmdir /S /Q storage\mroonga\ + - move ..\mroonga storage\mroonga + - git clone --quiet --depth 1 https://github.com/groonga/groonga.git ..\groonga + - rmdir /S /Q ..\groonga\test\ + - mkdir storage\mroonga\vendor + - move ..\groonga storage\mroonga\vendor\groonga + - git clone --quiet --depth 1 https://github.com/groonga/groonga-normalizer-mysql.git storage\mroonga\vendor\groonga\vendor\plugins\groonga-normalizer-mysql +build_script: + - "echo # > win\\packaging\\CMakeLists.txt" + - cmake . -G "Visual Studio 12 Win64" + -DCMAKE_BUILD_TYPE=Debug + -DWITHOUT_ARCHIVE=ON + -DWITHOUT_BLACKHOLE=ON + -DWITHOUT_CASSANDRA=ON + -DWITHOUT_CONNECT=ON + -DWITHOUT_CSV=ON + -DWITHOUT_EXAMPLE=ON + -DWITHOUT_FEDERATED=ON + -DWITHOUT_FEDERATEDX=ON + -DWITHOUT_HEAP=ON + -DWITHOUT_INNOBASE=ON + -DWITHOUT_MYISAM=ON + -DWITHOUT_MYISAMMRG=ON + -DWITHOUT_OQGRAPH=ON + -DWITHOUT_PERFSCHEMA=OFF + -DWITHOUT_SEQUENCE=ON + -DWITHOUT_SPHINX=ON + -DWITHOUT_SPIDER=ON + -DWITHOUT_TEST_SQL_DISCOVERY=ON + -DWITHOUT_TOKUDB=ON + -DWITHOUT_XTRADB=ON + -DWITH_UNIT_TESTS=OFF + - cmake --build . --config Debug + +notifications: + - provider: Email + to: + - groonga-mysql-commit@lists.sourceforge.jp + - kou@clear-code.com + on_build_status_changed: true + +test: off diff --git a/storage/mroonga/configure.ac b/storage/mroonga/configure.ac index 48312a44c8c..6d8fa0fe31d 100644 --- a/storage/mroonga/configure.ac +++ b/storage/mroonga/configure.ac @@ -174,6 +174,10 @@ AC_DEFUN([CONFIG_OPTION_MYSQL],[ MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_build_dir/include" MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_source_dir/sql" MYSQL_INCLUDES="$MYSQL_INCLUDES -I$ac_mysql_source_dir/include" + if test -d "$ac_mysql_source_dir/extra/rapidjson"; then + mysql_rapidjson_include_dir="$ac_mysql_source_dir/extra/rapidjson/include" + MYSQL_INCLUDES="$MYSQL_INCLUDES -I$mysql_rapidjson_include_dir" + fi if test -d "$ac_mysql_source_dir/pcre"; then mysql_regex_include_dir="$ac_mysql_source_dir/pcre" else @@ -461,7 +465,6 @@ AC_CONFIG_FILES([ packages/Makefile packages/rpm/Makefile packages/rpm/centos/Makefile - packages/rpm/fedora/Makefile packages/yum/Makefile packages/apt/Makefile packages/source/Makefile @@ -486,8 +489,6 @@ AC_OUTPUT([ packages/rpm/centos/mysql55-mroonga.spec packages/rpm/centos/mysql56-community-mroonga.spec packages/rpm/centos/mariadb-mroonga.spec - packages/rpm/fedora/mysql-mroonga.spec - packages/rpm/fedora/mariadb-mroonga.spec packages/yum/env.sh data/install.sql ]) diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index 8b9a08b59dc..3ff89d02e03 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -2,7 +2,7 @@ /* Copyright(C) 2010 Tetsuro IKEDA Copyright(C) 2010-2013 Kentoku SHIBA - Copyright(C) 2011-2014 Kouhei Sutou + Copyright(C) 2011-2015 Kouhei Sutou Copyright(C) 2013 Kenji Maruyama This library is free software; you can redistribute it and/or @@ -116,23 +116,14 @@ } \ } while (0) #else -# if MYSQL_VERSION_ID >= 50500 -# ifdef DBUG_OFF -# ifndef _WIN32 -extern mysql_mutex_t LOCK_open; -# endif -# endif -static mysql_mutex_t *mrn_LOCK_open; -# define mrn_open_mutex_lock(share) mysql_mutex_lock(mrn_LOCK_open) -# define mrn_open_mutex_unlock(share) mysql_mutex_unlock(mrn_LOCK_open) -# else +# ifdef DBUG_OFF # ifndef _WIN32 -extern pthread_mutex_t LOCK_open; +extern mysql_mutex_t LOCK_open; # endif -static pthread_mutex_t *mrn_LOCK_open; -# define mrn_open_mutex_lock(share) -# define mrn_open_mutex_unlock(share) # endif +static mysql_mutex_t *mrn_LOCK_open; +# define mrn_open_mutex_lock(share) mysql_mutex_lock(mrn_LOCK_open) +# define mrn_open_mutex_unlock(share) mysql_mutex_unlock(mrn_LOCK_open) #endif #if MYSQL_VERSION_ID >= 50600 @@ -208,19 +199,44 @@ int grn_atoi(const char *nptr, const char *end, const char **rest); uint grn_atoui(const char *nptr, const char *end, const char **rest); /* global variables */ -static pthread_mutex_t mrn_log_mutex; handlerton *mrn_hton_ptr; HASH mrn_open_tables; -pthread_mutex_t mrn_open_tables_mutex; +mysql_mutex_t mrn_open_tables_mutex; +static PSI_mutex_key mrn_open_tables_mutex_key; HASH mrn_long_term_share; -pthread_mutex_t mrn_long_term_share_mutex; +mysql_mutex_t mrn_long_term_share_mutex; +static PSI_mutex_key mrn_long_term_share_mutex_key; + +HASH mrn_allocated_thds; +mysql_mutex_t mrn_allocated_thds_mutex; +PSI_mutex_key mrn_allocated_thds_mutex_key; + +PSI_mutex_key mrn_share_mutex_key; +PSI_mutex_key mrn_long_term_share_auto_inc_mutex_key; /* internal variables */ static grn_ctx mrn_ctx; +static mysql_mutex_t mrn_log_mutex; +static PSI_mutex_key mrn_log_mutex_key; static grn_obj *mrn_db; static grn_ctx mrn_db_manager_ctx; +static mysql_mutex_t mrn_db_manager_mutex; +static PSI_mutex_key mrn_db_manager_mutex_key; mrn::DatabaseManager *mrn_db_manager = NULL; +static PSI_mutex_info mrn_mutexes[] = +{ + {&mrn_open_tables_mutex_key, "open_tables", PSI_FLAG_GLOBAL}, + {&mrn_long_term_share_mutex_key, "long_term_share", PSI_FLAG_GLOBAL}, + {&mrn_allocated_thds_mutex_key, "allocated_thds", PSI_FLAG_GLOBAL}, + {&mrn_share_mutex_key, "share", 0}, + {&mrn_long_term_share_auto_inc_mutex_key, + "long_term_share::auto_inc", 0}, + {&mrn_log_mutex_key, "log", PSI_FLAG_GLOBAL}, + {&mrn_db_manager_mutex_key, "DatabaseManager", PSI_FLAG_GLOBAL} +}; + + #ifdef WIN32 static inline double round(double x) { @@ -506,6 +522,31 @@ static int mrn_lock_timeout = grn_get_lock_timeout(); static char *mrn_libgroonga_version = const_cast(grn_get_version()); static char *mrn_version = const_cast(MRN_VERSION); static char *mrn_vector_column_delimiter = NULL; +static my_bool mrn_libgroonga_support_zlib = FALSE; +static my_bool mrn_libgroonga_support_lz4 = FALSE; +typedef enum { + MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT = (1 << 0), + MRN_BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_QUERY = (1 << 1), + MRN_BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_SCRIPT = (1 << 2), + MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_COLUMN = (1 << 3), + MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_UPDATE = (1 << 4), + MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_LEADING_NOT = (1 << 5) +} mrn_boolean_mode_syntax_flag; +static const char *mrn_boolean_mode_sytnax_flag_names[] = { + "DEFAULT", + "SYNTAX_QUERY", + "SYNTAX_SCRIPT", + "ALLOW_COLUMN", + "ALLOW_UPDATE", + "ALLOW_LEADING_NOT", + NullS +}; +static TYPELIB mrn_boolean_mode_syntax_flags_typelib = { + array_elements(mrn_boolean_mode_sytnax_flag_names) - 1, + "", + mrn_boolean_mode_sytnax_flag_names, + NULL +}; typedef enum { MRN_ACTION_ON_ERROR_ERROR, @@ -552,9 +593,6 @@ static grn_logger mrn_logger = { NULL }; -/* global hashes and mutexes */ -HASH mrn_allocated_thds; -pthread_mutex_t mrn_allocated_thds_mutex; static uchar *mrn_allocated_thds_get_key(const uchar *record, size_t *length, my_bool not_used __attribute__ ((unused))) @@ -578,13 +616,21 @@ static struct st_mysql_show_var mrn_status_variables[] = {NullS, NullS, SHOW_LONG} }; -static const char *mrn_log_level_type_names[] = { "NONE", "EMERG", "ALERT", - "CRIT", "ERROR", "WARNING", - "NOTICE", "INFO", "DEBUG", - "DUMP", NullS }; -static TYPELIB mrn_log_level_typelib = -{ - array_elements(mrn_log_level_type_names)-1, +static const char *mrn_log_level_type_names[] = { + "NONE", + "EMERG", + "ALERT", + "CRIT", + "ERROR", + "WARNING", + "NOTICE", + "INFO", + "DEBUG", + "DUMP", + NullS +}; +static TYPELIB mrn_log_level_typelib = { + array_elements(mrn_log_level_type_names) - 1, "mrn_log_level_typelib", mrn_log_level_type_names, NULL @@ -678,7 +724,7 @@ static void mrn_log_file_update(THD *thd, struct st_mysql_sys_var *var, #ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR char *old_log_file_name = *old_value_ptr; *old_value_ptr = my_strdup(new_log_file_name, MYF(MY_WME)); - my_free(old_log_file_name, MYF(0)); + my_free(old_log_file_name); #else *old_value_ptr = my_strdup(new_log_file_name, MYF(MY_WME)); #endif @@ -717,7 +763,7 @@ static void mrn_default_parser_update(THD *thd, struct st_mysql_sys_var *var, } #ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR - my_free(*old_value_ptr, MYF(0)); + my_free(*old_value_ptr); *old_value_ptr = my_strdup(new_value, MYF(MY_WME)); #else *old_value_ptr = (char *)new_value; @@ -771,7 +817,7 @@ static void mrn_vector_column_delimiter_update(THD *thd, struct st_mysql_sys_var char **old_value_ptr = (char **)var_ptr; #ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR - my_free(*old_value_ptr, MYF(0)); + my_free(*old_value_ptr); *old_value_ptr = my_strdup(new_value, MYF(MY_WME)); #else *old_value_ptr = (char *)new_value; @@ -796,7 +842,7 @@ static void mrn_database_path_prefix_update(THD *thd, char **old_value_ptr = (char **)var_ptr; #ifdef MRN_NEED_FREE_STRING_MEMALLOC_PLUGIN_VAR if (*old_value_ptr) - my_free(*old_value_ptr, MYF(0)); + my_free(*old_value_ptr); if (new_value) *old_value_ptr = my_strdup(new_value, MYF(MY_WME)); else @@ -876,6 +922,58 @@ static MYSQL_SYSVAR_STR(version, mrn_version, NULL, MRN_VERSION); +static my_bool grn_check_zlib_support() +{ + bool is_zlib_support = false; + grn_obj grn_support_p; + + GRN_BOOL_INIT(&grn_support_p, 0); + grn_obj_get_info(&mrn_ctx, NULL, GRN_INFO_SUPPORT_ZLIB, &grn_support_p); + is_zlib_support = (GRN_BOOL_VALUE(&grn_support_p)); + grn_obj_unlink(&mrn_ctx, &grn_support_p); + + return is_zlib_support; +} + +static my_bool grn_check_lz4_support() +{ + bool is_lz4_support = false; + grn_obj grn_support_p; + + GRN_BOOL_INIT(&grn_support_p, 0); + grn_obj_get_info(&mrn_ctx, NULL, GRN_INFO_SUPPORT_LZ4, &grn_support_p); + is_lz4_support = (GRN_BOOL_VALUE(&grn_support_p)); + grn_obj_unlink(&mrn_ctx, &grn_support_p); + + return is_lz4_support; +} + +static MYSQL_SYSVAR_BOOL(libgroonga_support_zlib, mrn_libgroonga_support_zlib, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + "The status of libgroonga supports zlib", + NULL, + NULL, + grn_check_zlib_support()); + +static MYSQL_SYSVAR_BOOL(libgroonga_support_lz4, mrn_libgroonga_support_lz4, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + "The status of libgroonga supports LZ4", + NULL, + NULL, + grn_check_lz4_support()); + +static MYSQL_THDVAR_SET(boolean_mode_syntax_flags, + PLUGIN_VAR_RQCMDARG, + "The flags to custom syntax in BOOLEAN MODE. " + "Available flags: " + "DEFAULT(=SYNTAX_QUERY,ALLOW_LEADING_NOT), " + "SYNTAX_QUERY, SYNTAX_SCRIPT, " + "ALLOW_COLUMN, ALLOW_UPDATE and ALLOW_LEADING_NOT", + NULL, + NULL, + MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT, + &mrn_boolean_mode_syntax_flags_typelib); + static struct st_mysql_sys_var *mrn_system_variables[] = { MYSQL_SYSVAR(log_level), @@ -891,6 +989,9 @@ static struct st_mysql_sys_var *mrn_system_variables[] = MYSQL_SYSVAR(libgroonga_version), MYSQL_SYSVAR(version), MYSQL_SYSVAR(vector_column_delimiter), + MYSQL_SYSVAR(libgroonga_support_zlib), + MYSQL_SYSVAR(libgroonga_support_lz4), + MYSQL_SYSVAR(boolean_mode_syntax_flags), NULL }; @@ -917,7 +1018,7 @@ static ST_FIELD_INFO i_s_mrn_stats_fields_info[] = MYSQL_TYPE_LONG, 0, 0, - "Rows written to groonga", + "Rows written to Groonga", SKIP_OPEN_TABLE }, { @@ -926,7 +1027,7 @@ static ST_FIELD_INFO i_s_mrn_stats_fields_info[] = MYSQL_TYPE_LONG, 0, 0, - "Rows read from groonga", + "Rows read from Groonga", SKIP_OPEN_TABLE } }; @@ -1191,6 +1292,65 @@ static grn_builtin_type mrn_grn_type_from_field(grn_ctx *ctx, Field *field, return type; } +grn_obj_flags mrn_parse_grn_column_create_flags(THD *thd, + grn_ctx *ctx, + const char *flag_names, + uint flag_names_length) +{ + grn_obj_flags flags = 0; + const char *flag_names_end = flag_names + flag_names_length; + + while (flag_names < flag_names_end) { + uint rest_length = flag_names_end - flag_names; + + if (*flag_names == '|' || *flag_names == ' ') { + flag_names += 1; + continue; + } + if (rest_length >= 13 && !memcmp(flag_names, "COLUMN_SCALAR", 13)) { + flags |= GRN_OBJ_COLUMN_SCALAR; + flag_names += 13; + } else if (rest_length >= 13 && !memcmp(flag_names, "COLUMN_VECTOR", 13)) { + flags |= GRN_OBJ_COLUMN_VECTOR; + flag_names += 13; + } else if (rest_length >= 13 && !memcmp(flag_names, "COMPRESS_ZLIB", 13)) { + if (mrn_libgroonga_support_zlib) { + flags |= GRN_OBJ_COMPRESS_ZLIB; + } else { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM, + ER_MRN_UNSUPPORTED_COLUMN_FLAG_STR, + "COMPRESS_ZLIB"); + } + flag_names += 13; + } else if (rest_length >= 12 && !memcmp(flag_names, "COMPRESS_LZ4", 12)) { + if (mrn_libgroonga_support_lz4) { + flags |= GRN_OBJ_COMPRESS_LZ4; + } else { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM, + ER_MRN_UNSUPPORTED_COLUMN_FLAG_STR, + "COMPRESS_LZ4"); + } + flag_names += 12; + } else { + char invalid_flag_name[MRN_MESSAGE_BUFFER_SIZE]; + snprintf(invalid_flag_name, MRN_MESSAGE_BUFFER_SIZE, + "%.*s", + static_cast(rest_length), + flag_names); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_MRN_INVALID_COLUMN_FLAG_NUM, + ER_MRN_INVALID_COLUMN_FLAG_STR, + invalid_flag_name, + "COLUMN_SCALAR"); + flags |= GRN_OBJ_COLUMN_SCALAR; + break; + } + } + return flags; +} + #ifdef HAVE_SPATIAL static int mrn_set_geometry(grn_ctx *ctx, grn_obj *buf, const char *wkb, uint wkb_size) @@ -1275,7 +1435,7 @@ static int mrn_init(void *p) hton = (handlerton *)p; hton->state = SHOW_OPTION_YES; hton->create = mrn_handler_create; - hton->flags = HTON_NO_PARTITION; + hton->flags = 0; hton->drop_database = mrn_drop_database; hton->close_connection = mrn_close_connection; hton->flush_logs = mrn_flush_logs; @@ -1294,13 +1454,8 @@ static int mrn_init(void *p) # endif # ifndef MRN_HAVE_TDC_LOCK_TABLE_SHARE mrn_LOCK_open = -# if MYSQL_VERSION_ID >= 50500 (mysql_mutex_t *)GetProcAddress(current_module, "?LOCK_open@@3Ust_mysql_mutex@@A"); -# else - (pthread_mutex_t *)GetProcAddress(current_module, - "?LOCK_open@@3U_RTL_CRITICAL_SECTION@@A"); -# endif # endif # ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE mrn_table_share_lock_share = @@ -1321,7 +1476,12 @@ static int mrn_init(void *p) # endif #endif - // init groonga + if (PSI_server) { + const char *category = "mroonga"; + int n_mutexes = array_elements(mrn_mutexes); + PSI_server->register_mutex(category, mrn_mutexes, n_mutexes); + } + if (grn_init() != GRN_SUCCESS) { goto err_grn_init; } @@ -1335,7 +1495,9 @@ static int mrn_init(void *p) if (mrn_change_encoding(ctx, system_charset_info)) goto err_mrn_change_encoding; - if (pthread_mutex_init(&mrn_log_mutex, NULL) != 0) { + if (mysql_mutex_init(mrn_log_mutex_key, + &mrn_log_mutex, + MY_MUTEX_INIT_FAST) != 0) { goto err_log_mutex_init; } @@ -1358,25 +1520,39 @@ static int mrn_init(void *p) grn_ctx_init(&mrn_db_manager_ctx, 0); grn_logger_set(&mrn_db_manager_ctx, &mrn_logger); - mrn_db_manager = new mrn::DatabaseManager(&mrn_db_manager_ctx); + if (mysql_mutex_init(mrn_db_manager_mutex_key, + &mrn_db_manager_mutex, + MY_MUTEX_INIT_FAST) != 0) { + GRN_LOG(&mrn_db_manager_ctx, GRN_LOG_ERROR, + "failed to initialize mutex for database manager"); + goto err_db_manager_mutex_init; + } + mrn_db_manager = new mrn::DatabaseManager(&mrn_db_manager_ctx, + &mrn_db_manager_mutex); if (!mrn_db_manager->init()) { goto err_db_manager_init; } - if ((pthread_mutex_init(&mrn_allocated_thds_mutex, NULL) != 0)) { + if ((mysql_mutex_init(mrn_allocated_thds_mutex_key, + &mrn_allocated_thds_mutex, + MY_MUTEX_INIT_FAST) != 0)) { goto err_allocated_thds_mutex_init; } if (my_hash_init(&mrn_allocated_thds, system_charset_info, 32, 0, 0, mrn_allocated_thds_get_key, 0, 0)) { goto error_allocated_thds_hash_init; } - if ((pthread_mutex_init(&mrn_open_tables_mutex, NULL) != 0)) { + if ((mysql_mutex_init(mrn_open_tables_mutex_key, + &mrn_open_tables_mutex, + MY_MUTEX_INIT_FAST) != 0)) { goto err_allocated_open_tables_mutex_init; } if (my_hash_init(&mrn_open_tables, system_charset_info, 32, 0, 0, mrn_open_tables_get_key, 0, 0)) { goto error_allocated_open_tables_hash_init; } - if ((pthread_mutex_init(&mrn_long_term_share_mutex, NULL) != 0)) { + if ((mysql_mutex_init(mrn_long_term_share_mutex_key, + &mrn_long_term_share_mutex, + MY_MUTEX_INIT_FAST) != 0)) { goto error_allocated_long_term_share_mutex_init; } if (my_hash_init(&mrn_long_term_share, system_charset_info, 32, 0, 0, @@ -1391,18 +1567,20 @@ static int mrn_init(void *p) return 0; error_allocated_long_term_share_hash_init: - pthread_mutex_destroy(&mrn_long_term_share_mutex); + mysql_mutex_destroy(&mrn_long_term_share_mutex); error_allocated_long_term_share_mutex_init: my_hash_free(&mrn_open_tables); error_allocated_open_tables_hash_init: - pthread_mutex_destroy(&mrn_open_tables_mutex); + mysql_mutex_destroy(&mrn_open_tables_mutex); err_allocated_open_tables_mutex_init: my_hash_free(&mrn_allocated_thds); error_allocated_thds_hash_init: - pthread_mutex_destroy(&mrn_allocated_thds_mutex); + mysql_mutex_destroy(&mrn_allocated_thds_mutex); err_allocated_thds_mutex_init: err_db_manager_init: delete mrn_db_manager; + mysql_mutex_destroy(&mrn_db_manager_mutex); +err_db_manager_mutex_init: grn_ctx_fin(&mrn_db_manager_ctx); grn_obj_unlink(ctx, mrn_db); err_db_create: @@ -1411,7 +1589,7 @@ err_db_create: mrn_log_file_opened = false; } err_log_file_open: - pthread_mutex_destroy(&mrn_log_mutex); + mysql_mutex_destroy(&mrn_log_mutex); err_log_mutex_init: err_mrn_change_encoding: grn_ctx_fin(ctx); @@ -1450,12 +1628,13 @@ static int mrn_deinit(void *p) } my_hash_free(&mrn_long_term_share); - pthread_mutex_destroy(&mrn_long_term_share_mutex); + mysql_mutex_destroy(&mrn_long_term_share_mutex); my_hash_free(&mrn_open_tables); - pthread_mutex_destroy(&mrn_open_tables_mutex); + mysql_mutex_destroy(&mrn_open_tables_mutex); my_hash_free(&mrn_allocated_thds); - pthread_mutex_destroy(&mrn_allocated_thds_mutex); + mysql_mutex_destroy(&mrn_allocated_thds_mutex); delete mrn_db_manager; + mysql_mutex_destroy(&mrn_db_manager_mutex); grn_ctx_fin(&mrn_db_manager_ctx); grn_obj_unlink(ctx, mrn_db); @@ -1466,7 +1645,7 @@ static int mrn_deinit(void *p) fclose(mrn_log_file); mrn_log_file_opened = false; } - pthread_mutex_destroy(&mrn_log_mutex); + mysql_mutex_destroy(&mrn_log_mutex); return 0; } @@ -1489,6 +1668,18 @@ mrn_declare_plugin(MRN_PLUGIN_NAME) i_s_mrn_stats mrn_declare_plugin_end; +static double mrn_get_score_value(grn_obj *score) +{ + MRN_DBUG_ENTER_FUNCTION(); + double score_value; + if (score->header.domain == GRN_DB_FLOAT) { + score_value = GRN_FLOAT_VALUE(score); + } else { + score_value = (double)GRN_INT32_VALUE(score); + } + DBUG_RETURN(score_value); +} + static void mrn_generic_ft_clear(FT_INFO *handler) { MRN_DBUG_ENTER_FUNCTION(); @@ -1555,7 +1746,7 @@ static float mrn_wrapper_ft_find_relevance(FT_INFO *handler, uchar *record, GRN_BULK_REWIND(&(info->score)); grn_obj_get_value(info->ctx, info->score_column, result_record_id, &(info->score)); - score = (float)GRN_INT32_VALUE(&(info->score)); + score = mrn_get_score_value(&(info->score)); } } @@ -1593,7 +1784,7 @@ static float mrn_wrapper_ft_get_relevance(FT_INFO *handler) GRN_BULK_REWIND(&(info->score)); grn_obj_get_value(info->ctx, info->score_column, result_record_id, &(info->score)); - score = (float)GRN_INT32_VALUE(&(info->score)); + score = mrn_get_score_value(&(info->score)); } } @@ -1640,7 +1831,7 @@ static float mrn_storage_ft_find_relevance(FT_INFO *handler, uchar *record, GRN_BULK_REWIND(&(info->score)); grn_obj_get_value(info->ctx, info->score_column, result_record_id, &(info->score)); - score = (float)GRN_INT32_VALUE(&(info->score)); + score = mrn_get_score_value(&(info->score)); } } DBUG_PRINT("info", ("mroonga: record_id=%d score=%g", @@ -1672,7 +1863,7 @@ static float mrn_storage_ft_get_relevance(FT_INFO *handler) GRN_BULK_REWIND(&(info->score)); grn_obj_get_value(info->ctx, info->score_column, result_record_id, &(info->score)); - score = (float)GRN_INT32_VALUE(&(info->score)); + score = mrn_get_score_value(&(info->score)); } } DBUG_PRINT("info", @@ -1916,7 +2107,6 @@ ha_mroonga::ha_mroonga(handlerton *hton, TABLE_SHARE *share_arg) grn_column_ranges(NULL), grn_index_tables(NULL), grn_index_columns(NULL), - grn_table_is_referenced(false), grn_source_column_geo(NULL), cursor_geo(NULL), @@ -2126,7 +2316,7 @@ uint ha_mroonga::wrapper_max_supported_key_length() const uint ha_mroonga::storage_max_supported_key_length() const { MRN_DBUG_ENTER_METHOD(); - DBUG_RETURN(HA_MAX_REC_LENGTH); + DBUG_RETURN(GRN_TABLE_MAX_KEY_SIZE); } uint ha_mroonga::max_supported_key_length() const @@ -2173,7 +2363,7 @@ uint ha_mroonga::wrapper_max_supported_key_part_length() const uint ha_mroonga::storage_max_supported_key_part_length() const { MRN_DBUG_ENTER_METHOD(); - DBUG_RETURN(HA_MAX_REC_LENGTH); + DBUG_RETURN(GRN_TABLE_MAX_KEY_SIZE); } uint ha_mroonga::max_supported_key_part_length() const @@ -2467,7 +2657,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table, share = NULL; if (wrap_key_info) { - my_free(wrap_key_info, MYF(0)); + my_free(wrap_key_info); wrap_key_info = NULL; } base_key_info = NULL; @@ -2486,7 +2676,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table, if (wrap_key_info) { - my_free(wrap_key_info, MYF(0)); + my_free(wrap_key_info); wrap_key_info = NULL; } base_key_info = NULL; @@ -2838,9 +3028,9 @@ int ha_mroonga::storage_create(const char *name, TABLE *table, if (key_parts == 1) { grn_obj *normalizer = NULL; if (tmp_share->normalizer) { - normalizer = grn_ctx_get(ctx, - tmp_share->normalizer, - tmp_share->normalizer_length); + normalizer = grn_ctx_get(ctx, + tmp_share->normalizer, + tmp_share->normalizer_length); } else { Field *field = &(key_info.key_part->field[0]); if (should_normalize(field)) { @@ -2902,12 +3092,10 @@ int ha_mroonga::storage_create(const char *name, TABLE *table, grn_obj_flags col_flags = GRN_OBJ_PERSISTENT; if (tmp_share->col_flags[i]) { - // TODO: parse flags - if (strcmp(tmp_share->col_flags[i], "COLUMN_VECTOR") == 0) { - col_flags |= GRN_OBJ_COLUMN_VECTOR; - } else { - col_flags |= GRN_OBJ_COLUMN_SCALAR; - } + col_flags |= mrn_parse_grn_column_create_flags(ha_thd(), + ctx, + tmp_share->col_flags[i], + tmp_share->col_flags_length[i]); } else { col_flags |= GRN_OBJ_COLUMN_SCALAR; } @@ -3448,7 +3636,8 @@ int ha_mroonga::storage_create_indexes(TABLE *table, const char *grn_table_name, } if (error) { while (true) { - if (index_tables[i]) { + if (index_tables[i] && + !(tmp_share->index_table && tmp_share->index_table[i])) { grn_obj_remove(ctx, index_tables[i]); } if (!i) @@ -3574,7 +3763,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked) MRN_SET_BASE_TABLE_KEY(this, table); if (wrap_key_info) { - my_free(wrap_key_info, MYF(0)); + my_free(wrap_key_info); wrap_key_info = NULL; } base_key_info = NULL; @@ -3598,7 +3787,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked) MRN_SET_BASE_TABLE_KEY(this, table); if (wrap_key_info) { - my_free(wrap_key_info, MYF(0)); + my_free(wrap_key_info); wrap_key_info = NULL; } base_key_info = NULL; @@ -3626,7 +3815,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked) wrap_handler = NULL; if (wrap_key_info) { - my_free(wrap_key_info, MYF(0)); + my_free(wrap_key_info); wrap_key_info = NULL; } base_key_info = NULL; @@ -3806,55 +3995,6 @@ int ha_mroonga::storage_open(const char *name, int mode, uint test_if_locked) DBUG_RETURN(0); } -void ha_mroonga::update_grn_table_is_referenced() -{ - MRN_DBUG_ENTER_METHOD(); - - grn_table_is_referenced = false; - - grn_table_cursor *cursor; - int flags = GRN_CURSOR_BY_ID | GRN_CURSOR_ASCENDING;; - cursor = grn_table_cursor_open(ctx, grn_ctx_db(ctx), - NULL, 0, - NULL, 0, - 0, -1, flags); - if (cursor) { - grn_id id; - grn_id grn_table_id; - - grn_table_id = grn_obj_id(ctx, grn_table); - while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { - grn_obj *object; - grn_id range = GRN_ID_NIL; - - object = grn_ctx_at(ctx, id); - if (!object) { - ctx->rc = GRN_SUCCESS; - continue; - } - - switch (object->header.type) { - case GRN_COLUMN_FIX_SIZE: - case GRN_COLUMN_VAR_SIZE: - range = grn_obj_get_range(ctx, object); - break; - default: - break; - } - grn_obj_unlink(ctx, object); - - if (range == grn_table_id) { - grn_table_is_referenced = true; - break; - } - } - - grn_table_cursor_close(ctx, cursor); - } - - DBUG_VOID_RETURN; -} - int ha_mroonga::open_table(const char *name) { int error; @@ -3881,8 +4021,6 @@ int ha_mroonga::open_table(const char *name) DBUG_RETURN(error); } - update_grn_table_is_referenced(); - DBUG_RETURN(0); } @@ -4104,7 +4242,7 @@ int ha_mroonga::wrapper_close() wrap_handler = NULL; if (wrap_key_info) { - my_free(wrap_key_info, MYF(0)); + my_free(wrap_key_info); wrap_key_info = NULL; } base_key_info = NULL; @@ -4323,7 +4461,6 @@ int ha_mroonga::delete_table(const char *name) } if (!tmp_table_share) { - mrn::PathMapper mapper(name); #ifdef MRN_TABLE_LIST_INIT_REQUIRE_ALIAS table_list.init_one_table(mapper.db_name(), strlen(mapper.db_name()), mapper.mysql_table_name(), @@ -5090,6 +5227,7 @@ int ha_mroonga::storage_write_row(uchar *buf) { MRN_DBUG_ENTER_METHOD(); int error = 0; + bool unique_indexes_are_processed = false; if (is_dry_write()) { DBUG_PRINT("info", ("mroonga: dry write: ha_mroonga::%s", __FUNCTION__)); @@ -5098,7 +5236,6 @@ int ha_mroonga::storage_write_row(uchar *buf) THD *thd = ha_thd(); int i; - uint j; int n_columns = table->s->fields; if (table->next_number_field && buf == table->record[0]) @@ -5156,6 +5293,11 @@ int ha_mroonga::storage_write_row(uchar *buf) } } + if (grn_table->header.type != GRN_TABLE_NO_KEY && pkey_size == 0) { + my_message(ER_ERROR_ON_WRITE, "primary key is empty", MYF(0)); + DBUG_RETURN(ER_ERROR_ON_WRITE); + } + int added; record_id = grn_table_add(ctx, grn_table, pkey, pkey_size, &added); if (ctx->rc) { @@ -5179,6 +5321,7 @@ int ha_mroonga::storage_write_row(uchar *buf) { goto err; } + unique_indexes_are_processed = true; grn_obj colbuf; GRN_VOID_INIT(&colbuf); @@ -5270,13 +5413,16 @@ int ha_mroonga::storage_write_row(uchar *buf) DBUG_RETURN(0); err: - for (j = 0; j < table->s->keys; j++) { - if (j == pkey_nr) { - continue; - } - KEY *key_info = &table->key_info[j]; - if (key_info->flags & HA_NOSAME) { - grn_table_delete_by_id(ctx, grn_index_tables[j], key_id[j]); + if (unique_indexes_are_processed) { + uint j; + for (j = 0; j < table->s->keys; j++) { + if (j == pkey_nr) { + continue; + } + KEY *key_info = &table->key_info[j]; + if (key_info->flags & HA_NOSAME) { + grn_table_delete_by_id(ctx, grn_index_tables[j], key_id[j]); + } } } grn_table_delete_by_id(ctx, grn_table, record_id); @@ -5363,6 +5509,7 @@ err: int ha_mroonga::storage_write_row_unique_index(uchar *buf, KEY *key_info, grn_obj *index_table, + grn_obj *index_column, grn_id *key_id) { char *ukey = NULL; @@ -5398,7 +5545,29 @@ int ha_mroonga::storage_write_row_unique_index(uchar *buf, if (!added) { // duplicated error error = HA_ERR_FOUND_DUPP_KEY; - memcpy(dup_ref, key_id, sizeof(grn_id)); + grn_id duplicated_record_id = GRN_ID_NIL; + { + grn_table_cursor *table_cursor; + table_cursor = grn_table_cursor_open(ctx, index_table, + ukey, ukey_size, + ukey, ukey_size, + 0, -1, 0); + if (table_cursor) { + grn_obj *index_cursor; + index_cursor = grn_index_cursor_open(ctx, table_cursor, index_column, + GRN_ID_NIL, GRN_ID_MAX, 0); + if (index_cursor) { + grn_posting *posting; + posting = grn_index_cursor_next(ctx, index_cursor, NULL); + if (posting) { + duplicated_record_id = posting->rid; + } + } + grn_obj_unlink(ctx, index_cursor); + } + grn_table_cursor_close(ctx, table_cursor); + } + memcpy(dup_ref, &duplicated_record_id, sizeof(grn_id)); if (!ignoring_duplicated_key) { GRN_LOG(ctx, GRN_LOG_ERROR, "duplicated id on insert: update unique index: <%.*s>", @@ -5431,9 +5600,14 @@ int ha_mroonga::storage_write_row_unique_indexes(uchar *buf) if (!index_table) { continue; } + grn_obj *index_column = grn_index_columns[i]; + if (!index_column) { + continue; + } if ((error = storage_write_row_unique_index(buf, key_info, - index_table, &key_id[i]))) + index_table, index_column, + &key_id[i]))) { if (error == HA_ERR_FOUND_DUPP_KEY) { @@ -5449,7 +5623,16 @@ err: mrn_change_encoding(ctx, NULL); do { i--; + + if (i == table->s->primary_key) { + continue; + } + KEY *key_info = &table->key_info[i]; + if (!(key_info->flags & HA_NOSAME)) { + continue; + } + if (key_info->flags & HA_NOSAME) { grn_table_delete_by_id(ctx, grn_index_tables[i], key_id[i]); } @@ -5914,6 +6097,13 @@ int ha_mroonga::storage_update_row_unique_indexes(uchar *new_data) continue; } + grn_obj *index_column = grn_index_columns[i]; + if (!index_column) { + key_id[i] = GRN_ID_NIL; + del_key_id[i] = GRN_ID_NIL; + continue; + } + if ( KEY_N_KEY_PARTS(key_info) == 1 && !bitmap_is_set(table->write_set, @@ -5926,7 +6116,8 @@ int ha_mroonga::storage_update_row_unique_indexes(uchar *new_data) } if ((error = storage_write_row_unique_index(new_data, key_info, - index_table, &key_id[i]))) + index_table, index_column, + &key_id[i]))) { if (error == HA_ERR_FOUND_DUPP_KEY) { @@ -7594,6 +7785,34 @@ bool ha_mroonga::generic_ft_init_ext_parse_pragma_w(struct st_mrn_ft_info *info, DBUG_RETURN(n_weights > 0); } +grn_expr_flags ha_mroonga::expr_flags_in_boolean_mode() +{ + MRN_DBUG_ENTER_METHOD(); + + ulonglong syntax_flags = THDVAR(ha_thd(), boolean_mode_syntax_flags); + grn_expr_flags expression_flags = 0; + if (syntax_flags == MRN_BOOLEAN_MODE_SYNTAX_FLAG_DEFAULT) { + expression_flags = GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT; + } else { + if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_SYNTAX_SCRIPT) { + expression_flags |= GRN_EXPR_SYNTAX_SCRIPT; + } else { + expression_flags |= GRN_EXPR_SYNTAX_QUERY; + } + if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_COLUMN) { + expression_flags |= GRN_EXPR_ALLOW_COLUMN; + } + if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_UPDATE) { + expression_flags |= GRN_EXPR_ALLOW_UPDATE; + } + if (syntax_flags & MRN_BOOLEAN_MODE_SYNTAX_FLAG_ALLOW_LEADING_NOT) { + expression_flags |= GRN_EXPR_ALLOW_LEADING_NOT; + } + } + + DBUG_RETURN(expression_flags); +} + grn_rc ha_mroonga::generic_ft_init_ext_prepare_expression_in_boolean_mode( struct st_mrn_ft_info *info, String *key, @@ -7674,12 +7893,10 @@ grn_rc ha_mroonga::generic_ft_init_ext_prepare_expression_in_boolean_mode( if (!weight_specified) { grn_expr_append_obj(info->ctx, match_columns, index_column, GRN_OP_PUSH, 1); } - grn_expr_flags expression_flags = - GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT; rc = grn_expr_parse(info->ctx, expression, keyword, keyword_length, match_columns, GRN_OP_MATCH, default_operator, - expression_flags); + expr_flags_in_boolean_mode()); if (rc) { char error_message[MRN_MESSAGE_BUFFER_SIZE]; snprintf(error_message, MRN_MESSAGE_BUFFER_SIZE, @@ -8351,7 +8568,8 @@ int ha_mroonga::drop_index(MRN_SHARE *target_share, uint key_index) const char *table_name = target_share->index_table[key_index]; snprintf(target_name, GRN_TABLE_MAX_KEY_SIZE, "%s.%s", table_name, key_info[key_index].name); - grn_obj *index_column = grn_ctx_get(ctx, target_name, strlen(target_name)); + target_name_length = strlen(target_name); + grn_obj *index_column = grn_ctx_get(ctx, target_name, target_name_length); if (index_column) { rc = grn_obj_remove(ctx, index_column); } @@ -8366,6 +8584,8 @@ int ha_mroonga::drop_index(MRN_SHARE *target_share, uint key_index) target_name_length = grn_obj_name(ctx, index_table, target_name, GRN_TABLE_MAX_KEY_SIZE); rc = grn_obj_remove(ctx, index_table); + } else { + target_name_length = 0; } } @@ -8421,6 +8641,7 @@ grn_obj *ha_mroonga::find_normalizer(KEY *key_info) { MRN_DBUG_ENTER_METHOD(); grn_obj *normalizer = NULL; + bool use_normalizer = true; #if MYSQL_VERSION_ID >= 50500 if (key_info->comment.length > 0) { mrn::ParametersParser parser(key_info->comment.str, @@ -8428,11 +8649,15 @@ grn_obj *ha_mroonga::find_normalizer(KEY *key_info) parser.parse(); const char *normalizer_name = parser["normalizer"]; if (normalizer_name) { - normalizer = grn_ctx_get(ctx, normalizer_name, -1); + if (strcmp(normalizer_name, "none") == 0) { + use_normalizer = false; + } else { + normalizer = grn_ctx_get(ctx, normalizer_name, -1); + } } } #endif - if (!normalizer) { + if (use_normalizer && !normalizer) { Field *field = key_info->key_part[0].field; mrn::FieldNormalizer field_normalizer(ctx, ha_thd(), field); normalizer = field_normalizer.find_grn_normalizer(); @@ -9438,9 +9663,9 @@ int ha_mroonga::generic_store_bulk_blob(Field *field, grn_obj *buf) int error = 0; String buffer; Field_blob *blob = (Field_blob *)field; - const char *value = blob->val_str(0, &buffer)->ptr(); + String *value = blob->val_str(0, &buffer); grn_obj_reinit(ctx, buf, GRN_DB_TEXT, 0); - GRN_TEXT_SET(ctx, buf, value, blob->get_length()); + GRN_TEXT_SET(ctx, buf, value->ptr(), value->length()); DBUG_RETURN(error); } @@ -9451,8 +9676,9 @@ int ha_mroonga::generic_store_bulk_geometry(Field *field, grn_obj *buf) #ifdef HAVE_SPATIAL String buffer; Field_geom *geometry = (Field_geom *)field; - const char *wkb = geometry->val_str(0, &buffer)->ptr(); - int len = geometry->get_length(); + String *value = geometry->val_str(0, &buffer); + const char *wkb = value->ptr(); + int len = value->length(); error = mrn_set_geometry(ctx, buf, wkb, len); #endif DBUG_RETURN(error); @@ -9994,7 +10220,7 @@ void ha_mroonga::storage_store_field(Field *field, } } -void ha_mroonga::storage_store_field_column(Field *field, +void ha_mroonga::storage_store_field_column(Field *field, bool is_primary_key, int nth_column, grn_id record_id) { MRN_DBUG_ENTER_METHOD(); @@ -10009,7 +10235,6 @@ void ha_mroonga::storage_store_field_column(Field *field, grn_obj_reinit(ctx, value, range_id, GRN_OBJ_VECTOR); grn_obj_get_value(ctx, column, record_id, value); - // TODO: Check whether reference type or not grn_obj unvectored_value; GRN_TEXT_INIT(&unvectored_value, 0); int n_ids = GRN_BULK_VSIZE(value) / sizeof(grn_id); @@ -10042,7 +10267,15 @@ void ha_mroonga::storage_store_field_column(Field *field, } else { grn_obj_reinit(ctx, value, range_id, 0); grn_obj_get_value(ctx, column, record_id, value); - storage_store_field(field, GRN_BULK_HEAD(value), GRN_BULK_VSIZE(value)); + if (is_primary_key && GRN_BULK_VSIZE(value) == 0) { + char key[GRN_TABLE_MAX_KEY_SIZE]; + int key_length; + key_length = grn_table_get_key(ctx, grn_table, record_id, + &key, GRN_TABLE_MAX_KEY_SIZE); + storage_store_field(field, key, key_length); + } else { + storage_store_field(field, GRN_BULK_HEAD(value), GRN_BULK_VSIZE(value)); + } } DBUG_VOID_RETURN; @@ -10056,9 +10289,11 @@ void ha_mroonga::storage_store_fields(uchar *buf, grn_id record_id) my_ptrdiff_t ptr_diff = PTR_BYTE_DIFF(buf, table->record[0]); Field *primary_key_field = NULL; - if (grn_table_is_referenced && table->s->primary_key != MAX_INDEXES) { + if (table->s->primary_key != MAX_INDEXES) { KEY *key_info = &(table->s->key_info[table->s->primary_key]); - primary_key_field = key_info->key_part[0].field; + if (KEY_N_KEY_PARTS(key_info) == 1) { + primary_key_field = key_info->key_part[0].field; + } } int i; @@ -10087,13 +10322,9 @@ void ha_mroonga::storage_store_fields(uchar *buf, grn_id record_id) } else if (primary_key_field && strcmp(primary_key_field->field_name, column_name) == 0) { // for primary key column - char key[GRN_TABLE_MAX_KEY_SIZE]; - int key_length; - key_length = grn_table_get_key(ctx, grn_table, record_id, - &key, GRN_TABLE_MAX_KEY_SIZE); - storage_store_field(field, key, key_length); + storage_store_field_column(field, true, i, record_id); } else { - storage_store_field_column(field, i ,record_id); + storage_store_field_column(field, false, i, record_id); } field->move_field_offset(-ptr_diff); } @@ -10770,12 +11001,12 @@ int ha_mroonga::wrapper_reset() MRN_SET_BASE_TABLE_KEY(this, table); #ifdef MRN_HANDLER_HAVE_CHECK_IF_SUPPORTED_INPLACE_ALTER if (alter_key_info_buffer) { - my_free(alter_key_info_buffer, MYF(0)); + my_free(alter_key_info_buffer); alter_key_info_buffer = NULL; } #else if (wrap_alter_key_info) { - my_free(wrap_alter_key_info, MYF(0)); + my_free(wrap_alter_key_info); wrap_alter_key_info = NULL; } #endif @@ -11787,7 +12018,7 @@ void ha_mroonga::update_create_info(HA_CREATE_INFO* create_info) if (slot_data) { slot_data->alter_create_info = create_info; if (slot_data->alter_connect_string) { - my_free(slot_data->alter_connect_string, MYF(0)); + my_free(slot_data->alter_connect_string); slot_data->alter_connect_string = NULL; } if (create_info->connect_string.str) { @@ -11797,7 +12028,7 @@ void ha_mroonga::update_create_info(HA_CREATE_INFO* create_info) MYF(MY_WME)); } if (slot_data->alter_comment) { - my_free(slot_data->alter_comment, MYF(0)); + my_free(slot_data->alter_comment); slot_data->alter_comment = NULL; } if (create_info->comment.str) { @@ -12184,6 +12415,44 @@ bool ha_mroonga::auto_repair() const DBUG_RETURN(crashed); } +int ha_mroonga::generic_disable_index(int i, KEY *key_info) +{ + MRN_DBUG_ENTER_METHOD(); + + int error = 0; + if (share->index_table[i]) { + char index_column_name[GRN_TABLE_MAX_KEY_SIZE]; + snprintf(index_column_name, GRN_TABLE_MAX_KEY_SIZE - 1, + "%s.%s", share->index_table[i], key_info[i].name); + grn_obj *index_column = grn_ctx_get(ctx, + index_column_name, + strlen(index_column_name)); + if (index_column) { + grn_obj_remove(ctx, index_column); + } + } else { + mrn::PathMapper mapper(share->table_name); + mrn::IndexTableName index_table_name(mapper.table_name(), + key_info[i].name); + grn_obj *index_table = grn_ctx_get(ctx, + index_table_name.c_str(), + index_table_name.length()); + if (index_table) { + grn_obj_remove(ctx, index_table); + } + } + if (ctx->rc == GRN_SUCCESS) { + grn_index_tables[i] = NULL; + grn_index_columns[i] = NULL; + } else { + // TODO: Implement ctx->rc to error converter and use it. + error = ER_ERROR_ON_WRITE; + my_message(error, ctx->errbuf, MYF(0)); + } + + DBUG_RETURN(error); +} + int ha_mroonga::wrapper_disable_indexes(uint mode) { int error = 0; @@ -12212,23 +12481,16 @@ int ha_mroonga::wrapper_disable_indexes(uint mode) } } KEY *key_info = table_share->key_info; - mrn::PathMapper mapper(share->table_name); for (i = 0; i < table_share->keys; i++) { if (!(key_info[i].flags & HA_FULLTEXT) && !mrn_is_geo_key(&key_info[i])) { continue; } - mrn::IndexTableName index_table_name(mapper.table_name(), - key_info[i].name); - grn_obj *index_table = grn_ctx_get(ctx, - index_table_name.c_str(), - index_table_name.length()); - if (index_table) { - grn_obj_remove(ctx, index_table); + int sub_error = generic_disable_index(i, key_info); + if (error != 0 && sub_error != 0) { + error = sub_error; } - grn_index_tables[i] = NULL; - grn_index_columns[i] = NULL; } } else { error = HA_ERR_WRONG_COMMAND; @@ -12239,6 +12501,7 @@ int ha_mroonga::wrapper_disable_indexes(uint mode) int ha_mroonga::storage_disable_indexes(uint mode) { + int error = 0; MRN_DBUG_ENTER_METHOD(); if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE || mode == HA_KEY_SWITCH_ALL) { uint i; @@ -12252,7 +12515,6 @@ int ha_mroonga::storage_disable_indexes(uint mode) } } KEY *key_info = table_share->key_info; - mrn::PathMapper mapper(share->table_name); for (i = 0; i < table_share->keys; i++) { if (i == table->s->primary_key) { continue; @@ -12262,21 +12524,15 @@ int ha_mroonga::storage_disable_indexes(uint mode) continue; } - mrn::IndexTableName index_table_name(mapper.table_name(), - key_info[i].name); - grn_obj *index_table = grn_ctx_get(ctx, - index_table_name.c_str(), - index_table_name.length()); - if (index_table) { - grn_obj_remove(ctx, index_table); + int sub_error = generic_disable_index(i, key_info); + if (error != 0 && sub_error != 0) { + error = sub_error; } - grn_index_tables[i] = NULL; - grn_index_columns[i] = NULL; } } else { DBUG_RETURN(HA_ERR_WRONG_COMMAND); } - DBUG_RETURN(0); + DBUG_RETURN(error); } int ha_mroonga::disable_indexes(uint mode) @@ -12305,7 +12561,7 @@ int ha_mroonga::wrapper_enable_indexes(uint mode) if (share->wrap_key_nr[i] < MAX_KEY) { continue; } - if (!grn_index_tables[i]) { + if (!grn_index_columns[i]) { break; } } @@ -12334,7 +12590,7 @@ int ha_mroonga::wrapper_enable_indexes(uint mode) } index_tables[i] = NULL; index_columns[i] = NULL; - if (!grn_index_tables[i]) { + if (!grn_index_columns[i]) { if ( (key_info[i].flags & HA_FULLTEXT) && (error = wrapper_create_index_fulltext(mapper.table_name(), @@ -12394,7 +12650,7 @@ int ha_mroonga::storage_enable_indexes(uint mode) if (i == table->s->primary_key) { continue; } - if (!grn_index_tables[i]) { + if (!grn_index_columns[i]) { break; } } @@ -12420,7 +12676,7 @@ int ha_mroonga::storage_enable_indexes(uint mode) break; } index_tables[i] = NULL; - if (!grn_index_tables[i]) { + if (!grn_index_columns[i]) { if ((error = storage_create_index(table, mapper.table_name(), grn_table, share, &key_info[i], index_tables, index_columns, i))) @@ -12434,6 +12690,8 @@ int ha_mroonga::storage_enable_indexes(uint mode) mrn_set_bitmap_by_key(table->read_set, &key_info[i]); have_multiple_column_index = true; } + grn_index_tables[i] = index_tables[i]; + grn_index_columns[i] = index_columns[i]; } else { index_columns[i] = NULL; } @@ -12902,6 +13160,7 @@ int ha_mroonga::storage_add_index_multiple_columns(KEY *key_info, if ((error = storage_write_row_unique_index(table->record[0], current_key_info, index_tables[i], + index_columns[i], &key_id))) { if (error == HA_ERR_FOUND_DUPP_KEY) @@ -13308,7 +13567,7 @@ bool ha_mroonga::wrapper_inplace_alter_table( result = true; } mrn_free_share_alloc(tmp_share); - my_free(tmp_share, MYF(0)); + my_free(tmp_share); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); DBUG_RETURN(result); @@ -13434,6 +13693,12 @@ bool ha_mroonga::storage_inplace_alter_table_index( ha_alter_info->key_count, index_tables, index_columns, false); + if (error == HA_ERR_FOUND_DUPP_UNIQUE) { + my_printf_error(ER_DUP_UNIQUE, ER(ER_DUP_UNIQUE), MYF(0), + table_share->table_name); + } else if (error) { + my_message(error, "failed to create multiple column index", MYF(0)); + } for (i = 0; i < n_columns; ++i) { Field *field = altered_table->field[i]; field->move_field_offset(-ptr_diff); @@ -13460,7 +13725,7 @@ bool ha_mroonga::storage_inplace_alter_table_index( have_error = true; } mrn_free_share_alloc(tmp_share); - my_free(tmp_share, MYF(0)); + my_free(tmp_share); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); @@ -13532,12 +13797,10 @@ bool ha_mroonga::storage_inplace_alter_table_add_column( grn_obj_flags col_flags = GRN_OBJ_PERSISTENT; if (tmp_share->col_flags[i]) { - // TODO: parse flags - if (strcmp(tmp_share->col_flags[i], "COLUMN_VECTOR") == 0) { - col_flags |= GRN_OBJ_COLUMN_VECTOR; - } else { - col_flags |= GRN_OBJ_COLUMN_SCALAR; - } + col_flags |= mrn_parse_grn_column_create_flags(ha_thd(), + ctx, + tmp_share->col_flags[i], + tmp_share->col_flags_length[i]); } else { col_flags |= GRN_OBJ_COLUMN_SCALAR; } @@ -13570,7 +13833,7 @@ bool ha_mroonga::storage_inplace_alter_table_add_column( grn_obj_unlink(ctx, table_obj); mrn_free_share_alloc(tmp_share); - my_free(tmp_share, MYF(0)); + my_free(tmp_share); DBUG_RETURN(have_error); } @@ -13752,7 +14015,7 @@ bool ha_mroonga::wrapper_commit_inplace_alter_table( bool result; MRN_DBUG_ENTER_METHOD(); if (!alter_handler_flags) { - my_free(alter_key_info_buffer, MYF(0)); + my_free(alter_key_info_buffer); alter_key_info_buffer = NULL; DBUG_RETURN(false); } @@ -13765,7 +14028,7 @@ bool ha_mroonga::wrapper_commit_inplace_alter_table( MRN_SET_BASE_ALTER_KEY(this, ha_alter_info); MRN_SET_BASE_SHARE_KEY(share, table->s); MRN_SET_BASE_TABLE_KEY(this, table); - my_free(alter_key_info_buffer, MYF(0)); + my_free(alter_key_info_buffer); alter_key_info_buffer = NULL; DBUG_RETURN(result); } @@ -13990,7 +14253,7 @@ int ha_mroonga::wrapper_add_index(TABLE *table_arg, KEY *key_info, } #endif mrn_free_share_alloc(tmp_share); - my_free(tmp_share, MYF(0)); + my_free(tmp_share); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); DBUG_RETURN(error); @@ -14104,7 +14367,7 @@ int ha_mroonga::storage_add_index(TABLE *table_arg, KEY *key_info, } #endif mrn_free_share_alloc(tmp_share); - my_free(tmp_share, MYF(0)); + my_free(tmp_share); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_tables); MRN_FREE_VARIABLE_LENGTH_ARRAYS(index_columns); DBUG_RETURN(error); @@ -15277,7 +15540,7 @@ void ha_mroonga::wrapper_free_foreign_key_create_info(char* str) void ha_mroonga::storage_free_foreign_key_create_info(char* str) { MRN_DBUG_ENTER_METHOD(); - my_free(str, MYF(0)); + my_free(str); DBUG_VOID_RETURN; } #else diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp index 224abb09732..14dd7960e5d 100644 --- a/storage/mroonga/ha_mroonga.hpp +++ b/storage/mroonga/ha_mroonga.hpp @@ -263,7 +263,6 @@ private: grn_obj **grn_column_ranges; grn_obj **grn_index_tables; grn_obj **grn_index_columns; - bool grn_table_is_referenced; // buffers grn_obj encoded_key_buffer; @@ -641,7 +640,7 @@ private: void storage_store_field_geometry(Field *field, const char *value, uint value_length); void storage_store_field(Field *field, const char *value, uint value_length); - void storage_store_field_column(Field *field, + void storage_store_field_column(Field *field, bool is_primary_key, int nth_column, grn_id record_id); void storage_store_fields(uchar *buf, grn_id record_id); void storage_store_fields_for_prep_update(const uchar *old_data, @@ -742,7 +741,6 @@ private: int wrapper_open(const char *name, int mode, uint test_if_locked); int wrapper_open_indexes(const char *name); int storage_open(const char *name, int mode, uint test_if_locked); - void update_grn_table_is_referenced(); int open_table(const char *name); int storage_open_columns(void); int storage_open_indexes(const char *name); @@ -785,7 +783,9 @@ private: grn_obj *index_column); int storage_write_row_multiple_column_indexes(uchar *buf, grn_id record_id); int storage_write_row_unique_index(uchar *buf, - KEY *key_info, grn_obj *index_table, + KEY *key_info, + grn_obj *index_table, + grn_obj *index_column, grn_id *key_id); int storage_write_row_unique_indexes(uchar *buf); int wrapper_get_record_id(uchar *data, grn_id *record_id, const char *context); @@ -904,6 +904,7 @@ private: grn_obj *match_columns, uint *consumed_keyword_length, grn_obj *tmp_objects); + grn_expr_flags expr_flags_in_boolean_mode(); grn_rc generic_ft_init_ext_prepare_expression_in_boolean_mode( struct st_mrn_ft_info *info, String *key, @@ -1029,6 +1030,7 @@ private: bool storage_is_crashed() const; bool wrapper_auto_repair(int error) const; bool storage_auto_repair(int error) const; + int generic_disable_index(int i, KEY *key_info); int wrapper_disable_indexes(uint mode); int storage_disable_indexes(uint mode); int wrapper_enable_indexes(uint mode); diff --git a/storage/mroonga/lib/mrn_database_manager.cpp b/storage/mroonga/lib/mrn_database_manager.cpp index 52ec78fccc0..365f47337fa 100644 --- a/storage/mroonga/lib/mrn_database_manager.cpp +++ b/storage/mroonga/lib/mrn_database_manager.cpp @@ -26,6 +26,8 @@ #include "mrn_lock.hpp" #include "mrn_path_mapper.hpp" +#include + // for debug #define MRN_CLASS_NAME "mrn::DatabaseManager" @@ -38,19 +40,19 @@ # define MRN_MKDIR(pathname, mode) mkdir((pathname), (mode)) #endif +extern "C" { + grn_rc GRN_PLUGIN_IMPL_NAME_TAGGED(init, normalizers_mysql)(grn_ctx *ctx); + grn_rc GRN_PLUGIN_IMPL_NAME_TAGGED(register, normalizers_mysql)(grn_ctx *ctx); +} + namespace mrn { - DatabaseManager::DatabaseManager(grn_ctx *ctx) + DatabaseManager::DatabaseManager(grn_ctx *ctx, mysql_mutex_t *mutex) : ctx_(ctx), cache_(NULL), - mutex_(), - mutex_initialized_(false) { + mutex_(mutex) { } DatabaseManager::~DatabaseManager(void) { - if (mutex_initialized_) { - pthread_mutex_destroy(&mutex_); - } - if (cache_) { void *db_address; GRN_HASH_EACH(ctx_, cache_, id, NULL, 0, &db_address, { @@ -75,13 +77,6 @@ namespace mrn { DBUG_RETURN(false); } - if (pthread_mutex_init(&mutex_, NULL) != 0) { - GRN_LOG(ctx_, GRN_LOG_ERROR, - "failed to initialize mutex for opened database cache hash table"); - DBUG_RETURN(false); - } - - mutex_initialized_ = true; DBUG_RETURN(true); } @@ -92,7 +87,7 @@ namespace mrn { *db = NULL; mrn::PathMapper mapper(path); - mrn::Lock lock(&mutex_); + mrn::Lock lock(mutex_); error = mrn::encoding::set(ctx_, system_charset_info); if (error) { @@ -145,7 +140,7 @@ namespace mrn { MRN_DBUG_ENTER_METHOD(); mrn::PathMapper mapper(path); - mrn::Lock lock(&mutex_); + mrn::Lock lock(mutex_); grn_id id; void *db_address; @@ -171,7 +166,7 @@ namespace mrn { MRN_DBUG_ENTER_METHOD(); mrn::PathMapper mapper(path); - mrn::Lock lock(&mutex_); + mrn::Lock lock(mutex_); grn_id id; void *db_address; @@ -211,7 +206,7 @@ namespace mrn { int error = 0; - mrn::Lock lock(&mutex_); + mrn::Lock lock(mutex_); grn_hash_cursor *cursor; cursor = grn_hash_cursor_open(ctx_, cache_, @@ -323,15 +318,12 @@ namespace mrn { if (mysql_normalizer) { grn_obj_unlink(ctx_, mysql_normalizer); } else { -#ifdef GROONGA_NORMALIZER_MYSQL_PLUGIN_IS_BUNDLED_STATIC - char ref_path[FN_REFLEN + 1], *tmp; - tmp = strmov(ref_path, opt_plugin_dir); - tmp = strmov(tmp, "/ha_mroonga"); - strcpy(tmp, SO_EXT); - grn_plugin_register_by_path(ctx_, ref_path); -#else +# ifdef MRN_GROONGA_NORMALIZER_MYSQL_EMBED + GRN_PLUGIN_IMPL_NAME_TAGGED(init, normalizers_mysql)(ctx_); + GRN_PLUGIN_IMPL_NAME_TAGGED(register, normalizers_mysql)(ctx_); +# else grn_plugin_register(ctx_, GROONGA_NORMALIZER_MYSQL_PLUGIN_NAME); -#endif +# endif } } #endif diff --git a/storage/mroonga/lib/mrn_database_manager.hpp b/storage/mroonga/lib/mrn_database_manager.hpp index 46bce7ab1a5..76c76dab6d5 100644 --- a/storage/mroonga/lib/mrn_database_manager.hpp +++ b/storage/mroonga/lib/mrn_database_manager.hpp @@ -27,7 +27,7 @@ namespace mrn { class DatabaseManager { public: - DatabaseManager(grn_ctx *ctx); + DatabaseManager(grn_ctx *ctx, mysql_mutex_t *mutex); ~DatabaseManager(void); bool init(void); int open(const char *path, grn_obj **db); @@ -38,8 +38,7 @@ namespace mrn { private: grn_ctx *ctx_; grn_hash *cache_; - pthread_mutex_t mutex_; - bool mutex_initialized_; + mysql_mutex_t *mutex_; void mkdir_p(const char *directory); void ensure_database_directory(void); diff --git a/storage/mroonga/lib/mrn_lock.cpp b/storage/mroonga/lib/mrn_lock.cpp index 94f8a4774af..3340149b237 100644 --- a/storage/mroonga/lib/mrn_lock.cpp +++ b/storage/mroonga/lib/mrn_lock.cpp @@ -20,12 +20,12 @@ #include "mrn_lock.hpp" namespace mrn { - Lock::Lock(pthread_mutex_t *mutex) + Lock::Lock(mysql_mutex_t *mutex) : mutex_(mutex) { - pthread_mutex_lock(mutex_); + mysql_mutex_lock(mutex_); } Lock::~Lock() { - pthread_mutex_unlock(mutex_); + mysql_mutex_unlock(mutex_); } } diff --git a/storage/mroonga/lib/mrn_lock.hpp b/storage/mroonga/lib/mrn_lock.hpp index 31dd7b3e53b..08e47b39c58 100644 --- a/storage/mroonga/lib/mrn_lock.hpp +++ b/storage/mroonga/lib/mrn_lock.hpp @@ -26,10 +26,10 @@ namespace mrn { class Lock { public: - Lock(pthread_mutex_t *mutex); + Lock(mysql_mutex_t *mutex); ~Lock(); private: - pthread_mutex_t *mutex_; + mysql_mutex_t *mutex_; }; } diff --git a/storage/mroonga/lib/mrn_parameters_parser.cpp b/storage/mroonga/lib/mrn_parameters_parser.cpp index 9a05097e548..3edf910ee91 100644 --- a/storage/mroonga/lib/mrn_parameters_parser.cpp +++ b/storage/mroonga/lib/mrn_parameters_parser.cpp @@ -35,10 +35,10 @@ namespace mrn { }; ~Parameter() { if (key_) { - my_free(key_, MYF(0)); + my_free(key_); } if (value_) { - my_free(value_, MYF(0)); + my_free(value_); } }; }; diff --git a/storage/mroonga/lib/mrn_path_mapper.cpp b/storage/mroonga/lib/mrn_path_mapper.cpp index ee5432f16bb..796101a10d1 100644 --- a/storage/mroonga/lib/mrn_path_mapper.cpp +++ b/storage/mroonga/lib/mrn_path_mapper.cpp @@ -2,7 +2,7 @@ /* Copyright(C) 2010 Tetsuro IKEDA Copyright(C) 2011-2013 Kentoku SHIBA - Copyright(C) 2011-2012 Kouhei Sutou + Copyright(C) 2011-2015 Kouhei Sutou This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -184,6 +184,9 @@ namespace mrn { int i = len, j = 0; for (; mysql_path_[--i] != FN_LIBCHAR ;) {} for (; i < len ;) { + if (len - i - 1 >= 3 && strncmp(mysql_path_ + i + 1, "#P#", 3) == 0) { + break; + } mysql_table_name_[j++] = mysql_path_[++i]; } mysql_table_name_[j] = '\0'; diff --git a/storage/mroonga/mrn_err.h b/storage/mroonga/mrn_err.h index c2ca885407a..bfaf2d44fa8 100644 --- a/storage/mroonga/mrn_err.h +++ b/storage/mroonga/mrn_err.h @@ -28,5 +28,11 @@ #define ER_MRN_ERROR_FROM_GROONGA_STR "Error from Groonga [%s]" #define ER_MRN_INVALID_NULL_VALUE_NUM 16505 #define ER_MRN_INVALID_NULL_VALUE_STR "NULL value can't be used for %s" +#define ER_MRN_UNSUPPORTED_COLUMN_FLAG_NUM 16506 +#define ER_MRN_UNSUPPORTED_COLUMN_FLAG_STR \ + "The column flag '%-.64s' is unsupported. It is ignored" +#define ER_MRN_INVALID_COLUMN_FLAG_NUM 16507 +#define ER_MRN_INVALID_COLUMN_FLAG_STR \ + "The column flag '%-.64s' is invalid. '%-64s' is used instead" #endif /* MRN_ERR_H_ */ diff --git a/storage/mroonga/mrn_mysql_compat.h b/storage/mroonga/mrn_mysql_compat.h index 7312dd70827..61b4ddd67a2 100644 --- a/storage/mroonga/mrn_mysql_compat.h +++ b/storage/mroonga/mrn_mysql_compat.h @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2011-2013 Kouhei Sutou + Copyright(C) 2011-2014 Kouhei Sutou This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -22,15 +22,6 @@ #include "mrn_mysql.h" -#if MYSQL_VERSION_ID >= 50500 -# define my_free(PTR, FLAG) my_free(PTR) -#endif - -#if MYSQL_VERSION_ID < 50500 -# define mysql_mutex_lock(mutex) pthread_mutex_lock(mutex) -# define mysql_mutex_unlock(mutex) pthread_mutex_unlock(mutex) -#endif - #if MYSQL_VERSION_ID >= 50604 # define MRN_HAVE_MYSQL_TYPE_TIMESTAMP2 # define MRN_HAVE_MYSQL_TYPE_DATETIME2 diff --git a/storage/mroonga/mrn_table.cpp b/storage/mroonga/mrn_table.cpp index fd406ac2dcf..4fec67b423d 100644 --- a/storage/mroonga/mrn_table.cpp +++ b/storage/mroonga/mrn_table.cpp @@ -61,14 +61,16 @@ extern "C" { #endif extern HASH mrn_open_tables; -extern pthread_mutex_t mrn_open_tables_mutex; +extern mysql_mutex_t mrn_open_tables_mutex; extern HASH mrn_long_term_share; -extern pthread_mutex_t mrn_long_term_share_mutex; +extern mysql_mutex_t mrn_long_term_share_mutex; extern char *mrn_default_parser; extern char *mrn_default_wrapper_engine; extern handlerton *mrn_hton_ptr; extern HASH mrn_allocated_thds; -extern pthread_mutex_t mrn_allocated_thds_mutex; +extern mysql_mutex_t mrn_allocated_thds_mutex; +extern PSI_mutex_key mrn_share_mutex_key; +extern PSI_mutex_key mrn_long_term_share_auto_inc_mutex_key; static char *mrn_get_string_between_quote(const char *ptr) { @@ -424,7 +426,7 @@ int mrn_parse_table_param(MRN_SHARE *share, TABLE *table) } } - my_free(params_string, MYF(0)); + my_free(params_string); params_string = NULL; } } @@ -455,7 +457,7 @@ int mrn_parse_table_param(MRN_SHARE *share, TABLE *table) !strncasecmp(share->engine, MRN_GROONGA_STR, MRN_GROONGA_LEN) ) ) { - my_free(share->engine, MYF(0)); + my_free(share->engine); share->engine = NULL; share->engine_length = 0; } else { @@ -474,7 +476,7 @@ int mrn_parse_table_param(MRN_SHARE *share, TABLE *table) error: if (params_string) - my_free(params_string, MYF(0)); + my_free(params_string); DBUG_RETURN(error); } @@ -500,7 +502,7 @@ int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i) if (key_info->comment.length == 0) { if (share->key_parser[i]) { - my_free(share->key_parser[i], MYF(0)); + my_free(share->key_parser[i]); } if ( !(share->key_parser[i] = my_strdup(mrn_default_parser, MYF(MY_WME))) @@ -574,12 +576,12 @@ int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i) } if (param_string) - my_free(param_string, MYF(0)); + my_free(param_string); DBUG_RETURN(0); error: if (param_string) - my_free(param_string, MYF(0)); + my_free(param_string); #if MYSQL_VERSION_ID >= 50500 error_alloc_param_string: #endif @@ -677,12 +679,12 @@ int mrn_add_column_param(MRN_SHARE *share, Field *field, int i) } if (param_string) - my_free(param_string, MYF(0)); + my_free(param_string); DBUG_RETURN(0); error: if (param_string) - my_free(param_string, MYF(0)); + my_free(param_string); error_alloc_param_string: DBUG_RETURN(error); } @@ -714,26 +716,26 @@ int mrn_free_share_alloc( uint i; MRN_DBUG_ENTER_FUNCTION(); if (share->engine) - my_free(share->engine, MYF(0)); + my_free(share->engine); if (share->default_tokenizer) - my_free(share->default_tokenizer, MYF(0)); + my_free(share->default_tokenizer); if (share->normalizer) - my_free(share->normalizer, MYF(0)); + my_free(share->normalizer); if (share->token_filters) - my_free(share->token_filters, MYF(0)); + my_free(share->token_filters); for (i = 0; i < share->table_share->keys; i++) { if (share->index_table && share->index_table[i]) - my_free(share->index_table[i], MYF(0)); + my_free(share->index_table[i]); if (share->key_parser[i]) - my_free(share->key_parser[i], MYF(0)); + my_free(share->key_parser[i]); } for (i = 0; i < share->table_share->fields; i++) { if (share->col_flags && share->col_flags[i]) - my_free(share->col_flags[i], MYF(0)); + my_free(share->col_flags[i]); if (share->col_type && share->col_type[i]) - my_free(share->col_type[i], MYF(0)); + my_free(share->col_type[i]); } DBUG_RETURN(0); } @@ -745,8 +747,8 @@ void mrn_free_long_term_share(MRN_LONG_TERM_SHARE *long_term_share) mrn::Lock lock(&mrn_long_term_share_mutex); my_hash_delete(&mrn_long_term_share, (uchar*) long_term_share); } - pthread_mutex_destroy(&long_term_share->auto_inc_mutex); - my_free(long_term_share, MYF(0)); + mysql_mutex_destroy(&long_term_share->auto_inc_mutex); + my_free(long_term_share); DBUG_VOID_RETURN; } @@ -775,8 +777,9 @@ MRN_LONG_TERM_SHARE *mrn_get_long_term_share(const char *table_name, long_term_share->table_name = tmp_name; long_term_share->table_name_length = table_name_length; memcpy(long_term_share->table_name, table_name, table_name_length); - if (pthread_mutex_init(&long_term_share->auto_inc_mutex, - MY_MUTEX_INIT_FAST)) + if (mysql_mutex_init(mrn_long_term_share_auto_inc_mutex_key, + &long_term_share->auto_inc_mutex, + MY_MUTEX_INIT_FAST) != 0) { *error = HA_ERR_OUT_OF_MEM; goto error_init_auto_inc_mutex; @@ -790,9 +793,9 @@ MRN_LONG_TERM_SHARE *mrn_get_long_term_share(const char *table_name, DBUG_RETURN(long_term_share); error_hash_insert: - pthread_mutex_destroy(&long_term_share->auto_inc_mutex); + mysql_mutex_destroy(&long_term_share->auto_inc_mutex); error_init_auto_inc_mutex: - my_free(long_term_share, MYF(0)); + my_free(long_term_share); error_alloc_long_term_share: DBUG_RETURN(NULL); } @@ -912,7 +915,9 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error) share->wrap_table_share = wrap_table_share; } - if (pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST)) + if (mysql_mutex_init(mrn_share_mutex_key, + &share->mutex, + MY_MUTEX_INIT_FAST) != 0) { *error = HA_ERR_OUT_OF_MEM; goto error_init_mutex; @@ -934,11 +939,11 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error) error_hash_insert: error_get_long_term_share: - pthread_mutex_destroy(&share->mutex); + mysql_mutex_destroy(&share->mutex); error_init_mutex: error_parse_table_param: mrn_free_share_alloc(share); - my_free(share, MYF(0)); + my_free(share); error_alloc_share: DBUG_RETURN(NULL); } @@ -954,7 +959,7 @@ int mrn_free_share(MRN_SHARE *share) plugin_unlock(NULL, share->plugin); mrn_free_share_alloc(share); thr_lock_delete(&share->lock); - pthread_mutex_destroy(&share->mutex); + mysql_mutex_destroy(&share->mutex); if (share->wrapper_mode) { #ifdef MRN_TABLE_SHARE_HAVE_LOCK_SHARE mysql_mutex_destroy(&(share->wrap_table_share->LOCK_share)); @@ -963,7 +968,7 @@ int mrn_free_share(MRN_SHARE *share) mysql_mutex_destroy(&(share->wrap_table_share->LOCK_ha_data)); #endif } - my_free(share, MYF(0)); + my_free(share); } DBUG_RETURN(0); } @@ -1025,9 +1030,9 @@ TABLE_SHARE *mrn_create_tmp_table_share(TABLE_LIST *table_list, const char *path } share->tmp_table = INTERNAL_TMP_TABLE; // TODO: is this right? share->path.str = (char *) path; - share->path.length = strlen(path); - share->normalized_path.str = share->path.str; - share->normalized_path.length = share->path.length; + share->path.length = strlen(share->path.str); + share->normalized_path.str = my_strdup(path, MYF(MY_WME)); + share->normalized_path.length = strlen(share->normalized_path.str); if (open_table_def(thd, share, GTS_TABLE)) { *error = ER_CANT_OPEN_FILE; @@ -1039,7 +1044,9 @@ TABLE_SHARE *mrn_create_tmp_table_share(TABLE_LIST *table_list, const char *path void mrn_free_tmp_table_share(TABLE_SHARE *tmp_table_share) { MRN_DBUG_ENTER_FUNCTION(); + char *normalized_path = tmp_table_share->normalized_path.str; free_table_share(tmp_table_share); + my_free(normalized_path); DBUG_VOID_RETURN; } @@ -1131,11 +1138,11 @@ void mrn_clear_alter_share(THD *thd) slot_data->alter_create_info = NULL; slot_data->disable_keys_create_info = NULL; if (slot_data->alter_connect_string) { - my_free(slot_data->alter_connect_string, MYF(0)); + my_free(slot_data->alter_connect_string); slot_data->alter_connect_string = NULL; } if (slot_data->alter_comment) { - my_free(slot_data->alter_comment, MYF(0)); + my_free(slot_data->alter_comment); slot_data->alter_comment = NULL; } } diff --git a/storage/mroonga/mrn_table.hpp b/storage/mroonga/mrn_table.hpp index 813e69e1023..9118455b53d 100644 --- a/storage/mroonga/mrn_table.hpp +++ b/storage/mroonga/mrn_table.hpp @@ -33,7 +33,7 @@ typedef struct st_mroonga_long_term_share uint table_name_length; // for auto_increment (storage mode only) - pthread_mutex_t auto_inc_mutex; + mysql_mutex_t auto_inc_mutex; bool auto_inc_inited; ulonglong auto_inc_value; } MRN_LONG_TERM_SHARE; @@ -43,7 +43,7 @@ typedef struct st_mroonga_share char *table_name; uint table_name_length; uint use_count; - pthread_mutex_t mutex; + mysql_mutex_t mutex; THR_LOCK lock; TABLE_SHARE *table_share; TABLE_SHARE *wrap_table_share; diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_lz4.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_lz4.inc new file mode 100644 index 00000000000..1c74cbffc46 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_lz4.inc @@ -0,0 +1,20 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--disable_query_log +let $libgroonga_support_lz4 = + `SELECT @@mroonga_libgroonga_support_lz4;`; +--enable_query_log diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zlib.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zlib.inc new file mode 100644 index 00000000000..5ab5fcd2fb8 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/check_libgroonga_support_zlib.inc @@ -0,0 +1,20 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--disable_query_log +let $libgroonga_support_zlib = + `SELECT @@mroonga_libgroonga_support_zlib;`; +--enable_query_log diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_lz4.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_lz4.inc new file mode 100644 index 00000000000..e67f826b0ce --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_lz4.inc @@ -0,0 +1,22 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/check_libgroonga_support_lz4.inc + +if (!$libgroonga_support_lz4) { + --source ../../include/mroonga/have_mroonga_deinit.inc + skip "This test is for libgroonga supports lz4"; +} diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zlib.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zlib.inc new file mode 100644 index 00000000000..9f5196f742b --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/support_libgroonga_zlib.inc @@ -0,0 +1,22 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/check_libgroonga_support_zlib.inc + +if (!$libgroonga_support_zlib) { + --source ../../include/mroonga/have_mroonga_deinit.inc + skip "This test is for libgroonga supports zlib"; +} diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_lz4.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_lz4.inc new file mode 100644 index 00000000000..80874a7a50b --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_lz4.inc @@ -0,0 +1,22 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/check_libgroonga_support_lz4.inc + +if ($libgroonga_support_lz4) { + --source ../../include/mroonga/have_mroonga_deinit.inc + skip "This test is for libgroonga doesn't support lz4"; +} diff --git a/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zlib.inc b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zlib.inc new file mode 100644 index 00000000000..d6c3f6dbeda --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/include/mroonga/unsupport_libgroonga_zlib.inc @@ -0,0 +1,22 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/check_libgroonga_support_zlib.inc + +if ($libgroonga_support_zlib) { + --source ../../include/mroonga/have_mroonga_deinit.inc + skip "This test is for libgroonga doesn't support zlib"; +} diff --git a/storage/mroonga/mysql-test/mroonga/storage/disabled.def b/storage/mroonga/mysql-test/mroonga/storage/disabled.def index 3f546dad2a4..6866adc1e35 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/disabled.def +++ b/storage/mroonga/mysql-test/mroonga/storage/disabled.def @@ -6,4 +6,5 @@ create_table_token_filters_index_comment_one_token_filter : Bundled Mroonga does create_table_token_filters_table_comment_multiple_token_filters : Bundled Mroonga does not support token filter yet. create_table_token_filters_table_comment_one_token_filter : Bundled Mroonga does not support token filter yet. foreign_key_create : Bundled Mroonga does not support this test yet. +partition_insert : Bundled Mroonga does not support this test yet. diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_unique_multiple_column_duplicated.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_unique_multiple_column_duplicated.result new file mode 100644 index 00000000000..8ab7ef22aca --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_add_index_unique_multiple_column_duplicated.result @@ -0,0 +1,19 @@ +DROP TABLE IF EXISTS ids; +CREATE TABLE ids ( +id1 INT, +id2 INT +) DEFAULT CHARSET=utf8mb4; +INSERT INTO ids (id1, id2) values (1, 2), (1, 2); +ALTER TABLE ids ADD UNIQUE INDEX (id1, id2); +ERROR 23000: Can't write, because of unique constraint, to table 'ids' +SHOW CREATE TABLE ids; +Table Create Table +ids CREATE TABLE `ids` ( + `id1` int(11) DEFAULT NULL, + `id2` int(11) DEFAULT NULL +) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4 +SELECT * FROM ids; +id1 id2 +1 2 +1 2 +DROP TABLE ids; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_disable_keys_fulltext_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_disable_keys_fulltext_table.result new file mode 100644 index 00000000000..7e5b1530d33 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_disable_keys_fulltext_table.result @@ -0,0 +1,27 @@ +SET NAMES utf8; +CREATE TABLE terms ( +term varchar(256) NOT NULL PRIMARY KEY +) COMMENT='default_tokenizer "TokenBigram", normalizer "NormalizerAuto"' + DEFAULT CHARSET=utf8; +CREATE TABLE memos ( +id int PRIMARY KEY, +content text NOT NULL, +FULLTEXT INDEX content_index (content) COMMENT 'table "terms"' +) DEFAULT CHARSET=utf8; +SELECT mroonga_command("dump"); +mroonga_command("dump") +table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto +column_create terms term COLUMN_SCALAR ShortText +table_create memos TABLE_PAT_KEY Int32 +column_create memos content COLUMN_SCALAR LongText +column_create memos id COLUMN_SCALAR Int32 +column_create terms content_index COLUMN_INDEX|WITH_POSITION memos content +ALTER TABLE memos DISABLE KEYS; +SELECT mroonga_command("dump"); +mroonga_command("dump") +table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto +column_create terms term COLUMN_SCALAR ShortText +table_create memos TABLE_PAT_KEY Int32 +column_create memos content COLUMN_SCALAR LongText +column_create memos id COLUMN_SCALAR Int32 +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_enable_keys_fulltext_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_enable_keys_fulltext_table.result new file mode 100644 index 00000000000..74c4867fab4 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/alter_table_enable_keys_fulltext_table.result @@ -0,0 +1,28 @@ +SET NAMES utf8; +CREATE TABLE terms ( +term varchar(256) NOT NULL PRIMARY KEY +) COMMENT='default_tokenizer "TokenBigram", normalizer "NormalizerAuto"' + DEFAULT CHARSET=utf8; +CREATE TABLE memos ( +id int PRIMARY KEY, +content text NOT NULL, +FULLTEXT INDEX content_index (content) COMMENT 'table "terms"' +) DEFAULT CHARSET=utf8; +ALTER TABLE memos DISABLE KEYS; +SELECT mroonga_command("dump"); +mroonga_command("dump") +table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto +column_create terms term COLUMN_SCALAR ShortText +table_create memos TABLE_PAT_KEY Int32 +column_create memos content COLUMN_SCALAR LongText +column_create memos id COLUMN_SCALAR Int32 +ALTER TABLE memos ENABLE KEYS; +SELECT mroonga_command("dump"); +mroonga_command("dump") +table_create terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto +column_create terms term COLUMN_SCALAR ShortText +table_create memos TABLE_PAT_KEY Int32 +column_create memos content COLUMN_SCALAR LongText +column_create memos id COLUMN_SCALAR Int32 +column_create terms content_index COLUMN_INDEX|WITH_POSITION memos content +DROP TABLE memos; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_other_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_other_table.result index 87c14a98f15..767fe491e99 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_other_table.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_other_table.result @@ -1,42 +1,30 @@ -DROP DATABASE IF EXISTS mroonga; -CREATE DATABASE mroonga; -USE mroonga; -CREATE TABLE tags ( +CREATE TABLE terms ( name VARCHAR(64) PRIMARY KEY ) DEFAULT CHARSET=utf8 -COLLATE=utf8_bin -COMMENT='default_tokenizer "TokenDelimit"'; +COMMENT='default_tokenizer "TokenBigram"'; CREATE TABLE bugs ( id INT UNSIGNED PRIMARY KEY, -tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "tags"', -FULLTEXT INDEX bugs_tags_index (tags) COMMENT 'table "tags"' +title TEXT, +FULLTEXT INDEX (title) COMMENT 'table "terms"' ) DEFAULT CHARSET=utf8; -INSERT INTO bugs (id, tags) VALUES (1, "Linux MySQL groonga"); -SELECT mroonga_command("dump"); -mroonga_command("dump") -table_create tags TABLE_PAT_KEY ShortText --default_tokenizer TokenDelimit -column_create tags name COLUMN_SCALAR ShortText -table_create bugs TABLE_PAT_KEY UInt32 -column_create bugs id COLUMN_SCALAR UInt32 -column_create bugs tags COLUMN_VECTOR tags -column_create tags bugs_tags_index COLUMN_INDEX|WITH_POSITION bugs tags -load --table tags -[ -["_key","name"], -["Linux",""], -["MySQL",""], -["groonga",""] -] -load --table bugs -[ -["_key","id","tags"], -[1,1,["Linux","MySQL","groonga"]] -] -SELECT *, MATCH (tags) AGAINST ("MySQL" IN BOOLEAN MODE) AS score +INSERT INTO bugs (id, title) VALUES (1, "Mroonga can't build with MySQL X.Y.Z"); +SELECT * FROM terms ORDER BY name; +name +' +. +BUILD +CAN +MROONGA +MYSQL +T +WITH +X +Y +Z +SELECT *, MATCH (title) AGAINST ("+MySQL" IN BOOLEAN MODE) AS score FROM bugs -WHERE MATCH (tags) AGAINST ("MySQL" IN BOOLEAN MODE); -id tags score -1 Linux MySQL groonga 1 +WHERE MATCH (title) AGAINST ("+MySQL" IN BOOLEAN MODE); +id title score +1 Mroonga can't build with MySQL X.Y.Z 1 DROP TABLE bugs; -DROP TABLE tags; -DROP DATABASE mroonga; +DROP TABLE terms; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_vector_other_table.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_vector_other_table.result new file mode 100644 index 00000000000..6ac2e1937fe --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_index_fulltext_vector_other_table.result @@ -0,0 +1,42 @@ +DROP DATABASE IF EXISTS mroonga; +CREATE DATABASE mroonga; +USE mroonga; +CREATE TABLE tags ( +name VARCHAR(64) PRIMARY KEY +) DEFAULT CHARSET=utf8 +COLLATE=utf8_bin +COMMENT='default_tokenizer "TokenDelimit"'; +CREATE TABLE bugs ( +id INT UNSIGNED PRIMARY KEY, +tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "tags"', +FULLTEXT INDEX bugs_tags_index (tags) COMMENT 'table "tags"' +) DEFAULT CHARSET=utf8; +INSERT INTO bugs (id, tags) VALUES (1, "Linux MySQL groonga"); +SELECT mroonga_command("dump"); +mroonga_command("dump") +table_create tags TABLE_PAT_KEY ShortText --default_tokenizer TokenDelimit +column_create tags name COLUMN_SCALAR ShortText +table_create bugs TABLE_PAT_KEY UInt32 +column_create bugs id COLUMN_SCALAR UInt32 +column_create bugs tags COLUMN_VECTOR tags +column_create tags bugs_tags_index COLUMN_INDEX|WITH_POSITION bugs tags +load --table tags +[ +["_key","name"], +["Linux",""], +["MySQL",""], +["groonga",""] +] +load --table bugs +[ +["_key","id","tags"], +[1,1,["Linux","MySQL","groonga"]] +] +SELECT *, MATCH (tags) AGAINST ("+MySQL" IN BOOLEAN MODE) AS score +FROM bugs +WHERE MATCH (tags) AGAINST ("+MySQL" IN BOOLEAN MODE); +id tags score +1 Linux MySQL groonga 1 +DROP TABLE bugs; +DROP TABLE tags; +DROP DATABASE mroonga; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_lz4.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_lz4.result new file mode 100644 index 00000000000..11875e15018 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_lz4.result @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS entries; +CREATE TABLE entries ( +id INT UNSIGNED PRIMARY KEY, +content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_LZ4"' +) DEFAULT CHARSET=utf8; +INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!"); +SELECT * FROM entries; +id content +1 I found Mroonga that is a MySQL storage engine to use Groonga! +DROP TABLE entries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_zlib.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_zlib.result new file mode 100644 index 00000000000..5d704e3ebec --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_support_zlib.result @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS entries; +CREATE TABLE entries ( +id INT UNSIGNED PRIMARY KEY, +content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZLIB"' +) DEFAULT CHARSET=utf8; +INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!"); +SELECT * FROM entries; +id content +1 I found Mroonga that is a MySQL storage engine to use Groonga! +DROP TABLE entries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_lz4.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_lz4.result new file mode 100644 index 00000000000..a9a5f55fd7f --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_lz4.result @@ -0,0 +1,12 @@ +DROP TABLE IF EXISTS entries; +CREATE TABLE entries ( +id INT UNSIGNED PRIMARY KEY, +content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_LZ4"' +) DEFAULT CHARSET=utf8; +Warnings: +Warning 16506 The column flag 'COMPRESS_LZ4' is unsupported. It is ignored +INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!"); +SELECT * FROM entries; +id content +1 I found Mroonga that is a MySQL storage engine to use Groonga! +DROP TABLE entries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_zlib.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_zlib.result new file mode 100644 index 00000000000..068ce58bf74 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_groonga_scalar_unsupport_zlib.result @@ -0,0 +1,12 @@ +DROP TABLE IF EXISTS entries; +CREATE TABLE entries ( +id INT UNSIGNED PRIMARY KEY, +content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZLIB"' +) DEFAULT CHARSET=utf8; +Warnings: +Warning 16506 The column flag 'COMPRESS_ZLIB' is unsupported. It is ignored +INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!"); +SELECT * FROM entries; +id content +1 I found Mroonga that is a MySQL storage engine to use Groonga! +DROP TABLE entries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_comment.result similarity index 100% rename from storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index.result rename to storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_comment.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_no_utf8_charset_with_utf8_normalizer.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.result similarity index 100% rename from storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_no_utf8_charset_with_utf8_normalizer.result rename to storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_none.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_none.result new file mode 100644 index 00000000000..52c6f055e88 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_fulltext_index_none.result @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS diaries; +SET NAMES utf8; +CREATE TABLE diaries ( +day DATE PRIMARY KEY, +content VARCHAR(64) NOT NULL, +FULLTEXT INDEX (content) COMMENT 'normalizer "none"' +) DEFAULT CHARSET=utf8; +INSERT INTO diaries VALUES ("2013-04-23", "Mroonga"); +SELECT * FROM diaries +WHERE MATCH (content) AGAINST ("+Mroonga" IN BOOLEAN MODE); +day content +2013-04-23 Mroonga +SELECT * FROM diaries +WHERE MATCH (content) AGAINST ("+mroonga" IN BOOLEAN MODE); +day content +DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_table_comment.result b/storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment.result similarity index 100% rename from storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_table_comment.result rename to storage/mroonga/mysql-test/mroonga/storage/r/create_table_normalizer_primary_key_table_comment.result diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/index_unique_search_after_duplicated.result b/storage/mroonga/mysql-test/mroonga/storage/r/index_unique_search_after_duplicated.result new file mode 100644 index 00000000000..1d9d5fbbf51 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/index_unique_search_after_duplicated.result @@ -0,0 +1,18 @@ +DROP TABLE IF EXISTS users; +CREATE TABLE users ( +id int PRIMARY KEY, +name varchar(100) NOT NULL, +UNIQUE KEY (name) +) DEFAULT CHARSET=utf8; +INSERT INTO users VALUES (1, "Alice"); +INSERT INTO users VALUES (2, "Bob"); +INSERT INTO users VALUES (3, "Bob"); +ERROR 23000: Duplicate entry 'Bob' for key 'name' +SELECT * FROM users; +id name +1 Alice +2 Bob +SELECT * FROM users WHERE name = "Bob"; +id name +2 Bob +DROP TABLE users; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/information_schema_plugins.result b/storage/mroonga/mysql-test/mroonga/storage/r/information_schema_plugins.result index 8d3decfa32a..63ecb8c669a 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/information_schema_plugins.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/information_schema_plugins.result @@ -1,4 +1,4 @@ select PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_TYPE from information_schema.plugins where plugin_name = "Mroonga"; PLUGIN_NAME PLUGIN_VERSION PLUGIN_TYPE -Mroonga 4.6 STORAGE ENGINE +Mroonga 5.0 STORAGE ENGINE diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_unique_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_unique_key.result index 288e9e3a2c8..fbec44527f7 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_unique_key.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/insert_on_duplicate_key_update_unique_key.result @@ -15,16 +15,19 @@ diaries CREATE TABLE `diaries` ( UNIQUE KEY `day` (`day`) ) ENGINE=Mroonga DEFAULT CHARSET=utf8 INSERT INTO diaries (day, title) -VALUES ("2012-02-14", "clear day") -ON DUPLICATE KEY UPDATE title = "clear day (duplicated)"; +VALUES ("2012-02-14", "clear day1") +ON DUPLICATE KEY UPDATE title = "clear day1 (duplicated)"; INSERT INTO diaries (day, title) -VALUES ("2012-02-14", "rainy day") -ON DUPLICATE KEY UPDATE title = "rainy day (duplicated)"; +VALUES ("2012-02-14", "clear day2") +ON DUPLICATE KEY UPDATE title = "clear day2 (duplicated)"; +INSERT INTO diaries (day, title) +VALUES ("2012-02-14", "clear day3") +ON DUPLICATE KEY UPDATE title = "clear day3 (duplicated)"; INSERT INTO diaries (day, title) VALUES ("2012-02-15", "cloudy day") ON DUPLICATE KEY UPDATE title = "cloudy day (duplicated)"; SELECT * FROM diaries; id day title -1 2012-02-14 rainy day (duplicated) -3 2012-02-15 cloudy day +1 2012-02-14 clear day3 (duplicated) +4 2012-02-15 cloudy day DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/partition_insert.result b/storage/mroonga/mysql-test/mroonga/storage/r/partition_insert.result new file mode 100644 index 00000000000..ea1e63e39d0 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/partition_insert.result @@ -0,0 +1,42 @@ +DROP TABLE IF EXISTS logs; +SET NAMES UTF8; +CREATE TABLE logs ( +timestamp DATETIME, +message TEXT +) DEFAULT CHARSET=UTF8 +PARTITION BY RANGE (TO_DAYS(timestamp)) ( +PARTITION p201501 VALUES LESS THAN (TO_DAYS('2015-02-01')), +PARTITION p201502 VALUES LESS THAN (TO_DAYS('2015-03-01')), +PARTITION p201503 VALUES LESS THAN (TO_DAYS('2015-04-01')), +PARTITION pfuture VALUES LESS THAN MAXVALUE +); +SHOW CREATE TABLE logs; +Table Create Table +logs CREATE TABLE `logs` ( + `timestamp` datetime DEFAULT NULL, + `message` text +) ENGINE=Mroonga DEFAULT CHARSET=utf8 +/*!50100 PARTITION BY RANGE (TO_DAYS(timestamp)) +(PARTITION p201501 VALUES LESS THAN (735995) ENGINE = Mroonga, + PARTITION p201502 VALUES LESS THAN (736023) ENGINE = Mroonga, + PARTITION p201503 VALUES LESS THAN (736054) ENGINE = Mroonga, + PARTITION pfuture VALUES LESS THAN MAXVALUE ENGINE = Mroonga) */ +INSERT INTO logs VALUES('2015-01-01 00:00:00', 'Start'); +INSERT INTO logs VALUES('2015-01-31 23:59:59', 'Shutdown'); +INSERT INTO logs VALUES('2015-02-01 00:00:00', 'Start'); +INSERT INTO logs VALUES('2015-02-28 23:59:59', 'Shutdown'); +INSERT INTO logs VALUES('2015-03-01 00:00:00', 'Start'); +INSERT INTO logs VALUES('2015-03-31 23:59:59', 'Shutdown'); +INSERT INTO logs VALUES('2015-04-01 00:00:00', 'Start'); +INSERT INTO logs VALUES('2015-04-30 23:59:59', 'Shutdown'); +SELECT * FROM logs ORDER BY timestamp; +timestamp message +2015-01-01 00:00:00 Start +2015-01-31 23:59:59 Shutdown +2015-02-01 00:00:00 Start +2015-02-28 23:59:59 Shutdown +2015-03-01 00:00:00 Start +2015-03-31 23:59:59 Shutdown +2015-04-01 00:00:00 Start +2015-04-30 23:59:59 Shutdown +DROP TABLE logs; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result b/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result new file mode 100644 index 00000000000..2c6c1cbc7e8 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/replace_without_key.result @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS diaries; +SET NAMES utf8; +CREATE TABLE diaries ( +id varchar(32) NOT NULL PRIMARY KEY, +content text, +FULLTEXT INDEX (content) +) DEFAULT CHARSET=utf8; +REPLACE INTO diaries(content) VALUES("Hello"); +ERROR HY000: primary key is empty +DROP TABLE diaries; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_column.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_column.result new file mode 100644 index 00000000000..37826335b02 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_column.result @@ -0,0 +1,18 @@ +SET @mroonga_boolean_mode_syntax_flags_backup = +@@mroonga_boolean_mode_syntax_flags; +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_QUERY,ALLOW_COLUMN"; +SET NAMES UTF8; +CREATE TABLE diaries ( +title TEXT, +content TEXT, +FULLTEXT KEY (title), +FULLTEXT KEY (content) +) DEFAULT CHARSET=utf8; +INSERT INTO diaries VALUES("Groonga", "Hello Groonga"); +SELECT * FROM diaries +WHERE MATCH(title) AGAINST("content:@Hello" IN BOOLEAN MODE); +title content +Groonga Hello Groonga +DROP TABLE diaries; +SET mroonga_boolean_mode_syntax_flags = +@mroonga_boolean_mode_syntax_flags_backup; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_leading_not.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_leading_not.result new file mode 100644 index 00000000000..d3ccb150eab --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_leading_not.result @@ -0,0 +1,16 @@ +SET @mroonga_boolean_mode_syntax_flags_backup = +@@mroonga_boolean_mode_syntax_flags; +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_QUERY,ALLOW_LEADING_NOT"; +SET NAMES UTF8; +CREATE TABLE diaries ( +title TEXT, +FULLTEXT KEY (title) +) DEFAULT CHARSET=utf8; +INSERT INTO diaries VALUES("Groonga"); +INSERT INTO diaries VALUES("Mroonga"); +SELECT * FROM diaries WHERE MATCH(title) AGAINST("-Groonga" IN BOOLEAN MODE); +title +Mroonga +DROP TABLE diaries; +SET mroonga_boolean_mode_syntax_flags = +@mroonga_boolean_mode_syntax_flags_backup; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_update.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_update.result new file mode 100644 index 00000000000..55cd8742758 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_allow_update.result @@ -0,0 +1,18 @@ +SET @mroonga_boolean_mode_syntax_flags_backup = +@@mroonga_boolean_mode_syntax_flags; +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_QUERY,ALLOW_COLUMN,ALLOW_UPDATE"; +SET NAMES UTF8; +CREATE TABLE diaries ( +title TEXT, +content TEXT, +FULLTEXT KEY (title), +FULLTEXT KEY (content) +) DEFAULT CHARSET=utf8; +INSERT INTO diaries VALUES("Groonga", "Hello Groonga"); +SELECT * FROM diaries +WHERE MATCH(title) AGAINST('content:="Hello Mroonga"' IN BOOLEAN MODE); +title content +Groonga Hello Mroonga +DROP TABLE diaries; +SET mroonga_boolean_mode_syntax_flags = +@mroonga_boolean_mode_syntax_flags_backup; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_syntax_query.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_syntax_query.result new file mode 100644 index 00000000000..5736fd52c89 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_syntax_query.result @@ -0,0 +1,15 @@ +SET @mroonga_boolean_mode_syntax_flags_backup = +@@mroonga_boolean_mode_syntax_flags; +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_QUERY"; +SET NAMES UTF8; +CREATE TABLE diaries ( +title TEXT, +FULLTEXT KEY (title) +) DEFAULT CHARSET=utf8; +INSERT INTO diaries VALUES("Re:Mroonga"); +SELECT * FROM diaries WHERE MATCH(title) AGAINST("Re:Mroonga" IN BOOLEAN MODE); +title +Re:Mroonga +DROP TABLE diaries; +SET mroonga_boolean_mode_syntax_flags = +@mroonga_boolean_mode_syntax_flags_backup; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_syntax_script.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_syntax_script.result new file mode 100644 index 00000000000..e42fa259e4a --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_boolean_mode_syntax_flags_syntax_script.result @@ -0,0 +1,16 @@ +SET @mroonga_boolean_mode_syntax_flags_backup = +@@mroonga_boolean_mode_syntax_flags; +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_SCRIPT"; +SET NAMES UTF8; +CREATE TABLE diaries ( +title TEXT, +FULLTEXT KEY (title) +) DEFAULT CHARSET=utf8; +INSERT INTO diaries VALUES("Re:Mroonga"); +SELECT * FROM diaries +WHERE MATCH(title) AGAINST("title @ 'Re:Mroonga'" IN BOOLEAN MODE); +title +Re:Mroonga +DROP TABLE diaries; +SET mroonga_boolean_mode_syntax_flags = +@mroonga_boolean_mode_syntax_flags_backup; diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/variable_version.result b/storage/mroonga/mysql-test/mroonga/storage/r/variable_version.result index aae83fe2b38..9b99165c047 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/variable_version.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/variable_version.result @@ -1,3 +1,3 @@ show variables like 'mroonga_version'; Variable_name Value -mroonga_version 4.06 +mroonga_version 5.00 diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_multiple_column_duplicated.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_multiple_column_duplicated.test new file mode 100644 index 00000000000..72e0ebc14a4 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_add_index_unique_multiple_column_duplicated.test @@ -0,0 +1,39 @@ +# Copyright(C) 2015 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/not_embedded.inc +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS ids; +--enable_warnings + +CREATE TABLE ids ( + id1 INT, + id2 INT +) DEFAULT CHARSET=utf8mb4; + +INSERT INTO ids (id1, id2) values (1, 2), (1, 2); + +--error ER_DUP_UNIQUE +ALTER TABLE ids ADD UNIQUE INDEX (id1, id2); +SHOW CREATE TABLE ids; + +SELECT * FROM ids; + +DROP TABLE ids; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_table.test new file mode 100644 index 00000000000..7a03224abb9 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_disable_keys_fulltext_table.test @@ -0,0 +1,45 @@ +# Copyright(C) 2014 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SET NAMES utf8; +CREATE TABLE terms ( + term varchar(256) NOT NULL PRIMARY KEY +) COMMENT='default_tokenizer "TokenBigram", normalizer "NormalizerAuto"' + DEFAULT CHARSET=utf8; + +CREATE TABLE memos ( + id int PRIMARY KEY, + content text NOT NULL, + FULLTEXT INDEX content_index (content) COMMENT 'table "terms"' +) DEFAULT CHARSET=utf8; + +SELECT mroonga_command("dump"); +ALTER TABLE memos DISABLE KEYS; +SELECT mroonga_command("dump"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_table.test new file mode 100644 index 00000000000..2e9022128df --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/alter_table_enable_keys_fulltext_table.test @@ -0,0 +1,46 @@ +# Copyright(C) 2014 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_query_log +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--enable_query_log + +SET NAMES utf8; +CREATE TABLE terms ( + term varchar(256) NOT NULL PRIMARY KEY +) COMMENT='default_tokenizer "TokenBigram", normalizer "NormalizerAuto"' + DEFAULT CHARSET=utf8; + +CREATE TABLE memos ( + id int PRIMARY KEY, + content text NOT NULL, + FULLTEXT INDEX content_index (content) COMMENT 'table "terms"' +) DEFAULT CHARSET=utf8; + +ALTER TABLE memos DISABLE KEYS; +SELECT mroonga_command("dump"); +ALTER TABLE memos ENABLE KEYS; +SELECT mroonga_command("dump"); + +DROP TABLE memos; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_other_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_other_table.test index 805c744236f..dbaf2fb429f 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_other_table.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_other_table.test @@ -1,4 +1,4 @@ -# Copyright(C) 2013 Kouhei Sutou +# Copyright(C) 2014 Kouhei Sutou # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -16,39 +16,27 @@ --source include/not_embedded.inc --source ../../include/mroonga/have_mroonga.inc ---source ../../include/mroonga/load_mroonga_functions.inc ---disable_warnings -DROP DATABASE IF EXISTS mroonga; ---enable_warnings - -CREATE DATABASE mroonga; -USE mroonga; - -CREATE TABLE tags ( +CREATE TABLE terms ( name VARCHAR(64) PRIMARY KEY ) DEFAULT CHARSET=utf8 - COLLATE=utf8_bin - COMMENT='default_tokenizer "TokenDelimit"'; + COMMENT='default_tokenizer "TokenBigram"'; CREATE TABLE bugs ( id INT UNSIGNED PRIMARY KEY, - tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "tags"', - FULLTEXT INDEX bugs_tags_index (tags) COMMENT 'table "tags"' + title TEXT, + FULLTEXT INDEX (title) COMMENT 'table "terms"' ) DEFAULT CHARSET=utf8; -INSERT INTO bugs (id, tags) VALUES (1, "Linux MySQL groonga"); +INSERT INTO bugs (id, title) VALUES (1, "Mroonga can't build with MySQL X.Y.Z"); -SELECT mroonga_command("dump"); +SELECT * FROM terms ORDER BY name; -SELECT *, MATCH (tags) AGAINST ("MySQL" IN BOOLEAN MODE) AS score +SELECT *, MATCH (title) AGAINST ("+MySQL" IN BOOLEAN MODE) AS score FROM bugs - WHERE MATCH (tags) AGAINST ("MySQL" IN BOOLEAN MODE); + WHERE MATCH (title) AGAINST ("+MySQL" IN BOOLEAN MODE); DROP TABLE bugs; -DROP TABLE tags; +DROP TABLE terms; -DROP DATABASE mroonga; - ---source ../../include/mroonga/unload_mroonga_functions.inc --source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_vector_other_table.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_vector_other_table.test new file mode 100644 index 00000000000..86ef09cc8bb --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_index_fulltext_vector_other_table.test @@ -0,0 +1,54 @@ +# Copyright(C) 2013 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source include/not_embedded.inc +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_warnings +DROP DATABASE IF EXISTS mroonga; +--enable_warnings + +CREATE DATABASE mroonga; +USE mroonga; + +CREATE TABLE tags ( + name VARCHAR(64) PRIMARY KEY +) DEFAULT CHARSET=utf8 + COLLATE=utf8_bin + COMMENT='default_tokenizer "TokenDelimit"'; + +CREATE TABLE bugs ( + id INT UNSIGNED PRIMARY KEY, + tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "tags"', + FULLTEXT INDEX bugs_tags_index (tags) COMMENT 'table "tags"' +) DEFAULT CHARSET=utf8; + +INSERT INTO bugs (id, tags) VALUES (1, "Linux MySQL groonga"); + +SELECT mroonga_command("dump"); + +SELECT *, MATCH (tags) AGAINST ("+MySQL" IN BOOLEAN MODE) AS score + FROM bugs + WHERE MATCH (tags) AGAINST ("+MySQL" IN BOOLEAN MODE); + +DROP TABLE bugs; +DROP TABLE tags; + +DROP DATABASE mroonga; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_lz4.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_lz4.test new file mode 100644 index 00000000000..5de8f951d8f --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_lz4.test @@ -0,0 +1,37 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/support_libgroonga_lz4.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_warnings +DROP TABLE IF EXISTS entries; +--enable_warnings + +CREATE TABLE entries ( + id INT UNSIGNED PRIMARY KEY, + content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_LZ4"' +) DEFAULT CHARSET=utf8; + +INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!"); + +SELECT * FROM entries; + +DROP TABLE entries; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zlib.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zlib.test new file mode 100644 index 00000000000..3ec14ebef76 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_support_zlib.test @@ -0,0 +1,37 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/support_libgroonga_zlib.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_warnings +DROP TABLE IF EXISTS entries; +--enable_warnings + +CREATE TABLE entries ( + id INT UNSIGNED PRIMARY KEY, + content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZLIB"' +) DEFAULT CHARSET=utf8; + +INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!"); + +SELECT * FROM entries; + +DROP TABLE entries; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_lz4.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_lz4.test new file mode 100644 index 00000000000..324b7ac89f5 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_lz4.test @@ -0,0 +1,37 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/unsupport_libgroonga_lz4.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_warnings +DROP TABLE IF EXISTS entries; +--enable_warnings + +CREATE TABLE entries ( + id INT UNSIGNED PRIMARY KEY, + content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_LZ4"' +) DEFAULT CHARSET=utf8; + +INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!"); + +SELECT * FROM entries; + +DROP TABLE entries; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zlib.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zlib.test new file mode 100644 index 00000000000..10e77e40e3d --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_groonga_scalar_unsupport_zlib.test @@ -0,0 +1,37 @@ +# Copyright(C) 2014 Naoya Murakami +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/unsupport_libgroonga_zlib.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_warnings +DROP TABLE IF EXISTS entries; +--enable_warnings + +CREATE TABLE entries ( + id INT UNSIGNED PRIMARY KEY, + content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZLIB"' +) DEFAULT CHARSET=utf8; + +INSERT INTO entries (id, content) VALUES (1, "I found Mroonga that is a MySQL storage engine to use Groonga!"); + +SELECT * FROM entries; + +DROP TABLE entries; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_comment.test similarity index 100% rename from storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index.test rename to storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_comment.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_no_utf8_charset_with_utf8_normalizer.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.test similarity index 100% rename from storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_no_utf8_charset_with_utf8_normalizer.test rename to storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_no_utf8_charset_with_utf8_normalizer.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_none.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_none.test new file mode 100644 index 00000000000..ae4d4cb9f1b --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_fulltext_index_none.test @@ -0,0 +1,42 @@ +# Copyright(C) 2014 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc +--source ../../include/mroonga/load_mroonga_functions.inc + +--disable_warnings +DROP TABLE IF EXISTS diaries; +--enable_warnings + +SET NAMES utf8; + +CREATE TABLE diaries ( + day DATE PRIMARY KEY, + content VARCHAR(64) NOT NULL, + FULLTEXT INDEX (content) COMMENT 'normalizer "none"' +) DEFAULT CHARSET=utf8; + +INSERT INTO diaries VALUES ("2013-04-23", "Mroonga"); + +SELECT * FROM diaries + WHERE MATCH (content) AGAINST ("+Mroonga" IN BOOLEAN MODE); +SELECT * FROM diaries + WHERE MATCH (content) AGAINST ("+mroonga" IN BOOLEAN MODE); + +DROP TABLE diaries; + +--source ../../include/mroonga/unload_mroonga_functions.inc +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_table_comment.test b/storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment.test similarity index 100% rename from storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_table_comment.test rename to storage/mroonga/mysql-test/mroonga/storage/t/create_table_normalizer_primary_key_table_comment.test diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_search_after_duplicated.test b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_search_after_duplicated.test new file mode 100644 index 00000000000..533422ec087 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/index_unique_search_after_duplicated.test @@ -0,0 +1,40 @@ +# Copyright(C) 2015 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS users; +--enable_warnings + +CREATE TABLE users ( + id int PRIMARY KEY, + name varchar(100) NOT NULL, + UNIQUE KEY (name) +) DEFAULT CHARSET=utf8; + +INSERT INTO users VALUES (1, "Alice"); + +INSERT INTO users VALUES (2, "Bob"); +-- error ER_DUP_ENTRY +INSERT INTO users VALUES (3, "Bob"); + +SELECT * FROM users; +SELECT * FROM users WHERE name = "Bob"; + +DROP TABLE users; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_unique_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_unique_key.test index 782b7bee9ca..350440515c1 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_unique_key.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/insert_on_duplicate_key_update_unique_key.test @@ -29,11 +29,14 @@ CREATE TABLE diaries ( SHOW CREATE TABLE diaries; INSERT INTO diaries (day, title) - VALUES ("2012-02-14", "clear day") - ON DUPLICATE KEY UPDATE title = "clear day (duplicated)"; + VALUES ("2012-02-14", "clear day1") + ON DUPLICATE KEY UPDATE title = "clear day1 (duplicated)"; INSERT INTO diaries (day, title) - VALUES ("2012-02-14", "rainy day") - ON DUPLICATE KEY UPDATE title = "rainy day (duplicated)"; + VALUES ("2012-02-14", "clear day2") + ON DUPLICATE KEY UPDATE title = "clear day2 (duplicated)"; +INSERT INTO diaries (day, title) + VALUES ("2012-02-14", "clear day3") + ON DUPLICATE KEY UPDATE title = "clear day3 (duplicated)"; INSERT INTO diaries (day, title) VALUES ("2012-02-15", "cloudy day") ON DUPLICATE KEY UPDATE title = "cloudy day (duplicated)"; diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/partition_insert.test b/storage/mroonga/mysql-test/mroonga/storage/t/partition_insert.test new file mode 100644 index 00000000000..219c3440d69 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/partition_insert.test @@ -0,0 +1,49 @@ +# Copyright(C) 2015 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS logs; +--enable_warnings + +SET NAMES UTF8; +CREATE TABLE logs ( + timestamp DATETIME, + message TEXT +) DEFAULT CHARSET=UTF8 + PARTITION BY RANGE (TO_DAYS(timestamp)) ( + PARTITION p201501 VALUES LESS THAN (TO_DAYS('2015-02-01')), + PARTITION p201502 VALUES LESS THAN (TO_DAYS('2015-03-01')), + PARTITION p201503 VALUES LESS THAN (TO_DAYS('2015-04-01')), + PARTITION pfuture VALUES LESS THAN MAXVALUE +); +SHOW CREATE TABLE logs; + +INSERT INTO logs VALUES('2015-01-01 00:00:00', 'Start'); +INSERT INTO logs VALUES('2015-01-31 23:59:59', 'Shutdown'); +INSERT INTO logs VALUES('2015-02-01 00:00:00', 'Start'); +INSERT INTO logs VALUES('2015-02-28 23:59:59', 'Shutdown'); +INSERT INTO logs VALUES('2015-03-01 00:00:00', 'Start'); +INSERT INTO logs VALUES('2015-03-31 23:59:59', 'Shutdown'); +INSERT INTO logs VALUES('2015-04-01 00:00:00', 'Start'); +INSERT INTO logs VALUES('2015-04-30 23:59:59', 'Shutdown'); + +SELECT * FROM logs ORDER BY timestamp; + +DROP TABLE logs; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test b/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test new file mode 100644 index 00000000000..a38c4953e67 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/replace_without_key.test @@ -0,0 +1,35 @@ +# Copyright(C) 2014 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +--disable_warnings +DROP TABLE IF EXISTS diaries; +--enable_warnings + +SET NAMES utf8; +CREATE TABLE diaries ( + id varchar(32) NOT NULL PRIMARY KEY, + content text, + FULLTEXT INDEX (content) +) DEFAULT CHARSET=utf8; + +-- error ER_ERROR_ON_WRITE +REPLACE INTO diaries(content) VALUES("Hello"); + +DROP TABLE diaries; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_column.test new file mode 100644 index 00000000000..11ca867d82c --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_column.test @@ -0,0 +1,43 @@ +# Copyright(C) 2014 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +SET @mroonga_boolean_mode_syntax_flags_backup = + @@mroonga_boolean_mode_syntax_flags; + +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_QUERY,ALLOW_COLUMN"; + +SET NAMES UTF8; + +CREATE TABLE diaries ( + title TEXT, + content TEXT, + FULLTEXT KEY (title), + FULLTEXT KEY (content) +) DEFAULT CHARSET=utf8; + +INSERT INTO diaries VALUES("Groonga", "Hello Groonga"); + +SELECT * FROM diaries + WHERE MATCH(title) AGAINST("content:@Hello" IN BOOLEAN MODE); + +DROP TABLE diaries; + +SET mroonga_boolean_mode_syntax_flags = + @mroonga_boolean_mode_syntax_flags_backup; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_leading_not.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_leading_not.test new file mode 100644 index 00000000000..665682fde6e --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_leading_not.test @@ -0,0 +1,41 @@ +# Copyright(C) 2014 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +SET @mroonga_boolean_mode_syntax_flags_backup = + @@mroonga_boolean_mode_syntax_flags; + +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_QUERY,ALLOW_LEADING_NOT"; + +SET NAMES UTF8; + +CREATE TABLE diaries ( + title TEXT, + FULLTEXT KEY (title) +) DEFAULT CHARSET=utf8; + +INSERT INTO diaries VALUES("Groonga"); +INSERT INTO diaries VALUES("Mroonga"); + +SELECT * FROM diaries WHERE MATCH(title) AGAINST("-Groonga" IN BOOLEAN MODE); + +DROP TABLE diaries; + +SET mroonga_boolean_mode_syntax_flags = + @mroonga_boolean_mode_syntax_flags_backup; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_update.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_update.test new file mode 100644 index 00000000000..8a55c0fb0f7 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_allow_update.test @@ -0,0 +1,43 @@ +# Copyright(C) 2014 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +SET @mroonga_boolean_mode_syntax_flags_backup = + @@mroonga_boolean_mode_syntax_flags; + +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_QUERY,ALLOW_COLUMN,ALLOW_UPDATE"; + +SET NAMES UTF8; + +CREATE TABLE diaries ( + title TEXT, + content TEXT, + FULLTEXT KEY (title), + FULLTEXT KEY (content) +) DEFAULT CHARSET=utf8; + +INSERT INTO diaries VALUES("Groonga", "Hello Groonga"); + +SELECT * FROM diaries + WHERE MATCH(title) AGAINST('content:="Hello Mroonga"' IN BOOLEAN MODE); + +DROP TABLE diaries; + +SET mroonga_boolean_mode_syntax_flags = + @mroonga_boolean_mode_syntax_flags_backup; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_query.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_query.test new file mode 100644 index 00000000000..0ff2d8aed43 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_query.test @@ -0,0 +1,40 @@ +# Copyright(C) 2014 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +SET @mroonga_boolean_mode_syntax_flags_backup = + @@mroonga_boolean_mode_syntax_flags; + +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_QUERY"; + +SET NAMES UTF8; + +CREATE TABLE diaries ( + title TEXT, + FULLTEXT KEY (title) +) DEFAULT CHARSET=utf8; + +INSERT INTO diaries VALUES("Re:Mroonga"); + +SELECT * FROM diaries WHERE MATCH(title) AGAINST("Re:Mroonga" IN BOOLEAN MODE); + +DROP TABLE diaries; + +SET mroonga_boolean_mode_syntax_flags = + @mroonga_boolean_mode_syntax_flags_backup; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_script.test b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_script.test new file mode 100644 index 00000000000..61d5daa63d9 --- /dev/null +++ b/storage/mroonga/mysql-test/mroonga/storage/t/variable_boolean_mode_syntax_flags_syntax_script.test @@ -0,0 +1,41 @@ +# Copyright(C) 2014 Kouhei Sutou +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +--source ../../include/mroonga/have_mroonga.inc + +SET @mroonga_boolean_mode_syntax_flags_backup = + @@mroonga_boolean_mode_syntax_flags; + +SET mroonga_boolean_mode_syntax_flags = "SYNTAX_SCRIPT"; + +SET NAMES UTF8; + +CREATE TABLE diaries ( + title TEXT, + FULLTEXT KEY (title) +) DEFAULT CHARSET=utf8; + +INSERT INTO diaries VALUES("Re:Mroonga"); + +SELECT * FROM diaries + WHERE MATCH(title) AGAINST("title @ 'Re:Mroonga'" IN BOOLEAN MODE); + +DROP TABLE diaries; + +SET mroonga_boolean_mode_syntax_flags = + @mroonga_boolean_mode_syntax_flags_backup; + +--source ../../include/mroonga/have_mroonga_deinit.inc diff --git a/storage/mroonga/packages/Makefile.am b/storage/mroonga/packages/Makefile.am new file mode 100644 index 00000000000..fed925c3dfc --- /dev/null +++ b/storage/mroonga/packages/Makefile.am @@ -0,0 +1,7 @@ +SUBDIRS = \ + apt \ + rpm \ + source \ + ubuntu \ + windows \ + yum diff --git a/storage/mroonga/packages/apt/Makefile.am b/storage/mroonga/packages/apt/Makefile.am new file mode 100644 index 00000000000..26f5609c527 --- /dev/null +++ b/storage/mroonga/packages/apt/Makefile.am @@ -0,0 +1,67 @@ +REPOSITORIES_PATH = repositories +DISTRIBUTIONS = debian +ARCHITECTURES = i386 amd64 +CODE_NAMES = wheezy + +all: + +release: build sign-packages update-repository sign-repository upload + +remove-existing-packages: + for distribution in $(DISTRIBUTIONS); do \ + find $(REPOSITORIES_PATH)/$${distribution}/pool \ + -type f -delete; \ + done + +download: + for distribution in $(DISTRIBUTIONS); do \ + rsync -avz --progress --delete \ + $(RSYNC_PATH)/$${distribution} $(REPOSITORIES_PATH)/; \ + done + +sign-packages: + ./sign-packages.sh '$(GPG_UID)' '$(REPOSITORIES_PATH)/' '$(CODE_NAMES)' + +update-repository: + ./update-repository.sh '$(PACKAGE_NAME)' '$(REPOSITORIES_PATH)/' \ + '$(ARCHITECTURES)' '$(CODE_NAMES)' + +sign-repository: + ./sign-repository.sh '$(GPG_UID)' '$(REPOSITORIES_PATH)/' '$(CODE_NAMES)' + +ensure-rsync-path: + @if test -z "$(RSYNC_PATH)"; then \ + echo "--with-rsync-path configure option must be specified."; \ + false; \ + fi + +upload: ensure-rsync-path + for distribution in $(DISTRIBUTIONS); do \ + (cd $(REPOSITORIES_PATH)/$${distribution}; \ + rsync -avz --progress --delete \ + dists pool $(RSYNC_PATH)/$${distribution}; \ + ); \ + done + +build: build-package-deb + +build-package-deb: prepare-build-package-deb + vagrant destroy --force + for architecture in $(ARCHITECTURES); do \ + for code_name in $(CODE_NAMES); do \ + id=debian-$$code_name-$$architecture; \ + vagrant up $$id || exit 1; \ + vagrant destroy --force $$id; \ + done; \ + done + +prepare-build-package-deb: source env.sh + cp env.sh tmp/ + rm -rf tmp/debian + cp -rp $(srcdir)/../debian tmp/ + +source: tmp/$(PACKAGE)-$(VERSION).tar.gz + +tmp/$(PACKAGE)-$(VERSION).tar.gz: $(abs_top_builddir)/$(PACKAGE)-$(VERSION).tar.gz + mkdir -p tmp + cp $(abs_top_builddir)/$(PACKAGE)-$(VERSION).tar.gz $@ diff --git a/storage/mroonga/packages/apt/Vagrantfile b/storage/mroonga/packages/apt/Vagrantfile new file mode 100644 index 00000000000..4483412326a --- /dev/null +++ b/storage/mroonga/packages/apt/Vagrantfile @@ -0,0 +1,29 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + vms = [ + { + :id => "debian-wheezy-i386", + :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.8-i386_chef-provisionerless.box", + }, + { + :id => "debian-wheezy-amd64", + :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.8_chef-provisionerless.box", + }, + ] + + vms.each do |vm| + config.vm.define(vm[:id]) do |node| + node.vm.box = vm[:id] + node.vm.box_url = vm[:box_url] + node.vm.provision(:shell, :path => "build-deb.sh") + node.vm.provider("virtualbox") do |virtual_box| + virtual_box.memory = 768 + end + end + end +end diff --git a/storage/mroonga/packages/apt/build-deb.sh b/storage/mroonga/packages/apt/build-deb.sh new file mode 100755 index 00000000000..7db24068a7c --- /dev/null +++ b/storage/mroonga/packages/apt/build-deb.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +LANG=C + +mysql_server_package=mysql-server + +run() +{ + "$@" + if test $? -ne 0; then + echo "Failed $@" + exit 1 + fi +} + +. /vagrant/tmp/env.sh + +grep '^deb ' /etc/apt/sources.list | \ + sed -e 's/^deb /deb-src /' > /etc/apt/sources.list.d/base-source.list + +run apt-get update +run apt-get install -y lsb-release + +distribution=$(lsb_release --id --short | tr 'A-Z' 'a-z') +code_name=$(lsb_release --codename --short) +case "${distribution}" in + debian) + component=main + run cat < /etc/apt/sources.list.d/groonga.list +deb http://packages.groonga.org/debian/ wheezy main +deb-src http://packages.groonga.org/debian/ wheezy main +EOF + if ! grep --quiet security /etc/apt/sources.list; then + run cat < /etc/apt/sources.list.d/security.list +deb http://security.debian.org/ ${code_name}/updates main +deb-src http://security.debian.org/ ${code_name}/updates main +EOF + fi + run apt-get update + run apt-get install -y --allow-unauthenticated groonga-keyring + run apt-get update + ;; + ubuntu) + component=universe + run cat < /etc/apt/sources.list.d/security.list +deb http://security.ubuntu.com/ubuntu ${code_name}-security main restricted +deb-src http://security.ubuntu.com/ubuntu ${code_name}-security main restricted +EOF + run sed -e 's/main/universe/' /etc/apt/sources.list > \ + /etc/apt/sources.list.d/universe.list + run apt-get -y install software-properties-common + run add-apt-repository -y universe + run add-apt-repository -y ppa:groonga/ppa + run apt-get update + ;; +esac + +run apt-get install -V -y build-essential devscripts ${DEPENDED_PACKAGES} +run apt-get build-dep -y ${mysql_server_package} + +run mkdir -p build +run cp /vagrant/tmp/${PACKAGE}-${VERSION}.tar.gz \ + build/${PACKAGE}_${VERSION}.orig.tar.gz +run cd build +run tar xfz ${PACKAGE}_${VERSION}.orig.tar.gz +run cd ${PACKAGE}-${VERSION}/ +run cp -rp /vagrant/tmp/debian debian +# export DEB_BUILD_OPTIONS=noopt +MYSQL_PACKAGE_INFO=$(apt-cache show mysql-server | grep Version | sort | tail -1) +MYSQL_PACKAGE_VERSION=${MYSQL_PACKAGE_INFO##Version: } +sed -i "s/MYSQL_VERSION/$MYSQL_PACKAGE_VERSION/" debian/control +run debuild -us -uc +run cd - + +package_initial=$(echo "${PACKAGE}" | sed -e 's/\(.\).*/\1/') +pool_dir="/vagrant/repositories/${distribution}/pool/${code_name}/${component}/${package_initial}/${PACKAGE}" +run mkdir -p "${pool_dir}/" +run cp *.tar.gz *.diff.gz *.dsc *.deb "${pool_dir}/" diff --git a/storage/mroonga/packages/apt/env.sh.in b/storage/mroonga/packages/apt/env.sh.in new file mode 100644 index 00000000000..a44d6b36871 --- /dev/null +++ b/storage/mroonga/packages/apt/env.sh.in @@ -0,0 +1,15 @@ +PACKAGE=@PACKAGE@ +VERSION=@VERSION@ +DEPENDED_PACKAGES=" +debhelper +autotools-dev +libgroonga-dev +pkg-config +libmecab-dev +mecab-utils +libmysqlclient-dev +libmysqld-dev +libssl-dev +groonga-normalizer-mysql +wget +" diff --git a/storage/mroonga/packages/apt/sign-packages.sh b/storage/mroonga/packages/apt/sign-packages.sh new file mode 100755 index 00000000000..11a4aea26db --- /dev/null +++ b/storage/mroonga/packages/apt/sign-packages.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +script_base_dir=`dirname $0` + +if [ $# != 3 ]; then + echo "Usage: $0 GPG_UID DESITINATION CODES" + echo " e.g.: $0 'F10399C0' repositories/ 'lenny unstable hardy karmic'" + exit 1 +fi + +GPG_UID=$1 +DESTINATION=$2 +CODES=$3 + +run() +{ + "$@" + if test $? -ne 0; then + echo "Failed $@" + exit 1 + fi +} + +for code_name in ${CODES}; do + case ${code_name} in + squeeze|wheezy|jessie|unstable) + distribution=debian + ;; + *) + distribution=ubuntu + ;; + esac + + base_directory=${DESTINATION}${distribution} + debsign -pgpg2 --re-sign -k${GPG_UID} \ + $(find ${base_directory} -name '*.dsc' -or -name '*.changes') & + if [ "${PARALLEL}" != "yes" ]; then + wait + fi +done + +wait diff --git a/storage/mroonga/packages/apt/sign-repository.sh b/storage/mroonga/packages/apt/sign-repository.sh new file mode 100755 index 00000000000..fb0de850d6f --- /dev/null +++ b/storage/mroonga/packages/apt/sign-repository.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +script_base_dir=`dirname $0` + +if [ $# != 3 ]; then + echo "Usage: $0 GPG_UID DESTINATION CODES" + echo " e.g.: $0 'F10399C0' repositories/ 'lenny unstable hardy karmic'" + exit 1 +fi + +GPG_UID=$1 +DESTINATION=$2 +CODES=$3 + +run() +{ + "$@" + if test $? -ne 0; then + echo "Failed $@" + exit 1 + fi +} + +for code_name in ${CODES}; do + case ${code_name} in + squeeze|wheezy|jessie|unstable) + distribution=debian + ;; + *) + distribution=ubuntu + ;; + esac + + release=${DESTINATION}${distribution}/dists/${code_name}/Release + rm -f ${release}.gpg + gpg2 --sign --detach-sign --armor \ + --local-user ${GPG_UID} \ + --output ${release}.gpg \ + ${release} & + + if [ "${PARALLEL}" != "yes" ]; then + wait + fi +done + +wait diff --git a/storage/mroonga/packages/apt/update-repository.sh b/storage/mroonga/packages/apt/update-repository.sh new file mode 100755 index 00000000000..da1f8cd121c --- /dev/null +++ b/storage/mroonga/packages/apt/update-repository.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +script_base_dir=`dirname $0` + +if [ $# != 4 ]; then + echo "Usage: $0 PROJECT_NAME DESTINATION ARCHITECTURES CODES" + echo " e.g.: $0 mroonga repositories/ 'i386 amd64' 'lenny unstable hardy karmic'" + exit 1 +fi + +PROJECT_NAME=$1 +DESTINATION=$2 +ARCHITECTURES=$3 +CODES=$4 + +run() +{ + "$@" + if test $? -ne 0; then + echo "Failed $@" + exit 1 + fi +} + +update_repository() +{ + distribution=$1 + code_name=$2 + component=$3 + + rm -rf dists/${code_name} + mkdir -p dists/${code_name}/${component}/binary-i386/ + mkdir -p dists/${code_name}/${component}/binary-amd64/ + mkdir -p dists/${code_name}/${component}/source/ + + cat < dists/.htaccess +Options +Indexes +EOF + + cat < dists/${code_name}/${component}/binary-i386/Release +Archive: ${code_name} +Component: ${component} +Origin: The ${PROJECT_NAME} project +Label: The ${PROJECT_NAME} project +Architecture: i386 +EOF + + cat < dists/${code_name}/${component}/binary-amd64/Release +Archive: ${code_name} +Component: ${component} +Origin: The ${PROJECT_NAME} project +Label: The ${PROJECT_NAME} project +Architecture: amd64 +EOF + + cat < dists/${code_name}/${component}/source/Release +Archive: ${code_name} +Component: ${component} +Origin: The ${PROJECT_NAME} project +Label: The ${PROJECT_NAME} project +Architecture: source +EOF + + cat < generate-${code_name}.conf +Dir::ArchiveDir "."; +Dir::CacheDir "."; +TreeDefault::Directory "pool/${code_name}/${component}"; +TreeDefault::SrcDirectory "pool/${code_name}/${component}"; +Default::Packages::Extensions ".deb"; +Default::Packages::Compress ". gzip bzip2"; +Default::Sources::Compress ". gzip bzip2"; +Default::Contents::Compress "gzip bzip2"; + +BinDirectory "dists/${code_name}/${component}/binary-i386" { + Packages "dists/${code_name}/${component}/binary-i386/Packages"; + Contents "dists/${code_name}/Contents-i386"; + SrcPackages "dists/${code_name}/${component}/source/Sources"; +}; + +BinDirectory "dists/${code_name}/${component}/binary-amd64" { + Packages "dists/${code_name}/${component}/binary-amd64/Packages"; + Contents "dists/${code_name}/Contents-amd64"; + SrcPackages "dists/${code_name}/${component}/source/Sources"; +}; + +Tree "dists/${code_name}" { + Sections "${component}"; + Architectures "i386 amd64 source"; +}; +EOF + apt-ftparchive generate generate-${code_name}.conf + chmod 644 dists/${code_name}/Contents-* + + rm -f dists/${code_name}/Release* + rm -f *.db + cat < release-${code_name}.conf +APT::FTPArchive::Release::Origin "The ${PROJECT_NAME} project"; +APT::FTPArchive::Release::Label "The ${PROJECT_NAME} project"; +APT::FTPArchive::Release::Architectures "i386 amd64"; +APT::FTPArchive::Release::Codename "${code_name}"; +APT::FTPArchive::Release::Suite "${code_name}"; +APT::FTPArchive::Release::Components "${component}"; +APT::FTPArchive::Release::Description "${PACKAGE_NAME} packages"; +EOF + apt-ftparchive -c release-${code_name}.conf \ + release dists/${code_name} > /tmp/Release + mv /tmp/Release dists/${code_name} +} + +for code_name in ${CODES}; do + case ${code_name} in + squeeze|wheezy|jessie|unstable) + distribution=debian + component=main + ;; + *) + distribution=ubuntu + component=universe + ;; + esac + + mkdir -p ${DESTINATION}${distribution} + (cd ${DESTINATION}${distribution} + update_repository $distribution $code_name $component) & + if [ "${PARALLEL}" != "yes" ]; then + wait + fi +done + +wait diff --git a/storage/mroonga/packages/check-utility.sh b/storage/mroonga/packages/check-utility.sh new file mode 100755 index 00000000000..211e231a473 --- /dev/null +++ b/storage/mroonga/packages/check-utility.sh @@ -0,0 +1,665 @@ +#!/bin/sh + +# Usage: check-utility.sh [--install-groonga] +# [--check-install] +# [--check-address] +# [--enable-repository] +# +# CODES="squeeze wheezy unstable lucid natty oneiric precise" +# DISTRIBUTIONS="centos fedora" + +CHROOT_ROOT=/var/lib/chroot +CHECK_ADDRESS=0 +CHECK_INSTALL=0 +CHECK_INSTALL_PACKAGE=mysql-server-mroonga +CHECK_BUILD=0 +CHECK_DEPENDS=0 +CHECK_PROVIDES=0 +ENABLE_REPOSITORY=0 +DISABLE_REPOSITORY=0 +INSTALL_SCRIPT=0 +INSTALL_MROONGA=0 +UNINSTALL_MROONGA=0 + +common_deb_procedure () +{ + for code in $CODES; do + for arch in $DEB_ARCHITECTURES; do + root_dir=$CHROOT_ROOT/$code-$arch + eval $1 $code $arch $root_dir + done + done +} + +common_rpm_procedure () +{ + for dist in $DISTRIBUTIONS; do + case $dist in + "fedora") + DISTRIBUTIONS_VERSION="19" + ;; + "centos") + DISTRIBUTIONS_VERSION="5 6" + ;; + esac + for ver in $DISTRIBUTIONS_VERSION; do + for arch in $RPM_ARCHITECTURES; do + root_dir=$CHROOT_ROOT/$dist-$ver-$arch + eval $1 $dist $arch $ver $root_dir + done + done + done +} + +echo_packages_repository_address () +{ + root_dir=$1 + code=$2 + arch=$3 + address=`grep "packages.groonga.org" $root_dir/etc/hosts | grep -v "#"` + if [ -z "$address" ]; then + echo "$code-$arch: default" + else + echo "$code-$arch: $address" + fi +} + +setup_distributions () +{ + if [ -z "$DISTRIBUTIONS" ]; then + DISTRIBUTIONS="centos fedora" + fi +} + +setup_rpm_architectures () +{ + if [ -z "$RPM_ARCHITECTURES" ]; then + RPM_ARCHITECTURES="i386 x86_64" + fi +} + +setup_codes () +{ + if [ -z "$CODES" ]; then + CODES="squeeze wheezy jessie unstable lucid precise quantal raring" + fi +} +setup_deb_architectures () +{ + if [ -z "$DEB_ARCHITECTURES" ]; then + DEB_ARCHITECTURES="i386 amd64" + fi +} + +check_packages_repository_address () +{ + common_deb_procedure "check_packages_deb_repository_address" + common_rpm_procedure "check_packages_rpm_repository_address" +} + +check_packages_deb_repository_address () +{ + code=$1 + arch=$2 + root_dir=$4 + echo_packages_repository_address "$root_dir" "$code" "$arch" +} + +check_packages_rpm_repository_address () +{ + dist=$1 + arch=$2 + ver=$3 + root_dir=$4 + echo_packages_repository_address "$root_dir" "$dist-$ver" "$arch" +} + +host_address () +{ + ifconfig_result=`LANG=C /sbin/ifconfig wlan0` + inet_addr=`echo "$ifconfig_result" | grep "inet addr:192"` + address=`echo $inet_addr | ruby -ne '/inet addr:(.+?)\s/ =~ $_ && puts($1)'` + HOST_ADDRESS=$address +} + +check_build_packages () +{ + common_deb_procedure "check_build_deb_packages" + common_rpm_procedure "check_build_rpm_packages" +} + +check_build_deb_packages () +{ + code=$1 + arch=$2 + BASE_VERSION=`cat ../version` + RESULT_SET=`find apt/repositories -name "*$BASE_VERSION*" | grep $code | grep $arch` + if [ -z "$RESULT_SET" ]; then + printf "%8s %5s %s => 0 deb\n" $code $arch $BASE_VERSION + else + PACKAGE_COUNT=`find apt/repositories -name "*$BASE_VERSION*" | grep $code | grep $arch | wc | awk '{print \$1}'` + printf "%8s %5s %s => %2d debs\n" $code $arch $BASE_VERSION $PACKAGE_COUNT + fi +} + +check_build_rpm_packages () +{ + dist=$1 + arch=$2 + ver=$3 + BASE_VERSION=`cat ../version` + FIND_PATH=yum/repositories/$dist/$ver/$arch + RESULT_SET=`find $FIND_PATH -name "*$BASE_VERSION*"` + if [ -z "$RESULT_SET" ]; then + printf "%8s %6s %s => 0 rpm\n" $dist$ver $arch $BASE_VERSION + else + PACKAGE_COUNT=`find $FIND_PATH -name "*$BASE_VERSION*" | wc -l` + printf "%8s %6s %s => %2d rpms\n" $dist$ver $arch $BASE_VERSION $PACKAGE_COUNT + fi +} + +check_depends_packages () +{ + common_deb_procedure "check_depends_deb_packages" + common_rpm_procedure "check_depends_rpm_packages" +} + +check_depends_deb_packages () +{ + code=$1 + arch=$2 + BASE_VERSION=`cat ../version` + FIND_PATH=apt/repositories/*/pool/$code + RESULT_SET=`find $FIND_PATH -name "*$BASE_VERSION*.deb"` + if [ -z "$RESULT_SET" ]; then + printf "%8s %5s %s => 404 deb\n" $code $arch $BASE_VERSION + else + for pkg in $RESULT_SET; do + DEB_NAME=`basename $pkg` + DEPENDS=`dpkg -I $pkg | grep "Depends"` + printf "%8s %5s %s => %s\n" $code $arch $DEB_NAME "$DEPENDS" + done + fi +} + +check_depends_rpm_packages () +{ + dist=$1 + arch=$2 + ver=$3 + BASE_VERSION=`cat ../version` + FIND_PATH=yum/repositories/$dist/$ver/$arch + RESULT_SET=`find $FIND_PATH -name "*$BASE_VERSION*"` + if [ -z "$RESULT_SET" ]; then + printf "%8s %6s %s => 404 rpm\n" $dist$ver $arch $BASE_VERSION + else + for pkg in $RESULT_SET; do + RPM_NAME=`basename $pkg` + DEPENDS=`rpm -qp --requires $pkg | grep -i "mysql" | tr -t '\n' ' '` + printf "%9s %6s %s => %s\n" $dist$ver $arch $RPM_NAME "$DEPENDS" + done + fi +} + +check_provided_mysql_packages () +{ + common_deb_procedure "check_provided_mysql_deb_packages" + common_rpm_procedure "check_provided_mysql_rpm_packages" + for code in $CODES; do + echo $code + cat tmp/$code-amd64-mysql-server.txt + done + for dist in $DISTRIBUTIONS; do + echo $dist + cat tmp/$dist-x86_64-mysql-server.txt + done +} + +check_provided_mysql_deb_packages () +{ + code=$1 + arch=$2 + root_dir=$3 + cat > tmp/check-provided-mysql.sh < /dev/null +apt-cache show mysql-server | grep "Version" | head -1 > /tmp/$code-$arch-mysql-server.txt +EOF + if [ -d $root_dir ]; then + CHECK_SCRIPT=check-provided-mysql.sh + echo "copy check script $CHECK_SCRIPT to $root_dir/tmp" + sudo rm -f $root_dir/tmp/$CHECK_SCRIPT + cp tmp/$CHECK_SCRIPT $root_dir/tmp + sudo chmod 755 $root_dir/tmp/$CHECK_SCRIPT + sudo chname $code-$arch chroot $root_dir /tmp/$CHECK_SCRIPT + cp $root_dir/tmp/$code-$arch-mysql-server.txt tmp + fi +} + +check_provided_mysql_rpm_packages () +{ + dist=$1 + arch=$2 + ver=$3 + root_dir=$4 + cat > tmp/check-provided-mysql.sh < /dev/null +yum info mysql-server | grep "Version" > /tmp/$code-$arch-mysql-server.txt +EOF + if [ -d $root_dir ]; then + CHECK_SCRIPT=check-provided-mysql.sh + echo "copy check script $CHECK_SCRIPT to $root_dir/tmp" + sudo rm -f $root_dir/tmp/$CHECK_SCRIPT + cp tmp/$CHECK_SCRIPT $root_dir/tmp + sudo chmod 755 $root_dir/tmp/$CHECK_SCRIPT + sudo chname $code-$arch chroot $root_dir /tmp/$CHECK_SCRIPT + cp $root_dir/tmp/$code-$arch-mysql-server.txt tmp + fi +} + +check_installed_mroonga_packages () +{ + common_deb_procedure "check_installed_mroonga_deb_packages" + common_rpm_procedure "check_installed_mroonga_rpm_packages" +} + +check_installed_mroonga_deb_packages () +{ + code=$1 + arch=$2 + root_dir=$3 + cat > tmp/check-deb-mroonga.sh < tmp/check-rpm-mroonga.sh < tmp/install-aptitude-mroonga.sh < tmp/install-aptget-mroonga.sh < tmp/install-centos5-mroonga.sh < tmp/install-centos6-mroonga.sh < tmp/install-fedora-mroonga.sh < $UNINSTALL_SCRIPT < tmp/$UNINSTALL_SCRIPT < tmp/enable-repository.sh < /tmp/hosts +echo "$HOST_ADDRESS packages.groonga.org" >> /tmp/hosts +cp -f /tmp/hosts /etc/hosts +EOF + common_deb_procedure "enable_temporaly_mroonga_deb_repository" + common_rpm_procedure "enable_temporaly_mroonga_rpm_repository" + check_packages_repository_address +} + +enable_temporaly_mroonga_deb_repository () +{ + code=$1 + arch=$2 + root_dir=$4 + today=`date '+%Y%m%d.%s'` + if [ -d $root_dir ]; then + sudo cp $root_dir/etc/hosts $root_dir/etc/hosts.$today + sudo cp tmp/enable-repository.sh $root_dir/tmp + sudo chname $code-$arch chroot $root_dir /tmp/enable-repository.sh + fi +} + +enable_temporaly_mroonga_rpm_repository () +{ + dist=$1 + arch=$2 + ver=$3 + root_dir=$4 + today=`date '+%Y%m%d.%s'` + if [ -d $root_dir ]; then + sudo cp $root_dir/etc/hosts $root_dir/etc/hosts.$today + sudo cp tmp/enable-repository.sh $root_dir/tmp + sudo chname $code-$arch chroot $root_dir /tmp/enable-repository.sh + fi +} + +disable_temporaly_mroonga_repository () +{ + cat > tmp/disable-repository.sh < /tmp/hosts +cp -f /tmp/hosts /etc/hosts +EOF + common_deb_procedure "disable_temporaly_mroonga_deb_repository" + common_rpm_procedure "disable_temporaly_mroonga_rpm_repository" + check_packages_repository_address +} + +disable_temporaly_mroonga_deb_repository () +{ + code=$1 + arch=$2 + root_dir=$4 + DISABLE_SCRIPT=disable-repository.sh + today=`date '+%Y%m%d.%s'` + if [ -d $root_dir ]; then + sudo cp $root_dir/etc/hosts $root_dir/etc/hosts.$today + cp tmp/$DISABLE_SCRIPT $root_dir/tmp + chmod 755 $root_dir/tmp/$DISABLE_SCRIPT + sudo chname $code-$arch chroot $root_dir /tmp/$DISABLE_SCRIPT + fi + +} + +disable_temporaly_mroonga_rpm_repository () +{ + dist=$1 + arch=$2 + ver=$3 + root_dir=$4 + DISABLE_SCRIPT=disable-repository.sh + today=`date '+%Y%m%d.%s'` + if [ -d $root_dir ]; then + sudo cp $root_dir/etc/hosts $root_dir/etc/hosts.$today + cp tmp/$DISABLE_SCRIPT $root_dir/tmp + chmod 755 $root_dir/tmp/$DISABLE_SCRIPT + sudo chname $code-$arch chroot $root_dir /tmp/$DISABLE_SCRIPT + fi +} + +host_address +echo $HOST_ADDRESS + +while [ $# -ne 0 ]; do + case $1 in + --check-install) + CHECK_INSTALL=1 + shift + if [ ! -z "$1" ]; then + case $1 in + groonga|mroonga|roonga|mecab|mysql) + CHECK_INSTALL_PACKAGE=$1 + ;; + *) + ;; + esac + fi + ;; + --check-address) + CHECK_ADDRESS=1 + shift + ;; + --check-depends) + CHECK_DEPENDS=1 + shift + ;; + --check-provides) + CHECK_PROVIDES=1 + shift + ;; + --check-build) + CHECK_BUILD=1 + shift + ;; + --enable-repository) + ENABLE_REPOSITORY=1 + shift + ;; + --disable-repository) + DISABLE_REPOSITORY=1 + shift + ;; + --install-mroonga) + INSTALL_MROONGA=1 + shift + ;; + --uninstall-mroonga) + UNINSTALL_MROONGA=1 + shift + ;; + --code) + shift + if [ "$1" = "all" ]; then + setup_codes + else + CODES=$1 + fi + shift + ;; + --code-arch) + shift + if [ "$1" = "all" ]; then + setup_deb_architectures + else + DEB_ARCHITECTURES=$1 + fi + shift + ;; + --dist) + shift + if [ "$1" = "all" ]; then + setup_distributions + else + DISTRIBUTIONS=$1 + fi + shift + ;; + --dist-arch) + shift + if [ "$1" = "all" ]; then + setup_rpm_architectures + else + RPM_ARCHITECTURES=$1 + fi + shift + ;; + *) + shift + ;; + esac +done + +mkdir -p tmp +setup_deb_architectures +setup_rpm_architectures + +if [ $CHECK_INSTALL -ne 0 ]; then + check_installed_mroonga_packages +fi +if [ $CHECK_ADDRESS -ne 0 ]; then + check_packages_repository_address +fi +if [ $CHECK_BUILD -ne 0 ]; then + check_build_packages +fi +if [ $CHECK_DEPENDS -ne 0 ]; then + check_depends_packages +fi +if [ $CHECK_PROVIDES -ne 0 ]; then + check_provided_mysql_packages +fi +if [ $ENABLE_REPOSITORY -ne 0 ]; then + enable_temporaly_mroonga_repository +fi +if [ $DISABLE_REPOSITORY -ne 0 ]; then + disable_temporaly_mroonga_repository +fi +if [ $INSTALL_MROONGA -ne 0 ]; then + install_mroonga_packages +fi +if [ $UNINSTALL_MROONGA -ne 0 ]; then + uninstall_mroonga_packages +fi + diff --git a/storage/mroonga/packages/debian/apparmor/mysql-server-mroonga b/storage/mroonga/packages/debian/apparmor/mysql-server-mroonga new file mode 100644 index 00000000000..259f8d1dc0c --- /dev/null +++ b/storage/mroonga/packages/debian/apparmor/mysql-server-mroonga @@ -0,0 +1,5 @@ +/usr/lib/groonga/plugins/ r, +/usr/lib/groonga/plugins/** rm, +/etc/mecabrc r, +/var/lib/mecab/dic/** r, +#include diff --git a/storage/mroonga/packages/debian/changelog b/storage/mroonga/packages/debian/changelog new file mode 100644 index 00000000000..6aa6fd58d17 --- /dev/null +++ b/storage/mroonga/packages/debian/changelog @@ -0,0 +1,391 @@ +mroonga (5.00-1) unstable; urgency=low + + * New upstream release. + + -- Mon, 09 Feb 2015 00:00:00 +0900 + +mroonga (4.10-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Thu, 29 Jan 2015 00:00:00 +0900 + +mroonga (4.09-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Mon, 29 Dec 2014 00:00:00 +0900 + +mroonga (4.08-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sat, 29 Nov 2014 00:00:00 +0900 + +mroonga (4.07-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Wed, 29 Oct 2014 00:00:00 +0900 + +mroonga (4.06-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Mon, 29 Sep 2014 00:00:00 +0900 + +mroonga (4.05-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Fri, 29 Aug 2014 00:00:00 +0900 + +mroonga (4.04-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Tue, 29 Jul 2014 00:00:00 +0900 + +mroonga (4.03-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Thu, 29 May 2014 00:00:00 +0900 + +mroonga (4.02-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Tue, 29 Apr 2014 00:00:00 +0900 + +mroonga (4.01-2) unstable; urgency=low + + * Built for mysql-server 5.5.37 + + -- HAYASHI Kentaro Mon, 28 Apr 2014 00:00:00 +0900 + +mroonga (4.01-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sat, 29 Mar 2014 00:00:00 +0900 + +mroonga (4.00-2) unstable; urgency=low + + * Built for mysql-server 5.5.35+dfsg-2 on Debian jessie + * Built for mysql-server 5.5.35+dfsg-2 on Debian sid + + -- HAYASHI Kentaro Thu, 06 Mar 2014 00:00:00 +0900 + +mroonga (4.00-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sun, 09 Feb 2014 00:00:00 +0900 + +mroonga (3.12-2) unstable; urgency=low + + * Built for mysql-server updates on Ubuntu 12.04,12.10, and 13.10. + + -- HAYASHI Kentaro Wed, 29 Jan 2014 13:12:56 +0900 + +mroonga (3.12-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Wed, 29 Jan 2014 00:00:00 +0900 + +mroonga (3.11-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sun, 29 Dec 2013 00:00:00 +0900 + +mroonga (3.10-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Fri, 29 Nov 2013 00:00:00 +0900 + +mroonga (3.09-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Tue, 29 Oct 2013 00:00:00 +0900 + +mroonga (3.08-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sun, 29 Sep 2013 00:00:00 +0900 + +mroonga (3.07-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Thu, 29 Aug 2013 00:00:00 +0900 + +mroonga (3.06-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Mon, 29 Jul 2013 00:00:00 +0900 + +mroonga (3.05-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sat, 29 Jun 2013 00:00:00 +0900 + +mroonga (3.04-2) unstable; urgency=low + + * Built for mysql-server 5.5.31-0ubuntu0.12.04.2 on Ubuntu 12.04 (precise) + + -- HAYASHI Kentaro Thu, 13 Jun 2013 00:00:00 +0900 + +mroonga (3.04-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Wed, 29 May 2013 00:00:00 +0900 + +mroonga (3.03-2) unstable; urgency=low + + * Built for mysql-server 5.5.31+dfsg-0+wheezy1 on Debian wheezy + * Built for mysql-server 5.5.31+dfsg-1 on Debian unstable + + -- HAYASHI Kentaro Thu, 16 May 2013 00:00:00 +0900 + +mroonga (3.03-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Mon, 29 Apr 2013 00:00:00 +0900 + +mroonga (3.02-2) unstable; urgency=low + + * Built for mysql-server 5.5.29-0ubuntu0.12.04.2 on Ubuntu 12.04 (precise) + + -- HAYASHI Kentaro Fri, 29 Mar 2013 22:15:39 +0900 + +mroonga (3.02-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Fri, 29 Mar 2013 00:00:00 +0900 + +mroonga (3.01-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Thu, 28 Feb 2013 00:00:00 +0900 + +mroonga (3.00-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sat, 09 Feb 2013 00:00:00 +0900 + +mroonga (2.10-2) unstable; urgency=low + + * Built for mysql-server 5.5.29+dfsg-1 on Debian/unstable. + * Built for mysql-server 5.1.67-0ubuntu0.10.04.1 on Ubuntu 10.04(lucid). + * Built for mysql-server 5.1.67-0ubuntu0.11.10.1 on Ubuntu 11.10(oneiric). + * Built for mysql-server 5.5.29-0ubuntu0.12.04.1 on Ubuntu 12.04(precise). + * Built for mysql-server 5.5.29-0ubuntu0.12.10.1 on Ubuntu 12.10(quantal). + + -- HAYASHI Kentaro Thu, 24 Jan 2013 10:28:16 +0900 + +mroonga (2.10-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sat, 29 Dec 2012 00:00:00 +0900 + +mroonga (2.09-2) unstable; urgency=low + + * Built for mysql-server 5.5.28-0ubuntu0.12.10.2 on Ubuntu 12.10. + Reported by @watanabekiyokaz + + -- HAYASHI Kentaro Wed, 12 Dec 2012 13:28:00 +0900 + +mroonga (2.09-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Thu, 29 Nov 2012 00:00:00 +0900 + +mroonga (2.08-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Mon, 29 Oct 2012 00:00:00 +0900 + +mroonga (2.07-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sat, 29 Sep 2012 00:00:00 +0900 + +mroonga (2.06-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Wed, 29 Aug 2012 00:00:00 +0900 + +mroonga (2.05-1) unstable; urgency=low + + * New upstream release. + + -- HAYASHI Kentaro Sun, 29 Jul 2012 00:00:00 +0900 + +mroonga (2.04-1) unstable; urgency=low + + * New upstream release. + * Ensure deleting mroonga plugin before install. + Suggested by Kazuhiro Isobe. Thanks!!! + + -- Kouhei Sutou Fri, 29 Jun 2012 00:00:00 +0900 + +mroonga (2.03-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Tue, 29 May 2012 00:00:00 +0900 + +mroonga (2.02-1) unstable; urgency=low + + * New upstream release. + * Require groonga >= 2.0.2. + + -- Kouhei Sutou Sun, 29 Apr 2012 00:00:00 +0900 + +mroonga (2.01-1) unstable; urgency=low + + * New upstream release. + * Ensure plugin is uninstalled by closing all tables use mroonga. + + -- Kouhei Sutou Thu, 29 Mar 2012 00:00:00 +0900 + +mroonga (2.00-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Wed, 29 Feb 2012 00:00:00 +0900 + +mroonga (1.20-1) unstable; urgency=low + + * New upstream release. + * Add mysql-server-mroonga-compatible package for "groonga" storage engine. + + -- Kouhei Sutou Sun, 29 Jan 2012 00:00:00 +0900 + +mroonga (1.11-1) unstable; urgency=low + + * New upstream release. + * Change apparmor configuration file name: + mysql-server-groonga -> mysql-server-mroonga + + -- Kouhei Sutou Thu, 29 Dec 2011 00:00:00 +0900 + +mroonga (1.10-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Sat, 29 Oct 2011 00:00:00 +0900 + +groonga-storage-engine (1.0.0-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Thu, 29 Sep 2011 00:00:00 +0900 + +groonga-storage-engine (0.9-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Mon, 29 Aug 2011 00:00:00 +0900 + +groonga-storage-engine (0.8-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Fri, 29 Jul 2011 00:00:00 +0900 + +groonga-storage-engine (0.7-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Wed, 29 Jun 2011 00:00:00 +0900 + +groonga-storage-engine (0.6-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Sun, 29 May 2011 00:00:00 +0900 + +groonga-storage-engine (0.5-4) unstable; urgency=low + + * fix a typo. + + -- Kouhei Sutou Tue, 30 Mar 2011 01:05:00 +0900 + +groonga-storage-engine (0.5-3) unstable; urgency=low + + * fix AppArmor files. + + -- Kouhei Sutou Tue, 30 Mar 2011 00:59:00 +0900 + +groonga-storage-engine (0.5-2) unstable; urgency=low + + * hook script fix. + + -- Kouhei Sutou Tue, 30 Mar 2011 00:58:00 +0900 + +groonga-storage-engine (0.5-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Tue, 29 Mar 2011 00:00:00 +0900 + +groonga-storage-engine (0.4-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Mon, 29 Nov 2010 00:00:00 +0900 + +groonga-storage-engine (0.3-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Fri, 29 Oct 2010 16:34:04 +0900 + +groonga-storage-engine (0.2-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Sat, 25 Sep 2010 14:52:49 +0900 + +groonga-storage-engine (0.1-4) unstable; urgency=low + + * follow configure option changes. + + -- Kouhei Sutou Fri, 10 Sep 2010 08:45:53 +0900 + +groonga-storage-engine (0.1-3) unstable; urgency=low + + * Use HEAD. + + -- Kouhei Sutou Thu, 02 Sep 2010 12:03:46 +0900 + +groonga-storage-engine (0.1-2) unstable; urgency=low + + * Built with groonga 1.0.0. + + -- Kouhei Sutou Mon, 30 Aug 2010 13:26:25 +0900 + +groonga-storage-engine (0.1-1) unstable; urgency=low + + * New upstream release. + + -- Kouhei Sutou Mon, 23 Aug 2010 13:52:01 +0900 diff --git a/storage/mroonga/packages/debian/compat b/storage/mroonga/packages/debian/compat new file mode 100644 index 00000000000..ec635144f60 --- /dev/null +++ b/storage/mroonga/packages/debian/compat @@ -0,0 +1 @@ +9 diff --git a/storage/mroonga/packages/debian/control.in b/storage/mroonga/packages/debian/control.in new file mode 100644 index 00000000000..d6d03fa9a4e --- /dev/null +++ b/storage/mroonga/packages/debian/control.in @@ -0,0 +1,51 @@ +Source: mroonga +Section: database +Priority: optional +Maintainer: Kouhei Sutou +Build-Depends: + debhelper (>= 7.0.50), + autotools-dev, + pkg-config, + libgroonga-dev (>= @REQUIRED_GROONGA_VERSION@), + groonga-normalizer-mysql, + libmysqlclient-dev, + libmysqld-dev, + libssl-dev, + wget, + lsb-release +Standards-Version: 3.9.1 +Homepage: http://mroonga.org/ + +Package: mysql-server-mroonga +Section: database +Architecture: any +Replaces: mysql-server-groonga (<< 1.10-1) +Breaks: mysql-server-groonga (<< 1.10-1) +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + libgroonga0 (>= @REQUIRED_GROONGA_VERSION@), + mysql-server (= MYSQL_VERSION), + groonga-normalizer-mysql +Description: A fast fulltext searchable storage engine for MySQL. + Mroonga is a fast fulltext searchable storage engine for MySQL. + It is based on Groonga, a fast fulltext search engine and column store. + Groonga is good at real time update. + . + This package provides a MySQL storage engine as a shared library. + This provides "mroonga" storage engine. It means you can use + "ENGINE = mroonga" in "CREATE TABLE". + +Package: mysql-server-mroonga-doc +Section: doc +Architecture: all +Replaces: mysql-server-groonga-doc (<< 1.10-1) +Breaks: mysql-server-groonga-doc (<< 1.10-1) +Depends: + ${misc:Depends} +Description: Documentation of Mroonga. + Mroonga is a fast fulltext searchable storage engine for MySQL. + It is based on Groonga, a fast fulltext search engine and column store. + Groonga is good at real time update. + . + This package provides documentation of Mroonga. diff --git a/storage/mroonga/packages/debian/copyright b/storage/mroonga/packages/debian/copyright new file mode 100644 index 00000000000..bb41984e8e4 --- /dev/null +++ b/storage/mroonga/packages/debian/copyright @@ -0,0 +1,27 @@ +This work was packaged for Debian by: + + Kouhei Sutou on Thu, 02 Sep 2010 13:51:56 +0900. + +It was downloaded: + + + +Upstream Author(s): + + Tetsuro IKEDA + Daijiro MORI + Tasuku SUENAGA + Kouhei Sutou + +Copyright: + + Copyright(C) 2009-2010 Tetsuro IKEDA + +License: + + LGPLv2.1 + + See `/usr/share/common-licenses/LGPL-2.1'. + +The Debian packaging is done by Kouhei Sutou in 2010, +and put into public domain, anyone can use it for any purpose. diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga-doc.install b/storage/mroonga/packages/debian/mysql-server-mroonga-doc.install new file mode 100644 index 00000000000..ad2e27ef7dd --- /dev/null +++ b/storage/mroonga/packages/debian/mysql-server-mroonga-doc.install @@ -0,0 +1 @@ +usr/share/doc/mysql-server-mroonga-doc/ diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga.install b/storage/mroonga/packages/debian/mysql-server-mroonga.install new file mode 100644 index 00000000000..03f64cfedb4 --- /dev/null +++ b/storage/mroonga/packages/debian/mysql-server-mroonga.install @@ -0,0 +1,3 @@ +usr/lib/mysql/plugin/ha_mroonga.so* +usr/share/mroonga/* +debian/apparmor/mysql-server-mroonga etc/apparmor.d/abstractions/ diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga.postinst b/storage/mroonga/packages/debian/mysql-server-mroonga.postinst new file mode 100755 index 00000000000..9a3db8784a2 --- /dev/null +++ b/storage/mroonga/packages/debian/mysql-server-mroonga.postinst @@ -0,0 +1,72 @@ +#! /bin/sh + +set -e + +prevver="$2" + +install_plugin() { + cat /usr/share/mroonga/install.sql | \ + mysql --defaults-file=/etc/mysql/debian.cnf || true +} + +install_apparmor() { + mysql_apparmor_profile_name=usr.sbin.mysqld + mysql_apparmor_profile=/etc/apparmor.d/${mysql_apparmor_profile_name} + mysql_local_apparmor_profile=/etc/apparmor.d/local/${mysql_apparmor_profile_name} + apparmor_profile_name=mysql-server-mroonga + include_profile="#include " + local_apparmor_profile=/etc/apparmor.d/local/${apparmor_profile_name} + if test -f "${mysql_local_apparmor_profile}"; then + if ! grep -q "${include_profile}" "${mysql_local_apparmor_profile}"; then + echo >> "${mysql_local_apparmor_profile}" + echo "${include_profile}" >> "${mysql_local_apparmor_profile}" + fi + else + mysql_abstraction_apparmor_profile=/etc/apparmor.d/abstractions/mysql + mysql_plugin_dir=/usr/lib/mysql/plugin + if test -f "${mysql_abstraction_apparmor_profile}" && \ + ! grep -q "${mysql_plugin_dir}" \ + "${mysql_abstraction_apparmor_profile}"; then + # For Lucid. + cat <> "${mysql_abstraction_apparmor_profile}" + +# ${apparmor_profile_name}: START +# Added by mysql-server-mroonga. +${mysql_plugin_dir}/ r, +${mysql_plugin_dir}/*.so* mr, +${include_profile} +# ${apparmor_profile_name}: END +EOF + fi + fi + + if ! test -e "$local_apparmor_profile"; then + mkdir -p $(dirname "$local_apparmor_profile") + cat < "$local_apparmor_profile" +# Site-specific additions and overrides for ${apparmor_profile_name}. +# For more details, please see /etc/apparmor.d/local/README. +EOF + fi + + if aa-status --enabled 2>/dev/null; then + apparmor_parser -r -T -W "${mysql_apparmor_profile}" || true + fi + + true +} + +case "$1" in + configure) + install_apparmor + install_plugin + ;; + abort-upgrade|abort-deconfigure|abort-remove) + : + ;; + *) + echo "Called with unknown argument $1, bailing out." + exit 1 + ;; +esac + +#DEBHELPER# diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga.postrm b/storage/mroonga/packages/debian/mysql-server-mroonga.postrm new file mode 100755 index 00000000000..84d7f1ef4ab --- /dev/null +++ b/storage/mroonga/packages/debian/mysql-server-mroonga.postrm @@ -0,0 +1,38 @@ +#! /bin/sh + +set -e + +if [ "$1" = "purge" ]; then + mysql_apparmor_profile_name=usr.sbin.mysqld + mysql_apparmor_profile=/etc/apparmor.d/${mysql_apparmor_profile_name} + mysql_local_apparmor_profile=/etc/apparmor.d/local/${mysql_apparmor_profile_name} + mysql_abstraction_apparmor_profile=/etc/apparmor.d/abstractions/mysql + apparmor_profile_name=mysql-server-mroonga + if test -f "${mysql_local_apparmor_profile}"; then + include_profile="#include " + if grep -q "${include_profile}" "${mysql_local_apparmor_profile}"; then + sed -i'' -e "s,${include_profile},," \ + "${mysql_local_apparmor_profile}" + fi + else + start_marker_re="^# ${apparmor_profile_name}: START$" + end_marker_re="^# ${apparmor_profile_name}: END$" + if test -f "${mysql_abstraction_apparmor_profile}" && \ + grep -q "${start_marker_re}" \ + "${mysql_abstraction_apparmor_profile}"; then + sed -i'' -e "/${start_marker_re}/,/${end_marker_re}/d" \ + "${mysql_abstraction_apparmor_profile}" + fi + fi + + rm -f "/etc/apparmor.d/local/${apparmor_profile_name}" || true + rmdir /etc/apparmor.d/local 2>/dev/null || true + + if aa-status --enabled 2>/dev/null; then + apparmor_parser -r -T -W "${mysql_apparmor_profile}" || true + fi +fi + +#DEBHELPER# + +exit 0 diff --git a/storage/mroonga/packages/debian/mysql-server-mroonga.prerm b/storage/mroonga/packages/debian/mysql-server-mroonga.prerm new file mode 100755 index 00000000000..7fad990d75f --- /dev/null +++ b/storage/mroonga/packages/debian/mysql-server-mroonga.prerm @@ -0,0 +1,10 @@ +#! /bin/sh + +set -e + +cat /usr/share/mroonga/uninstall.sql | \ + mysql --defaults-file=/etc/mysql/debian.cnf || true + +#DEBHELPER# + +exit 0 diff --git a/storage/mroonga/packages/debian/rules b/storage/mroonga/packages/debian/rules new file mode 100755 index 00000000000..2a397b333e1 --- /dev/null +++ b/storage/mroonga/packages/debian/rules @@ -0,0 +1,39 @@ +#!/usr/bin/make -f +# -*- makefile-gmake -*- +# +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 +# This has to be exported to make some magic below work. +export DH_OPTIONS + +export MYSQL_VERSION := $(shell apt-cache show mysql-server-5.5 | grep Version | head -n 1 | awk '{print $$2}' | awk -F '-' '{print $$1}') + +%: + dh $@ + +override_dh_auto_configure: + path=main/m/mysql-5.5/mysql-5.5_$(MYSQL_VERSION).orig.tar.gz; \ + if [ "$$(lsb_release --id --short)" = "Ubuntu" ]; then \ + base_url=http://archive.ubuntu.com/ubuntu/pool; \ + security_base_url=http://security.ubuntu.com/ubuntu/pool; \ + else \ + base_url=http://ftp.debian.org/debian/pool; \ + security_base_url=http://security.debian.org/pool/updates; \ + fi; \ + wget $${security_base_url}/$${path} || \ + wget $${base_url}/$${path} + tar xf mysql-5.5_$(MYSQL_VERSION).orig.tar.gz + dh_auto_configure -- --with-mysql-source=./mysql-$(MYSQL_VERSION) + +# disable 'make check'. +override_dh_auto_test: + +override_dh_install: + mv debian/tmp/usr/share/doc/mroonga/ \ + debian/tmp/usr/share/doc/mysql-server-mroonga-doc/ + dh_install +# if test -x /usr/bin/dh_apparmor; then \ +# dh_apparmor \ +# -pmysql-server-mroonga \ +# --profile-name=usr.lib.mysql.plugin.ha_mroonga; \ +# fi diff --git a/storage/mroonga/packages/rpm/Makefile.am b/storage/mroonga/packages/rpm/Makefile.am new file mode 100644 index 00000000000..aa1ba3ad9c6 --- /dev/null +++ b/storage/mroonga/packages/rpm/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = \ + centos diff --git a/storage/mroonga/packages/rpm/centos/Makefile.am b/storage/mroonga/packages/rpm/centos/Makefile.am new file mode 100644 index 00000000000..e7b22cfa025 --- /dev/null +++ b/storage/mroonga/packages/rpm/centos/Makefile.am @@ -0,0 +1,9 @@ +EXTRA_DIST = \ + mysql55-mroonga.spec.in \ + mysql56-community-mroonga.spec.in \ + mariadb-mroonga.spec.in + +noinst_DATA = \ + mysql55-mroonga.spec \ + mysql56-community-mroonga.spec \ + mariadb-mroonga.spec diff --git a/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in new file mode 100644 index 00000000000..337eeccb1cf --- /dev/null +++ b/storage/mroonga/packages/rpm/centos/mariadb-mroonga.spec.in @@ -0,0 +1,396 @@ +%define mariadb_epoch_default 1 +%define mariadb_version_default 5.5.41 +%define mariadb_release_default 1 +%define mariadb_dist_default .el7_0 +%define mariadb_download_base_url_default http://vault.centos.org/7.0.1406/updates/Source/SPackages +%define mariadb_spec_file_default mariadb.spec + +%{!?mariadb_epoch:%define mariadb_epoch %{mariadb_epoch_default}} +%{!?mariadb_version:%define mariadb_version %{mariadb_version_default}} +%{!?mariadb_release:%define mariadb_release %{mariadb_release_default}} +%{!?mariadb_dist:%define mariadb_dist %{mariadb_dist_default}} +%{!?mariadb_download_base_url:%define mariadb_download_base_url %{mariadb_download_base_url_default}} +%{!?mariadb_spec_file:%define mariadb_spec_file %{mariadb_spec_file_default}} + +%define mariadb_package_version %{mariadb_epoch}:%{mariadb_version}-%{mariadb_release}%{mariadb_dist} + +%define groonga_required_version @REQUIRED_GROONGA_VERSION@ + +Name: mariadb-mroonga +Version: @VERSION@ +Release: 1%{?dist} +Summary: A fast fulltext searchable storage engine for MariaDB + +Group: Applications/Databases +License: LGPLv2.1 +URL: http://mroonga.org/ +Source0: http://packages.groonga.org/source/mroonga/mroonga-%{version}.tar.gz + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%(%{__id_u} -n) +BuildRequires: groonga-devel >= %{groonga_required_version} +BuildRequires: groonga-normalizer-mysql-devel +BuildRequires: wget +BuildRequires: mariadb-devel +Requires: mariadb-server = %{mariadb_package_version} +Requires: mariadb = %{mariadb_package_version} +Requires: groonga-libs >= %{groonga_required_version} +Requires: groonga-normalizer-mysql + +%description +Mroonga is a fast fulltext searchable storage plugin for MariaDB. +It is based on Groonga that is a fast fulltext search engine and +column store. Groonga is good at real-time update. + +%package doc +Summary: Documentation for Mroonga +Group: Documentation +License: LGPLv2.1 + +%description doc +Documentation for Mroonga + + +%prep +%setup -q -n mroonga-%{version} + +mariadb_full_version=%{mariadb_version}-%{mariadb_release}%{mariadb_dist} +srpm=mariadb-${mariadb_full_version}.src.rpm +if [ ! -f ../../SRPMS/$srpm ]; then + wget --continue -O ../../SRPMS/$srpm %{mariadb_download_base_url}/$srpm + rpm -Uvh ../../SRPMS/$srpm + rm ../../SRPMS/$srpm +fi + +%build +mariadb_source=../mariadb-%{mariadb_version} +if [ ! -d ${mariadb_source} ]; then + rpmbuild -bc \ + --define 'runselftest 0' \ + --define 'optflags -O0' \ + ../../SPECS/%{mariadb_spec_file} +fi +%configure \ + --disable-static \ + --with-mysql-source=${mariadb_source} \ + %{?mroonga_configure_options} +make %{?_smp_mflags} + + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +rm $RPM_BUILD_ROOT%{_libdir}/mysql/plugin/*.la +mv $RPM_BUILD_ROOT%{_datadir}/doc/mroonga/ mysql-mroonga-doc/ + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +if /usr/bin/mysql -u root -e "quit"; then + password_option="" +else + password_option="-p" +fi +current_version=0 +version=$(echo %{groonga_required_version} | sed -e 's/\.//g') +required_version=$(expr $version) +version=$(/usr/bin/mysql -e "SHOW VARIABLES LIKE 'mroonga_libgroonga_version'" | \ + grep mroonga | cut -f 2 | sed -e 's/\.//g') +if [ -n "$version" ]; then + current_version=$(expr $version) +fi +install_sql=%{_datadir}/mroonga/install.sql +uninstall_sql=%{_datadir}/mroonga/uninstall.sql + +if [ "$1" = 2 ] ; then + if [ $current_version -lt $required_version ]; then + command="/usr/bin/mysql -u root $password_option" + echo "run the following command after restarting MySQL server:"; + echo " $command < ${uninstall_sql}" + echo " $command < ${install_sql}" + exit 0 + else + command="/usr/bin/mysql -u root $password_option" + command="${command} < ${uninstall_sql}" + echo $command + eval $command || \ + (echo "run the following command to unregister Mroonga:"; \ + echo " $command") + fi +fi + +command="/usr/bin/mysql -u root $password_option < ${install_sql}" +echo $command +eval $command || \ + (echo "run the following command to register Mroonga:"; \ + echo " $command") + +%preun +uninstall_sql=%{_datadir}/mroonga/uninstall.sql + +if mysql -u root -e "quit"; then + password_option="" +else + password_option="-p" +fi +if [ "$1" = 0 ]; then + command="/usr/bin/mysql -u root $password_option < ${uninstall_sql}" + echo $command + eval $command || \ + (echo "run the following command to unregister Mroonga:"; \ + echo " $command") +fi + +%files +%defattr(-,root,root,-) +%{_libdir}/mysql/plugin/ +%{_datadir}/mroonga/* +%{_datadir}/man/man1/* +%{_datadir}/man/*/man1/* + +%files doc +%defattr(-,root,root,-) +%doc README COPYING +%doc mysql-mroonga-doc/* + +%changelog +* Mon Feb 09 2015 - 5.00-1 +- new upstream release. + +* Thu Jan 29 2015 HAYASHI Kentaro - 4.10-1 +- new upstream release. + +* Wed Jan 14 2015 HAYASHI Kentaro - 4.09-2 +- build against mariadb-5.5.40-2.el7_0. + +* Mon Dec 29 2014 Kouhei Sutou - 4.09-1 +- new upstream release. + +* Sat Nov 29 2014 HAYASHI Kentaro - 4.08-1 +- new upstream release. + +* Wed Oct 29 2014 Kouhei Sutou - 4.07-1 +- new upstream release. + +* Mon Sep 29 2014 Kouhei Sutou - 4.06-1 +- new upstream release. + +* Fri Aug 29 2014 Kouhei Sutou - 4.05-1 +- new upstream release. + +* Thu Aug 14 2014 Kouhei Sutou - 4.04-4 +- build MariaDB for libmysqlservices.a. + +* Thu Aug 14 2014 Kouhei Sutou - 4.04-3 +- support epoch in MariaDB. + +* Wed Aug 13 2014 Kouhei Sutou - 4.04-2 +- build against mariadb-5.5.37-1.el7_0. + +* Sun Aug 10 2014 Kouhei Sutou - 4.04-1 +- initial packaging for CentOS 7 based on mysql-mroogna package. + +* Tue Jul 29 2014 HAYASHI Kentaro - 4.04-1 +- new upstream release. + +* Thu May 29 2014 Kouhei Sutou - 4.03-1 +- new upstream release. + +* Tue Apr 29 2014 Kouhei Sutou - 4.02-1 +- new upstream release. + +* Sat Mar 29 2014 HAYASHI Kentaro - 4.01-1 +- new upstream release. + +* Thu Feb 13 2014 HAYASHI Kentaro - 4.00-2 +- use MySQL 5.1.73-3 on CentOS 6. + +* Sun Feb 09 2014 HAYASHI Kentaro - 4.00-1 +- new upstream release. + +* Wed Jan 29 2014 HAYASHI Kentaro - 3.12-1 +- new upstream release. + +* Sun Dec 29 2013 HAYASHI Kentaro - 3.11-1 +- new upstream release. + +* Sat Dec 7 2013 HAYASHI Kentaro - 3.10-2 +- use MySQL 5.1.71-1 on CentOS 6. + +* Fri Nov 29 2013 HAYASHI Kentaro - 3.10-1 +- new upstream release. + +* Tue Oct 29 2013 HAYASHI Kentaro - 3.09-1 +- new upstream release. + +* Sun Sep 29 2013 HAYASHI Kentaro - 3.08-1 +- new upstream release. +- use MySQL 5.6.14-1 on CentOS 5. + +* Wed Sep 4 2013 HAYASHI Kentaro - 3.07-2 +- fix a bug that mroonga is removed accidentally on upgrade #1918. + Reported by @ceekz. Thanks!!! + +* Thu Aug 29 2013 HAYASHI Kentaro - 3.07-1 +- new upstream release. +- use MySQL 5.6.13-1 on CentOS 5. + +* Mon Jul 29 2013 HAYASHI Kentaro - 3.06-1 +- new upstream release. +- use MySQL 5.6.12-2 on CentOS 5. + +* Sat Jun 29 2013 HAYASHI Kentaro - 3.05-1 +- new upstream release. +- use MySQL 5.6.12 on CentOS 5. + +* Wed May 29 2013 HAYASHI Kentaro - 3.04-1 +- new upstream release. + +* Fri May 10 2013 HAYASHI Kentaro - 3.03-2 +- use MySQL 5.6.11-2 on CentOS 5. see http://bugs.mysql.com/bug.php?id=69027 + Reported by Y.Kentaro. Thanks!!! + +* Mon Apr 29 2013 HAYASHI Kentaro - 3.03-1 +- new upstream release. + +* Fri Mar 29 2013 HAYASHI Kentaro - 3.02-0 +- new upstream release. + +* Thu Feb 28 2013 HAYASHI Kentaro - 3.01-0 +- new upstream release. + +* Sat Feb 09 2013 HAYASHI Kentaro - 3.00-0 +- new upstream release. +- require groonga 3.0.0 or later + +* Tue Feb 05 2013 HAYASHI Kentaro - 2.10-2 +- use MySQL 5.1.67-1 on CentOS 6. + Reported by wakisuke.ua. Thanks!!! + +* Sat Dec 29 2012 HAYASHI Kentaro - 2.10-0 +- new upstream release. + +* Mon Dec 10 2012 HAYASHI Kentaro - 2.09-1 +- use MySQL 5.1.66-2 on CentOS 6. + Reported by wakisuke.ua. Thanks!!! + +* Thu Nov 29 2012 HAYASHI Kentaro - 2.09-0 +- new upstream release. +- use MySQL 5.5.28 on CentOS 5. +- use MySQL 5.1.66 on CentOS 6. + +* Mon Oct 29 2012 HAYASHI Kentaro - 2.08-0 +- new upstream release. +- add missing "DROP FUNCTION mroonga_snippet". + Reported by @tokuhy. Thanks!!! + +* Sat Sep 29 2012 HAYASHI Kentaro - 2.07-0 +- new upstream release. + +* Wed Aug 29 2012 Kouhei Sutou - 2.06-0 +- new upstream release. +- make MySQL spec file name customizable. +- make mroonga configure options customizable. +- add missing mysql-devel BuildRequires. Reported by wing. Thanks!!! +- use MySQL 5.5.27. + +* Sun Jul 29 2012 HAYASHI Kentaro - 2.05-0 +- new upstream release. +- use MySQL 5.5.25a. + +* Fri Jun 29 2012 Kouhei Sutou - 2.04-0 +- new upstream release. +- ensure deleting mroonga plugin before install. + Suggested by Kazuhiro Isobe. Thanks!!! +- use MySQL 5.5.25. + +* Tue May 29 2012 Kouhei Sutou - 2.03-0 +- new upstream release. +- use MySQL 5.5.24. +- make mysql_* variables customizable +- require groonga 2.0.3 or later. + +* Sun Apr 29 2012 Kouhei Sutou - 2.02-0 +- new upstream release. +- use MySQL 5.5.23. +- require groonga 2.0.2 or later. + +* Thu Mar 29 2012 Kouhei Sutou - 2.01-0 +- new upstream release. +- ensure plugin is uninstalled by closing all tables use mroonga. + +* Wed Feb 29 2012 Kouhei Sutou - 2.00-0 +- new upstream release. +- always install/uninstall plugin. +- use MySQL 5.1.61 and 5.5.21. +- require groonga 2.0.0 or later. + +* Sun Jan 29 2012 Kouhei Sutou - 1.20-0 +- new upstream release. +- require groonga 1.3.0. +- groonga -> mroonga. +- use MySQL 5.5.20. + +* Thu Dec 29 2011 Kouhei Sutou - 1.11-0 +- new upstream release. + +* Sat Oct 29 2011 Kouhei Sutou - 1.10-0 +- new upstream release. +- groonga storage engine -> mroonga. + +* Thu Sep 29 2011 Kouhei Sutou - 1.0.0-0 +- new upstream release. + +* Mon Aug 29 2011 Kouhei Sutou - 0.9-0 +- new upstream release. + +* Fri Jul 29 2011 Kouhei Sutou - 0.8-0 +- new upstream release. + +* Wed Jun 29 2011 Kouhei Sutou - 0.7-0 +- new upstream release. + +* Sun May 29 2011 Kouhei Sutou - 0.6-0 +- new upstream release. + +* Tue May 17 2011 Kouhei Sutou - 0.5-2 +- use MySQL 5.5.12. + +* Tue Mar 29 2011 Kouhei Sutou - 0.5-1 +- new upstream release. + +* Sat Jan 29 2011 Kouhei Sutou - 0.4-4 +- do not remove plugin on upgrade. + +* Wed Jan 12 2011 Kouhei Sutou - 0.4-3 +- rebuild without debug symbol. + +* Thu Dec 30 2010 Kouhei Sutou - 0.4-2 +- use MySQL 5.5.8-1. +- fix SQL literal notation. + +* Mon Nov 29 2010 Kouhei Sutou - 0.4-1 +- use the latest MySQL. +- new upstream release. + +* Sun Nov 21 2010 Kouhei Sutou - 0.3-2 +- install user define function. + +* Fri Oct 29 2010 Kouhei Sutou - 0.3-1 +- new upstream release. + +* Fri Oct 08 2010 Kouhei Sutou - 0.2-2 +- specify target MySQL version. +- use %{version}. + +* Wed Sep 29 2010 Kouhei Sutou - 0.2-1 +- new upstream release. + +* Sun Sep 12 2010 Kouhei Sutou - 0.1-3 +- require MySQL-client-community. + +* Fri Sep 10 2010 Kouhei Sutou - 0.1-2 +- use MySQL-devel-community. + +* Fri Sep 03 2010 Kouhei Sutou - 0.1-1 +- initial packaging for CentOS. diff --git a/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in new file mode 100644 index 00000000000..f1f5b2f4692 --- /dev/null +++ b/storage/mroonga/packages/rpm/centos/mysql55-mroonga.spec.in @@ -0,0 +1,218 @@ +%{?scl:%scl_package mroonga} +%{!?scl:%global pkg_name %{name}} +%{!?centos_ver:%define centos_ver 5} + +%if %{centos_ver} == 6 +%define mysql_version_default 5.5.41 +%define mysql_release_default 2 +%define mysql_dist_default el6.centos.alt +%define mysql_download_base_url_default http://vault.centos.org/6.6/SCL/Source/SPackages +%define mysql_spec_file_default mysql.spec +%else +%define mysql_version_default 5.5.40 +%define mysql_release_default 2 +%define mysql_dist_default el5 +%define mysql_download_base_url_default http://vault.centos.org/5.11/updates/SRPMS +%define mysql_spec_file_default mysql.spec +%endif + +%{!?mysql_version:%define mysql_version %{mysql_version_default}} +%{!?mysql_release:%define mysql_release %{mysql_release_default}} +%{!?mysql_dist:%define mysql_dist %{mysql_dist_default}} +%{!?mysql_download_base_url:%define mysql_download_base_url %{mysql_download_base_url_default}} +%{!?mysql_spec_file:%define mysql_spec_file %{mysql_spec_file_default}} + +%define groonga_required_version @REQUIRED_GROONGA_VERSION@ + +Name: %{?scl_prefix}mroonga +Version: @VERSION@ +Release: 1%{?dist} +Summary: A fast fulltext searchable storage engine for MySQL + +Group: Applications/Databases +License: LGPLv2.1 +URL: http://mroonga.org/ +Source0: http://packages.groonga.org/source/mroonga/mroonga-%{version}.tar.gz + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%(%{__id_u} -n) +BuildRequires: groonga-devel >= %{groonga_required_version} +BuildRequires: groonga-normalizer-mysql-devel +BuildRequires: wget +BuildRequires: which +BuildRequires: mysql55-mysql-devel +BuildRequires: mysql55-build +Requires: mysql55-mysql-server = %{mysql_version}-%{mysql_release}.%{mysql_dist} +Requires: mysql55-mysql = %{mysql_version}-%{mysql_release}.%{mysql_dist} +Requires: groonga-libs >= %{groonga_required_version} +Requires: groonga-normalizer-mysql +%{?scl:Requires: %scl_runtime} + +%description +Mroonga is a fast fulltext searchable storage plugin for MySQL. +It is based on Groonga that is a fast fulltext search engine and +column store. Groonga is good at real-time update. + +%package doc +Summary: Documentation for Mroonga +Group: Documentation +License: LGPLv2.1 + +%description doc +Documentation for Mroonga + + +%prep +%setup -q -n %{pkg_name}-%{version} + +mysql_full_version=%{mysql_version}-%{mysql_release}.%{mysql_dist} +srpm=mysql55-mysql-${mysql_full_version}.src.rpm +if [ ! -f ../../SRPMS/$srpm ]; then + wget --continue -O ../../SRPMS/$srpm %{mysql_download_base_url}/$srpm + rpm -Uvh ../../SRPMS/$srpm +fi + +%build +mysql_source=../mysql-%{mysql_version} +if [ ! -d ${mysql_source} ]; then + specs_dir= + MYSQL_RPMBUILD_TEST=no rpmbuild -bp \ + --define 'runselftest 0' \ + --define 'optflags -O0' \ + ../../SPECS/%{mysql_spec_file} +fi +%configure --disable-static --with-mysql-source=${mysql_source} \ + --disable-fast-mutexes \ + --with-mysql-config=`scl enable mysql55 'which mysql_config'` \ + %{?mroonga_configure_options} +make %{?_smp_mflags} + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +rm $RPM_BUILD_ROOT%{_libdir}/mysql/plugin/*.la +mv $RPM_BUILD_ROOT%{_datadir}/doc/mroonga/ mysql-mroonga-doc/ + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +mysql_command=`scl enable mysql55 'which mysql'` +password_option="" +$mysql_command -u root -e "quit" +if [ $? -ne 0 ]; then + password_option="-p" +fi +current_version=0 +version=`echo %{groonga_required_version} | sed -e 's/\.//g'` +required_version=`expr $version` +version=`$mysql_command -e "SHOW VARIABLES LIKE 'mroonga_libgroonga_version'" | \ + grep mroonga | cut -f 2 | sed -e 's/\.//g'` +if [ -n "$version" ]; then + current_version=`expr $version` +fi +install_sql=%{_datadir}/mroonga/install.sql +uninstall_sql=%{_datadir}/mroonga/uninstall.sql + +if [ "$1" = 2 ] ; then + if [ $current_version -lt $required_version ]; then + command="$mysql_command -u root $password_option" + echo "run the following command after restarting MySQL server:"; + echo " $command < ${uninstall_sql}" + echo " $command < ${install_sql}" + exit 0 + else + command="$mysql_command -u root $password_option < ${uninstall_sql}" + echo $command + eval $command || \ + (echo "run the following command to unregister Mroonga:"; \ + echo " $command") + fi +fi +command="$mysql_command -u root $password_option < ${install_sql}" +echo $command +eval $command || \ + (echo "run the following command to register Mroonga:"; \ + echo " $command") + +%preun +uninstall_sql=%{_datadir}/mroonga/uninstall.sql +mysql_command=`scl enable mysql55 'which mysql'` +if $mysql_command -u root -e "quit"; then + password_option="" +else + password_option="-p" +fi +if [ "$1" = 0 ]; then + command="$mysql_command -u root $password_option < ${uninstall_sql}" + echo $command + eval $command || \ + (echo "run the following command to unregister Mroonga:"; \ + echo " $command") +fi + +%files +%defattr(-,root,root,-) +%{_libdir}/mysql/plugin/ +%{_datadir}/mroonga/* +%{_datadir}/man/man1/* +%{_datadir}/man/*/man1/* + +%files doc +%defattr(-,root,root,-) +%doc README COPYING +%doc mysql-mroonga-doc/* + +%changelog +* Mon Feb 09 2015 - 5.00-1 +- new upstream release. + +* Thu Jan 29 2015 HAYASHI Kentaro - 4.10-1 +- new upstream release. + +* Mon Dec 29 2014 Kouhei Sutou - 4.09-1 +- new upstream release. + +* Sat Nov 29 2014 HAYASHI Kentaro - 4.08-1 +- new upstream release. + +* Wed Oct 29 2014 Kouhei Sutou - 4.07-1 +- new upstream release. + +* Mon Sep 29 2014 Kouhei Sutou - 4.06-1 +- new upstream release. + +* Fri Aug 29 2014 Kouhei Sutou - 4.05-1 +- new upstream release. + +* Tue Jul 29 2014 HAYASHI Kentaro - 4.04-1 +- new upstream release. + +* Thu May 29 2014 Kouhei Sutou - 4.03-2 +- build against MySQL 5.6.37. Reported by YOSHIDA Mitsuo. Thanks!!! + +* Thu May 29 2014 Kouhei Sutou - 4.03-1 +- new upstream release. + +* Tue Apr 29 2014 Kouhei Sutou - 4.02-1 +- new upstream release. + +* Sat Mar 29 2014 HAYASHI Kentaro - 4.01-1 +- new upstream release. + +* Thu Mar 06 2014 HAYASHI Kentaro - 4.00-2 +- use MySQL 5.5.36 on CentOS 5. + +* Sun Feb 09 2014 HAYASHI Kentaro - 4.00-1 +- new upstream release. + +* Wed Jan 29 2014 HAYASHI Kentaro - 3.12-1 +- new upstream release. + +* Sun Dec 29 2013 HAYASHI Kentaro - 3.11-1 +- new upstream release. + +* Fri Nov 29 2013 HAYASHI Kentaro - 3.10-1 +- new upstream release. + +* Tue Oct 29 2013 HAYASHI Kentaro - 3.09-1 +- initial packaging for MySQL 5.5 on CentOS 5. diff --git a/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in b/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in new file mode 100644 index 00000000000..37ae5d41b2f --- /dev/null +++ b/storage/mroonga/packages/rpm/centos/mysql56-community-mroonga.spec.in @@ -0,0 +1,222 @@ +%{!?centos_ver:%define centos_ver 6} + +%if %{centos_ver} == 7 +%define mysql_version_default 5.6.23 +%define mysql_release_default 2 +%define mysql_dist_default el7 +%define mysql_download_base_url_default http://repo.mysql.com/yum/mysql-5.6-community/el/7/SRPMS +%define mysql_spec_file_default mysql.spec +%else +%define mysql_version_default 5.6.23 +%define mysql_release_default 2 +%define mysql_dist_default el6 +%define mysql_download_base_url_default http://repo.mysql.com/yum/mysql-5.6-community/el/6/SRPMS +%define mysql_spec_file_default mysql.spec +%endif + +%{!?mysql_version:%define mysql_version %{mysql_version_default}} +%{!?mysql_release:%define mysql_release %{mysql_release_default}} +%{!?mysql_dist:%define mysql_dist %{mysql_dist_default}} +%{!?mysql_download_base_url:%define mysql_download_base_url %{mysql_download_base_url_default}} +%{!?mysql_spec_file:%define mysql_spec_file %{mysql_spec_file_default}} + +%define groonga_required_version @REQUIRED_GROONGA_VERSION@ + +Name: mysql-community-mroonga +Version: @VERSION@ +Release: 1%{?dist} +Summary: A fast fulltext searchable storage engine for MySQL + +Group: Applications/Databases +License: LGPLv2.1 +URL: http://mroonga.org/ +Source0: http://packages.groonga.org/source/mroonga/mroonga-%{version}.tar.gz + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-%(%{__id_u} -n) +BuildRequires: groonga-devel >= %{groonga_required_version} +BuildRequires: groonga-normalizer-mysql-devel +BuildRequires: wget +BuildRequires: which +BuildRequires: gcc, gcc-c++ +BuildRequires: mysql-community-devel +Requires: mysql-community-server = %{mysql_version}-%{mysql_release}.%{mysql_dist} +Requires: mysql-community-client = %{mysql_version}-%{mysql_release}.%{mysql_dist} +Requires: groonga-libs >= %{groonga_required_version} +Requires: groonga-normalizer-mysql + +%description +Mroonga is a fast fulltext searchable storage plugin for MySQL. +It is based on Groonga that is a fast fulltext search engine and +column store. Groonga is good at real-time update. + +%package doc +Summary: Documentation for Mroonga +Group: Documentation +License: LGPLv2.1 + +%description doc +Documentation for Mroonga + + +%prep +%setup -q -n mroonga-%{version} + +mysql_full_version=%{mysql_version}-%{mysql_release}.%{mysql_dist} +srpm=mysql-community-${mysql_full_version}.src.rpm +if [ ! -f ../../SRPMS/$srpm ]; then + wget --continue -O ../../SRPMS/$srpm %{mysql_download_base_url}/$srpm + rpm -Uvh ../../SRPMS/$srpm +fi + +%build +mysql_source=../mysql-%{mysql_version}/mysql-%{mysql_version} +if [ ! -d ${mysql_source} ]; then + specs_dir= + MYSQL_RPMBUILD_TEST=no rpmbuild -bp \ + --define 'runselftest 0' \ + --define 'optflags -O0' \ + ../../SPECS/%{mysql_spec_file} +fi +%configure --disable-static --with-mysql-source=${mysql_source} \ + %{?mroonga_configure_options} +make %{?_smp_mflags} + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +rm $RPM_BUILD_ROOT%{_libdir}/mysql/plugin/*.la +mv $RPM_BUILD_ROOT%{_datadir}/doc/mroonga/ mysql-mroonga-doc/ + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +mysql_command=`which mysql` +password_option="" +$mysql_command -u root -e "quit" +if [ $? -ne 0 ]; then + password_option="-p" +fi +current_version=0 +version=`echo %{groonga_required_version} | sed -e 's/\.//g'` +required_version=`expr $version` +version=`$mysql_command -e "SHOW VARIABLES LIKE 'mroonga_libgroonga_version'" | \ + grep mroonga | cut -f 2 | sed -e 's/\.//g'` +if [ -n "$version" ]; then + current_version=`expr $version` +fi +install_sql=%{_datadir}/mroonga/install.sql +uninstall_sql=%{_datadir}/mroonga/uninstall.sql + +if [ "$1" = 2 ] ; then + if [ $current_version -lt $required_version ]; then + command="$mysql_command -u root $password_option" + echo "run the following command after restarting MySQL server:"; + echo " $command < ${uninstall_sql}" + echo " $command < ${install_sql}" + exit 0 + else + command="$mysql_command -u root $password_option < ${uninstall_sql}" + echo $command + eval $command || \ + (echo "run the following command to unregister Mroonga:"; \ + echo " $command") + fi +fi +command="$mysql_command -u root $password_option < ${install_sql}" +echo $command +eval $command || \ + (echo "run the following command to register Mroonga:"; \ + echo " $command") + +%preun +uninstall_sql=%{_datadir}/mroonga/uninstall.sql +mysql_command=`which mysql` +if $mysql_command -u root -e "quit"; then + password_option="" +else + password_option="-p" +fi +if [ "$1" = 0 ]; then + command="$mysql_command -u root $password_option < ${uninstall_sql}" + echo $command + eval $command || \ + (echo "run the following command to unregister Mroonga:"; \ + echo " $command") +fi + +%files +%defattr(-,root,root,-) +%{_libdir}/mysql/plugin/ +%{_datadir}/mroonga/* +%{_datadir}/man/man1/* +%{_datadir}/man/*/man1/* + +%files doc +%defattr(-,root,root,-) +%doc README COPYING +%doc mysql-mroonga-doc/* + +%changelog +* Mon Feb 09 2015 - 5.00-1 +- new upstream release. + +* Wed Feb 04 2015 HAYASHI Kentaro - 4.10-2 +- build against MySQL 5.6.23-2 on MySQL yum repository. + +* Thu Jan 29 2015 HAYASHI Kentaro - 4.10-1 +- new upstream release. + +* Mon Dec 29 2014 Kouhei Sutou - 4.09-1 +- new upstream release. + +* Sat Nov 29 2014 HAYASHI Kentaro - 4.08-1 +- new upstream release. + +* Wed Oct 29 2014 Kouhei Sutou - 4.07-1 +- new upstream release. + +* Mon Sep 29 2014 Kouhei Sutou - 4.06-1 +- new upstream release. + +* Sat Sep 27 2014 Eiichi Sato - 4.05-2 +- build against MySQL 5.6.21-2 on MySQL yum repository. + +* Fri Aug 29 2014 Kouhei Sutou - 4.05-1 +- new upstream release. + +* Sat Aug 09 2014 Eiichi Sato - 4.04-2 +- build against MySQL 5.6.20-4 on MySQL yum repository. + +* Tue Jul 29 2014 HAYASHI Kentaro - 4.04-1 +- new upstream release. + +* Thu May 29 2014 Kouhei Sutou - 4.03-2 +- build against MySQL 5.6.37. Reported by YOSHIDA Mitsuo. Thanks!!! + +* Thu May 29 2014 Kouhei Sutou - 4.03-1 +- new upstream release. + +* Tue Apr 29 2014 Kouhei Sutou - 4.02-1 +- new upstream release. + +* Sat Mar 29 2014 HAYASHI Kentaro - 4.01-1 +- new upstream release. + +* Thu Mar 06 2014 HAYASHI Kentaro - 4.00-2 +- use MySQL 5.5.36 on CentOS 5. + +* Sun Feb 09 2014 HAYASHI Kentaro - 4.00-1 +- new upstream release. + +* Wed Jan 29 2014 HAYASHI Kentaro - 3.12-1 +- new upstream release. + +* Sun Dec 29 2013 HAYASHI Kentaro - 3.11-1 +- new upstream release. + +* Fri Nov 29 2013 HAYASHI Kentaro - 3.10-1 +- new upstream release. + +* Tue Oct 29 2013 HAYASHI Kentaro - 3.09-1 +- initial packaging for MySQL 5.5 on CentOS 5. diff --git a/storage/mroonga/packages/source/Makefile.am b/storage/mroonga/packages/source/Makefile.am new file mode 100644 index 00000000000..30721406f0b --- /dev/null +++ b/storage/mroonga/packages/source/Makefile.am @@ -0,0 +1,123 @@ +MROONGA_BASE = $(PACKAGE)-$(VERSION) +MROONGA_TAR_GZ = $(MROONGA_BASE).tar.gz + +GROONGA_VERSION = 5.0.0 +GROONGA_BASE = groonga-$(GROONGA_VERSION) +GROONGA_TAR_GZ = $(GROONGA_BASE).tar.gz + +GROONGA_NORMALIZER_MYSQL_VERSION = 1.0.8 +GROONGA_NORMALIZER_MYSQL_BASE = \ + groonga-normalizer-mysql-$(GROONGA_NORMALIZER_MYSQL_VERSION) +GROONGA_NORMALIZER_MYSQL_TAR_GZ = \ + $(GROONGA_NORMALIZER_MYSQL_BASE).tar.gz + +MARIADB_VERSION = 10.0.16 +MARIADB_BASE = mariadb-$(MARIADB_VERSION) +MARIADB_TAR_GZ = $(MARIADB_BASE).tar.gz + +MARIADB_WITH_MROONGA_BASE = $(MARIADB_BASE)-with-$(MROONGA_BASE) +MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE = $(MARIADB_WITH_MROONGA_BASE)-for-windows + +GROONGA_PROJECT_DOWNLOAD_BASE = http://packages.groonga.org/source +GROONGA_DOWNLOAD_BASE = $(GROONGA_PROJECT_DOWNLOAD_BASE)/groonga +GROONGA_NORMALIZER_MYSQL_DOWNLOAD_BASE = \ + $(GROONGA_PROJECT_DOWNLOAD_BASE)/groonga-normalizer-mysql +MARIADB_DOWNLOAD_BASE = http://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb + + +CURL = curl --fail --silent --show-error + +all: + +release: archive upload + +ensure-rsync-path: + @if test -z "$(RSYNC_PATH)"; then \ + echo "--with-rsync-path configure option must be specified."; \ + false; \ + fi + +download: ensure-rsync-path + rsync -avz --progress --delete $(RSYNC_PATH)/source/mroonga/ files + +ARCHIVES = \ + files/$(MROONGA_TAR_GZ) \ + files/$(MARIADB_WITH_MROONGA_BASE).tar.gz \ + files/$(MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE).zip + +archive: $(ARCHIVES) + +upload: ensure-rsync-path + rsync -avz --progress --delete files/ $(RSYNC_PATH)/source/mroonga + +files/$(MROONGA_TAR_GZ): $(top_builddir)/$(MROONGA_TAR_GZ) + mkdir -p files + cp -p $< $@ + +tmp/$(GROONGA_TAR_GZ): + mkdir -p tmp + $(CURL) --output $@ $(GROONGA_DOWNLOAD_BASE)/$(GROONGA_TAR_GZ) + +tmp/$(GROONGA_NORMALIZER_MYSQL_TAR_GZ): + mkdir -p tmp + $(CURL) --output $@ $(GROONGA_NORMALIZER_MYSQL_DOWNLOAD_BASE)/$(GROONGA_NORMALIZER_MYSQL_TAR_GZ) + +tmp/$(MARIADB_TAR_GZ): + mkdir -p tmp + $(CURL) --output $@ $(MARIADB_DOWNLOAD_BASE)/mariadb-$(MARIADB_VERSION)/source/$(MARIADB_TAR_GZ) + +MARIADB_WITH_MROONGA_ARCHIVES = \ + tmp/$(GROONGA_TAR_GZ) \ + tmp/$(GROONGA_NORMALIZER_MYSQL_TAR_GZ) \ + tmp/$(MARIADB_TAR_GZ) \ + $(top_builddir)/$(MROONGA_TAR_GZ) + +BUNDLED_MROONGA_PATH = $(MARIADB_BASE)/storage/$(PACKAGE) +BUNDLED_GROONGA_PATH = $(BUNDLED_MROONGA_PATH)/vendor/groonga +BUNDLED_GROONGA_NORMALIZER_MYSQL_PATH = \ + $(BUNDLED_GROONGA_PATH)/vendor/plugins/groonga-normalizer-mysql + +tmp/$(MARIADB_WITH_MROONGA_BASE).stamp: $(MARIADB_WITH_MROONGA_ARCHIVES) + rm -rf $(MARIADB_BASE) + tar xf tmp/$(MARIADB_TAR_GZ) + + rm -fr $(MARIADB_BASE)/storage/mroonga + tar xf $(top_builddir)/$(MROONGA_TAR_GZ) + mv $(MROONGA_BASE) $(BUNDLED_MROONGA_PATH) + + mkdir -p $$(dirname $(BUNDLED_GROONGA_PATH)) + tar xf tmp/$(GROONGA_TAR_GZ) + rm -rf $(GROONGA_BASE)/test + mv $(GROONGA_BASE) $(BUNDLED_GROONGA_PATH) + + tar xf tmp/$(GROONGA_NORMALIZER_MYSQL_TAR_GZ) + rm -rf $(GROONGA_NORMALIZER_MYSQL_BASE)/test + mv $(GROONGA_NORMALIZER_MYSQL_BASE) $(BUNDLED_GROONGA_NORMALIZER_MYSQL_PATH) + + rm -rf tmp/$(MARIADB_WITH_MROONGA_BASE) + mv $(MARIADB_BASE) tmp/$(MARIADB_WITH_MROONGA_BASE) + + touch $@ + +files/$(MARIADB_WITH_MROONGA_BASE).tar.gz: tmp/$(MARIADB_WITH_MROONGA_BASE).stamp + mkdir -p files/ + (cd tmp && tar czf ../$@ $(MARIADB_WITH_MROONGA_BASE)) + +PATCHES = \ + patches/mariadb-10.0.3-windows-build.diff + +tmp/$(MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE).stamp: tmp/$(MARIADB_WITH_MROONGA_BASE).stamp $(PATCHES) + rm -rf tmp/$(MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE) + cp -a \ + tmp/$(MARIADB_WITH_MROONGA_BASE) \ + tmp/$(MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE) + for patch in $(PATCHES); do \ + (cd tmp/$(MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE) && \ + patch -p1 < $(abs_srcdir)/$${patch}); \ + done + + touch $@ + +files/$(MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE).zip: tmp/$(MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE).stamp + mkdir -p files/ + (cd tmp && zip -q -r ../$@ $(MARIADB_WITH_MROONGA_FOR_WINDOWS_BASE)) diff --git a/storage/mroonga/packages/source/patches/mariadb-10.0.3-windows-build.diff b/storage/mroonga/packages/source/patches/mariadb-10.0.3-windows-build.diff new file mode 100644 index 00000000000..c135088b8cc --- /dev/null +++ b/storage/mroonga/packages/source/patches/mariadb-10.0.3-windows-build.diff @@ -0,0 +1,9 @@ +diff -ur mariadb-10.0.2.orig/sql/sql_locale.cc mariadb-10.0.2/sql/sql_locale.cc +--- mariadb-10.0.2.orig/sql/sql_locale.cc 2013-04-23 13:13:59.000000000 +0900 ++++ mariadb-10.0.2/sql/sql_locale.cc 2013-05-19 12:55:27.590366542 +0900 +@@ -1,4 +1,4 @@ +-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. ++/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by diff --git a/storage/mroonga/packages/ubuntu/Makefile.am b/storage/mroonga/packages/ubuntu/Makefile.am new file mode 100644 index 00000000000..493419275b3 --- /dev/null +++ b/storage/mroonga/packages/ubuntu/Makefile.am @@ -0,0 +1,24 @@ +CODE_NAMES = precise,trusty,utopic +SOURCE = ../$(PACKAGE)-$(VERSION).tar.gz + +all: + +ensure-launchpad-configuration: + @if test -z "$(LAUNCHPAD_UPLOADER_PGP_KEY)"; then \ + echo "--with-launchpad-uploader-pgp-key configure option must be specified."; \ + false; \ + fi + +upload: source ensure-launchpad-configuration + ./upload.rb \ + --package '$(PACKAGE)' \ + --version '$(VERSION)' \ + --source-archive '$(SOURCE)' \ + --code-names '$(CODE_NAMES)' \ + --debian-directory '$(srcdir)/../debian/' \ + --pgp-sign-key '$(LAUNCHPAD_UPLOADER_PGP_KEY)' + +source: $(SOURCE) + +$(SOURCE): + ln -s $(abs_top_builddir)/$(PACKAGE)-$(VERSION).tar.gz $(SOURCE) diff --git a/storage/mroonga/packages/ubuntu/upload.rb b/storage/mroonga/packages/ubuntu/upload.rb new file mode 100755 index 00000000000..3331de6d5eb --- /dev/null +++ b/storage/mroonga/packages/ubuntu/upload.rb @@ -0,0 +1,168 @@ +#!/usr/bin/env ruby +# +# Copyright(C) 2014 Kouhei Sutou +# Copyright(C) 2014 HAYASHI Kentaro +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require "optparse" +require "fileutils" +require "pathname" +require "open-uri" + +class Uploader + def initialize + @dput_configuration_name = "groonga-ppa" + end + + def run + ensure_dput_configuration + + parse_command_line! + + ensure_mysql_version + + @required_groonga_version = required_groonga_version + + @code_names.each do |code_name| + upload(code_name) + end + end + + private + def ensure_dput_configuration + dput_cf_path = Pathname.new("~/.dput.cf").expand_path + if dput_cf_path.exist? + dput_cf_content = dput_cf_path.read + else + dput_cf_content = "" + end + dput_cf_content.each_line do |line| + return if line.chomp == "[#{@dput_configuration_name}]" + end + + dput_cf_path.open("w") do |dput_cf| + dput_cf.puts(dput_cf_content) + dput_cf.puts(<<-CONFIGURATION) +[#{@dput_configuration_name}] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~groonga/ppa/ubuntu/ +login = anonymous +allow_unsigned_uploads = 0 + CONFIGURATION + end + end + + def ensure_mysql_version + @mysql_version = {} + @code_names.each do |code_name| + open("http://packages.ubuntu.com/#{code_name}/allpackages?format=txt.gz") do |file| + file.each_line do |line| + @mysql_version[code_name] = $1 if line =~ /\Amysql-server \((.+?)\).+/ + end + end + end + end + + def parse_command_line! + + parser = OptionParser.new + parser.on("--package=NAME", + "The package name") do |name| + @package = name + end + parser.on("--version=VERSION", + "The version") do |version| + @version = version + end + parser.on("--source-archive=ARCHIVE", + "The source archive") do |source_archive| + @source_archive = Pathname.new(source_archive).expand_path + end + parser.on("--code-names=CODE_NAME1,CODE_NAME2,CODE_NAME3,...", Array, + "The target code names") do |code_names| + @code_names = code_names + end + parser.on("--debian-directory=DIRECTORY", + "The debian/ directory") do |debian_directory| + @debian_directory = Pathname.new(debian_directory).expand_path + end + parser.on("--pgp-sign-key=KEY", + "The PGP key to sign .changes and .dsc") do |pgp_sign_key| + @pgp_sign_key = pgp_sign_key + end + parser.on("--pbuilder", + "Use pbuilder for build check") do |pbuilder| + @use_pbuilder = pbuilder + end + + parser.parse! + end + + def upload(code_name) + in_temporary_directory do + FileUtils.cp(@source_archive.to_s, + "#{@package}_#{@version}.orig.tar.gz") + run_command("tar", "xf", @source_archive.to_s) + directory_name = "#{@package}-#{@version}" + Dir.chdir(directory_name) do + FileUtils.cp_r(@debian_directory.to_s, "debian") + deb_version = "#{current_deb_version.succ}~#{code_name}1" + run_command("dch", + "--distribution", code_name, + "--newversion", deb_version, + "Build for #{code_name}.") + run_command("sed", + "-i", "-e", "s,MYSQL_VERSION,#{@mysql_version[code_name]},", + "debian/control") + run_command("debuild", "-S", "-sa", "-pgpg2", "-k#{@pgp_sign_key}") + if @use_pbuilder + run_command("pbuilder-dist", code_name, "build", + "../#{@package}_#{deb_version}.dsc") + else + run_command("dput", @dput_configuration_name, + "../#{@package}_#{deb_version}_source.changes") + end + end + end + end + + def required_groonga_version + File.read("../../required_groonga_version").lines.first.chomp + end + + def current_deb_version + /\((.+)\)/ =~ File.read("debian/changelog").lines.first + $1 + end + + def in_temporary_directory + name = "tmp" + FileUtils.rm_rf(name) + FileUtils.mkdir_p(name) + Dir.chdir(name) do + yield + end + end + + def run_command(*command_line) + unless system(*command_line) + raise "failed to run command: #{command_line.join(' ')}" + end + end +end + +uploader = Uploader.new +uploader.run diff --git a/storage/mroonga/packages/windows/Makefile.am b/storage/mroonga/packages/windows/Makefile.am new file mode 100644 index 00000000000..a2ff8f59792 --- /dev/null +++ b/storage/mroonga/packages/windows/Makefile.am @@ -0,0 +1,12 @@ +EXTRA_DIST = \ + README.md \ + build-vc2010.bat \ + build-vc2010-zip-32.bat \ + build-vc2010-zip-64.bat \ + build-vc2010-msi-32.bat \ + build-vc2010-msi-64.bat \ + build-vc2013.bat \ + build-vc2013-zip-32.bat \ + build-vc2013-zip-64.bat \ + build-vc2013-msi-32.bat \ + build-vc2013-msi-64.bat diff --git a/storage/mroonga/packages/windows/README.md b/storage/mroonga/packages/windows/README.md new file mode 100644 index 00000000000..f7788ffe26b --- /dev/null +++ b/storage/mroonga/packages/windows/README.md @@ -0,0 +1,20 @@ +# How to build Windows binaries + +## Preparation + +TODO... + +## Build with Visual C++ Express + +You need to use Visual C++ 2012 or later to build Mroonga with Express +edition. `build-vc2013.bat` is a build batch script to build with +Visual C++ Express 2013. + +Note that you can't build MSI file with Express edition. You need to +use Professional edition or upper editions to build MSI file. + +## Build with Visual C++ Professional + +You can build both zip file MSI file with Professional edition. +`build-vc2010.bat` is a build batch script to build with Visual C++ +Professional 2010. diff --git a/storage/mroonga/packages/windows/build-vc2010-msi-32.bat b/storage/mroonga/packages/windows/build-vc2010-msi-32.bat new file mode 100644 index 00000000000..15185eaba92 --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2010-msi-32.bat @@ -0,0 +1,8 @@ +rmdir /S /Q build-vc2010-msi-32 +mkdir build-vc2010-msi-32 +cd build-vc2010-msi-32 +cmake ..\source -G "Visual Studio 10" > config.log +cmake --build . --config RelWithDebInfo > build.log +cmake --build . --config RelWithDebInfo --target msi > msi.log +move *.msi ..\ +cd .. diff --git a/storage/mroonga/packages/windows/build-vc2010-msi-64.bat b/storage/mroonga/packages/windows/build-vc2010-msi-64.bat new file mode 100644 index 00000000000..ea0b7f07eb3 --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2010-msi-64.bat @@ -0,0 +1,8 @@ +rmdir /S /Q build-vc2010-msi-64 +mkdir build-vc2010-msi-64 +cd build-vc2010-msi-64 +cmake ..\source -G "Visual Studio 10 Win64" > config.log +cmake --build . --config RelWithDebInfo > build.log +cmake --build . --config RelWithDebInfo --target msi > msi.log +move *.msi ..\ +cd .. diff --git a/storage/mroonga/packages/windows/build-vc2010-zip-32.bat b/storage/mroonga/packages/windows/build-vc2010-zip-32.bat new file mode 100644 index 00000000000..013080755d4 --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2010-zip-32.bat @@ -0,0 +1,8 @@ +rmdir /S /Q build-vc2010-zip-32 +mkdir build-vc2010-zip-32 +cd build-vc2010-zip-32 +cmake ..\source -G "Visual Studio 10" -DMRN_GROONGA_EMBED=OFF -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF > config.log +cmake --build . --config RelWithDebInfo > build.log +cmake --build . --config RelWithDebInfo --target package > zip.log +move *.zip ..\ +cd .. diff --git a/storage/mroonga/packages/windows/build-vc2010-zip-64.bat b/storage/mroonga/packages/windows/build-vc2010-zip-64.bat new file mode 100644 index 00000000000..040c921fcef --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2010-zip-64.bat @@ -0,0 +1,8 @@ +rmdir /S /Q build-vc2010-zip-64 +mkdir build-vc2010-zip-64 +cd build-vc2010-zip-64 +cmake ..\source -G "Visual Studio 10 Win64" -DMRN_GROONGA_EMBED=OFF -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF > config.log +cmake --build . --config RelWithDebInfo > build.log +cmake --build . --config RelWithDebInfo --target package > zip.log +move *.zip ..\ +cd .. diff --git a/storage/mroonga/packages/windows/build-vc2010.bat b/storage/mroonga/packages/windows/build-vc2010.bat new file mode 100644 index 00000000000..5fcf0639412 --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2010.bat @@ -0,0 +1,4 @@ +build-vc2010-zip-32.bat +build-vc2010-zip-64.bat +build-vc2010-msi-32.bat +build-vc2010-msi-64.bat diff --git a/storage/mroonga/packages/windows/build-vc2013-msi-32.bat b/storage/mroonga/packages/windows/build-vc2013-msi-32.bat new file mode 100644 index 00000000000..22b29972885 --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2013-msi-32.bat @@ -0,0 +1,8 @@ +rmdir /S /Q build-vc2013-msi-32 +mkdir build-vc2013-msi-32 +cd build-vc2013-msi-32 +cmake ..\source -G "Visual Studio 12" > config.log +cmake --build . --config RelWithDebInfo > build.log +cmake --build . --config RelWithDebInfo --target msi > msi.log +move *.msi ..\ +cd .. diff --git a/storage/mroonga/packages/windows/build-vc2013-msi-64.bat b/storage/mroonga/packages/windows/build-vc2013-msi-64.bat new file mode 100644 index 00000000000..c83a376cdb9 --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2013-msi-64.bat @@ -0,0 +1,8 @@ +rmdir /S /Q build-vc2013-msi-64 +mkdir build-vc2013-msi-64 +cd build-vc2013-msi-64 +cmake ..\source -G "Visual Studio 12 Win64" > config.log +cmake --build . --config RelWithDebInfo > build.log +cmake --build . --config RelWithDebInfo --target msi > msi.log +move *.msi ..\ +cd .. diff --git a/storage/mroonga/packages/windows/build-vc2013-zip-32.bat b/storage/mroonga/packages/windows/build-vc2013-zip-32.bat new file mode 100644 index 00000000000..d3e0e4f8b8e --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2013-zip-32.bat @@ -0,0 +1,8 @@ +rmdir /S /Q build-vc2013-zip-32 +mkdir build-vc2013-zip-32 +cd build-vc2013-zip-32 +cmake ..\source -G "Visual Studio 12" -DMRN_GROONGA_EMBED=OFF -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF > config.log +cmake --build . --config RelWithDebInfo > build.log +cmake --build . --config RelWithDebInfo --target package > zip.log +move *.zip ..\ +cd .. diff --git a/storage/mroonga/packages/windows/build-vc2013-zip-64.bat b/storage/mroonga/packages/windows/build-vc2013-zip-64.bat new file mode 100644 index 00000000000..6ca288b6a8b --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2013-zip-64.bat @@ -0,0 +1,8 @@ +rmdir /S /Q build-vc2013-zip-64 +mkdir build-vc2013-zip-64 +cd build-vc2013-zip-64 +cmake ..\source -G "Visual Studio 12 Win64" -DMRN_GROONGA_EMBED=OFF -DMRN_GROONGA_NORMALIZER_MYSQL_EMBED=OFF > config.log +cmake --build . --config RelWithDebInfo > build.log +cmake --build . --config RelWithDebInfo --target package > zip.log +move *.zip ..\ +cd .. diff --git a/storage/mroonga/packages/windows/build-vc2013.bat b/storage/mroonga/packages/windows/build-vc2013.bat new file mode 100644 index 00000000000..99d7e4042c5 --- /dev/null +++ b/storage/mroonga/packages/windows/build-vc2013.bat @@ -0,0 +1,4 @@ +build-vc2013-zip-32.bat +build-vc2013-zip-64.bat +REM build-vc2013-msi-32.bat +REM build-vc2013-msi-64.bat diff --git a/storage/mroonga/packages/yum/Makefile.am b/storage/mroonga/packages/yum/Makefile.am new file mode 100644 index 00000000000..b110b478a14 --- /dev/null +++ b/storage/mroonga/packages/yum/Makefile.am @@ -0,0 +1,63 @@ +REPOSITORIES_PATH = repositories +DISTRIBUTIONS = centos +ARCHITECTURES = i386 x86_64 +MYSQL_VARIANTS = mysql55 mysql56-community mariadb +SPEC_DIR = $(builddir)/../rpm/centos + +all: + +release: download build sign-packages update-repository upload + +remove-existing-packages: + for distribution in $(DISTRIBUTIONS); do \ + find $${distribution} -name "*.rpm" -delete; \ + done + +ensure-rsync-path: + @if test -z "$(RSYNC_PATH)"; then \ + echo "--with-rsync-path configure option must be specified."; \ + false; \ + fi + +sign-packages: + ./sign-rpm.sh '$(GPG_UID)' '$(REPOSITORIES_PATH)/' '$(DISTRIBUTIONS)' + +update-repository: + ./update-repository.sh '$(REPOSITORIES_PATH)/' '$(DISTRIBUTIONS)' + +upload: ensure-rsync-path + for distribution in $(DISTRIBUTIONS); do \ + rsync -avz --progress --delete --exclude .gitignore \ + $(REPOSITORIES_PATH)/$${distribution}/ \ + $(RSYNC_PATH)/$${distribution}; \ + done + +download: ensure-rsync-path + mkdir -p $(REPOSITORIES_PATH) + for distribution in $(DISTRIBUTIONS); do \ + rsync -avz --progress --delete \ + $(RSYNC_PATH)/$${distribution}/ \ + $(REPOSITORIES_PATH)/$${distribution}; \ + done + +build: build-in-vm + +build-in-vm: source specs env.sh + ./build-in-vm.sh \ + "$(PACKAGE)" \ + "$(SPEC_DIR)" \ + "$(MYSQL_VARIANTS)" \ + "$(ARCHITECTURES)" + +source: tmp/$(PACKAGE)-$(VERSION).tar.gz + +tmp/$(PACKAGE)-$(VERSION).tar.gz: $(abs_top_builddir)/$(PACKAGE)-$(VERSION).tar.gz + mkdir -p tmp/ + cp $(abs_top_builddir)/$(PACKAGE)-$(VERSION).tar.gz tmp/ + +$(abs_top_builddir)/$(PACKAGE)-$(VERSION).tar.gz: + cd $(abs_top_builddir) && $(MAKE) dist + +specs: $(SPEC_DIR)/mysql55-$(PACKAGE).spec +specs: $(SPEC_DIR)/mysql56-community-$(PACKAGE).spec +specs: $(SPEC_DIR)/mariadb-$(PACKAGE).spec diff --git a/storage/mroonga/packages/yum/Vagrantfile b/storage/mroonga/packages/yum/Vagrantfile new file mode 100644 index 00000000000..1a9e4584ee4 --- /dev/null +++ b/storage/mroonga/packages/yum/Vagrantfile @@ -0,0 +1,50 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + vms = [ + { + :id => "centos-5-i386", + :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-5.11-i386_chef-provisionerless.box", + }, + { + :id => "centos-5-x86_64", + :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-5.11_chef-provisionerless.box", + }, + { + :id => "centos-6-i386", + :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.6-i386_chef-provisionerless.box", + }, + { + :id => "centos-6-x86_64", + :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.6_chef-provisionerless.box", + }, + { + :id => "centos-7-x86_64", + :box_url => "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.0_chef-provisionerless.box", + }, + ] + + vms.each do |vm| + config.vm.define(vm[:id]) do |node| + node.vm.box = vm[:id] + node.vm.box_url = vm[:box_url] + node.vm.provision(:shell, :path => "build-rpm.sh") + node.vm.provider("virtualbox") do |virtual_box| + system_n_cpus = 1 + if File.exist?("/proc/cpuinfo") + system_n_cpus = File.readlines("/proc/cpuinfo").grep(/^processor/).size + end + if system_n_cpus > 1 + vm_n_cpus = system_n_cpus / 2 + else + vm_n_cpus = 1 + end + virtual_box.cpus = vm_n_cpus + end + end + end +end diff --git a/storage/mroonga/packages/yum/build-in-vm.sh b/storage/mroonga/packages/yum/build-in-vm.sh new file mode 100755 index 00000000000..5dc27ec38dd --- /dev/null +++ b/storage/mroonga/packages/yum/build-in-vm.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +if [ $# != 4 ]; then + echo "Usage: $0 PACKAGE SPEC_DIR MYSQL_VARIANTS ARCHITECTURES" + echo " e.g.: $0 mroonga ../rpm/centos 'mysql55 mariadb' 'i386 x86_64'" + exit 1 +fi + +PACKAGE="$1" +SPEC_DIR="$2" +MYSQL_VARIANTS="$3" +ARCHITECTURES="$4" + +run() +{ + "$@" + if test $? -ne 0; then + echo "Failed $@" + exit 1 + fi +} + +run vagrant destroy --force + +for mysql_variant in ${MYSQL_VARIANTS}; do + rm -rf tmp/centos/ + mkdir -p tmp/centos/ + cp ${SPEC_DIR}/${mysql_variant}-${PACKAGE}.spec tmp/centos/ + + architectures="${ARCHITECTURES}" + case ${mysql_variant} in + mysql55) + centos_versions="5 6" + ;; + mysql56-community) + centos_versions="6 7" + ;; + mariadb) + centos_versions="7" + ;; + esac + + for architecture in ${architectures}; do + for centos_version in ${centos_versions}; do + if [ ${mysql_variant} = mysql55 -a ${centos_version} = 6 -a ${architecture} = i386 ]; then + continue + fi + if [ ${centos_version} = 7 -a ${architecture} = i386 ]; then + continue + fi + id=centos-${centos_version}-${architecture} + vagrant up ${id} + build_status=$? + if [ $build_status -ne 0 ]; then + exit $build_status + fi + vagrant destroy --force ${id} + done + done +done diff --git a/storage/mroonga/packages/yum/build-rpm.sh b/storage/mroonga/packages/yum/build-rpm.sh new file mode 100755 index 00000000000..6eaa2cce02a --- /dev/null +++ b/storage/mroonga/packages/yum/build-rpm.sh @@ -0,0 +1,108 @@ +#!/bin/sh + +LANG=C + +run() +{ + "$@" + if test $? -ne 0; then + echo "Failed $@" + exit 1 + fi +} + +rpmbuild_options= + +. /vagrant/env.sh + +distribution=$(cut -d " " -f 1 /etc/redhat-release | tr "A-Z" "a-z") +if grep -q Linux /etc/redhat-release; then + distribution_version=$(cut -d " " -f 4 /etc/redhat-release) +else + distribution_version=$(cut -d " " -f 3 /etc/redhat-release) +fi +distribution_version=$(echo ${distribution_version} | sed -e 's/\..*$//g') + +architecture="$(arch)" +case "${architecture}" in + i*86) + architecture=i386 + ;; +esac + +run yum groupinstall -y "Development Tools" +run yum install -y rpm-build rpmdevtools tar wget + +if [ -x /usr/bin/rpmdev-setuptree ]; then + rm -rf .rpmmacros + run rpmdev-setuptree +else + run cat < ~/.rpmmacros +%_topdir ${HOME}/rpmbuild +EOM + run mkdir -p ~/rpmbuild/SOURCES + run mkdir -p ~/rpmbuild/SPECS + run mkdir -p ~/rpmbuild/BUILD + run mkdir -p ~/rpmbuild/RPMS + run mkdir -p ~/rpmbuild/SRPMS +fi + +repository="/vagrant/repositories/${distribution}/${distribution_version}" +rpm_dir="${repository}/${architecture}/Packages" +srpm_dir="${repository}/source/SRPMS" +run mkdir -p "${rpm_dir}" "${srpm_dir}" + +rpmbuild_options="" + +# for debug +# rpmbuild_options="${rpmbuild_options} --define 'optflags -O0 -g3'" + +cd + +run cp /vagrant/tmp/${PACKAGE}-${VERSION}.* rpmbuild/SOURCES/ +run cp /vagrant/tmp/${distribution}/*.spec rpmbuild/SPECS/ + +package_name=$(cd rpmbuild/SPECS; echo *.spec | sed -e 's/\.spec$//g') + +case ${distribution} in + fedora) + USE_MYSQLSERVICES_COMPAT=yes + run yum install -y mariadb-devel + ;; + centos) + case ${package_name} in + mysql55-${PACKAGE}) + USE_MYSQLSERVICES_COMPAT=yes + run yum install -y scl-utils-build + if [ ${distribution_version} = 6 ]; then + run yum install -y centos-release-SCL + fi + run yum install -y mysql55-mysql-devel mysql55-build + ;; + mysql56-community-${PACKAGE}) + release_rpm=mysql-community-release-el${distribution_version}-5.noarch.rpm + run yum -y install http://repo.mysql.com/${release_rpm} + run yum -y install mysql-community-devel + ;; + mariadb-${PACKAGE}) + run yum -y install mariadb-devel + ;; + esac + + release_rpm=groonga-release-1.1.0-1.noarch.rpm + wget http://packages.groonga.org/${distribution}/${release_rpm} + run rpm -U ${release_rpm} + rm -f ${release_rpm} + run yum makecache + ;; +esac +run yum install -y ${DEPENDED_PACKAGES} + +if [ "${USE_MYSQLSERVICES_COMPAT}" = "yes" ]; then + rpmbuild_options="$rpmbuild_options --define 'mroonga_configure_options --with-libmysqlservices-compat'" +fi + +run eval rpmbuild -ba ${rpmbuild_options} rpmbuild/SPECS/${package_name}.spec + +run mv rpmbuild/RPMS/*/* "${rpm_dir}/" +run mv rpmbuild/SRPMS/* "${srpm_dir}/" diff --git a/storage/mroonga/packages/yum/env.sh.in b/storage/mroonga/packages/yum/env.sh.in new file mode 100644 index 00000000000..90e701ec89e --- /dev/null +++ b/storage/mroonga/packages/yum/env.sh.in @@ -0,0 +1,27 @@ +PACKAGE=@PACKAGE@ +VERSION=@VERSION@ +DEPENDED_PACKAGES=" +intltool +libtool +gcc +gcc-c++ +make +gperf +readline-devel +openssl-devel +time +wget +ncurses-devel +sudo +pkgconfig +tar +cmake +libaio-devel +systemtap-sdt-devel +perl-Time-HiRes +perl-Env +perl-Test-Simple +pam-devel +groonga-devel +groonga-normalizer-mysql-devel +" diff --git a/storage/mroonga/packages/yum/sign-rpm.sh b/storage/mroonga/packages/yum/sign-rpm.sh new file mode 100755 index 00000000000..b3a45afe7f5 --- /dev/null +++ b/storage/mroonga/packages/yum/sign-rpm.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +script_base_dir=`dirname $0` + +if [ $# != 3 ]; then + echo "Usage: $0 GPG_UID DESTINATION DISTRIBUTIONS" + echo " e.g.: $0 'F10399C0' repositories/ 'fedora centos'" + exit 1 +fi + +GPG_UID=$1 +DESTINATION=$2 +DISTRIBUTIONS=$3 + +run() +{ + "$@" + if test $? -ne 0; then + echo "Failed $@" + exit 1 + fi +} + +unsigned_rpms() +{ + while read rpm; do + rpm --checksig "$rpm" | grep -v 'gpg OK' | cut -d":" -f1 + done +} + +if ! gpg --list-keys "${GPG_UID}" > /dev/null 2>&1; then + run gpg --keyserver keyserver.ubuntu.com --recv-key "${GPG_UID}" +fi +run mkdir -p tmp +run gpg --armor --export "${GPG_UID}" > tmp/sign-key +run rpm --import tmp/sign-key +run rm -rf tmp/sign-key + +rpms="" +for distribution in ${DISTRIBUTIONS}; do + rpms="${rpms} $(find ${DESTINATION}${distribution} -name '*.rpm' | unsigned_rpms)" +done + +echo "NOTE: YOU JUST ENTER! YOU DON'T NEED TO INPUT PASSWORD!" +echo " IT'S JUST FOR rpm COMMAND RESTRICTION!" +run echo $rpms | xargs rpm \ + -D "_gpg_name ${GPG_UID}" \ + -D "_gpg_digest_algo sha1" \ + -D "__gpg /usr/bin/gpg2" \ + -D "__gpg_check_password_cmd /bin/true true" \ + -D "__gpg_sign_cmd %{__gpg} gpg --batch --no-verbose --no-armor %{?_gpg_digest_algo:--digest-algo %{_gpg_digest_algo}} --no-secmem-warning -u \"%{_gpg_name}\" -sbo %{__signature_filename} %{__plaintext_filename}" \ + --resign diff --git a/storage/mroonga/packages/yum/update-repository.sh b/storage/mroonga/packages/yum/update-repository.sh new file mode 100755 index 00000000000..630b6c87422 --- /dev/null +++ b/storage/mroonga/packages/yum/update-repository.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +script_base_dir=`dirname $0` + +if [ $# != 2 ]; then + echo "Usage: $0 DESTINATION DISTRIBUTIONS" + echo " e.g.: $0 repositories/ 'fedora centos'" + exit 1 +fi + +DESTINATION=$1 +DISTRIBUTIONS=$2 + +run() +{ + "$@" + if test $? -ne 0; then + echo "Failed $@" + exit 1 + fi +} + +for distribution in ${DISTRIBUTIONS}; do + for dir in ${DESTINATION}${distribution}/*/*; do + # "--checksum sha" is for CentOS 5. If we drop CentOS 5 support, + # we can remove the option. + test -d $dir && run createrepo --checksum sha $dir + done; +done diff --git a/storage/mroonga/plugin_version b/storage/mroonga/plugin_version index be9fc83102e..6e636605163 100644 --- a/storage/mroonga/plugin_version +++ b/storage/mroonga/plugin_version @@ -1 +1 @@ -4.6 \ No newline at end of file +5.0 \ No newline at end of file diff --git a/storage/mroonga/required_groonga_version b/storage/mroonga/required_groonga_version index fcdb2e109f6..43beb4001b8 100644 --- a/storage/mroonga/required_groonga_version +++ b/storage/mroonga/required_groonga_version @@ -1 +1 @@ -4.0.0 +4.0.7 diff --git a/storage/mroonga/tools/travis/install.sh b/storage/mroonga/tools/travis/install.sh index fd3d2187914..95b8b23ba19 100755 --- a/storage/mroonga/tools/travis/install.sh +++ b/storage/mroonga/tools/travis/install.sh @@ -21,8 +21,8 @@ set -e mariadb_download_base=http://mirror.jmu.edu/pub/mariadb -export GROONGA_MASTER=yes -export GROONGA_NORMALIZER_MYSQL_MASTER=yes +# export GROONGA_MASTER=yes +# export GROONGA_NORMALIZER_MYSQL_MASTER=yes curl --silent --location https://github.com/groonga/groonga/raw/master/data/travis/setup.sh | sh curl --silent --location https://github.com/groonga/groonga-normalizer-mysql/raw/master/data/travis/setup.sh | sh @@ -43,6 +43,7 @@ if [ "${MROONGA_BUNDLED}" = "yes" ]; then curl -O ${download_base}/source/${tar_gz} tar xzf $tar_gz mv ${MYSQL_VERSION}/* ./ + rm -rf storage/mroonga mv .mroonga storage/mroonga rm -rf ${MYSQL_VERSION} else @@ -57,7 +58,8 @@ else sudo apt-get -qq -y build-dep mysql-server if [ "$version" = "system" ]; then sudo apt-get -qq -y install \ - mysql-server mysql-testsuite libmysqld-dev + mysql-server mysql-server-5.5 mysql-server-core-5.5 \ + mysql-testsuite libmysqld-dev apt-get -qq source mysql-server ln -s $(find . -maxdepth 1 -type d | sort | tail -1) mysql else diff --git a/storage/mroonga/udf/mrn_udf_command.cpp b/storage/mroonga/udf/mrn_udf_command.cpp index ba92e8daa26..172f64896a2 100644 --- a/storage/mroonga/udf/mrn_udf_command.cpp +++ b/storage/mroonga/udf/mrn_udf_command.cpp @@ -26,10 +26,10 @@ #include #include -extern mrn::DatabaseManager *mrn_db_manager; - MRN_BEGIN_DECLS +extern mrn::DatabaseManager *mrn_db_manager; + struct CommandInfo { grn_ctx ctx; @@ -100,7 +100,7 @@ error: grn_obj_close(&(info->ctx), info->db); } grn_ctx_fin(&(info->ctx)); - my_free(info, MYF(0)); + my_free(info); } return TRUE; } @@ -164,7 +164,7 @@ MRN_API void mroonga_command_deinit(UDF_INIT *initid) } grn_ctx_fin(&(info->ctx)); info->result.free(); - my_free(info, MYF(0)); + my_free(info); } } diff --git a/storage/mroonga/udf/mrn_udf_escape.cpp b/storage/mroonga/udf/mrn_udf_escape.cpp index ff997e7581f..36179788596 100644 --- a/storage/mroonga/udf/mrn_udf_escape.cpp +++ b/storage/mroonga/udf/mrn_udf_escape.cpp @@ -81,7 +81,7 @@ MRN_API my_bool mroonga_escape_init(UDF_INIT *initid, UDF_ARGS *args, error: if (info) { grn_ctx_fin(&(info->ctx)); - my_free(info, MYF(0)); + my_free(info); } return TRUE; } @@ -147,7 +147,7 @@ MRN_API void mroonga_escape_deinit(UDF_INIT *initid) grn_obj_unlink(&(info->ctx), &(info->target_characters)); grn_obj_unlink(&(info->ctx), &(info->escaped_query)); grn_ctx_fin(&(info->ctx)); - my_free(info, MYF(0)); + my_free(info); } } diff --git a/storage/mroonga/udf/mrn_udf_snippet.cpp b/storage/mroonga/udf/mrn_udf_snippet.cpp index 84166a36f16..3eaf05eed95 100644 --- a/storage/mroonga/udf/mrn_udf_snippet.cpp +++ b/storage/mroonga/udf/mrn_udf_snippet.cpp @@ -198,7 +198,7 @@ error: if (snip_info) { grn_obj_close(&snip_info->ctx, grn_ctx_db(&snip_info->ctx)); grn_ctx_fin(&snip_info->ctx); - my_free(snip_info, MYF(0)); + my_free(snip_info); } return TRUE; } @@ -295,7 +295,7 @@ MRN_API void mroonga_snippet_deinit(UDF_INIT *initid) snip_info->result_str.free(); grn_obj_close(&snip_info->ctx, grn_ctx_db(&snip_info->ctx)); grn_ctx_fin(&snip_info->ctx); - my_free(snip_info, MYF(0)); + my_free(snip_info); } } diff --git a/storage/mroonga/vendor/groonga/CMakeLists.txt b/storage/mroonga/vendor/groonga/CMakeLists.txt index abaa9911fd6..cddb3df28f6 100644 --- a/storage/mroonga/vendor/groonga/CMakeLists.txt +++ b/storage/mroonga/vendor/groonga/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright(C) 2012-2014 Brazil +# Copyright(C) 2012-2015 Brazil # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -20,12 +20,19 @@ cmake_minimum_required(VERSION 2.6.2) set(GRN_PROJECT_NAME "groonga") project("${GRN_PROJECT_NAME}") +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(CMAKE_COMPILER_IS_CLANGC ON) +endif() +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CMAKE_COMPILER_IS_CLANGCXX ON) +endif() + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/base_version" VERSION) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/version.sh") file(READ "${CMAKE_CURRENT_SOURCE_DIR}/version.sh" GRN_VERSION) else() if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/version.sh") - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND EXISTS "/bin/sh") execute_process(COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/version-gen.sh") file(READ "${CMAKE_CURRENT_BINARY_DIR}/version.sh" GRN_VERSION) else() @@ -44,6 +51,15 @@ include(CheckCXXCompilerFlag) include(FindPkgConfig) include(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake_modules/ReadFileList.cmake) +if(DEFINED GRN_EMBED) + set(GRN_EMBED_DEFAULT ${GRN_EMBED}) +else() + set(GRN_EMBED_DEFAULT OFF) +endif() +option(GRN_EMBED + "Build as a static library to embed into an application" + ${GRN_EMBED_DEFAULT}) + set(BIN_DIR "bin") set(SBIN_DIR "sbin") set(LIB_DIR "lib") @@ -53,10 +69,14 @@ set(DATA_DIR "share") set(GRN_DATA_DIR "${DATA_DIR}/${GRN_PROJECT_NAME}") set(CONFIG_DIR "etc") set(GRN_CONFIG_DIR "${CONFIG_DIR}/${GRN_PROJECT_NAME}") +set(GRN_CONFIG_PATH "${CMAKE_INSTALL_PREFIX}/${GRN_CONFIG_DIR}/groonga.conf") set(GRN_LOG_PATH "${CMAKE_INSTALL_PREFIX}/var/log/${GRN_PROJECT_NAME}/${GRN_PROJECT_NAME}.log" CACHE FILEPATH "log file path") +set(GRN_DEFAULT_ENCODING + "utf8" + CACHE STRING "Groonga's default encoding") set(GRN_DEFAULT_MATCH_ESCALATION_THRESHOLD 0 CACHE STRING "groonga default match escalation threshold") @@ -69,6 +89,9 @@ set(GRN_DEFAULT_RELATIVE_DOCUMENT_ROOT set(GRN_DEFAULT_DOCUMENT_ROOT "${CMAKE_INSTALL_PREFIX}/${GRN_DATA_DIR}/${GRN_DEFAULT_DOCUMENT_ROOT_BASE}" CACHE PATH "groonga default document root") +set(GRN_DEFAULT_DB_KEY + "auto" + CACHE STRING "Groonga's default DB key management algorithm") set(GRN_STACK_SIZE 1024 CACHE STRING @@ -97,15 +120,21 @@ set(GRN_RUBY_SCRIPTS_DIR "${CMAKE_INSTALL_PREFIX}/${GRN_RELATIVE_RUBY_SCRIPTS_DIR}") macro(check_cflag flag) - check_c_compiler_flag(${flag} "HAVE_C_${flag}") - if(HAVE_C_${flag}) + string(REGEX REPLACE "[-=]" "_" temporary_variable_name ${flag}) + string(TOUPPER "${temporary_variable_name}" temporary_variable_name) + set(temporary_variable_name "CFLAG${temporary_variable_name}") + check_c_compiler_flag(${flag} ${temporary_variable_name}) + if(${temporary_variable_name}) set(GRN_C_COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS} ${flag}") endif() endmacro() macro(check_cxxflag flag) - check_cxx_compiler_flag(${flag} "HAVE_CXX_${flag}") - if(HAVE_CXX_${flag}) + string(REGEX REPLACE "[-=]" "_" temporary_variable_name ${flag}) + string(TOUPPER "${temporary_variable_name}" temporary_variable_name) + set(temporary_variable_name "CXXFLAG${temporary_variable_name}") + check_cxx_compiler_flag(${flag} ${temporary_variable_name}) + if(${temporary_variable_name}) set(GRN_CXX_COMPILE_FLAGS "${GRN_CXX_COMPILE_FLAGS} ${flag}") endif() endmacro() @@ -137,7 +166,10 @@ if(CMAKE_COMPILER_IS_GNUCXX) check_cxxflag("-fexceptions") check_cxxflag("-fimplicit-templates") check_build_flag("-Wno-clobbered") - if(MRN_GROONGA_BUNDLED) +endif() + +if(GRN_EMBED) + if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX) check_build_flag("-fPIC") endif() endif() @@ -154,17 +186,15 @@ add_definitions( -DHAVE_CONFIG_H ) -if(CMAKE_COMPILER_IS_GNUC OR - CMAKE_COMPILER_IS_GNUCXX OR - CMAKE_C_COMPILER_ID STREQUAL "Clang") +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX) set(_GNU_SOURCE TRUE) endif() include_directories( BEFORE ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/lib ) macro(ac_check_headers header) @@ -202,6 +232,7 @@ include(build/ac_macros/check_headers.m4) include(build/ac_macros/check_functions.m4) ac_check_symbols(fpclassify math.h) +ac_check_lib(m fpclassify) ac_check_lib(dl dlopen) ac_check_lib(execinfo backtrace) @@ -214,8 +245,7 @@ ac_check_lib(rt clock_gettime) if(HAVE_LIBRT) set(HAVE_CLOCK_GETTIME TRUE) endif() -if(MRN_GROONGA_BUNDLED) - ac_check_lib(m sincos) +if(GRN_EMBED) check_library_exists(stdc++ __cxa_begin_catch "${ARG2}" STDCPP) if(STDCPP) @@ -293,19 +323,29 @@ else() endif() endif() -option(GRN_WITH_ZLIB "use zlib for data compression." OFF) -if(GRN_WITH_ZLIB) +set(GRN_WITH_ZLIB "auto" + CACHE STRING "Support data compression by zlib.") +if(NOT ${GRN_WITH_ZLIB} STREQUAL "no") ac_check_lib(z compress) if(NOT HAVE_LIBZ) - message(FATAL_ERROR "No libz found") + if(${GRN_WITH_ZLIB} STREQUAL "yes") + message(FATAL_ERROR "No libz found") + endif() + set(GRN_WITH_ZLIB "no") endif() endif() -option(GRN_WITH_LZO "use LZO for data compression." OFF) -if(GRN_WITH_LZO) - ac_check_lib(lzo2 lzo1_compress) - if(NOT HAVE_LIBLZO2) - message(FATAL_ERROR "No liblzo2 found") +set(GRN_WITH_LZ4 "auto" + CACHE STRING "Support data compression by LZ4.") +if(NOT ${GRN_WITH_LZ4} STREQUAL "no") + pkg_check_modules(LIBLZ4 liblz4) + if(LIBLZ4_FOUND) + set(GRN_WITH_LZ4 TRUE) + else() + if(${GRN_WITH_LZ4} STREQUAL "yes") + message(FATAL_ERROR "No LZ4 found") + endif() + set(GRN_WITH_LZ4 FALSE) endif() endif() @@ -362,6 +402,38 @@ else() set(GRN_WITH_KYTEA FALSE) endif() +set(GRN_WITH_LIBSTEMMER "auto" + CACHE STRING "use libstemmer for stemming token filter") +if(NOT ${GRN_WITH_LIBSTEMMER} STREQUAL "no") + if(NOT ("${GRN_WITH_LIBSTEMMER}" STREQUAL "yes" OR + "${GRN_WITH_LIBSTEMMER}" STREQUAL "auto")) + if("${LIBSTEMMER_INCLUDE_DIRS}" STREQUAL "") + set(LIBSTEMMER_INCLUDE_DIRS "${GRN_WITH_LIBSTEMMER}/include") + endif() + if("${LIBSTEMMER_LIBRARY_DIRS}" STREQUAL "") + set(LIBSTEMMER_LIBRARY_DIRS "${GRN_WITH_LIBSTEMMER}/lib") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES_SAVE ${CMAKE_REQUIRED_INCLUDES}) + set(CMAKE_REQUIRED_INCLUDES + ${CMAKE_REQUIRED_INCLUDES} + ${LIBSTEMMER_INCLUDE_DIRS}) + ac_check_headers(libstemmer.h) + ac_check_lib(stemmer sb_stemmer_list "${LIBSTEMMER_LIBRARY_DIRS}") + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_SAVE}) + if(HAVE_LIBSTEMMER_H AND HAVE_LIBSTEMMER) + set(LIBSTEMMER_LIBRARIES "stemmer") + set(GRN_WITH_LIBSTEMMER TRUE) + else() + if(${GRN_WITH_LIBSTEMMER} STREQUAL "yes") + message(FATAL_ERROR "No libstemmer found") + endif() + set(GRN_WITH_LIBSTEMMER FALSE) + endif() +else() + set(GRN_WITH_LIBSTEMMER FALSE) +endif() + set(GRN_WITH_ZEROMQ "auto" CACHE STRING "use ZeroMQ for suggestion") if(NOT ${GRN_WITH_ZEROMQ} STREQUAL "no") @@ -447,12 +519,16 @@ else() set(MRUBY_LIBS "") endif() -#add_subdirectory(vendor) +if(NOT GRN_EMBED) + add_subdirectory(vendor) +endif() add_subdirectory(lib) -add_subdirectory(src) -#add_subdirectory(plugins) -add_subdirectory(include) -#add_subdirectory(data) +if(NOT GRN_EMBED) + add_subdirectory(src) + add_subdirectory(plugins) + add_subdirectory(include) + add_subdirectory(data) +endif() configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) @@ -476,10 +552,10 @@ set(GRN_EXPANDED_DEFAULT_DOCUMENT_ROOT "${GRN_DEFAULT_DOCUMENT_ROOT}") set(EXEEXT "${CMAKE_EXECUTABLE_SUFFIX}") configure_file(groonga.pc.in "${CMAKE_CURRENT_BINARY_DIR}/groonga.pc" @ONLY) -if(NOT MRN_GROONGA_BUNDLED) +if(NOT GRN_EMBED) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/groonga.pc" DESTINATION "${LIB_DIR}/pkgconfig/") endif() -#add_subdirectory(vendor/plugins) +add_subdirectory(vendor/plugins) diff --git a/storage/mroonga/vendor/groonga/Makefile.am b/storage/mroonga/vendor/groonga/Makefile.am index a5bf404d471..65b7c928770 100644 --- a/storage/mroonga/vendor/groonga/Makefile.am +++ b/storage/mroonga/vendor/groonga/Makefile.am @@ -69,7 +69,6 @@ update-latest-release: misc misc/update-latest-release.rb \ $(PACKAGE) $(OLD_RELEASE) $(OLD_RELEASE_DATE) \ $(VERSION) $(NEW_RELEASE_DATE) \ - packages/rpm/fedora/groonga.spec.in \ packages/rpm/centos/groonga.spec.in \ packages/debian/changelog \ doc/source/install.rst \ diff --git a/storage/mroonga/vendor/groonga/appveyor.yml b/storage/mroonga/vendor/groonga/appveyor.yml new file mode 100644 index 00000000000..aa4b65fb24e --- /dev/null +++ b/storage/mroonga/vendor/groonga/appveyor.yml @@ -0,0 +1,17 @@ +version: "{build}" +clone_depth: 10 +build_script: + - cmake . -G "Visual Studio 12 Win64" + - cmake --build . --config RelWithDebInfo + +notifications: + - provider: Email + to: + - kou@clear-code.com + - groonga-commit@lists.sourceforge.jp + on_build_status_changed: true + +before_test: + - gem install grntest +test_script: + - grntest --groonga src\groonga.exe --base-directory test\command test\command\suite diff --git a/storage/mroonga/vendor/groonga/autogen.sh b/storage/mroonga/vendor/groonga/autogen.sh index 9b3a98eab5d..66184bf13be 100755 --- a/storage/mroonga/vendor/groonga/autogen.sh +++ b/storage/mroonga/vendor/groonga/autogen.sh @@ -18,4 +18,9 @@ FreeBSD) ;; esac +if [ ! -e vendor/mruby-source/.git ]; then + rm -rf vendor/mruby-source +fi +git submodule update --init + ${AUTORECONF:-autoreconf} --force --install diff --git a/storage/mroonga/vendor/groonga/base_version b/storage/mroonga/vendor/groonga/base_version index 9eefef7bd65..28cbf7c0aae 100644 --- a/storage/mroonga/vendor/groonga/base_version +++ b/storage/mroonga/vendor/groonga/base_version @@ -1 +1 @@ -4.0.6 \ No newline at end of file +5.0.0 \ No newline at end of file diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c b/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c index 8e1d819538b..72d1d79b73f 100644 --- a/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c +++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c @@ -49,7 +49,7 @@ #include -#include +#include #include #include "lib/benchmark.h" diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c index b934f225330..7b57eaaffdc 100644 --- a/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c +++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c @@ -58,7 +58,7 @@ #include -#include +#include #include #include "lib/benchmark.h" diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c b/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c index 4c0b500aae2..d45d453cba6 100644 --- a/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c +++ b/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c @@ -53,7 +53,7 @@ #include #include -#include +#include #include #include "lib/benchmark.h" diff --git a/storage/mroonga/vendor/groonga/build/ac_macros/check_functions.m4 b/storage/mroonga/vendor/groonga/build/ac_macros/check_functions.m4 index 5046e8ce6ab..72e3a9a545d 100644 --- a/storage/mroonga/vendor/groonga/build/ac_macros/check_functions.m4 +++ b/storage/mroonga/vendor/groonga/build/ac_macros/check_functions.m4 @@ -1,5 +1,8 @@ # -*- autoconf -*- +AC_CHECK_FUNCS(_gmtime64_s) +AC_CHECK_FUNCS(_localtime64_s) +AC_CHECK_FUNCS(_stricmp) AC_CHECK_FUNCS(_strnicmp) AC_CHECK_FUNCS(_strtoui64) AC_CHECK_FUNCS(close) @@ -8,6 +11,8 @@ AC_CHECK_FUNCS(localtime_r) AC_CHECK_FUNCS(mkostemp) AC_CHECK_FUNCS(open) AC_CHECK_FUNCS(read) +AC_CHECK_FUNCS(strcasecmp) AC_CHECK_FUNCS(strncasecmp) AC_CHECK_FUNCS(strtoull) +AC_CHECK_FUNCS(unlink) AC_CHECK_FUNCS(write) diff --git a/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 b/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 index 513f61afac4..17de74c11a5 100644 --- a/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 +++ b/storage/mroonga/vendor/groonga/build/ac_macros/check_headers.m4 @@ -1,9 +1,11 @@ # -*- autoconf -*- +AC_CHECK_HEADERS(dirent.h) AC_CHECK_HEADERS(dlfcn.h) AC_CHECK_HEADERS(errno.h) AC_CHECK_HEADERS(execinfo.h) AC_CHECK_HEADERS(inttypes.h) +AC_CHECK_HEADERS(io.h) AC_CHECK_HEADERS(netdb.h) AC_CHECK_HEADERS(netinet/in.h) AC_CHECK_HEADERS(netinet/tcp.h) diff --git a/storage/mroonga/vendor/groonga/config.h.cmake b/storage/mroonga/vendor/groonga/config.h.cmake index d172bc36dba..e6482f070c7 100644 --- a/storage/mroonga/vendor/groonga/config.h.cmake +++ b/storage/mroonga/vendor/groonga/config.h.cmake @@ -83,8 +83,7 @@ #cmakedefine GRN_WITH_BENCHMARK #cmakedefine GRN_WITH_CUTTER #cmakedefine GRN_WITH_KYTEA -#cmakedefine GRN_WITH_LIBMEMCACHED -#cmakedefine GRN_WITH_LZO +#cmakedefine GRN_WITH_LZ4 #cmakedefine GRN_WITH_MECAB #cmakedefine GRN_WITH_MESSAGE_PACK #cmakedefine GRN_WITH_MRUBY @@ -93,10 +92,12 @@ #cmakedefine GRN_WITH_ZLIB /* headers */ +#cmakedefine HAVE_DIRENT_H #cmakedefine HAVE_DLFCN_H #cmakedefine HAVE_ERRNO_H #cmakedefine HAVE_EXECINFO_H #cmakedefine HAVE_INTTYPES_H +#cmakedefine HAVE_IO_H #cmakedefine HAVE_LINUX_FUTEX_H #cmakedefine HAVE_MEMORY_H #cmakedefine HAVE_NETDB_H @@ -133,6 +134,9 @@ #cmakedefine HAVE_MECAB_DICTIONARY_INFO_T /* functions */ +#cmakedefine HAVE__GMTIME64_S +#cmakedefine HAVE__LOCALTIME64_S +#cmakedefine HAVE__STRICMP #cmakedefine HAVE__STRNICMP #cmakedefine HAVE__STRTOUI64 #cmakedefine HAVE_BACKTRACE @@ -145,8 +149,10 @@ #cmakedefine HAVE_MKOSTEMP #cmakedefine HAVE_OPEN #cmakedefine HAVE_READ +#cmakedefine HAVE_STRCASECMP #cmakedefine HAVE_STRNCASECMP #cmakedefine HAVE_STRTOULL +#cmakedefine HAVE_UNLINK #cmakedefine HAVE_WRITE #cmakedefine HAVE_PTHREAD_MUTEXATTR_SETPSHARED #cmakedefine HAVE_PTHREAD_CONDATTR_SETPSHARED diff --git a/storage/mroonga/vendor/groonga/config.sh.in b/storage/mroonga/vendor/groonga/config.sh.in index b4cec3caba1..d15e5e366e7 100644 --- a/storage/mroonga/vendor/groonga/config.sh.in +++ b/storage/mroonga/vendor/groonga/config.sh.in @@ -4,3 +4,4 @@ export GROONGA="@GROONGA@" export GROONGA_HTTPD="@GROONGA_HTTPD@" export GROONGA_SUGGEST_CREATE_DATASET="@GROONGA_SUGGEST_CREATE_DATASET@" export GROONGA_BENCHMARK="@GROONGA_BENCHMARK@" +export GROONGA_MRUBY="@GROONGA_MRUBY@" diff --git a/storage/mroonga/vendor/groonga/configure.ac b/storage/mroonga/vendor/groonga/configure.ac index 2be82a165e2..1d74bac30f4 100644 --- a/storage/mroonga/vendor/groonga/configure.ac +++ b/storage/mroonga/vendor/groonga/configure.ac @@ -75,7 +75,8 @@ AC_MSG_RESULT([$solaris]) AC_C_BIGENDIAN AC_PROG_CXX AC_PROG_CC -AC_PROG_CC_C99 +m4_ifdef([AC_PROG_CC_C99], + [AC_PROG_CC_C99]) AM_PROG_CC_C_O m4_ifdef([PKG_PROG_PKG_CONFIG], [PKG_PROG_PKG_CONFIG([0.19]) @@ -160,7 +161,6 @@ if test "$GCC" = "yes"; then CHECK_BUILD_FLAG([-Wdisabled-optimization]) CHECK_BUILD_FLAG([-Wfloat-equal]) CHECK_BUILD_FLAG([-Wpointer-arith]) - CHECK_CFLAG([-Wdeclaration-after-statement]) CHECK_CFLAG([-Wbad-function-cast]) if test "$CLANG" = "no"; then CHECK_BUILD_FLAG([-Wcast-align]) @@ -235,6 +235,7 @@ AC_CONFIG_FILES([ plugins/query_expanders/Makefile plugins/ruby/Makefile plugins/token_filters/Makefile + plugins/sharding/Makefile examples/Makefile examples/dictionary/Makefile examples/dictionary/edict/Makefile @@ -246,7 +247,6 @@ AC_CONFIG_FILES([ packages/ubuntu/Makefile packages/rpm/Makefile packages/rpm/centos/Makefile - packages/rpm/fedora/Makefile packages/yum/Makefile packages/source/Makefile packages/windows/Makefile @@ -684,6 +684,10 @@ AC_SUBST(GROONGA_BENCHMARK) GROONGA_SUGGEST_CREATE_DATASET="${ac_pwd}/src/suggest/groonga-suggest-create-dataset" AC_SUBST(GROONGA_SUGGEST_CREATE_DATASET) +# groonga-mruby binary path +GROONGA_MRUBY="${ac_pwd}/src/groonga-mruby" +AC_SUBST(GROONGA_MRUBY) + # check Cutter with GLib support if available REQUIRED_MINIMUM_CUTTER_VERSION=1.1.6 REQUIRED_MINIMUM_CPPCUTTER_VERSION=1.2.0 @@ -867,28 +871,64 @@ fi # zlib AC_ARG_WITH(zlib, [AS_HELP_STRING([--with-zlib], - [use zlib for data compression. [default=no]])], + [Support data compression by zlib. [default=auto]])], [with_zlib="$withval"], - [with_zlib="no"]) + [with_zlib="auto"]) GRN_WITH_ZLIB=no -if test "x$with_zlib" = "xyes"; then - AC_DEFINE(GRN_WITH_ZLIB, [1], [with zlib]) - AC_SEARCH_LIBS(compress, z, [GRN_WITH_ZLIB=yes], - [AC_MSG_ERROR("No libz found")]) -else - AC_SEARCH_LIBS(compress, z, [GRN_WITH_ZLIB=yes], []) +if test "x$with_zlib" != "xno"; then + # TODO: Support custom zlib include and lib directory by --with-zlib. + AC_SEARCH_LIBS(compress, z, + [ + GRN_WITH_ZLIB=yes + AC_DEFINE(GRN_WITH_ZLIB, [1], + [Support data compression by zlib.]) + ], + [ + if test "x$with_zlib" != "xauto"; then + AC_MSG_ERROR("No libz found") + fi + ]) fi AC_SUBST(GRN_WITH_ZLIB) -# LZO -AC_ARG_WITH(lzo, - [AS_HELP_STRING([--with-lzo], - [use LZO for data compression. [default=no]])], - [with_lzo="$withval"], - [with_lzo="no"]) -if test "x$with_lzo" = "xyes"; then - AC_DEFINE(GRN_WITH_LZO, [1], [with lzo]) - AC_SEARCH_LIBS(lzo1_compress, lzo2, [], [AC_MSG_ERROR("No liblzo2 found")]) +# LZ4 +AC_ARG_WITH(lz4, + [AS_HELP_STRING([--with-lz4], + [Support data compression by LZ4. [default=auto]])], + [with_lz4="$withval"], + [with_lz4="auto"]) +if test "x$with_lz4" != "xno"; then + m4_ifdef([PKG_CHECK_MODULES], [ + PKG_CHECK_MODULES([LIBLZ4], + [liblz4], + [GRN_WITH_LZ4=yes], + [GRN_WITH_LZ4=no]) + ], + [GRN_WITH_LZ4=no]) + if test "$GRN_WITH_LZ4" = "yes"; then + AC_DEFINE(GRN_WITH_LZ4, [1], + [Support data compression by LZ4.]) + else + if test "x$with_lz4" != "xauto"; then + AC_MSG_ERROR("No liblz4 found") + fi + fi +fi + +# jemalloc +AC_ARG_WITH(jemalloc, + [AS_HELP_STRING([--with-jemalloc], + [Use jemalloc for memory allocation. [default=no]])], + [with_jemalloc="$withval"], + [with_jemalloc="no"]) +jemalloc_available="no" +if test "x$with_jemalloc" != "xno"; then + if test "x$with_jemalloc" != "xyes"; then + LDFLAGS="-L$with_jemalloc $LDFLAGS" + fi + AC_SEARCH_LIBS(malloc_conf, jemalloc, + [jemalloc_available="yes"], + [AC_MSG_ERROR("No libjemalloc found")]) fi # MeCab @@ -973,6 +1013,63 @@ if test "x$with_kytea" = "xyes"; then fi AM_CONDITIONAL(WITH_KYTEA, test "x$with_kytea" = "xyes") +# libstemmer +AC_ARG_WITH(libstemmer, + [AS_HELP_STRING([--with-libstemmer], + [use libstemmer for stemming. [default=auto]])], + [with_libstemmer="$withval"], + [with_libstemmer="auto"]) +AC_ARG_WITH(libstemmer-include, + [AS_HELP_STRING([--with-libstemmer-include], + [path to libstemmer.h. [default=auto]])]) +AC_ARG_WITH(libstemmer-lib, + [AS_HELP_STRING([--with-libstemmer-lib], + [path to libstemmer.so. [default=auto]])]) +AC_MSG_CHECKING([whether enable libstemmer]) +AC_MSG_RESULT($with_libstemmer) +if test "x$with_libstemmer" != "xno"; then + LIBSTEMMER_CFLAGS="" + LIBSTEMMER_LDFLAGS="" + LIBSTEMMER_LIBS="" + + CFLAGS_save="${CFLAGS}" + LDFLAGS_save="${LDFLAGS}" + if test "x$with_libstemmer" != "xauto"; then + if test -z "${with_libstemmer_include}"; then + with_libstemmer_include="${with_libstemmer}/include" + fi + LIBSTEMMER_CFLAGS="-I${with_libstemmer_include}" + if test -z "${with_libstemmer_lib}"; then + with_libstemmer_lib="${with_libstemmer}/lib" + fi + LIBSTEMMER_LDFLAGS="-L${with_libstemmer_lib}" + CFLAGS="${CFLAGS} ${LIBSTEMMER_CFLAGS}" + LDFLAGS="${LDFLAGS} ${LIBSTEMMER_LDFLAGS}" + fi + AC_CHECK_HEADERS(libstemmer.h, + [libstemmer_exists=yes], + [libstemmer_exists=no]) + if test "$libstemmer_exists" = "yes"; then + AC_CHECK_LIB(stemmer, sb_stemmer_list, + [LIBSTEMMER_LIBS="-lstemmer"], + [libstemmer_exists=no]) + fi + CFLAGS="${CFLAGS_save}" + LDFLAGS="${LDFLAGS_save}" + + if test "$libstemmer_exists" = "no" -a "x$with_libstemmer" != "xauto"; then + AC_MSG_ERROR("No libstemmer found at ${with_libstemmer_include} and ${with_libstemmer_lib}.") + fi + with_libstemmer="$libstemmer_exists" +fi +if test "x$with_libstemmer" = "xyes"; then + AC_SUBST(LIBSTEMMER_CFLAGS) + AC_SUBST(LIBSTEMMER_LDFLAGS) + AC_SUBST(LIBSTEMMER_LIBS) + AC_DEFINE(GRN_WITH_LIBSTEMMER, [1], [use libstemmer]) +fi +AM_CONDITIONAL(WITH_LIBSTEMMER, test "x$with_libstemmer" = "xyes") + # futex check AC_ARG_ENABLE(futex, [AS_HELP_STRING([--enable-futex], @@ -1136,15 +1233,15 @@ Install it and try again. How to install sphinx-build: For Debian GNU/Linux based system like Ubuntu: - % sudo apt-get install -y python-pip - % sudo pip install sphinx + % sudo apt-get install -y python-sphinx For Red Hat based system like CentOS: % sudo yum install -y python-pip % sudo pip install sphinx For OS X with Homebrew: - % brew install pip + % brew install python + % brew install gettext % export PATH="`brew --prefix gettext`/bin:\$PATH" % pip install sphinx]) fi @@ -1247,6 +1344,9 @@ AC_SUBST(ruby_pluginsdir) token_filter_pluginsdir="\${pluginsdir}/token_filters" AC_SUBST(token_filter_pluginsdir) +sharding_pluginsdir="\${pluginsdir}/sharding" +AC_SUBST(sharding_pluginsdir) + AC_MSG_CHECKING(for the suffix of plugin shared libraries) shrext_cmds=$(./libtool --config | grep '^shrext_cmds=') eval $shrext_cmds @@ -1361,15 +1461,10 @@ if test "$enable_mruby" = "yes"; then fi AC_DEFINE(GRN_WITH_MRUBY, [1], [Define to 1 if mruby is enabled.]) MRUBY_CFLAGS="-I\$(top_srcdir)/vendor/mruby-source/include" - MRUBY_LIBS="\$(top_builddir)/vendor/mruby/libmruby.la" - MRUBY_LIBS="${MRUBY_LIBS} \$(top_builddir)/vendor/onigmo-source/libonig.la" - AC_CONFIG_SUBDIRS([vendor/onigmo]) else - MRUBY_CFLAGS= - MRUBY_LIBS= + MRUBY_CFLAGS="" fi AC_SUBST(MRUBY_CFLAGS) -AC_SUBST(MRUBY_LIBS) AM_CONDITIONAL(WITH_MRUBY, test "$enable_mruby" = "yes") # This option is used in vendor/onigmo/configure @@ -1380,12 +1475,20 @@ AC_ARG_ENABLE(shared-onigmo, [enable_shared_onigmo="no"]) AM_CONDITIONAL(WITH_SHARED_ONIGMO, test "$enable_shared_onigmo" = "yes") +AC_DEFINE(GRN_WITH_ONIGMO, [1], [Use Onigmo.]) +AC_CONFIG_SUBDIRS([vendor/onigmo]) + +ONIGMO_CFLAGS="-I\$(top_srcdir)/vendor/onigmo-source" +ONIGMO_LIBS="\$(top_builddir)/vendor/onigmo-source/libonig.la" +AC_SUBST(ONIGMO_CFLAGS) +AC_SUBST(ONIGMO_LIBS) + # PCRE GRN_WITH_PCRE=no AC_ARG_WITH(pcre, [AS_HELP_STRING([--without-pcre], - [use PCRE for groonga-httpd. [default=auto-detect]])], - [with_pcre="$witheval"], + [Don't use PCRE for groonga-httpd. [default=auto-detect]])], + [with_pcre="$withval"], [with_pcre="auto"]) if test "x$with_pcre" != "xno"; then m4_ifdef([PKG_CHECK_MODULES], [ @@ -1446,7 +1549,6 @@ AC_SUBST(GROONGA_HTTPD_DEFAULT_DATABASE_PATH) AC_OUTPUT([ packages/rpm/centos/groonga.spec - packages/rpm/fedora/groonga.spec packages/apt/debian/groonga-keyring.postrm packages/apt/env.sh packages/yum/env.sh @@ -1489,6 +1591,14 @@ if test "x$with_kytea" = "xyes"; then fi echo +echo "Token filters:" +echo " libstemmer: $with_libstemmer" +if test "x$with_libstemmer" = "xyes"; then + echo " CFLAGS: $LIBSTEMMER_CFLAGS" + echo " LIBS: $LIBSTEMMER_LIBS" +fi +echo + echo "Libraries:" echo " ZeroMQ: $zeromq_available" if test "x$zeromq_available" = "xyes"; then @@ -1506,6 +1616,7 @@ if test "x$message_pack_available" = "xyes"; then echo " LIBS: ${MESSAGE_PACK_LIBS}" fi echo " mruby: $enable_mruby" +echo " jemalloc: $jemalloc_available" echo echo "groonga-httpd:" diff --git a/storage/mroonga/vendor/groonga/examples/Makefile.am b/storage/mroonga/vendor/groonga/examples/Makefile.am new file mode 100644 index 00000000000..f436342d053 --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = dictionary diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/Makefile.am b/storage/mroonga/vendor/groonga/examples/dictionary/Makefile.am new file mode 100644 index 00000000000..ee618a213bd --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/dictionary/Makefile.am @@ -0,0 +1,34 @@ +SUBDIRS = \ + edict \ + eijiro \ + gene95 \ + jmdict + +dist_examples_dictionary_SCRIPTS = \ + init-db.sh + +nobase_dist_examples_dictionary_DATA = \ + readme.txt \ + $(html_files) + +# find html -type f | sort | sed -e 's,^,\t,g' +html_files = \ + html/css/dictionary.css \ + html/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png \ + html/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png \ + html/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png \ + html/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png \ + html/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png \ + html/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png \ + html/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png \ + html/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png \ + html/css/smoothness/images/ui-icons_222222_256x240.png \ + html/css/smoothness/images/ui-icons_2e83ff_256x240.png \ + html/css/smoothness/images/ui-icons_454545_256x240.png \ + html/css/smoothness/images/ui-icons_888888_256x240.png \ + html/css/smoothness/images/ui-icons_cd0a0a_256x240.png \ + html/css/smoothness/jquery-ui-1.8.12.custom.css \ + html/index.html \ + html/js/dictionary.js \ + html/js/jquery-1.7.2.js \ + html/js/jquery-ui-1.8.18.custom.js diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/edict/Makefile.am b/storage/mroonga/vendor/groonga/examples/dictionary/edict/Makefile.am new file mode 100644 index 00000000000..376f9d520ab --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/dictionary/edict/Makefile.am @@ -0,0 +1,4 @@ +edictdir = $(examples_dictionarydir)/edict +dist_edict_SCRIPTS = \ + edict2grn.rb \ + edict-import.sh diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict-import.sh b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict-import.sh new file mode 100755 index 00000000000..b98397be05a --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict-import.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +base_dir=$(dirname $0) + +if [ 1 != $# -a 2 != $# ]; then + echo "usage: $0 db_path [edict.gz_path]" + exit 1 +fi + +if [ -z $2 ]; then + edict_gz=edict.gz + if [ ! -f $edict_gz ]; then + wget -O $edict_gz http://ftp.monash.edu.au/pub/nihongo/edict.gz + fi +else + edict_gz=$2 +fi + +if zcat $edict_gz | ${base_dir}/edict2grn.rb | groonga $1 > /dev/null; then + echo "edict data loaded." +fi diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb new file mode 100755 index 00000000000..664b12c2148 --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/dictionary/edict/edict2grn.rb @@ -0,0 +1,56 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +$KCODE = 'u' + +require 'English' +require 'kconv' + +class String + def to_json + a = split(//).map {|char| + case char + when '"' then '\\"' + when '\\' then '\\\\' + when "\b" then '\b' + when "\f" then '\f' + when "\n" then '\n' + when "\r" then '' + when "\t" then '\t' + else char + end + } + "\"#{a.join('')}\"" + end +end + +class Array + def to_json + '[' + map {|element| + element.to_json + }.join(',') + ']' + end +end + +puts < /dev/null; then + echo "eijiro data loaded." +fi diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/eijiro/eijiro2grn.rb b/storage/mroonga/vendor/groonga/examples/dictionary/eijiro/eijiro2grn.rb new file mode 100755 index 00000000000..62c1e1309bf --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/dictionary/eijiro/eijiro2grn.rb @@ -0,0 +1,61 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +$KCODE = 'u' + +require 'rubygems' +require 'fastercsv' + +class String + def to_json + a = split(//).map {|char| + case char + when '"' then '\\"' + when '\\' then '\\\\' + when "\b" then '\b' + when "\f" then '\f' + when "\n" then '\n' + when "\r" then '' + when "\t" then '\t' + else char + end + } + "\"#{a.join('')}\"" + end +end + +class Array + def to_json + '[' + map {|element| + element.to_json + }.join(',') + ']' + end +end + +puts < "\r\n").each {|l| + if n > 0 + keyword,word,trans,exp,level,memory,modify,pron,filelink = l + kana = '' + if trans =~ /【@】(.*?)(【|$)/ + kana = $1.split("、") + end + puts [word,keyword,trans,exp,level,memory,modify,pron,filelink,kana].map{|e| e || ''}.to_json + end + n += 1 +} + +puts "]" diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/gene95/Makefile.am b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/Makefile.am new file mode 100644 index 00000000000..e89f13f595c --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/Makefile.am @@ -0,0 +1,4 @@ +gene95dir = $(examples_dictionarydir)/gene95 +dist_gene95_SCRIPTS = \ + gene2grn.rb \ + gene-import.sh diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene-import.sh b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene-import.sh new file mode 100755 index 00000000000..488d6c83adc --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene-import.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +base_dir=$(dirname $0) + +if [ 1 != $# -a 2 != $# ]; then + echo "usage: $0 db_path [gene.txt_path]" + exit 1 +fi + +if [ -z $2 ]; then + dictionary_dir=gene95-dictionary + gene_txt=${dictionary_dir}/gene.txt + if [ ! -f $gene_txt ]; then + gene95_tar_gz=gene95.tar.gz + wget -O $gene95_tar_gz \ + http://www.namazu.org/~tsuchiya/sdic/data/gene95.tar.gz + mkdir -p ${dictionary_dir} + tar xvzf ${gene95_tar_gz} -C ${dictionary_dir} + fi +else + gene_txt=$2 +fi + +if cat $gene_txt | ${base_dir}/gene2grn.rb | groonga $1 > /dev/null; then + echo "gene95 data loaded." +fi diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb new file mode 100755 index 00000000000..0d10cfd1085 --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/dictionary/gene95/gene2grn.rb @@ -0,0 +1,46 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +$KCODE = 'u' + +require 'kconv' + +class String + def to_json + a = split(//).map {|char| + case char + when '"' then '\\"' + when '\\' then '\\\\' + when "\b" then '\b' + when "\f" then '\f' + when "\n" then '\n' + when "\r" then '' + when "\t" then '\t' + else char + end + } + "\"#{a.join('')}\"" + end +end + +class Array + def to_json + '[' + map {|element| + element.to_json + }.join(',') + ']' + end +end + +puts <N1x91EQ4=4yQ7#`R^ z$vje}bP0l+XkK DSH>_4 literal 0 HcmV?d00001 diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..ac8b229af950c29356abf64a6c4aa894575445f0 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsY*{5$B>N1x91EQ4=4yQYz+E8 zPo9&<{J;c_6SHRil>2s{Zw^OT)6@jj2u|u!(plXsM>LJD`vD!n;OXk;vd$@?2>^GI BH@yG= literal 0 HcmV?d00001 diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..ad3d6346e00f246102f72f2e026ed0491988b394 GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnour0hLi978O6-<~(*I$*%ybaDOn z{W;e!B}_MSUQoPXhYd^Y6RUoS1yepnPx`2Kz)7OXQG!!=-jY=F+d2OOy?#DnJ32>z UEim$g7SJdLPgg&ebxsLQ09~*s;{X5v literal 0 HcmV?d00001 diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..42ccba269b6e91bef12ad0fa18be651b5ef0ee68 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouqzpV=978O6-=0?FV^9z|eBtf= z|7WztIJ;WT>{+tN>ySr~=F{k$>;_x^_y?afmf9pRKH0)6?eSP?3s5hEr>mdKI;Vst E0O;M1& literal 0 HcmV?d00001 diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..5a46b47cb16631068aee9e0bd61269fc4e95e5cd GIT binary patch literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouq|7{B978O6lPf+wIa#m9#>Unb zm^4K~wN3Zq+uP{vDV26o)#~38k_!`W=^oo1w6ixmPC4R1b Tyd6G3lNdZ*{an^LB{Ts5`idse literal 0 HcmV?d00001 diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 0000000000000000000000000000000000000000..7c9fa6c6edcfcdd3e5b77e6f547b719e6fc66e30 GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^j6j^i!3HGVb)pi0l#Zv1V~E7mPmYTG^FX}c% zlGE{DS1Q;~I7-6ze&TN@+F-xsI6sd%SwK#*O5K|pDRZqEy< zJg0Nd8F@!OxqElm`~U#piM22@u@8B<moyKE%ct`B(jysxK+1m?G)UyIFs1t0}L zemGR&?jGaM1YQblj?v&@0iXS#fi-VbR9zLEnHLP?xQ|=%Ihrc7^yPWR!tW$yH!zrw z#I2}_!JnT^(qk)VgJr`NGdPtT^dmQIZc%=6nTAyJDXk+^3}wUOilJuwq>s=T_!9V) zr1)DT6VQ2~rgd@!Jlrte3}}m~j}juCS`J4(d-5+e-3@EzzTJNCE2z)w(kJ90z*QE) zBtnV@4mM>jTrZZ*$01SnGov0&=A-JrX5Ge%Pce1Vj}=5YQqBD^W@n4KmFxxpFK`uH zP;(xKV+6VJ2|g+?_Lct7`uElL<&jzGS8Gfva2+=8A@#V+xsAj9|Dkg)vL5yhX@~B= zN2KZSAUD%QH`x>H+@Ou(D1~Pyv#0nc&$!1kI?IO01yw3jD0@80qvc?T*Nr8?-%rC8 z@5$|WY?Hqp`ixmEkzeJTz_`_wsSRi1%Zivd`#+T{Aib6-rf$}M8sz6v zb6ERbr-SniO2wbOv!M4)nb}6UVzoVZEh5kQWh_5x4rYy3c!871NeaM(_p=4(kbS6U#x<*k8Wg^KHs2ttCz<+pBxQ$Z zQMv;kVm5_fF_vH`Mzrq$Y&6u?j6~ftIV0Yg)Nw7JysIN_ z-_n*K_v1c&D}-1{NbBwS2h#m1y0a5RiEcYil+58$8IDh49bPnzE7R8In6P%V{2IZU z7#clr=V4yyrRe@oXNqbqo^^LvlLE?%8XaI&N(Np90-psU}7kqmbWk zZ;YBwJNnNs$~d!mx9oMGyT( znaBoj0d}gpQ^aRr?6nW)$4god*`@Uh2e+YpS@0(Mw{|z|6ko3NbTvDiCu3YO+)egL z>uW(^ahKFj>iJ-JF!^KhKQyPTznJa;xyHYwxJgr16&Wid_9)-%*mEwo{B_|M9t@S1 zf@T@q?b2Qgl!~_(Roe;fdK)y|XG0;ls;ZbT)w-aOVttk#daQcY7$cpY496H*`m@+L zeP#$&yRbBjFWv}B)|5-1v=(66M_;V1SWv6MHnO}}1=vby&9l+gaP?|pXwp0AFDe#L z&MRJ^*qX6wgxhA_`*o=LGZ>G_NTX%AKHPz4bO^R72ZYK}ale3lffDgM8H!Wrw{B7A z{?c_|dh2J*y8b04c37OmqUw;#;G<* z@nz@dV`;7&^$)e!B}cd5tl0{g(Q>5_7H^@bEJi7;fQ4B$NGZerH#Ae1#8WDTH`iB&) zC6Et3BYY#mcJxh&)b2C^{aLq~psFN)Q1SucCaBaBUr%5PYX{~-q{KGEh)*;n;?75k z=hq%i^I}rd;z-#YyI`8-OfMpWz5kgJE3I!3ean6=UZi!BxG7i(YBk? z02HM7wS0)Wni{dWbQMRtd-A)_Az!t>F;IwWf~!*)-Az4}yryNkz&9)w>ElA80Oc`6 zHo#9H!Y3*Qx9n@Jn)!w6G^hb;e_n8zpIyXCN`JFkPc)^Q?2MsLNFhMgrcZI-<#1ne zjH;KFf?4eAT9mQZ}ZfHLGA#d%s;SZK4p0FwZT2S^{ zQ2BG1xJsbK6?yrHTjJi|5C0u=!|r!?*4FL%y%3q#(d+e>b_2I9!*iI!30}42Ia0bq zUf`Z?LGSEvtz8s``Tg5o_CP(FbR0X$FlE0yCnB7suDPmI2=yOg^*2#cY9o`X z;NY-3VBHZjnVcGS){GZ98{e+lq~O$u6pEcgd0CrnIsWffN1MbCZDH<7c^hv+Z0Ucf0{w zSzi^qKuUHD9Dgp0EAGg@@$zr32dQx>N=ws`MESEsmzgT2&L;?MSTo&ky&!-JR3g~1 zPGTt515X)wr+Bx(G9lWd;@Y3^Vl}50Wb&6-Tiy;HPS0drF`rC}qYq22K4)G#AoD0X zYw$E+Bz@Zr^50MAwu@$?%f9$r4WHH?*2|67&FXFhXBrVFGmg)6?h3^-1?t;UzH0*I zNVf9wQLNLnG2@q>6CGm>&y|lC`iCFfYd}9i%+xkl^5oBJ?<;aneCfcHqJh7Yl5uLS z9Fx-(kMdcNyZejXh22N{mCw_rX1O!cOE&3>e(ZH81PR95wQC37En4O{w;{3q9n1t&;p)D%&Z%Nw$gSPa!nz8Slh7=ko2am)XARwOWw zpsz0~K!s{(dM$NB=(A=kkp>T(*yU6<_dwIx>cH4+LWl282hXa6-EUq>R3t?G2623< z*RwTN%-fgBmD{fu*ejNn)1@KG?Sg*8z3hYtkQJQjB6 zQ|x>wA=o$=O)+nLmgTXW3_6diA;b4EY{*i*R%6dO2EMg z@6g?M3rpbnfB@hOdUeb96=~I?OIA3@BWAGmTwiQ{x5Cqq<8c10L!P zd@Qk^BseTX%$Q7^s}5n%HB|)gKx}H$d8Sb$bBnq9-AglT2dGR2(+I;_fL|R4p$odJ zllfb0NqI)7=^z~qAm1V{(PkpxXsQ#4*NH9yYZ`Vf@)?#ueGgtCmGGY|9U#v|hRdg- zQ%0#cGIfXCd{Y)JB~qykO;KPvHu|5Ck&(Hn%DF~cct@}j+87xhs2ew;fLm5#2+mb| z8{9e*YI(u|gt|{x1G+U=DA3y)9s2w7@cvQ($ZJIA)x$e~5_3LKFV~ASci8W}jF&VeJoPDUy(BB>ExJpck;%;!`0AAo zAcHgcnT8%OX&UW_n|%{2B|<6Wp2MMGvd5`T2KKv;ltt_~H+w00x6+SlAD`{K4!9zx z*1?EpQ%Lwiik){3n{-+YNrT;fH_niD_Ng9|58@m8RsKFVF!6pk@qxa{BH-&8tsim0 zdAQ(GyC^9ane7_KW*#^vMIoeQdpJqmPp%%px3GIftbwESu#+vPyI*YTuJ6+4`z{s? zpkv~0x4c_PFH`-tqafw5)>4AuQ78SkZ!$8}INLK;Egr;2tS18hEO5=t;QDmZ-qu?I zG+=DN`nR72Xto{{bJp||`k}-2G;5#xg8E~xgz22)^_Z;=K|4@(E&5J)SY2of=olcw z5)@L)_Ntcm!*5nEy0M9v0`S33;pO4TN;>4(Z+19p_0>u#e-vE zXCU(6gAvu~I7Cw(xd%0e59MNLw^U37ZDbsBrj%eDCexw8a3G`nTcXVNL6{B7Hj@i& zbVB{;ApEtHk76q08DJ48dSxd$C(;$K6=FpU<~l9pVoT9arW^Vu{%Bcn4`eIpkOVC| z$)AKYG_`ypM{0@BUb3^9lqi_c?ONH|4UJMJWDowMVjacycX7}9g={O7swOB+{;+?; zjBo!9?+nd)ie#x5IbFW-zBOo0c4q@9wGVt5;pNt`=-~Zgcw#*`m($6ibxtZ`H=e=} zF#GZ~5$%AUn};8U#tRem0J(JTR}d4vR(dgK2ML~lZsPhayJ2h1%sD4FVst| zKF)+@`iNzLRjg4=K8@**0=5cE>%?FDc({I^+g9USk<8$&^qD~@%W0i4b|yMG*p4`N zh}I!ltTRI8Ex$+@V{02Br%xq#O?UlhO{r8WsaZnZCZq0MK9%AXU%MDLT;3=0A9(BV z9VxxxJd7jo$hw3q;3o?yBLmA=azBUrd9>-<_ANs0n3?-Ic*6&ytb@H~?0E(*d>T5n z-HiH2jsDf6uWhID%#n>SzOqrFCPDfUcu5QPd?<(=w6pv1BE#nsxS{n!UnC9qAha1< z;3cpZ9A-e$+Y)%b;w@!!YRA9p%Kf9IHGGg^{+p`mh;q8i7}&e@V3EQaMsItEMS&=X plT@$;k0WcB_jb;cn%_Idz4HO$QU*abf4}+wi?e96N>fbq{{i|W0@(ln literal 0 HcmV?d00001 diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_2e83ff_256x240.png b/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..09d1cdc856c292c4ab6dd818c7543ac0828bd616 GIT binary patch literal 4369 zcmd^?`8O2)_s3@pGmLE*`#M>&Z`mr_kcu#tBo!IbqU=l7VaSrbQrTh%5m}S08Obh0 zGL{*mi8RK}U~J#s@6Y%1S9~7lb?$xLU+y{go_o*h`AW1wUF3v{Kmh;%r@5J_9RL9Q zdj+hqg8o{9`K7(TZrR4t{=9O`!T-(~c=yEWZ{eswJJe->5bP8)t4;f(Y*i_HU*sLM z2=7-8guZ}@*(HhVC)Mqgr$3T8?#a(hu& z?Kzuw!O%PM>AicSW`_U(cbvJYv3{HfpIP~Q>@$^c588E$vv)V2c|Mr% zuFO$+I~Hg@u}wPm17n%}j1Y+Pbu!bt?iPkjGAo7>9eRN0FZz3X2_QZj+V!}+*8oBQ z_=iI^_TCA;Ea2tPmRNOeX3+VM>KL;o1(h`c@`6Ah`vdH<&+$yTg)jGWW72T}6J`kUAv?2CgyV zrs0y@Fpvpj@kWVE0TzL@Cy#qHn~kgensb{hIm6J&I8hkoNHOz6o1QQ3QM4NZyu?;= zLd>`wPT*uGr+6vAxYv3k8{gMDR>tO}UavDKzzyi6hvbuP=XQ4Y|A)r4#B$U(q7{1Z z0iLeSjo3;T*diS*me%4|!s23l@>R}rn@#Zc{<%CFt;?gd5S<)b=8Yz32U zBBLprntW3RE3f|uNX5Aw|I(IlJjW-Byd?QFFRk%hLU}O*YyYQel}WcXilLMJp9cB4 z)E?D+*Y4zai&XY!>niMfTW-2pp-^KFT93%Leig@uoQGPYRCva-`w#orm`is`p8b4s zxD462;f*^XO$=3by=VzN9i@xxr<1w=pcxl!$!fjWt|fYmq1@@badT?v`d zIi$|e$Ji}FXsiVYf)?pN1R0LBw;+)B5aUJj2fP+=m;=_Eho84g%Jq#@MLPSQEX*@T z6sZb)m?)zby>{j1)(;rRML|gKSs+9jorf-XhQJ2Jyt5Cqc*`S3iX@A5C3jvgAns|4 z*|)YQ%Kmsj+YZ53;nMqh|AFvehUV-9R;1ZZ;w5r9l}8hjSw@#k;>)$P*r%)=Extyu zB!$Kd-F?*50aJ2;TNTR-fc8B{KAq3!vW{g$LlGPfGW+%#CXU zJDcMsvyT2`x~v>>w8@yssoA`KuIZ98CLU{Ia%*nW3G4t}@ApsbC@o^WCqL>OXx>Y^ zSuVWEQ;3=A=@RxCnt0>G@#(VWBQ`0$qTwA#e>SX{_N~JWGsBxFHCw|5|?CzDi>92F-^=b*8sMXnhUJdb!>yGD2nhN@{582 zRPcxuDzs&;8De)>_J19z{0xppXQop#T_5ejGCKv@l>$O#DA-@X{y_1B-AsiU)H}DR z3xDZ8G`amV_WmA&8!W=@jgm|%bnwH%qkg(@J$hLaSV zC-rXIFMM%y<|Gb)o?j zpe-`dJ*N5tC-iH)d0CgLdBsw*C!ST9hY1EkI|Y(&=p&dH&q;a&7HXa5#_wtMsenQL zcpyhwx)Ppw@XmVz?P)DI#^ee1oC!i`>>Jq1ESk-OuQ(Pbv=s{A0AjM@rw#FaU;RUh z*At0{U*NtGVY_-JcuG$?zuuf%ZBTWxKU2yf?iN#-MRWs>A*2;p0G1Tp3d29u5RbnY zDOON-G|PidOOGeybnbzu7UVv71l!b=w7eU5l*{EdKuoKu`#LZ}|fnUr-+lSST9(MTT`0tqOG z#+Q_=lXe-=;rE4u8s~;%i~~ z8v&&+VPeXG=2zw9B5sR$e?R(n%nf?p-(BCZ8}x!_-9T+LT;2=Zu?Wv)j3#>35$6dR z4*7xmI)#06qjh#sXvX(%`#D1mD8fn1G~I;l%Dk{pw)}>_{+3^Fv_q)>2#de5qGCId zPz?ix-3954nM&u@vaw{o%-#HU%_bLJMO#@enR^&B{3ihWdoU6%pBJ`o>im+b-c6r-;c{vd0Z_)`75$jApy2?!9G4_FGa)iZ~9`6VELiYM+n!-mUfvfm{jt zC?!1=%pxJhF>vyQ47Q}R;O48pxgMs)rz$SbM&jkp<6X$r4DHWg>ZnGB-$r2o1*nL# zW0^*itcRY_^Uv^XgQP>W#>KQgM~l{;S(GkVW@&vld^AhWzG^m|9#0#USbM>^en{k2 za8~DTL`(Q~=ofsL&Fc`!L6r~qTnnGo8r98<(aG*<0%aNEr!!BIyY>VV82kxhR%d>V(lN&#BId#urK_i~Pe6?>C~J!pU_lRon#&S_cXoQv;poG8FK4atc

N)npz1~X%p6x{M(Gw!!H=!}lmO0Xr*8ewyH(Q+>oy`fxQkxJ zzzB$)%*xM4s_2(O>)T-QXhwP|&DZam#{O+47q|WKfz_ZL-MypRN~o{fE*I#6@eM?I zs%f-6{Lz6j7rB#U$%O$~TIT!j?|Ip1CpSmb=JA9qCY3-mQf|fVCxswPjok|VofUEP zW5^pTd5B;wRkyW%1a;nYHB$ef6Pv8^);`m0jv6p72iNJl+sVBqZugsq6cq_pyNREi z>GN!h6ZQ6`aOMr_2KI@j=XR@$aJj(2jcpY?>f=2kMV@di5W7Swj?ug10zRe}F1nR* ztMm6+T^)LJe^SzGgSxahQajq0h7#|8oMV0>D~*N}jl?9_X`ka42R4@rryDc3o(c$R?1*!1O9zleSOczw zYPS3~xbJ$~C(3+D7Zkrfjs_lneY^zv^kHmxt)aqZ!aeGABHZ`gvA&K`72z}ihI$Ht z9V&)wQy0g@R9irwbf!{uE&_J2l9jXz^Vj#=qA77*3Pd9OjrE_tKDHADd!AjFQv(ji zct-BMUt9()1Ox!dsI_h1(^F_U)_QJrx|%+y`zWWlD4=Nd?JQ=URh0*{fb1!o4tS(H z^r_T(8t1SAHf1oduG+X^*EC_kL(!QnXL6Hp);449yO&1xE>MXGqT)t10lzvALllX;;Q)RiJX$dm zlR8ep5-GdHmRm9?N#QCjNUA);vC03Gw6yds6^?c4;(MH>;O5xmQ2nGK3Dmk8i*v5t z-{jJsQq30%z}0`g7SN-yN`l-`@6rkJ|V|>18`MV zwUeH}DxWw&h+A+Dn|4|YNr&EfKS`Hz_NkeW3*sI5Rq-J&FzG=!{-K`n65#7O%^&f> z`PkqxyC_K)>781~7H${^Nj{`>XEa&OPqqQhySR5%w2{5+sEakXXHazJp6~LP2QKDx zpkvZrkDOa+A4BbqqX6ls&O)5-Q7`qkZ_?6~c-wQ9tseNtET;nhEOL^`*naKwcMX;R zbto&a;oTR0s;vjfj3wigUg)Sj)!OHQfZoJwAsWYI1A4ntz>X=W4s|y?tUk1r=>#Ct zf+?hq^>rQ3$KNboG$UhCdEmp{qAR13DK$f0ES7kAG~7q+g!jfVq`1b5+c62N^0%~o zKw91o@Wv;0EW*7fINAX3O~L-V{`;xB0q()#^HKZOlLrXVL*Dtw-$SUp8*_J{r( zW`6r`cz0yZQ#f0#*y+m64{bs7GP|2V$phf42rswJB?s@9qf;Bfc^pm-ZS#^5dkG{u zzv;l&B$NYcegSqAnjnPN1?17VUQbPummcWry((85IFB(pFQNGN{hhN$Fv?~l_fr?| z9=%dK(+;kZ(8=mwptjwC-ikBD$Z{l2++~*8wq5ynF<+PNlZI7ba5V#fg~L}kE;UH5 zJ;{P(`G{tNl&z5rUiH~e{I>GT8~9&*(J;Myx9z5P!db!F8RTII^I7c)HU=ss*bYB` zgwiIMZ_q>KEC$4lFm+Afvu6^$X1jm1rB*4H)-EIO5Rvz_p24?OkJ zovD4{-1KA6*oL?a;3qR7GZRB!cE5oAdA#M@{w+fGgsJ-lSmQ^-?8E&Q%tbmjd=@gZ z(}Mg*jsDf6Z)|7s%@9pc-tuw5W&zqUXjv2bVkC%-X?O3F72W4EsIl#1e>Mdz=X4k*_>VxCu_2?jjg16N*5fwC-36OW&;Sz}@jMn}hgJdEd pO;bST+>R{W-aENZYk%(=^(_R5N$LmL{Qc?!%+I4tt4z=_{|902Wu5>4 literal 0 HcmV?d00001 diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_454545_256x240.png b/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..59bd45b907c4fd965697774ce8c5fc6b2fd9c105 GIT binary patch literal 4369 zcmd^?`8O2)_s3^p#%>toqJ#RmwV2==ic*rz7lOw=eaq=H~;_ux21)-Jpcgw zdj+hrf&W^f<%Qk9Zpqf#;jH;N^Z%VA?R|9mZ{esQd(2F=?y+!`XZ5CR?ue=UdHIfUDFM*m15I;g=VN2jw zQW9?wOhDI#+P0|`@JQoC3!pu=AzGMtYB>V&?8(2>_B5_p`1Sb1t{^|J%bZYv09RS? zQ*dcs7}$)taJ@vX0E<96P{ur)Eygr{&ALyNoMP%_94m}=qFVT)&CeG1DBBMLUSKP^ zp%%Q3$MEtKll)X*+$)3O_3x`4%cHY0uhy7U;5x^Ir}X1)mv&B%|A)@A$a>f}tP{5X z9-gkti`YyT+hk9)cZW7fAQhjT%$XLLI^&VR=qev36;`WGBOP!^&(?!sK6jSH0Dnz4 zoEMMNu}y&n=rd-GWI?rGBI8!GD*NJ$k&e5-6+~-9F^6tV<=5`FcY~t{iqRcncEU+F zkT~jww!oy(@~b~WGI8!lzjURX&IpJjFGxShOKUunP+rW$I{c|x0qM6!Gxf6n(;$D> z+QYiULqq)Fy4VDk&Mev)NyM@nvF z7O6M*A$C)kBi0HGMT_+xfQ^USTM)>*h_Rx%eSRxA%n|FuC&=F=Pz}E5uCqbcy;7j=%Qh`glqEA-jx0(a<)uKO5Fe|JLD-ndZ-vnW`G=O&^%pa}Ah(2%m?oANs{lJ`?RhrZ8n!`Q97TKw{YAw9 zD)=M{mD(~_jj`LTd%q6Veum)Cnd!7lw}(5h%ubHcg^2O`prn%u9es3C#&%TsnmSD3%3Ik^Yd@6-d%(I7kqT(B@dVX2 zIidXgd>qYT-oTZ=1sGI7^*_E9Q)1F2mooE0R zXopPnh^ci@+wz2ZDjo&Owyxh6t90Gt!u0miLxc!bue^LvHF?)O@Yf!dQUXfW$u8(f_n07^N)-vpIe;TrHv5uKm{h_v`-IN^zwWc>Lk ziGsSr89sDcdOR_wa~DjrqV&Nd*$18(vohPJ3hSzEJPF2d!u}415wrSMtS(zNa7 zbO0G4ajgKNp{`D7DO<(T?wowarQ0dIKLb<}#prQM)ytB73YNTPQgX^xoT zm>;yKSJ*c@QfD8HW`6&+mowOaA|A&~G0fO6&xwj;E3O9^Zu~ZXts~;-d%FyyeXrijORi<_S(dw_5@h&-fTY?#FJo% zQZZ1&ED%$if+n8JVM{s-ZoK@P>p@z4s`AoI6hYxE!Ie_Y)cpjZjc8@~uNMYVfy#J$ z)+sdEX7DK^{}kUAST8U6^p6#c>0Lc>T~9`0}`*2 zizaU)TFS4(u;BenUWZr?s{D)Z)rc9L5&gUvz3iSQaF#J)D)Ts{YgagdDcI1S`dtes zPqb4|h-RIkjhnpmn(Q2Je6Di5C?MkCUL)!WoKn|P#al41v#-Q8`K1$Gh64UhPQj|T zaZb%tJ}O{A?Cvl26!jeKS3OUkp5@8RDBYwh`Loxb5W<^m*R37+v}#*m-G{{ocF-#r z7!k3ZS^4Qu9sNRNZ3`laW2TqV{rsR#~gtVp6C zL0?}~gbLTv^jqtPQD@Cpq6{B6v&*Y)?tx})z=qQNB4Z_59 zpI2L)xQ`!|J8wWgs82jSw_8(;#}y7~Y^&hY9P1G)@`CGtIi*tZ%-%&;$PuG(!M%)E zQ?T#imBH8dCZxUBX^RWPwIh9LcnL3#$befQDr@UJl{=}o0){qIt52vU9X=3L_gvVW zPqp_YhhpM6XiE7Lvn-G0Wzo>0;g|$_-7|ucz~*w%bW@hr6M?~v9dT}L=>UotTj13& z?Uvt0_uOvzMq4iG6)gZqeU;W=P@EVod;}Vr7P*@=C19v;iz$4N+c5ewauTtKK5e;yIx(FQUec0 z`G)VlTUY|m2L=KusMRgMlapu#wt8MohK3=y`!J`tD6nYd%?xIZO`Q)skL)R%3Vf(P z__5Sx3h%fKF=sNdZo2p(w=_|}1M%ri7fO?8))sU1ySG;M4p4;zrr}4l0lzvA!WQ&a zrwX>%lJkv`Gr_u=K>kHOg6(AB(R3FOryElY)-vi|fRsBS<)$1;TC_?BnyScjY6>_ZD=T|bjcbjz@D6V+yfHd4SU+J*2Dh%n;$5ou zHh6R=)$>IH@%5js2KH#JkfFCVI}P>~U;|}>kk|06tA}^~B;|gJ$UvSF-l4GX43DAR z&M2mp8OgiTaK4li0|Q2qmGNYsm+Qq^JM8yfCP>5!31rjh4Mnq~+5X8+_$scfP1Fp!c zcQO*#6cfJ?ZRxn_$Se_|}Xo1oIF7s(7CllypCW@W8-y5%Bel_K*0G zd~8UWeYCWz>~^hF3ond|tQcClJ(8^9FW&&?U)a4O-pE;Y*u|FHGax>F*Kg_beOF5c z&?#xRN5Q?ckEwCnNr-${XC=w-te5%QH(6O~yxke=R!_ns))PU07Pu)CY`<>$+XicZ zCI=g^;q7NZnw=-vf;HoWLD+}`&Bph>kiqyX5jxjI1A41d$R3nahq@CHULV#9ItIwJ z0)^JGy{hB;@SD|}Zel8~2z;UjN96MR@dt;EV`9RP4X&zn8ib=n*107cICSp7z6srZ~4Qg|Vp$OB0By{IxAPaD7HGFw_HTza~wWN1A6 z3`7BZFse2a4{y#V^&;nRVcZOz*2>A?jm$%?)KawLR0cEz24qxxOOo9_2)9MrWpSg7 zPiPz+M7(zPRZ3$#11ti?uI!}bM!Dg%L#+uR+^2L2RX+QlMpL zg_DrR=GIT7C~b+^OZK)?l7*9c-78zWVbLo1oS}bItdscuF80}guwA8c^(47DfaBjV z^V@&JJHxYHqS+e7&X;ezZwsE2+t~n0?*m^(db@WnI{LgAnOqOa<8pRvo0E>*O&~J_ z&A)t2LOG)5=3$3n2_gi2Kpvgv)#LCUh2Y~ z!A&(~-8reT$sJk0=L;m~ES3k}k% zkF%gzzT(+nRU0IeUvuW8pq=8uzr&7HW>K5ZiD*8qL17AI^ zGqo>*mvIChU6+&t{A3|!W?~pi9_O$>k2d|#(Z721wcT{S1)_UFZ+}QS^KZ*u?5Y~bz z^cLI;2{$C_ZwWqM@sYMYwG+^N<^Ivq8ZOwV;7xT+WCh)I9PHC}ut;VNr?w z<@?HsG!Qg3zaV+-xQ3ldtad!U<6iGz_enGH*2akP_r)o1D&8p^5M)_c8IIj6Wy*7HJo&CBLuo~nj>(63pZzO(Vv^ZuB3 zMYigjkwA;FEy|G}1jpiMj6|NTm7Uyiw=@FDE*nX<>jR!W@9XIyf%$Fd*J5*D0Z0Lm z9}ZQxyT|x5ftNy?V>EbJz-K>bV9gs9RaXUP<^=;e?&Fqxj;6{ieR-a-@HycA1KMKhql8GOmcxwZ?_-(3hMK^^a*(gaFvBH ziIC!fgH4$W*NbKIaY&T?%&13``KbD@S-0`xQ%v3TV+B!;RC7O!+1a9QCA$H@3tR;k z)SSoR7(s4)f{zM}eWgFN{(ZH5d1O}l)f$ruT!)Q&NImXyZsTzOf9TwctcSfr+M)aJ z5otO+$jvm-P4)ykH)x|cO5xeb>?!`qGw$(>&axqLL6yoB${vsMXgL_-bz@2J_tS92 zdvZG-+vKl@K4Vr(EL{WQt@Z+Ea-hxX0}nTSZxnpi^#Kn8Ox8FgIS|hc}KJQ4tm*HO16ui{(O9} z1YN)GjiQt6fGq`Cj+^`zUf?8hk^(T{{cOQGWFP98am}is28A!5%{R#ENv8fCN!j69 zlMEK(2z?|BY=Je$XD9mB-Kkem*(d-j^9j$2#6r$Dz?s)-TCDCGCs z8>6Pvj{Y+YIeFA@qY22V$)awy@q!9A4rgk5b9TcC;s9Ig^G|6nDP+5=Fzg&?(L=vc zCbGd>fSu~@6!94td+o#d@sid!EIX$rx7*cawe6 z`dScJ+$HssdOjE)O#Ybs56vm-FQ$7yuJJD^Zqk%hMaIgAJ<2yb_MFQte_i;62ScT$ zpjifYyR_E=rQ+>H)pmlr-Udzg*-!|ssw(D7wJvC+Sf8bb9;;q8#z?0p!!bsd{wy|5 zpBaMHE-Ve>i#LLjHRaMLtp%9&(HCng7Sw96jVv!#0k%?F^K7&=T)mnYn)D9(i;4x5 z^NJTJwq~pv;kH@#ejTd*48~(J(r6j34|m`h9fEDj0im)~+%I5XphWymhT;_Zty|Q& zzjPg#-ufAHZ1M*Gccw?Kf|8Pnhtb0`!{N`Bqsa37J+>wC$!e z00k+2Egzz;rbcWoUB%Jvp8W1}$XD%e3>4y;;OZ1ccT-O#uW6Ys@C}Pa`nZrNKzR(2 z4e%3)@QI4SE&E!lW`5y14QhbepBG%_XBV-O(%5tj)@9#|;sC-MNev!zGDHk}JdpGC`iJF#8=8-P$Xoku_=Dw%Cv3{U7L>gf zRQ?<$t`cZ*MP5GQmbmx#!+*!zu>0MewRO9GFGS{b^m_fJ-N0?j@EqoFf>$khj+E|@ z7r3We&^tR^YZrxKe*d22agXqCO0l44&kqCv{u)T|(lv`~PK@DvE z{QI_TlCH5z*gR!>LO)k67{^R+vWx24U2^2ODXpwT;6y+6+$5m)_*w4WY&#do9dCeE z)>p+Ykdhq($DhmMiaYXey!@N%L26uz($aJ!QT{B^Wu}U$^9e#5)=c+XF9@Ill?ZmM zlNgHiz*9!vDc&uxOo;ZVxb`Q!Sk0*gnfxWzmbZh4(=%CD%qP?0=);n$&zaW_$UKV9 z8axdcN#AyZ{P)wj?V{P}vM)YY!>6@}^>U+iv$`9>nMTCPjN>z%yF&3yf%>+T@0vh4 zlC8Xa6zeo?%=o3}M8{aebLHcO{^1Ar8qiM=Gquf?Jo)q5`-+?sUpg?QXyEUpWSm+n z$K-UyqkIwHLquru~o(OF)hhz$Y*|X>ZIbswnxRvr~ z2=rdOGVuD|xRlpAZE<0!X1F(%Anpl^@V^D3vbM}qxe|NI;TTiZy7(IM;R69RkA>a& z6gwYE2sREzQ_LHmWqB+ogMk(fMaSFeoDq-!HkFB_nXt5+2ncFuk9BQL1I&oB1zZi) zYW{6_&-Ip1l*OVRA##1ILQS;5R{-K^0wGTiJbVSi@LA^$D$;@J>^G{6@&+%4{b3(s zC~LEHiTv(0b#zxt?YJ0r_~pUZM~mQ(??(n#>&tD%+@nq=Abj5*8R!~Ul1`G~=qFJ4 zfl|m8ZDCYgtr`4LcOpgiJYX9qRY5;DcWti~PmS$VB$E-Zt^f4)vLDOe_3XTq5^ylW zJ9PKm!V-8sAOJXnUfuFNIf0R9tK-pNs2hO04zr620}5B(Ok>yB)Of-3sP59qfQNbm zA4{w!2@cB;GbR(~szVrbO%(w=5S!X`o@o@x++wbN_tMPT0Vc)*I;Fgsbf^*g0 z2Di?HTApwKq3+YwfNsqd3iP%{hyK1iyuVZc@*0tO_3+N0#GFsz>8MjeJ2UJ%L!%hi zGYYAthH`E+ywA*u{(eJ=ia3h*%k?779rk-K<0VZAPkl;TFUbmei|$fqWO8!_zIvqt z$ly$VrlH46nnpX~X5Yk0iBJl;=WuA4>~X4-f&K0yWf42h&0b30t@NYX$7egQ1Fp!a zbui-D6cWCWV&|R1CY@G8(qOmWjWeX3eX7UggZPGimA}soOuQdXe4uZ#2>5zN>qlI0 z9xk}lE=tNpX1m6*nFr2EQ3xs79!^sCldDJYE$m(qYv3q7>}1R7?iZW7>$~*%zKaC| z=$N?ME$>#+%T&MZC`dW1wUl6Z)JgyCn~V%K&i0H|iwE%$>xsZW3tTfZxIUePci@p;cRu|d=ItIwF z1clVHy{hH?@SD|(Zfqi^0DQ1hczHN7xq85h)rzQqLHMX2^IkuK7FB!kI40s$|CY7~ zNX^{_UjN8}L%Med;|+=4RNTMozn8KT;2tb77bUPCmioh+rZBfIiM6f_P34cQ__o1G zWqQp3VL~~pE5?qODf%iiQQ3f42YF@09tQ*$4v_EKUx;t1KCPCBtgqg z@+Tn;O)a0uky_%jm+WjNB?=~VyH>V#L!*=l*@OS6SVyt_UEH&NA=?V2stHPyKkVNy z&jg<#cjros){#ji)dK z%)We0L_478=HZ8-@xnwsKrWs8)x`MB;(Y`Cmu2c-&SH(vN-F(*e`l?c%+l$|y_AJJ zhcDGnwLvN+bu;_sX|1AiePhx@u&%P$hf*xE+O=~D?_(_KGWQ!158YL-y9$*6mmPo;Rp*Dl5lm-mVM2i`h- zM@nxv590_tvMwPD_{l=b$iOm|+|S{D9&P%zeT$GgX6Akl-tfUF>tL@Ld!B&{pN39t zH>3Vhqkr}2Yul+jb7UiouWVGPNsxX7Ueba+9|~dz?d*QM$ng0DZfO0`7fAy?2yMm| zcnRzUhZ&IcwgjH9cuU!w+VStYa{p*)4IgBf|E8)sqMYtB2KH_}SfsFq(c9i(Q6S3U oBo%DI*Kv;w;*%(i9W@f3_WCF#rGn literal 0 HcmV?d00001 diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_cd0a0a_256x240.png b/storage/mroonga/vendor/groonga/examples/dictionary/html/css/smoothness/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..2ab019b73ec11a485fa09378f3a0e155194f6a5d GIT binary patch literal 4369 zcmd^?`8O2)_s3@pGmLE*`#M>&Z`mr_kcwz5Nh&gy7G+@45H9p05OJ)J0CH2owMSaGIN$+5!N; z<11j56?ANg=9hMl-IBGX-T8hf$N$b*H?$f4Xt&I`oABt1nR=k%#z{{*a!Axm|t}hCz zJg0Ln7;M4Zjx{$mwhMW+kWN;|j>qTx_-zNX!GzqEZRa}QF8_0yk6+=w}$QD^&hM4%OkT=uh$q9;5u~NL-I+NQyaVc|3l+iWI5~|(hA-G z08i8AMr@{uY_cWTxo^y|Qyb33mlZLvc7H2Zm~>mB7&=-1X^@|D z&0*~i?GBE&NM(Pv&Vt^zWu_bD3e|R?wTL{cSFwD^Ij9v%g=aLY@1U2Bxn#Te*{>%D zOOW-O-bfnJ7T8jd<*>8`Z2DsFQi~S$%^npJwXam5>>p zMd}QEjM)@~##n$LXpz1Hkl|2UGXi-JFFePXBWL+-5f%!S>L#KL3>Vl0w#d^21Jn<~_7q zWx^Xg1(>PsPGO&cu{S;(pRQ;=Vw2J<9NdQVWx<+g-`ia=Q@puS)75M+?u>DTa95e9 zt#1T?#a)uWC>Mia!K6>g|InPW{&Kp9$tC_3*;R_Xsz6^Eu|xW1$6j#0?XLs7^l+%O zlxddE)h^|=K(2UqS*0ECuDe0ic|H_^t*VOoTCKx0Qmn_^LyJ|b8l$Jvl3{2=3x8&7 z$1ik&YG>w#@x@y~$r`fhlUDo;yXecc6$`30m`3K8s{k8G&3RVp8n#|l6h(Xw`Axw9 z%6Y^J6k0P@4YAuSd%q7=eg)&u8EMoEmq$CWj1GY|rGQWw3ida!FHk&wCqrQh_0Bcw z!ZBS3CbxgZ+}~wzgGIQ#QId%T_TE~_qdUqxjqS#8#jPxdwO@(@-5_nSP&uT?aGYYD z6km36K9=gjUjImwO=5Hl#u85VF?r0HbW)#h^SR|s_L47Tl$&Z&Rz*ksl!t*(2O2;D z+8`6$qpLn}LchhCmv*X}moGMX5?F@juGeHQAddAn}0~r zS_0|d3*0v%Y)8+8K{ zGyoYPb|W9Grm9M4E?vb^@16ePbI4omZv+(NoZ##fLUmKlB(G_jEbtDCM*27t$v`JovAZa+%*Q5dDXF*Ftt*n!O>#ohCM4lZ)h5rdKV-3A za}2AO6@!`W>ROk5FN*>2Zza^Z%}8KT%*jBGH|rml2X1LR{wZhWx8V4>|5i}; zMnLIHn3!^)`87GYh}&Y`KMwyLbA#^pch}Z!`@P_qH&N^LS9SxpEy8mc!wFusq&Z@` zeO}<6PC@VNaII|=n(^cNUiLseig*$;NjG7;IwvfYCBN>kzv@v-V2eBQZ@oIs^)NLqMR935k|1}U;5<{s(Ebdj4r`?QtrrAPfQooq zmPs_(YTy|??+nitNIFDoR7~qLPPFFCf^_~8OUt{#!|9o*3Q{!@9ZAI$7O~piD!;WX8#v&RxNH27i59$`1{o zEYU_zE{bKEI%f3BbE0Fc;f2!4LjUlC`wgh4@R{1?O78r5t$hWKiLV{#QWWq{QZiPx zm3?x$;&DDRVt0SByRiFczw$-e)GSvpCRbzk^=E zz=(+LjEc{Ps_2(OYg=G(93!oS=IeJ|WA8STv+LgI*Oj1c-QC06N~mvJ&KKx{arGp5 zswvJ6{%BvBYo>#2$%O$~TITuh?Rr^jCpAUXh)}m74`O|aOU>w2KI`k<#efwa5=-l4Xx!o>Z9Evg`RLN5W7SQp3$@D3_hY4EV!0( ztMm6>zBcgY{RvHZ{9Ey&&)jr2B4s0qDPBUh1ITaAp&>rj3ng*B=VGXz* zs@eR<;J(XkpD6Q1U3}#FR)wlafiFMU(-=&e9(eQ`isrS-9aNwJ)7frS8RiXM4*SbC zL|4*c?h^jfYvSOpn%Z$W?C|TuZ;uy2pFWHXuGW`ZkGV&kPJsKqJJQ!NswAE!!cb2k zumi=AE$YIkm})cVlg>nn&PBjBRI*@mfhhRMsa5U8k#A!ztfiw)d7I_UyAif8$5sJ9a7WUv5!o%fL z(J7-8EQzv1YIc)BNeWkLK~m%y4vqe&q@|_ZR5;eC3-9rkf*T{_19jtuWKhdW4Bn|~ zZ-YyFLN!k)0AKg{dO)|v3K?=oy+dzb4%T1F4}JsByncB1Z(`2p@O0!E!JQelouN^* z%Q^YfQUh66D$Zx-RDZvLctsr9`_+1p#tz&4SMd@i_-8()tyg3OyhU~?Gt#-a{NKFN z0VGf+AH%@o6;-_*?$$T4QX-f_>Ny-5CV8Ccq+@>gNSeovbFr0@b}RiTcJbLx>ws&r zsvY!rR{4al#MpVKut~?&kTmF>_v3UaC!gvuxgg%5-{l{20}~&F6CUarF9N=u)BG71 zoQDlAwT+T=mfo&$Xy%4-kmW;4wuh6{{ABClybHV6L>t&k4?9_Ny8A_^?)ff#dEjhL z2RbC~cFVbz^fJ`$I0%prYc0g-9(7X3eUp}^#Mzv)Z1EsGW;qr3cY$+e2HU5d_O9L% zpbljP*1!A0PqpzNo3W&y(hD87qgweq5YQWYEkxrOuSain2-q@Z*P`x*ht-9)Fr5Ho zSTKduvc9h6`S^#$i)LgjDi3_PQ+RbaGP!!di^Y;4kB0lGo$y{if)rJIaXTbpRgO#B z1El6|18;s}$0FRjgK-7~ZwmI`_1{a`32+Y>&O_iTpm%vz6hNkjGR(#*! zpfJ2>OAQbTFba9S3j9BlRHXaG{)Zt(J<3ppA?}j+7F#{bV{M7zU)5e@~R&J_xf$+GKK~ z3{R;Y9fZGe^ifEqKL;!VMXv26=R~^TG(#*2!JKCWoo&c^$utAs#Gfq-?t!c&9TH5- zj&i5L4NWbdNs*djvsY}bC&ddUbh=iyc0;3-@Y#d^s8|Ql{ax(yenFcG#i|K%lRxy| zFys4w!@EPXp2AsbMUGc*eP|7uliAq-O6~(+MR>V(EZTd&9G+MY&gF2lZ=I8j*o`OC z`AxrmOGMeD=H_9Cq47clT|h34>-EI=%;E!my;o&wU(aKV&PymBzrV9q2uA62XS@JrjKYANZAU>;8mag#BU?Nv`+ZVhlAPV`HF_gKY_O zhbV2L`8qvR&f=@M5vH~geD+L&*L2s<)|5)clA0yt9TM{X)iWtx@wJO_!{vR#|AD6t z*OAg2&P_i8jjW5y0DdtOGcqvrCHD*1Uq_q1ZQmngPnf!2fHizH%sSX>#$2Rh!>1ur z+s(*-)abDuePc6~XNG8m@|KMXHVM#G4?~+V z1z!An!D0GD-7WqXE8ddUXLkI%u01$fTEhhy + + + + + +groonga dictionary search + + + + + + +

"); + $.each(items, + function(i, val) { + results.append($("
") + .append($("") + .text(val[0]) + .click(function() { + $(".search").val($(this).text()); + $("#search").submit(); + }))); + results.append($("
") + .append($("").text(val[1])) + .append($("").text(val[2])) + ); + }); + $("#result") + .empty() + .append(results); + }; + + var request_index = 0; + var columns = "_key,gene95_desc,edict_desc"; + var xhr; + function source(request, response) { + function onSuccess(data, status) { + if (this.autocomplete_request != request_index) { + return; + } + var completions = data[1]["complete"]; + var items = []; + if (completions && completions.length > 2) { + completions.shift(); + completions.shift(); + $.each(completions, + function(i, item) { + var key = item[0]; + items.push(key); + if (items.length >= 3) { + return false; + } + return true; + }); + } + if (completions.length > 0) { + displayItems(completions); + } + response(items); + } + + function onError() { + if (this.autocomplete_request != request_index) { + return; + } + response([]); + } + + if (xhr) { + xhr.abort(); + } + xhr = $.ajax(url, + { + data: { + query: request.term, + types: 'complete', + table: 'item_dictionary', + column: 'kana', + limit: 25, + output_columns: columns, + frequency_threshold: 1, + prefix_search: "yes" + }, + dataType: "jsonp", + autocomplete_request: ++request_index, + success: onSuccess, + error: onError + }); + }; + + return source; +} diff --git a/storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-1.7.2.js b/storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-1.7.2.js new file mode 100644 index 00000000000..3774ff98613 --- /dev/null +++ b/storage/mroonga/vendor/groonga/examples/dictionary/html/js/jquery-1.7.2.js @@ -0,0 +1,9404 @@ +/*! + * jQuery JavaScript Library v1.7.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Wed Mar 21 12:46:34 2012 -0700 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.2", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + fired = true; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + pixelMargin: true + }; + + // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead + jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, + paddingMarginBorderVisibility, paddingMarginBorder, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + paddingMarginBorder = "padding:0;margin:0;border:"; + positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; + paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; + style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; + html = "
" + + "" + + "
"; + + container = document.createElement("div"); + container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + div.innerHTML = ""; + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.width = div.style.padding = "1px"; + div.style.border = 0; + div.style.overflow = "hidden"; + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + } + + div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + if ( window.getComputedStyle ) { + div.style.marginTop = "1%"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } + + if ( typeof container.style.zoom !== "undefined" ) { + container.style.zoom = 1; + } + + body.removeChild( container ); + marginDiv = div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise( object ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: selector && quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process events on disabled elements (#6911, #8165) + if ( cur.disabled !== true ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} +// Expose origPOS +// "global" as in regardless of relation to brackets/parens +Expr.match.globalPOS = origPOS; + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.globalPOS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and