提交 9b5cd887 authored 作者: Thomas Mueller's avatar Thomas Mueller

The fulltext search methods and fields are now protected instead of private.

上级 e9447750
......@@ -49,35 +49,40 @@ import org.h2.value.DataType;
*/
public class FullText {
private static final String TRIGGER_PREFIX = "FT_";
private static final String SCHEMA = "FT";
private static final String SELECT_MAP_BY_WORD_ID = "SELECT ROWID FROM " + SCHEMA + ".MAP WHERE WORDID=?";
private static final String SELECT_ROW_BY_ID = "SELECT KEY, INDEXID FROM " + SCHEMA + ".ROWS WHERE ID=?";
/**
* A column name of the result set returned by the searchData method.
*/
private static final String FIELD_SCHEMA = "SCHEMA";
protected static final String FIELD_SCHEMA = "SCHEMA";
/**
* A column name of the result set returned by the searchData method.
*/
private static final String FIELD_TABLE = "TABLE";
protected static final String FIELD_TABLE = "TABLE";
/**
* A column name of the result set returned by the searchData method.
*/
private static final String FIELD_COLUMNS = "COLUMNS";
protected static final String FIELD_COLUMNS = "COLUMNS";
/**
* A column name of the result set returned by the searchData method.
*/
private static final String FIELD_KEYS = "KEYS";
protected static final String FIELD_KEYS = "KEYS";
/**
* The column name of the result set returned by the search method.
*/
private static final String FIELD_QUERY = "QUERY";
protected static final String FIELD_QUERY = "QUERY";
/**
* The hit score.
*/
protected static final String FIELD_SCORE = "SCORE";
private static final String TRIGGER_PREFIX = "FT_";
private static final String SCHEMA = "FT";
private static final String SELECT_MAP_BY_WORD_ID = "SELECT ROWID FROM " + SCHEMA + ".MAP WHERE WORDID=?";
private static final String SELECT_ROW_BY_ID = "SELECT KEY, INDEXID FROM " + SCHEMA + ".ROWS WHERE ID=?";
/**
* Initializes full text search functionality for this database. This adds
......@@ -247,6 +252,8 @@ public class FullText {
* <ul><li>QUERY (varchar): the query to use to get the data.
* The query does not include 'SELECT * FROM '. Example:
* PUBLIC.TEST WHERE ID = 1
* </li><li>SCORE (float) the relevance score. This value is always 1.0
* for the native fulltext search.
* </li></ul>
*
* @param conn the connection
......@@ -270,6 +277,9 @@ public class FullText {
* names. The column names are quoted if necessary. Example: (ID) </li>
* <li>KEYS (array of values): comma separated list of values. Example: (1)
* </li>
* <li>SCORE (float) the relevance score. This value is always 1.0
* for the native fulltext search.
* </li>
* </ul>
*
* @param conn the connection
......@@ -377,6 +387,7 @@ public class FullText {
} else {
result.addColumn(FullText.FIELD_QUERY, Types.VARCHAR, 0, 0);
}
result.addColumn(FullText.FIELD_SCORE, Types.FLOAT, 0, 0);
return result;
}
......@@ -501,7 +512,17 @@ public class FullText {
}
}
private static ResultSet search(Connection conn, String text, int limit, int offset, boolean data) throws SQLException {
/**
* Do the search.
*
* @param conn the database connection
* @param text the query
* @param limit the limit
* @param offset the offset
* @param data whether the raw data should be returned
* @return the result set
*/
protected static ResultSet search(Connection conn, String text, int limit, int offset, boolean data) throws SQLException {
SimpleResultSet result = createResultSet(data);
if (conn.getMetaData().getURL().startsWith("jdbc:columnlist:")) {
// this is just to query the result set columns
......@@ -559,12 +580,13 @@ public class FullText {
index.schema,
index.table,
columnData[0],
columnData[1]);
columnData[1],
1.0);
} else {
String query = StringUtils.quoteIdentifier(index.schema) +
"." + StringUtils.quoteIdentifier(index.table) +
" WHERE " + key;
result.addRow(query);
result.addRow(query, 1.0);
}
rowCount++;
if (limit > 0 && rowCount >= limit) {
......@@ -603,7 +625,7 @@ public class FullText {
* @param set the hash set
* @param reader the reader
*/
static void addWords(FullTextSettings setting, HashSet<String> set, Reader reader) throws SQLException {
protected static void addWords(FullTextSettings setting, HashSet<String> set, Reader reader) throws SQLException {
StreamTokenizer tokenizer = new StreamTokenizer(reader);
tokenizer.resetSyntax();
tokenizer.wordChars(' ' + 1, 255);
......@@ -628,14 +650,14 @@ public class FullText {
}
}
/**
/**
* Add all words in the given text to the hash set.
*
* @param setting the fulltext settings
* @param set the hash set
* @param text the text
*/
static void addWords(FullTextSettings setting, HashSet<String> set, String text) {
protected static void addWords(FullTextSettings setting, HashSet<String> set, String text) {
StringTokenizer tokenizer = new StringTokenizer(text, " \t\n\r\f+\"*%&/()=?'!,.;:-_#@|^~`{}[]");
while (tokenizer.hasMoreTokens()) {
String word = tokenizer.nextToken();
......@@ -646,7 +668,14 @@ public class FullText {
}
}
private static void createTrigger(Connection conn, String schema, String table) throws SQLException {
/**
* Create the trigger.
*
* @param conn the database connection
* @param schema the schema name
* @param table the table name
*/
protected static void createTrigger(Connection conn, String schema, String table) throws SQLException {
createOrDropTrigger(conn, schema, table, true);
}
......@@ -669,7 +698,14 @@ public class FullText {
}
}
private static void indexExistingRows(Connection conn, String schema, String table) throws SQLException {
/**
* Add the existing data to the index.
*
* @param conn the database connection
* @param schema the schema name
* @param table the table name
*/
protected static void indexExistingRows(Connection conn, String schema, String table) throws SQLException {
FullText.FullTextTrigger existing = new FullText.FullTextTrigger();
existing.init(conn, schema, null, table, false, Trigger.INSERT);
String sql = "SELECT * FROM " + StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(table);
......@@ -720,7 +756,7 @@ public class FullText {
* @param indexColumns the indexed columns
* @return true if the indexed columns don't match
*/
static boolean hasChanged(Object[] oldRow, Object[] newRow, int[] indexColumns) {
protected static boolean hasChanged(Object[] oldRow, Object[] newRow, int[] indexColumns) {
for (int c : indexColumns) {
Object o = oldRow[c], n = newRow[c];
if (o == null) {
......@@ -739,12 +775,12 @@ public class FullText {
*/
public static class FullTextTrigger implements Trigger, CloseListener {
private FullTextSettings setting;
private IndexInfo index;
private int[] columnTypes;
private PreparedStatement prepInsertWord, prepInsertRow, prepInsertMap;
private PreparedStatement prepDeleteRow, prepDeleteMap;
private PreparedStatement prepSelectRow;
protected FullTextSettings setting;
protected IndexInfo index;
protected int[] columnTypes;
protected PreparedStatement prepInsertWord, prepInsertRow, prepInsertMap;
protected PreparedStatement prepDeleteRow, prepDeleteMap;
protected PreparedStatement prepSelectRow;
/**
* INTERNAL
......@@ -859,7 +895,13 @@ public class FullText {
setting.removeIndexInfo(index);
}
private void insert(FullTextSettings setting, Object[] row) throws SQLException {
/**
* Add a row to the index.
*
* @param setting the setting
* @param row the row
*/
protected void insert(FullTextSettings setting, Object[] row) throws SQLException {
String key = getKey(row);
int hash = key.hashCode();
prepInsertRow.setInt(1, hash);
......@@ -877,7 +919,13 @@ public class FullText {
}
}
private void delete(FullTextSettings setting, Object[] row) throws SQLException {
/**
* Delete a row from the index.
*
* @param setting the setting
* @param row the row
*/
protected void delete(FullTextSettings setting, Object[] row) throws SQLException {
String key = getKey(row);
int hash = key.hashCode();
prepSelectRow.setInt(1, hash);
......
......@@ -53,7 +53,7 @@ public class FullTextLucene extends FullText {
/**
* Whether the text content should be stored in the Lucene index.
*/
static final boolean STORE_DOCUMENT_TEXT_IN_INDEX = Boolean.getBoolean("h2.storeDocumentTextInIndex");
protected static final boolean STORE_DOCUMENT_TEXT_IN_INDEX = Boolean.getBoolean("h2.storeDocumentTextInIndex");
//## Java 1.4 begin ##
private static final HashMap<String, IndexModifier> INDEX_MODIFIERS = New.hashMap();
......@@ -169,6 +169,7 @@ public class FullTextLucene extends FullText {
* <ul><li>QUERY (varchar): the query to use to get the data.
* The query does not include 'SELECT * FROM '. Example:
* PUBLIC.TEST WHERE ID = 1
* </li><li>SCORE (float) the relevance score as returned by Lucene.
* </li></ul>
*
* @param conn the connection
......@@ -193,6 +194,7 @@ public class FullTextLucene extends FullText {
* <li>COLUMNS (array of varchar): comma separated list of quoted column
* names. The column names are quoted if necessary. Example: (ID) </li>
* <li>KEYS (array of values): comma separated list of values. Example: (1)
* </li><li>SCORE (float) the relevance score as returned by Lucene.
* </li>
* </ul>
*
......@@ -213,13 +215,20 @@ public class FullTextLucene extends FullText {
* @param e the original exception
* @return the converted SQL exception
*/
static SQLException convertException(Exception e) {
protected static SQLException convertException(Exception e) {
SQLException e2 = new SQLException("FULLTEXT", "Error while indexing document");
e2.initCause(e);
return e2;
}
private static void createTrigger(Connection conn, String schema, String table) throws SQLException {
/**
* Create the trigger.
*
* @param conn the database connection
* @param schema the schema name
* @param table the table name
*/
protected static void createTrigger(Connection conn, String schema, String table) throws SQLException {
Statement stat = conn.createStatement();
String trigger = StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(TRIGGER_PREFIX + table);
stat.execute("DROP TRIGGER IF EXISTS " + trigger);
......@@ -241,7 +250,7 @@ public class FullTextLucene extends FullText {
* @param conn the connection
* @return the index modifier
*/
static IndexModifier getIndexModifier(Connection conn) throws SQLException {
protected static IndexModifier getIndexModifier(Connection conn) throws SQLException {
String path = getIndexPath(conn);
IndexModifier indexer;
synchronized (INDEX_MODIFIERS) {
......@@ -266,7 +275,7 @@ public class FullTextLucene extends FullText {
* @param conn the database connection
* @return the path
*/
static String getIndexPath(Connection conn) throws SQLException {
protected static String getIndexPath(Connection conn) throws SQLException {
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("CALL DATABASE_PATH()");
rs.next();
......@@ -278,7 +287,14 @@ public class FullTextLucene extends FullText {
return path;
}
private static void indexExistingRows(Connection conn, String schema, String table) throws SQLException {
/**
* Add the existing data to the index.
*
* @param conn the database connection
* @param schema the schema name
* @param table the table name
*/
protected static void indexExistingRows(Connection conn, String schema, String table) throws SQLException {
FullTextLucene.FullTextTrigger existing = new FullTextLucene.FullTextTrigger();
existing.init(conn, schema, null, table, false, Trigger.INSERT);
String sql = "SELECT * FROM " + StringUtils.quoteIdentifier(schema) + "." + StringUtils.quoteIdentifier(table);
......@@ -308,7 +324,7 @@ public class FullTextLucene extends FullText {
* @param indexModifier the index modifier
* @param indexPath the index path
*/
static void removeIndexModifier(IndexModifier indexModifier, String indexPath) throws SQLException {
protected static void removeIndexModifier(IndexModifier indexModifier, String indexPath) throws SQLException {
synchronized (INDEX_MODIFIERS) {
try {
INDEX_MODIFIERS.remove(indexPath);
......@@ -320,7 +336,17 @@ public class FullTextLucene extends FullText {
}
}
private static ResultSet search(Connection conn, String text, int limit, int offset, boolean data) throws SQLException {
/**
* Do the search.
*
* @param conn the database connection
* @param text the query
* @param limit the limit
* @param offset the offset
* @param data whether the raw data should be returned
* @return the result set
*/
protected static ResultSet search(Connection conn, String text, int limit, int offset, boolean data) throws SQLException {
SimpleResultSet result = createResultSet(data);
if (conn.getMetaData().getURL().startsWith("jdbc:columnlist:")) {
// this is just to query the result set columns
......@@ -345,6 +371,7 @@ public class FullTextLucene extends FullText {
}
for (int i = 0; i < limit && i + offset < max; i++) {
Document doc = hits.doc(i + offset);
float score = hits.score(i + offset);
String q = doc.get(FIELD_QUERY);
if (data) {
int idx = q.indexOf(" WHERE ");
......@@ -361,9 +388,10 @@ public class FullTextLucene extends FullText {
schemaName,
tableName,
columnData[0],
columnData[1]);
columnData[1],
score);
} else {
result.addRow(q);
result.addRow(q, score);
}
}
// TODO keep it open if possible
......@@ -385,14 +413,14 @@ public class FullTextLucene extends FullText {
{
//## Java 1.4 begin ##
private String schema;
private String table;
private int[] keys;
private int[] indexColumns;
private String[] columns;
private int[] columnTypes;
private String indexPath;
private IndexModifier indexModifier;
protected String schema;
protected String table;
protected int[] keys;
protected int[] indexColumns;
protected String[] columns;
protected int[] columnTypes;
protected String indexPath;
protected IndexModifier indexModifier;
//## Java 1.4 end ##
/**
......@@ -504,7 +532,12 @@ public class FullTextLucene extends FullText {
// ignore
}
private void insert(Object[] row) throws SQLException {
/**
* Add a row to the index.
*
* @param row the row
*/
protected void insert(Object[] row) throws SQLException {
String query = getQuery(row);
Document doc = new Document();
doc.add(new Field(FIELD_QUERY, query, Field.Store.YES, Field.Index.UN_TOKENIZED));
......@@ -528,7 +561,12 @@ public class FullTextLucene extends FullText {
}
}
private void delete(Object[] row) throws SQLException {
/**
* Delete a row from the index.
*
* @param row the row
*/
protected void delete(Object[] row) throws SQLException {
String query = getQuery(row);
try {
Term term = new Term(FIELD_QUERY, query);
......
......@@ -19,25 +19,60 @@ import org.h2.util.SoftHashMap;
/**
* The global settings of a full text search.
*/
class FullTextSettings {
public class FullTextSettings {
private static final HashMap<String, FullTextSettings> SETTINGS = New.hashMap();
/**
* The settings of open indexes.
*/
protected static final HashMap<String, FullTextSettings> SETTINGS = New.hashMap();
private boolean initialized;
private HashSet<String> ignoreList = New.hashSet();
private HashMap<String, Integer> words = New.hashMap();
private HashMap<Integer, IndexInfo> indexes = New.hashMap();
private SoftHashMap<String, PreparedStatement> cache = new SoftHashMap<String, PreparedStatement>();
/**
* Whether this instance has been initialized.
*/
protected boolean initialized;
private FullTextSettings() {
/**
* The set of words not to index (stop words).
*/
protected HashSet<String> ignoreList = New.hashSet();
/**
* The set of words / terms.
*/
protected HashMap<String, Integer> words = New.hashMap();
/**
* The set of indexes in this database.
*/
protected HashMap<Integer, IndexInfo> indexes = New.hashMap();
/**
* The prepared statement cache.
*/
protected SoftHashMap<String, PreparedStatement> cache = new SoftHashMap<String, PreparedStatement>();
/**
* Create a new instance.
*/
protected FullTextSettings() {
// don't allow construction
}
HashSet<String> getIgnoreList() {
/**
* Get the ignore list.
*
* @return the ignore list
*/
protected HashSet<String> getIgnoreList() {
return ignoreList;
}
HashMap<String, Integer> getWordList() {
/**
* Get the word list.
*
* @return the word list
*/
protected HashMap<String, Integer> getWordList() {
return words;
}
......@@ -47,7 +82,7 @@ class FullTextSettings {
* @param indexId the index id
* @return the index info
*/
IndexInfo getIndexInfo(int indexId) {
protected IndexInfo getIndexInfo(int indexId) {
return indexes.get(indexId);
}
......@@ -56,7 +91,7 @@ class FullTextSettings {
*
* @param index the index
*/
void addIndexInfo(IndexInfo index) {
protected void addIndexInfo(IndexInfo index) {
indexes.put(index.id, index);
}
......@@ -67,7 +102,7 @@ class FullTextSettings {
* @param word the word to convert and check
* @return the uppercase version of the word or null
*/
String convertWord(String word) {
protected String convertWord(String word) {
// TODO this is locale specific, document
word = word.toUpperCase();
if (ignoreList.contains(word)) {
......@@ -82,7 +117,7 @@ class FullTextSettings {
* @param conn the connection
* @return the settings
*/
static FullTextSettings getInstance(Connection conn) throws SQLException {
protected static FullTextSettings getInstance(Connection conn) throws SQLException {
String path = getIndexPath(conn);
FullTextSettings setting = SETTINGS.get(path);
if (setting == null) {
......@@ -92,7 +127,13 @@ class FullTextSettings {
return setting;
}
private static String getIndexPath(Connection conn) throws SQLException {
/**
* Get the file system path.
*
* @param conn the connection
* @return the file system path
*/
protected static String getIndexPath(Connection conn) throws SQLException {
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("CALL IFNULL(DATABASE_PATH(), 'MEM:' || DATABASE())");
rs.next();
......@@ -111,7 +152,7 @@ class FullTextSettings {
* @param sql the statement
* @return the prepared statement
*/
synchronized PreparedStatement prepare(Connection conn, String sql) throws SQLException {
protected synchronized PreparedStatement prepare(Connection conn, String sql) throws SQLException {
PreparedStatement prep = cache.get(sql);
if (prep != null && prep.getConnection().isClosed()) {
prep = null;
......@@ -126,7 +167,7 @@ class FullTextSettings {
/**
* Remove all indexes from the settings.
*/
void removeAllIndexes() {
protected void removeAllIndexes() {
indexes.clear();
}
......@@ -135,15 +176,25 @@ class FullTextSettings {
*
* @param index the index to remove
*/
void removeIndexInfo(IndexInfo index) {
protected void removeIndexInfo(IndexInfo index) {
indexes.remove(index.id);
}
void setInitialized(boolean b) {
/**
* Set the initialized flag.
*
* @param b the new value
*/
protected void setInitialized(boolean b) {
this.initialized = b;
}
boolean isInitialized() {
/**
* Get the initialized flag.
*
* @return whether this instance is initialized
*/
protected boolean isInitialized() {
return initialized;
}
......
......@@ -9,35 +9,35 @@ package org.h2.fulltext;
/**
* The settings of one full text search index.
*/
class IndexInfo {
public class IndexInfo {
/**
* The index id.
*/
int id;
protected int id;
/**
* The schema name.
*/
String schema;
protected String schema;
/**
* The table name.
*/
String table;
protected String table;
/**
* The column indexes of the key columns.
*/
int[] keys;
protected int[] keys;
/**
* The column indexes of the index columns.
*/
int[] indexColumns;
protected int[] indexColumns;
/**
* The column names.
*/
String[] columns;
protected String[] columns;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论