# Copyright (C) 2005 Network Applied Communication Laboratory Co., Ltd. # # This file is part of Rast. # See the file COPYING for redistribution information. # require "test/unit" require "fileutils" require "bdb" require "rast_test" require "rast_xmlrpc_client" require "rast/xmlrpc-server-testable" require "rast/merged-doc-id-check" module Rast class MergerTest < Test::Unit::TestCase include XMLRPCServerTestable include MergedDocIDCheck def test_s_open utf8_options = { "encoding" => "utf8", "preserve_text" => true, "properties" => [], } euc_jp_options = { "encoding" => "euc_jp", "preserve_text" => true, "properties" => [], } dbs = [] begin db_name = generate_db_name LocalDB.create(db_name, utf8_options) dbs.push(LocalDB.open(db_name)) db_name = generate_db_name LocalDB.create(db_name, utf8_options) dbs.push(LocalDB.open(db_name)) assert_nothing_raised do Merger.open(dbs) do end end ensure dbs.each do |db| db.close end end assert_raise(RastError) do Merger.open([]) do end end dbs = [] begin db_name = generate_db_name LocalDB.create(db_name, utf8_options) dbs.push(LocalDB.open(db_name)) db_name = generate_db_name LocalDB.create(db_name, euc_jp_options) dbs.push(LocalDB.open(db_name)) assert_raise(RastError) do Merger.open(dbs) do end end ensure dbs.each do |db| db.close end end end def test_search search_test_simple search_test_have_no_items_node search_test_sort_scoring search_test_sort_property search_test_discord_property search_test_set_range end def search_test_simple options = { "encoding" => "utf8", "preserve_text" => true, "properties" => [], } db_names = [] 4.times do |i| db_names.push(generate_db_name) LocalDB.create(db_names[i], options) LocalDB.open(db_names[i]) do |db| db.register("昨日は雨天なり", {}) db.register("本日は晴天なり", {}) db.register("明日は雪っす", {}) end end dbs = [] begin db11 = LocalDB.open(db_names[0]) db12 = LocalDB.open(db_names[1]) db1 = Merger.open([db11, db12]) dbs.push(db11, db12, db1) result = db1.search("晴天") assert_equal(2, result.num_indices) assert_equal(6, result.num_docs) assert_equal(2, result.hit_count) assert_equal("晴天", result.terms[0].term) assert_equal(2, result.terms[0].doc_count) assert_equal(1, result.terms.length) assert_equal(DocIDInfo.new(2, 0), split_doc_id(result.items[0].doc_id)) assert_equal(0, result.items[0].db_index) assert_equal(nil, result.items[0].properties) assert_equal(DocIDInfo.new(2, 1), split_doc_id(result.items[1].doc_id)) assert_equal(1, result.items[1].db_index) assert_equal(nil, result.items[1].properties) assert_equal(2, result.items.length) db2 = LocalDB.open(db_names[2]) kick_xmlrpc_client(db_names[3]) do |db3| db = Merger.open([db1, db2, db3]) dbs.push(db2, db) result = db.search("晴天") assert_equal(4, result.num_indices) assert_equal(12, result.num_docs) assert_equal(4, result.hit_count) assert_equal("晴天", result.terms[0].term) assert_equal(4, result.terms[0].doc_count) assert_equal(1, result.terms.length) assert_equal(DocIDInfo.new(2, 0), split_doc_id(result.items[0].doc_id)) assert_equal(0, result.items[0].db_index) assert_equal(nil, result.items[0].properties) assert_equal(DocIDInfo.new(2, 1), split_doc_id(result.items[1].doc_id)) assert_equal(0, result.items[1].db_index) assert_equal(nil, result.items[1].properties) assert_equal(DocIDInfo.new(2, 2), split_doc_id(result.items[2].doc_id)) assert_equal(1, result.items[2].db_index) assert_equal(nil, result.items[2].properties) assert_equal(DocIDInfo.new(2, 3), split_doc_id(result.items[3].doc_id)) assert_equal(2, result.items[3].db_index) assert_equal(nil, result.items[3].properties) assert_equal(4, result.items.length) end ensure dbs.each do |database| database.close end end end def search_test_have_no_items_node options = { "encoding" => "utf8", "preserve_text" => true, "properties" => [ { "name" => "filename", "type" => Rast::PROPERTY_TYPE_STRING, "search" => false, "text_search" => false, "full_text_search" => false, }, ], } db_names = [] db_names.push(generate_db_name) LocalDB.create(db_names[0], options) LocalDB.open(db_names[0]) do |db| db.register("本日は晴天なり", {"filename" => "hare.txt"}) end db_names.push(generate_db_name) LocalDB.create(db_names[1], options) LocalDB.open(db_names[1]) do |db| db.register("明日は雨っす", {"filename" => "ame.txt"}) end dbs = [] begin db1 = LocalDB.open(db_names[0]) db2 = LocalDB.open(db_names[1]) db = Merger.open([db1, db2]) dbs.push(db1, db2, db) result = db.search("晴天") assert_equal(DocIDInfo.new(1, 0), split_doc_id(result.items[0].doc_id)) assert_equal("晴天", result.terms[0].term) assert_equal(1, result.terms[0].doc_count) assert_equal(1, result.terms.length) assert_equal(0, result.items[0].db_index) assert_equal(1, result.items.length) result = db.search("雨っ") assert_equal(DocIDInfo.new(1, 1), split_doc_id(result.items[0].doc_id)) assert_equal("雨っ", result.terms[0].term) assert_equal(1, result.terms[0].doc_count) assert_equal(1, result.terms.length) assert_equal(1, result.items[0].db_index) assert_equal(1, result.items.length) ensure dbs.each do |database| database.close end end end def search_test_sort_scoring options = { "encoding" => "utf8", "preserve_text" => true, "properties" => [], } db_names = [] sole_db_name = generate_db_name LocalDB.create(sole_db_name, options) LocalDB.open(sole_db_name) do |db| 2.times do |i| db.register("012345" + i.to_s, {}) db.register("123456" + i.to_s, {}) db.register("234567" + i.to_s, {}) end end 2.times do |i| db_names.push(generate_db_name) LocalDB.create(db_names[i], options) LocalDB.open(db_names[i]) do |db| db.register("012345" + i.to_s, {}) db.register("123456" + i.to_s, {}) db.register("234567" + i.to_s, {}) end end db_names.push(generate_db_name) LocalDB.create(db_names[2], options) LocalDB.open(db_names[2]) do |db| db.register("本日は晴天なり", {}) end dbs = [] begin search_option = {"need_summary" => true} db1 = LocalDB.open(db_names[0]) db2 = LocalDB.open(db_names[1]) db = Merger.open([db1, db2]) sole_db = LocalDB.open(sole_db_name) dbs.push(db1, db2, db, sole_db) sole_result = sole_db.search("1", search_option) result = db.search("1", search_option) assert_equal(sole_result.items[0].summary, result.items[0].summary) assert_equal(sole_result.items[0].score, result.items[0].score) assert_equal(sole_result.items[1].summary, result.items[1].summary) assert_equal(sole_result.items[1].score, result.items[1].score) assert_equal(sole_result.items[2].summary, result.items[2].summary) assert_equal(sole_result.items[2].score, result.items[2].score) assert_equal(sole_result.items[3].summary, result.items[3].summary) assert_equal(sole_result.items[3].score, result.items[3].score) assert_equal(sole_result.items.length, result.items.length) db3 = LocalDB.open(db_names[2]) db = Merger.open([db1, db3]) dbs.push(db3, db) result = db.search("晴天", search_option) assert_operator(0, :<, result.items[0].score) assert_equal(1, result.items.length) db = Merger.open([db1, db2, db3]) dbs.push(db) result = db.search("晴天", search_option) assert_operator(0, :<, result.items[0].score) assert_equal(1, result.items.length) ensure dbs.each do |database| database.close end end end def search_test_sort_property options = { "encoding" => "utf8", "preserve_text" => true, "properties" => [ { "name" => "filename", "type" => Rast::PROPERTY_TYPE_STRING, "search" => false, "text_search" => false, "full_text_search" => false, }, ], } db_names = [] db_names.push(generate_db_name) LocalDB.create(db_names[0], options) LocalDB.open(db_names[0]) do |db| db.register("本日は晴天なり", {"filename" => "hare2.txt"}) end db_names.push(generate_db_name) LocalDB.create(db_names[1], options) LocalDB.open(db_names[1]) do |db| db.register("本日は晴天なり", {"filename" => "hare1.txt"}) end dbs = [] begin db1 = LocalDB.open(db_names[0]) db2 = LocalDB.open(db_names[1]) db = Merger.open([db1, db2]) dbs.push(db1, db2, db) result = db.search("晴天", { "sort_method" => Rast::SORT_METHOD_PROPERTY, "sort_property" => "filename", "properties" => ["filename"], }) assert_equal(2, result.num_indices) assert_equal(2, result.num_docs) assert_equal(2, result.hit_count) assert_equal("晴天", result.terms[0].term) assert_equal(2, result.terms[0].doc_count) assert_equal(1, result.terms.length) assert_equal(DocIDInfo.new(1, 1), split_doc_id(result.items[0].doc_id)) assert_equal(1, result.items[0].db_index) assert_equal(1, result.items[0].properties.length) assert_equal(DocIDInfo.new(1, 0), split_doc_id(result.items[1].doc_id)) assert_equal(0, result.items[1].db_index) assert_equal(1, result.items[1].properties.length) assert_operator(0, :<, result.items[0].score) assert_operator(0, :<, result.items[1].score) assert_equal(2, result.items.length) result = db.search("晴天", { "sort_method" => Rast::SORT_METHOD_PROPERTY, "sort_property" => "filename", "properties" => [], }) assert_equal(2, result.num_indices) assert_equal(2, result.num_docs) assert_equal(2, result.hit_count) assert_equal("晴天", result.terms[0].term) assert_equal(2, result.terms[0].doc_count) assert_equal(1, result.terms.length) assert_equal(DocIDInfo.new(1, 1), split_doc_id(result.items[0].doc_id)) assert_equal(1, result.items[0].db_index) assert_equal(nil, result.items[0].properties) assert_equal(DocIDInfo.new(1, 0), split_doc_id(result.items[1].doc_id)) assert_equal(0, result.items[1].db_index) assert_equal(nil, result.items[1].properties) assert_operator(0, :<, result.items[0].score) assert_operator(0, :<, result.items[1].score) assert_equal(2, result.items.length) ensure dbs.each do |database| database.close end end end def search_test_discord_property options1 = { "encoding" => "utf8", "preserve_text" => true, "properties" => [ { "name" => "filename", "type" => Rast::PROPERTY_TYPE_STRING, "search" => true, "text_search" => false, "full_text_search" => false, }, { "name" => "serial", "type" => Rast::PROPERTY_TYPE_UINT, "search" => true, "text_search" => false, "full_text_search" => false, }, ], } db_names = [] db_names.push(generate_db_name) LocalDB.create(db_names[0], options1) LocalDB.open(db_names[0]) do |db| db.register("本日は晴天なり", {"filename" => "hare.txt", "serial" => 1}) end options2 = { "encoding" => "utf8", "preserve_text" => true, "properties" => [ { "name" => "filename", "type" => Rast::PROPERTY_TYPE_STRING, "search" => true, "text_search" => false, "full_text_search" => false, }, ], } db_names.push(generate_db_name) LocalDB.create(db_names[1], options2) LocalDB.open(db_names[1]) do |db| db.register("明日は雨っす", {"filename" => "ame.txt"}) end dbs = [] begin db1 = LocalDB.open(db_names[0]) db2 = LocalDB.open(db_names[1]) db = Merger.open([db1, db2]) dbs.push(db1, db2, db) assert_nothing_raised do db.search("晴天") db.search("雨っ") db.search("日は") db.search("filename = hare.txt") db.search("日は", {"properties" => ["filename"]}) end assert_raise(RastError) do db.search("serial = 1") end assert_raise(RastError) do db.search("日は", {"properties" => ["serial"]}) end ensure dbs.each do |database| database.close end end end def search_test_set_range options = { "encoding" => "utf8", "preserve_text" => true, "properties" => [ { "name" => "filename", "type" => Rast::PROPERTY_TYPE_STRING, "search" => false, "text_search" => false, "full_text_search" => false, }, { "name" => "title", "type" => Rast::PROPERTY_TYPE_STRING, "search" => false, "text_search" => false, "full_text_search" => false, }, ], } db_names = [] db_names.push(generate_db_name) LocalDB.create(db_names[0], options) LocalDB.open(db_names[0]) do |db| db.register("本日は晴天なり", {"filename" => "3.txt", "title" =>"today"}) end db_names.push(generate_db_name) LocalDB.create(db_names[1], options) LocalDB.open(db_names[1]) do |db| db.register("本日は晴天なり", {"filename" => "1.txt", "title" => "tenki"}) end db_names.push(generate_db_name) LocalDB.create(db_names[2], options) LocalDB.open(db_names[2]) do |db| db.register("本日は晴天なり", {"filename" => "2.txt", "title" => "nikki"}) end dbs = [] begin db1 = LocalDB.open(db_names[0]) db2 = LocalDB.open(db_names[1]) db3 = LocalDB.open(db_names[2]) db = Merger.open([db1, db2, db3]) dbs.push(db1, db2, db3, db) result = db.search("晴天", { "sort_method" => Rast::SORT_METHOD_PROPERTY, "sort_property" => "filename", "properties" => [], "start_no" => 1, "num_items" => 2, }) assert_equal(3, result.num_indices) assert_equal(3, result.num_docs) assert_equal(3, result.hit_count) assert_equal("晴天", result.terms[0].term) assert_equal(3, result.terms[0].doc_count) assert_equal(1, result.terms.length) assert_equal(DocIDInfo.new(1, 2), split_doc_id(result.items[0].doc_id)) assert_equal(2, result.items[0].db_index) assert_equal(nil, result.items[0].properties) assert_equal(DocIDInfo.new(1, 0), split_doc_id(result.items[1].doc_id)) assert_equal(0, result.items[1].db_index) assert_equal(nil, result.items[1].properties) assert_equal(2, result.items.length) result1 = db.search("晴天", { "sort_method" => Rast::SORT_METHOD_PROPERTY, "sort_property" => "filename", "properties" => [], }) result2 = db.search("晴天", { "sort_method" => Rast::SORT_METHOD_PROPERTY, "sort_property" => "filename", "properties" => [], "start_no" => 1, "num_items" => 2, }) assert_equal(result1.items[1].doc_id, result2.items[0].doc_id) assert_equal(result1.items[2].doc_id, result2.items[1].doc_id) assert_equal(3, result1.items.length) assert_equal(2, result2.items.length) result1 = db.search("晴天", { "sort_method" => Rast::SORT_METHOD_PROPERTY, "sort_property" => "filename", "properties" => ["filename"], }) result2 = db.search("晴天", { "sort_method" => Rast::SORT_METHOD_PROPERTY, "sort_property" => "filename", "properties" => ["filename"], "start_no" => 2, "num_items" => 1, }) assert_equal(result1.items[2].doc_id, result2.items[0].doc_id) assert_equal(3, result1.items.length) assert_equal(1, result2.items.length) result2 = db.search("晴天", { "sort_method" => Rast::SORT_METHOD_PROPERTY, "sort_property" => "filename", "properties" => [], "start_no" => 2, }) assert_equal(result1.items[2].doc_id, result2.items[0].doc_id) assert_equal(result1.items[2].db_index, result2.items[0].db_index) assert_equal(result1.items[2].score, result2.items[0].score) assert_equal(1, result2.items.length) ensure dbs.each do |database| database.close end end end def test_properties options1 = { "encoding" => "utf8", "preserve_text" => true, "properties" => [ { "name" => "filename", "type" => Rast::PROPERTY_TYPE_STRING, "search" => false, "text_search" => false, "full_text_search" => false, }, { "name" => "title", "type" => Rast::PROPERTY_TYPE_STRING, "search" => false, "text_search" => false, "full_text_search" => false, }, ], } db_names = [] db_names.push(generate_db_name) LocalDB.create(db_names[0], options1) options2 = { "encoding" => "utf8", "preserve_text" => true, "properties" => [ { "name" => "date", "type" => Rast::PROPERTY_TYPE_DATE, "search" => false, "text_search" => false, "full_text_search" => false, }, { "name" => "filename", "type" => Rast::PROPERTY_TYPE_STRING, "search" => false, "text_search" => false, "full_text_search" => false, }, ], } db_names.push(generate_db_name) LocalDB.create(db_names[1], options2) dbs = [] begin db1 = LocalDB.open(db_names[0]) db2 = LocalDB.open(db_names[1]) db = Merger.open([db1, db2]) dbs.push(db1, db2, db) result = db.properties assert_equal("filename", result[0].name) assert_equal(Rast::PROPERTY_TYPE_STRING, result[0].type) assert_equal(false, result[0].search) assert_equal(false, result[0].text_search) assert_equal(false, result[0].full_text_search) assert_equal(false, result[0].unique) assert_equal(false, result[0].omit_property) assert_equal(1, result.length) ensure dbs.each do |database| database.close end end end def test_byte_order options = { "encoding" => "utf8", "preserve_text" => true, "properties" => [], } db_names = [] db_names.push(generate_db_name) LocalDB.create(db_names[0], options) db_names.push(generate_db_name) LocalDB.create(db_names[1], options) dbs = [] begin db1 = LocalDB.open(db_names[0]) db2 = LocalDB.open(db_names[1]) dbs.push(db1, db2) Merger.open([db1, db2]) do |db| assert_raise(RastError) do db.byte_order end end ensure dbs.each do |database| database.close end end end def test_encoding options = { "encoding" => "utf8", "preserve_text" => true, "properties" => [], } db_names = [] db_names.push(generate_db_name) LocalDB.create(db_names[0], options) db_names.push(generate_db_name) LocalDB.create(db_names[1], options) dbs = [] begin db1 = LocalDB.open(db_names[0]) db2 = LocalDB.open(db_names[1]) dbs.push(db1, db2) Merger.open([db1, db2]) do |db| assert_equal("UTF-8", db.encoding) end ensure dbs.each do |database| database.close end end end def test_sync_threshold_chars options = { "encoding" => "utf8", "preserve_text" => true, "properties" => [], } db_names = [] db_names.push(generate_db_name) LocalDB.create(db_names[0], options) db_names.push(generate_db_name) LocalDB.create(db_names[1], options) dbs = [] begin db1 = LocalDB.open(db_names[0]) db2 = LocalDB.open(db_names[1]) dbs.push(db1, db2) Merger.open([db1, db2]) do |db| assert_raise(RastError) do db.sync_threshold_chars end end ensure dbs.each do |database| database.close end end end end end