提交 ace817f4 authored 作者: Thomas Mueller's avatar Thomas Mueller

Lucene fulltext index

上级 2e9d60d5
...@@ -16,7 +16,9 @@ Change Log ...@@ -16,7 +16,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>The character '$' could not be used in identifier names (table name, <ul><li>The Lucene fulltext index was empty when opening a database with fulltext
index enabled, and re-indexing it didn't work. Fixed.
</li><li>The character '$' could not be used in identifier names (table name,
column names and so on). Fixed. column names and so on). Fixed.
</li><li>The new method org.h2.tools.Server.startWebServer(conn) starts the H2 Console </li><li>The new method org.h2.tools.Server.startWebServer(conn) starts the H2 Console
to inspect a database while debugging. to inspect a database while debugging.
......
...@@ -285,7 +285,7 @@ http://groups.google.com/group/h2-database/web/roadmap ...@@ -285,7 +285,7 @@ http://groups.google.com/group/h2-database/web/roadmap
</tr><tr> </tr><tr>
<td>Updatable Result Sets</td> <td>Updatable Result Sets</td>
<td class="compareY">Yes</td> <td class="compareY">Yes</td>
<td class="compareY">Yes</td> <td class="compareY">Yes *7</td>
<td class="compareN">No</td> <td class="compareN">No</td>
<td class="compareY">Yes</td> <td class="compareY">Yes</td>
<td class="compareY">Yes</td> <td class="compareY">Yes</td>
...@@ -346,7 +346,8 @@ http://groups.google.com/group/h2-database/web/roadmap ...@@ -346,7 +346,8 @@ http://groups.google.com/group/h2-database/web/roadmap
*3 Derby support for roles based security and password checking as an option.<br /> *3 Derby support for roles based security and password checking as an option.<br />
*4 Derby only supports global temporary tables.<br /> *4 Derby only supports global temporary tables.<br />
*5 The default H2 jar file contains debug information, jar files for other databases do not.<br /> *5 The default H2 jar file contains debug information, jar files for other databases do not.<br />
*6 PostgreSQL supports functional indexes. *6 PostgreSQL supports functional indexes.<br />
*7 Derby only supports updatable result sets if the query is not sorted.
</p> </p>
<h3>Derby and HSQLDB</h3> <h3>Derby and HSQLDB</h3>
......
...@@ -98,7 +98,8 @@ spread the word and have translated this project. Also many thanks to the donors ...@@ -98,7 +98,8 @@ spread the word and have translated this project. Also many thanks to the donors
via PayPal: via PayPal:
</p> </p>
<ul> <ul>
<li>Florent Ramiere, France <li>Ashwin Jayaprakash, USA
</li><li>Florent Ramiere, France
</li><li>Jun Iyama, Japan </li><li>Jun Iyama, Japan
</li><li>Antonio Casqueiro, Portugal </li><li>Antonio Casqueiro, Portugal
</li><li>Oliver Computing LLC, USA </li><li>Oliver Computing LLC, USA
......
...@@ -161,10 +161,8 @@ implements Trigger, CloseListener ...@@ -161,10 +161,8 @@ implements Trigger, CloseListener
stat.execute("CREATE ALIAS IF NOT EXISTS FTL_SEARCH_DATA FOR \"" + FullTextLucene.class.getName() + ".searchData\""); stat.execute("CREATE ALIAS IF NOT EXISTS FTL_SEARCH_DATA FOR \"" + FullTextLucene.class.getName() + ".searchData\"");
stat.execute("CREATE ALIAS IF NOT EXISTS FTL_REINDEX FOR \"" + FullTextLucene.class.getName() + ".reindex\""); stat.execute("CREATE ALIAS IF NOT EXISTS FTL_REINDEX FOR \"" + FullTextLucene.class.getName() + ".reindex\"");
stat.execute("CREATE ALIAS IF NOT EXISTS FTL_DROP_ALL FOR \"" + FullTextLucene.class.getName() + ".dropAll\""); stat.execute("CREATE ALIAS IF NOT EXISTS FTL_DROP_ALL FOR \"" + FullTextLucene.class.getName() + ".dropAll\"");
String path = getIndexPath(conn);
IndexModifier indexer = openIndexModifier(path, true);
try { try {
indexer.close(); getIndexModifier(conn);
} catch (Exception e) { } catch (Exception e) {
throw convertException(e); throw convertException(e);
} }
...@@ -583,21 +581,17 @@ implements Trigger, CloseListener ...@@ -583,21 +581,17 @@ implements Trigger, CloseListener
synchronized (indexers) { synchronized (indexers) {
indexer = (IndexModifier) indexers.get(path); indexer = (IndexModifier) indexers.get(path);
if (indexer == null) { if (indexer == null) {
boolean recreate = !IndexReader.indexExists(path);
indexer = openIndexModifier(path, recreate);
indexers.put(path, indexer);
}
}
return indexer;
}
private static IndexModifier openIndexModifier(String path, boolean recreate) throws SQLException {
try { try {
boolean recreate = !IndexReader.indexExists(path);
Analyzer analyzer = new StandardAnalyzer(); Analyzer analyzer = new StandardAnalyzer();
return new IndexModifier(path, analyzer, recreate); indexer = new IndexModifier(path, analyzer, recreate);
} catch (IOException e) { } catch (IOException e) {
throw convertException(e); throw convertException(e);
} }
indexers.put(path, indexer);
}
}
return indexer;
} }
private static String getIndexPath(Connection conn) throws SQLException { private static String getIndexPath(Connection conn) throws SQLException {
......
...@@ -269,6 +269,8 @@ java org.h2.test.TestAll timer ...@@ -269,6 +269,8 @@ java org.h2.test.TestAll timer
/* /*
document FTL_SEARCH, FTL_SEARCH_DATA
JaQu JaQu
row level locking row level locking
......
...@@ -12,6 +12,7 @@ import java.sql.ResultSet; ...@@ -12,6 +12,7 @@ import java.sql.ResultSet;
import java.sql.Statement; import java.sql.Statement;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.h2.store.fs.FileSystem;
import org.h2.test.TestBase; import org.h2.test.TestBase;
/** /**
...@@ -26,12 +27,14 @@ public class TestFullText extends TestBase { ...@@ -26,12 +27,14 @@ public class TestFullText extends TestBase {
test(false, "VARCHAR"); test(false, "VARCHAR");
test(false, "CLOB"); test(false, "CLOB");
testPerformance(false); testPerformance(false);
testReopen(false);
String luceneFullTextClassName = "org.h2.fulltext.FullTextLucene"; String luceneFullTextClassName = "org.h2.fulltext.FullTextLucene";
try { try {
Class.forName(luceneFullTextClassName); Class.forName(luceneFullTextClassName);
test(true, "VARCHAR"); test(true, "VARCHAR");
test(true, "CLOB"); test(true, "CLOB");
testPerformance(true); testPerformance(true);
testReopen(true);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
println("Class not found, not tested: " + luceneFullTextClassName); println("Class not found, not tested: " + luceneFullTextClassName);
// ok // ok
...@@ -42,8 +45,30 @@ public class TestFullText extends TestBase { ...@@ -42,8 +45,30 @@ public class TestFullText extends TestBase {
} }
private void testReopen(boolean lucene) throws Exception {
String prefix = lucene ? "FTL" : "FT";
deleteDb("fullTextReopen");
FileSystem.getInstance(baseDir).deleteRecursive(baseDir + "/fullTextReopen");
Connection conn = getConnection("fullTextReopen");
Statement stat = conn.createStatement();
String className = lucene ? "FullTextLucene" : "FullText";
stat.execute("CREATE ALIAS IF NOT EXISTS " + prefix + "_INIT FOR \"org.h2.fulltext." + className + ".init\"");
stat.execute("CALL " + prefix + "_INIT()");
stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
stat.execute("INSERT INTO TEST VALUES(1, 'Hello World')");
stat.execute("CALL " + prefix + "_CREATE_INDEX('PUBLIC', 'TEST', NULL)");
conn.close();
conn = getConnection("fullTextReopen");
stat = conn.createStatement();
ResultSet rs = stat.executeQuery("SELECT * FROM " + prefix + "_SEARCH('Hello', 0, 0)");
assertTrue(rs.next());
conn.close();
}
private void testPerformance(boolean lucene) throws Exception { private void testPerformance(boolean lucene) throws Exception {
deleteDb("fullText"); deleteDb("fullText");
FileSystem.getInstance(baseDir).deleteRecursive(baseDir + "/fullText");
Connection conn = getConnection("fullText"); Connection conn = getConnection("fullText");
String prefix = lucene ? "FTL" : "FT"; String prefix = lucene ? "FTL" : "FT";
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论