You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2014/03/29 18:32:18 UTC
svn commit: r1583032 - in /db/derby/code/trunk: ./ java/engine/
java/engine/org/apache/derby/impl/optional/lucene/
java/engine/org/apache/derby/optional/
java/testing/org/apache/derbyTesting/functionTests/tests/lang/
Author: rhillegas
Date: Sat Mar 29 17:32:18 2014
New Revision: 1583032
URL: http://svn.apache.org/r1583032
Log:
DERBY-590: Make the Lucene plugin locale-sensitive; commit derby-590-09-aa-localeSensitiveAnalysis.diff.
Added:
db/derby/code/trunk/java/engine/org/apache/derby/optional/
db/derby/code/trunk/java/engine/org/apache/derby/optional/LuceneUtils.java (with props)
db/derby/code/trunk/java/engine/org/apache/derby/optional/build.xml (with props)
Modified:
db/derby/code/trunk/build.xml
db/derby/code/trunk/java/engine/build.xml
db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneListIndexesVTI.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneQueryVTI.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneSupport.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/build.xml
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCollationTest.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportTest.java
Modified: db/derby/code/trunk/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/build.xml?rev=1583032&r1=1583031&r2=1583032&view=diff
==============================================================================
--- db/derby/code/trunk/build.xml (original)
+++ db/derby/code/trunk/build.xml Sat Mar 29 17:32:18 2014
@@ -1072,7 +1072,7 @@
<javadoc sourcepath="${out.javadoc.dir}/sourcedir"
bootclasspath="${bootClasspath}"
- classpath="${bootClasspath};${osgi};${servlet24};${out.dir}"
+ classpath="${bootClasspath};${osgi};${servlet24};${out.dir};${jars.javadoc}"
breakiterator="true"
destdir="${public.api.dir}"
Overview="${basedir}/published_api_overview.html"
Modified: db/derby/code/trunk/java/engine/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/build.xml?rev=1583032&r1=1583031&r2=1583032&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/build.xml (original)
+++ db/derby/code/trunk/java/engine/build.xml Sat Mar 29 17:32:18 2014
@@ -66,6 +66,7 @@
<ant dir="${derby.engine.dir}/jdbc"/>
<ant dir="${derby.engine.dir}/osgi"/>
<ant dir="${derby.engine.dir}/catalog"/>
+ <ant dir="${derby.engine.dir}/optional"/>
<ant dir="${derby.engine.dir}/diag"/>
<copy todir="${out.dir}/${derby.dir}">
<fileset dir="${derby.engine.dir}">
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneListIndexesVTI.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneListIndexesVTI.java?rev=1583032&r1=1583031&r2=1583032&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneListIndexesVTI.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneListIndexesVTI.java Sat Mar 29 17:32:18 2014
@@ -25,9 +25,12 @@ import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.security.PrivilegedActionException;
+import java.sql.Connection;
import java.sql.SQLException;
+import java.sql.Timestamp;
import java.text.DateFormat;
import java.util.ArrayList;
+import java.util.Properties;
import org.apache.derby.shared.common.reference.SQLState;
import org.apache.derby.vti.StringColumnVTI;
@@ -37,12 +40,17 @@ import org.apache.derby.vti.StringColumn
* See org.apache.derby.impl.optional.lucene.LuceneSupport.listIndexes.
*
*/
-public class LuceneListIndexesVTI extends StringColumnVTI {
-
- File[] indexes;
- int row = -1;
- String schema, table;
-
+public class LuceneListIndexesVTI extends StringColumnVTI
+{
+ private Connection connection;
+ private File[] indexes;
+ private int row = -1;
+
+ private String schema;
+ private String table;
+ private String column;
+ private Properties rowProperties;
+
/**
* Return a new LuceneListIndexesVTI.
*
@@ -51,9 +59,21 @@ public class LuceneListIndexesVTI extend
public LuceneListIndexesVTI()
throws IOException, PrivilegedActionException, SQLException
{
- super( new String[] { "SCHEMANAME","TABLENAME","COLUMNNAME","LASTUPDATED" } );
+ super
+ ( new String[]
+ {
+ "SCHEMANAME",
+ "TABLENAME",
+ "COLUMNNAME",
+ "LASTUPDATED",
+ "LUCENEVERSION",
+ "ANALYZER",
+ "ANALYZERMAKER",
+ }
+ );
- String dir = LuceneSupport.getIndexLocation( LuceneSupport.getDefaultConnection(), null, null, null );
+ connection = LuceneSupport.getDefaultConnection();
+ String dir = LuceneSupport.getIndexLocation( connection, null, null, null );
File luceneDir = new File(dir);
DirFilter dirFilter = new DirFilter();
@@ -80,11 +100,23 @@ public class LuceneListIndexesVTI extend
allIndexes.toArray( indexes );
}
- public void close() throws SQLException {
-
+ public void close() throws SQLException
+ {
+ connection = null;
+ indexes = null;
+ schema = null;
+ table = null;
+ column = null;
+ rowProperties = null;
}
- public boolean next() throws SQLException {
+ public boolean next() throws SQLException
+ {
+ schema = null;
+ table = null;
+ column = null;
+ rowProperties = null;
+
row++;
if (row < indexes.length) {
return true;
@@ -100,29 +132,39 @@ public class LuceneListIndexesVTI extend
* 4 == column name
* 5 == last modified
*/
- protected String getRawColumn(int col) throws SQLException {
-
- File columnDir = indexes[ row ];
- String columnPart = columnDir.getName();
- File tableDir = columnDir.getParentFile();
- String tablePart = tableDir.getName();
- File schemaDir = tableDir.getParentFile();
- String schemaPart = schemaDir.getName();
-
- if (col == 1) {
- return schemaPart;
- } else if (col == 2) {
- return tablePart;
- } else if (col == 3) {
- return columnPart;
- } else if (col == 4) {
+ protected String getRawColumn( int col ) throws SQLException
+ {
+ readSchemaTableColumn();
+
+ switch( col )
+ {
+ case 1: return schema;
+ case 2: return table;
+ case 3: return column;
+ case 5: return getProperty( LuceneSupport.LUCENE_VERSION );
+ case 6: return getProperty( LuceneSupport.ANALYZER );
+ case 7: return getProperty( LuceneSupport.ANALYZER_MAKER );
+ default:
+ throw LuceneSupport.newSQLException
+ (
+ SQLState.LANG_INVALID_COLUMN_POSITION,
+ new Integer( col ),
+ new Integer( getColumnCount() )
+ );
+ }
+ /*
try {
DateFormat df = DateFormat.getDateTimeInstance();
return df.format( LuceneSupport.getLastModified( columnDir ) );
}
catch (Exception e) { throw LuceneSupport.wrap( e ); }
- }
- else
+ */
+ }
+
+ /** Get the timestamp value of the 1-based column id */
+ public Timestamp getTimestamp( int col ) throws SQLException
+ {
+ if ( col != 4 )
{
throw LuceneSupport.newSQLException
(
@@ -130,12 +172,59 @@ public class LuceneListIndexesVTI extend
new Integer( col ),
new Integer( getColumnCount() )
);
- }
- }
+ }
+
+ try {
+ long timestampMillis = Long.parseLong( getProperty( LuceneSupport.UPDATE_TIMESTAMP ) );
+
+ return new Timestamp( timestampMillis );
+ }
+ catch (NumberFormatException nfe) { throw LuceneSupport.wrap( nfe ); }
+ }
+
public static class DirFilter implements FileFilter
{
public boolean accept( File file ) { return file.isDirectory(); }
}
+ /** Fill in the schema, table, and column names */
+ private void readSchemaTableColumn()
+ throws SQLException
+ {
+ if ( column != null ) { return; }
+
+ File columnDir = indexes[ row ];
+ column = columnDir.getName();
+ File tableDir = columnDir.getParentFile();
+ table = tableDir.getName();
+ File schemaDir = tableDir.getParentFile();
+ schema = schemaDir.getName();
+ }
+
+ /** get the string value of a property from the row properties */
+ private String getProperty( String key )
+ throws SQLException
+ {
+ return getRowProperties().getProperty( key );
+ }
+
+ /** get the properties of the current row */
+ private Properties getRowProperties()
+ throws SQLException
+ {
+ if ( rowProperties == null )
+ {
+ try {
+ readSchemaTableColumn();
+ File indexPropertiesFile = LuceneSupport.getIndexPropertiesFile( connection, schema, table, column );
+ rowProperties = LuceneSupport.readIndexProperties( indexPropertiesFile );
+ }
+ catch (IOException ioe) { throw LuceneSupport.wrap( ioe ); }
+ catch (PrivilegedActionException pae) { throw LuceneSupport.wrap( pae ); }
+ }
+
+ return rowProperties;
+ }
+
}
\ No newline at end of file
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneQueryVTI.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneQueryVTI.java?rev=1583032&r1=1583031&r2=1583032&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneQueryVTI.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneQueryVTI.java Sat Mar 29 17:32:18 2014
@@ -23,6 +23,7 @@ package org.apache.derby.impl.optional.l
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import java.security.PrivilegedActionException;
import java.sql.Connection;
import java.sql.Date;
@@ -30,8 +31,10 @@ import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
+import java.util.Properties;
import org.apache.derby.shared.common.reference.SQLState;
+import org.apache.derby.optional.LuceneUtils;
import org.apache.derby.vti.RestrictedVTI;
import org.apache.derby.vti.Restriction;
import org.apache.derby.vti.Restriction.ColumnQualifier;
@@ -417,12 +420,16 @@ public class LuceneQueryVTI extends Stri
// make sure the user has SELECT privilege on all relevant columns of the underlying table
vetPrivileges();
- String indexhome = LuceneSupport.getIndexLocation( _connection, _schema, _table, _column);
+ String indexhome = LuceneSupport.getIndexLocation( _connection, _schema, _table, _column);
+ File propertiesFile = LuceneSupport.getIndexPropertiesFile( _connection, _schema, _table, _column );
+ Properties indexProperties = LuceneSupport.readIndexProperties( propertiesFile );
+ String analyzerMaker = indexProperties.getProperty( LuceneSupport.ANALYZER_MAKER );
+ Analyzer analyzer = LuceneSupport.getAnalyzer( analyzerMaker );
_indexReader = LuceneSupport.getIndexReader( new File( indexhome.toString() ) );
_searcher = new IndexSearcher(_indexReader);
- Analyzer analyzer = new StandardAnalyzer( Version.LUCENE_45 );
- QueryParser qp = new QueryParser( Version.LUCENE_45, TEXT_FIELD_NAME, analyzer );
+
+ QueryParser qp = new QueryParser( LuceneUtils.currentVersion(), TEXT_FIELD_NAME, analyzer );
Query luceneQuery = qp.parse( _queryText );
TopScoreDocCollector tsdc = TopScoreDocCollector.create(1000, true);
if ( _rankCutoff != 0 ) {
@@ -435,6 +442,10 @@ public class LuceneQueryVTI extends Stri
catch (IOException ioe) { throw LuceneSupport.wrap( ioe ); }
catch (ParseException pe) { throw LuceneSupport.wrap( pe ); }
catch (PrivilegedActionException pae) { throw LuceneSupport.wrap( pae ); }
+ catch (ClassNotFoundException cnfe) { throw LuceneSupport.wrap( cnfe ); }
+ catch (IllegalAccessException iae) { throw LuceneSupport.wrap( iae ); }
+ catch (InvocationTargetException ite) { throw LuceneSupport.wrap( ite ); }
+ catch (NoSuchMethodException nsme) { throw LuceneSupport.wrap( nsme ); }
}
/**
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneSupport.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneSupport.java?rev=1583032&r1=1583031&r2=1583032&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneSupport.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/LuceneSupport.java Sat Mar 29 17:32:18 2014
@@ -23,7 +23,11 @@ package org.apache.derby.impl.optional.l
import java.io.File;
import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.security.AccessController;
import java.security.PrivilegedActionException;
@@ -41,12 +45,14 @@ import java.sql.Timestamp;
import java.sql.Types;
import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Properties;
import org.apache.derby.iapi.sql.dictionary.OptionalTool;
import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.util.IdUtil;
import org.apache.derby.impl.jdbc.EmbedConnection;
import org.apache.derby.shared.common.reference.SQLState;
+import org.apache.derby.optional.LuceneUtils;
import org.apache.derby.vti.Restriction.ColumnQualifier;
import org.apache.derby.vti.VTITemplate;
@@ -91,6 +97,23 @@ public class LuceneSupport implements Op
static final int TABLE_PART = 0;
static final int COLUMN_PART = TABLE_PART + 1;
static final int PART_COUNT = COLUMN_PART + 1;
+
+ // file which holds properties specific to a Lucene index
+ private static final String PROPERTIES_FILE_NAME = "derby-lucene.properties";
+
+ // properties which go in that file
+
+ /** property identifying the static method which materializes an Analyzer for the index */
+ public static final String ANALYZER_MAKER = "derby.lucene.analyzer.maker";
+
+ /** class name of the Analyzer used for the index */
+ public static final String ANALYZER = "derby.lucene.analyzer";
+
+ /** version of Lucene used to create or recreate an index */
+ public static final String LUCENE_VERSION = "derby.lucene.version";
+
+ /** system time when the index was created/updated */
+ public static final String UPDATE_TIMESTAMP = "derby.lucene.last.updated";
/////////////////////////////////////////////////////////////////////
//
@@ -130,7 +153,10 @@ public class LuceneSupport implements Op
listFunction.append("schemaname varchar( 128 ),");
listFunction.append("tablename varchar( 128 ),");
listFunction.append("columnname varchar( 128 ),");
- listFunction.append("lastupdated timestamp");
+ listFunction.append("lastupdated timestamp,");
+ listFunction.append("luceneversion varchar( 20 ),");
+ listFunction.append("analyzer varchar( 32672 ),");
+ listFunction.append("analyzermaker varchar( 32672 )");
listFunction.append(")");
listFunction.append("language java ");
listFunction.append("parameter style DERBY_JDBC_RESULT_SET ");
@@ -143,7 +169,8 @@ public class LuceneSupport implements Op
createProcedure.append("create procedure " + CREATE_INDEX );
createProcedure.append(" (schemaname varchar( 128 ),");
createProcedure.append("tablename varchar( 128 ),");
- createProcedure.append("textcolumn varchar( 128 ))");
+ createProcedure.append("textcolumn varchar( 128 ),");
+ createProcedure.append("analyzerMaker varchar( 32672 ))");
createProcedure.append("parameter style java modifies sql data language java external name ");
createProcedure.append("'" + getClass().getName() + ".createIndex'");
@@ -163,7 +190,8 @@ public class LuceneSupport implements Op
updateProcedure.append("create procedure " + UPDATE_INDEX );
updateProcedure.append(" (schemaname varchar( 128 ),");
updateProcedure.append("tablename varchar( 128 ),");
- updateProcedure.append("textcolumn varchar( 128 ))");
+ updateProcedure.append("textcolumn varchar( 128 ),");
+ updateProcedure.append("analyzerMaker varchar( 32672 ))");
updateProcedure.append("parameter style java reads sql data language java external name ");
updateProcedure.append("'" + getClass().getName() + ".updateIndex'");
@@ -300,11 +328,13 @@ public class LuceneSupport implements Op
* @param schema Schema where the indexed column resides
* @param table table where the indexed column resides
* @param textcol the indexed column
+ * @param analyzerMaker name of static method which instantiates an Analyzer. may be null.
* @throws SQLException
* @throws IOException
*/
- public static void updateIndex( String schema, String table, String textcol )
- throws SQLException, IOException, PrivilegedActionException
+ public static void updateIndex( String schema, String table, String textcol, String analyzerMaker )
+ throws SQLException, IOException, PrivilegedActionException,
+ ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
Connection conn = getDefaultConnection();
@@ -316,7 +346,7 @@ public class LuceneSupport implements Op
throw newSQLException( SQLState.LUCENE_INDEX_DOES_NOT_EXIST );
}
- createOrRecreateIndex( conn, schema, table, textcol, false );
+ createOrRecreateIndex( conn, schema, table, textcol, analyzerMaker, false );
}
/////////////////////////////////////////////////////////////////////
@@ -331,11 +361,13 @@ public class LuceneSupport implements Op
* @param schema The schema of the column to index
* @param table The table of the column to index
* @param textcol The column to create the Lucene index on
+ * @param analyzerMaker name of static method which instantiates an Analyzer. may be null.
* @throws SQLException
* @throws IOException
*/
- public static void createIndex( String schema, String table, String textcol )
- throws SQLException, IOException, PrivilegedActionException
+ public static void createIndex( String schema, String table, String textcol, String analyzerMaker )
+ throws SQLException, IOException, PrivilegedActionException,
+ ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
Connection conn = getDefaultConnection();
DatabaseMetaData dbmd = conn.getMetaData();
@@ -343,7 +375,7 @@ public class LuceneSupport implements Op
// First make sure that the text column exists and is a String type
vetTextColumn( dbmd, schema, table, textcol );
- createOrRecreateIndex( conn, schema, table, textcol, true );
+ createOrRecreateIndex( conn, schema, table, textcol, analyzerMaker, true );
}
/**
@@ -352,6 +384,7 @@ public class LuceneSupport implements Op
* @param schema The schema of the column to index
* @param table The table of the column to index
* @param textcol The column to create the Lucene index on
+ * @param analyzerMaker name of static method which instantiates an Analyzer. may be null.
* @param create True if the index is to be created, false if it is to be recreated
* @throws SQLException
* @throws IOException
@@ -362,9 +395,11 @@ public class LuceneSupport implements Op
String schema,
String table,
String textcol,
+ String analyzerMaker,
boolean create
)
- throws SQLException, IOException, PrivilegedActionException
+ throws SQLException, IOException, PrivilegedActionException,
+ ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
VTITemplate.ColumnDescriptor[] primaryKeys = getPrimaryKeys( conn, schema, table );
if ( primaryKeys.length == 0 )
@@ -373,11 +408,28 @@ public class LuceneSupport implements Op
}
int keyCount = 0;
+ File propertiesFile = getIndexPropertiesFile( conn, schema, table, textcol );
+
//
// Drop the old index directory if we're recreating the index.
// We do this after verifying that the key exists.
//
- if ( !create ) { dropIndexDirectories( schema, table, textcol ); }
+ if ( !create )
+ {
+ dropIndexDirectories( schema, table, textcol );
+ }
+
+ Version luceneVersion = LuceneUtils.currentVersion();
+
+ // get the Analyzer. use the default if the user didn't specify an override
+ if ( analyzerMaker == null ) { analyzerMaker = LuceneUtils.class.getName() + ".defaultAnalyzer"; }
+ Analyzer analyzer = getAnalyzer( analyzerMaker );
+
+ Properties indexProperties = new Properties();
+ indexProperties.setProperty( LUCENE_VERSION, luceneVersion.toString() );
+ indexProperties.setProperty( UPDATE_TIMESTAMP, Long.toString( System.currentTimeMillis() ) );
+ indexProperties.setProperty( ANALYZER_MAKER, analyzerMaker );
+ indexProperties.setProperty( ANALYZER, analyzer.getClass().getName() );
StringBuilder tableFunction = new StringBuilder();
tableFunction.append( "create function " + makeTableFunctionName( schema, table, textcol ) + "\n" );
@@ -388,7 +440,7 @@ public class LuceneSupport implements Op
ResultSet rs = null;
IndexWriter iw = null;
try {
- iw = getIndexWriter( schema, table, textcol );
+ iw = getIndexWriter( luceneVersion, analyzer, schema, table, textcol );
// select all keys and the textcol from this column, add to lucene index
StringBuilder query = new StringBuilder("select ");
@@ -439,6 +491,8 @@ public class LuceneSupport implements Op
doc.add(new TextField( LuceneQueryVTI.TEXT_FIELD_NAME, textcolValue, Store.NO));
}
addDocument( iw, doc );
+
+ writeIndexProperties( propertiesFile, indexProperties );
}
}
finally
@@ -969,6 +1023,76 @@ public class LuceneSupport implements Op
/////////////////////////////////////////////////////////////////////
//
+ // MANAGE THE INDEX PROPERTIES FILE
+ //
+ /////////////////////////////////////////////////////////////////////
+
+ /**
+ * <p>
+ * Get the handle on the file holding the index properties.
+ * </p>
+ */
+ static File getIndexPropertiesFile( Connection conn, String schema, String table, String textcol )
+ throws SQLException, IOException, PrivilegedActionException
+ {
+ File indexDir = new File( getIndexLocation( conn, schema, table, textcol ) );
+ File propertiesFile = new File( indexDir, PROPERTIES_FILE_NAME );
+
+ return propertiesFile;
+ }
+
+ /** Read the index properties file */
+ static Properties readIndexProperties( final File file )
+ throws IOException, PrivilegedActionException
+ {
+ return AccessController.doPrivileged
+ (
+ new PrivilegedExceptionAction<Properties>()
+ {
+ public Properties run() throws IOException
+ {
+ if ( file == null ) { return null; }
+ else
+ {
+ Properties properties = new Properties();
+
+ properties.load( new FileInputStream( file ) );
+
+ return properties;
+ }
+ }
+ }
+ );
+ }
+
+ /** Write the index properties file */
+ private static void writeIndexProperties( final File file, final Properties properties )
+ throws IOException, PrivilegedActionException
+ {
+ AccessController.doPrivileged
+ (
+ new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws IOException
+ {
+ if ( (file == null) || (properties == null) ) { return null; }
+ else
+ {
+ FileOutputStream fos = new FileOutputStream( file );
+
+ properties.store( fos, null );
+ fos.flush();
+ fos.close();
+
+ return null;
+ }
+ }
+ }
+ );
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ //
// SQL/JDBC SUPPORT
//
/////////////////////////////////////////////////////////////////////
@@ -1309,6 +1433,23 @@ public class LuceneSupport implements Op
);
}
+ /** Return true if the file exists */
+ static boolean fileExists( final File file )
+ throws IOException, PrivilegedActionException
+ {
+ return AccessController.doPrivileged
+ (
+ new PrivilegedExceptionAction<Boolean>()
+ {
+ public Boolean run() throws IOException
+ {
+ if ( file == null ) { return false; }
+ else { return file.exists(); }
+ }
+ }
+ ).booleanValue();
+ }
+
/**
* Get the system property derby.system.home using the security manager.
* @return Returns the value of the system property derby.system.home, or user.dir if not set.
@@ -1383,6 +1524,8 @@ public class LuceneSupport implements Op
* Returns a Lucene IndexWriter, that writes inside the lucene directory inside the database
* directory.
*
+ * @param luceneVersion the version of Lucene being used
+ * @param analyzer the Analyzer being used
* @param schema The schema of the indexed column
* @param table The table of the indexed column
* @param textcol The name of the column to be indexed
@@ -1390,6 +1533,8 @@ public class LuceneSupport implements Op
*/
private static IndexWriter getIndexWriter
(
+ final Version luceneVersion,
+ final Analyzer analyzer,
final String schema,
final String table,
final String textcol
@@ -1405,10 +1550,8 @@ public class LuceneSupport implements Op
Directory dir = FSDirectory.open(new File( getIndexLocation( getDefaultConnection(), schema, table, textcol ) ) );
// allow this to be overridden in the configuration during load later.
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45);
- IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_45,
- analyzer);
- IndexWriter iw = new IndexWriter(dir, iwc);
+ IndexWriterConfig iwc = new IndexWriterConfig( luceneVersion, analyzer );
+ IndexWriter iw = new IndexWriter( dir, iwc );
return iw;
}
@@ -1480,4 +1623,30 @@ public class LuceneSupport implements Op
);
}
+ /**
+ * Invoke a static method (possibly supplied by the user) to instantiate an Analyzer.
+ * The method has no arguments.
+ */
+ static Analyzer getAnalyzer( final String analyzerMaker )
+ throws ClassNotFoundException, IllegalAccessException, InvocationTargetException,
+ NoSuchMethodException, PrivilegedActionException
+ {
+ return AccessController.doPrivileged
+ (
+ new PrivilegedExceptionAction<Analyzer>()
+ {
+ public Analyzer run()
+ throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
+ {
+ int lastDotIdx = analyzerMaker.lastIndexOf( "." );
+ Class<? extends Object> klass = Class.forName( analyzerMaker.substring( 0, lastDotIdx ) );
+ String methodName = analyzerMaker.substring( lastDotIdx + 1, analyzerMaker.length() );
+ Method method = klass.getDeclaredMethod( methodName );
+
+ return (Analyzer) method.invoke( null );
+ }
+ }
+ );
+ }
+
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/build.xml?rev=1583032&r1=1583031&r2=1583032&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/build.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/optional/lucene/build.xml Sat Mar 29 17:32:18 2014
@@ -56,6 +56,7 @@
<pathelement path="${lucene_qp}"/>
</classpath>
<include name="${derby.dir}/${cur.dir}/**"/>
+ <compilerarg value="-Xlint:unchecked"/>
</javac>
</target>
</project>
Added: db/derby/code/trunk/java/engine/org/apache/derby/optional/LuceneUtils.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/optional/LuceneUtils.java?rev=1583032&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/optional/LuceneUtils.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/optional/LuceneUtils.java Sat Mar 29 17:32:18 2014
@@ -0,0 +1,191 @@
+/*
+
+ Derby - Class org.apache.derby.optional.LuceneUtils
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+package org.apache.derby.optional;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Locale;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.util.Version;
+
+import org.apache.derby.iapi.sql.conn.ConnectionUtil;
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+
+/**
+ * <p>
+ * Utility methods for the Lucene optional tool.
+ * </p>
+ */
+public abstract class LuceneUtils
+{
+ /////////////////////////////////////////////////////////////////
+ //
+ // CONSTANTS
+ //
+ /////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // STATE
+ //
+ /////////////////////////////////////////////////////////////////
+
+ /** Map of Analyzers keyed by language code */
+ private static HashMap<String,Class<? extends Analyzer>> _analyzerClasses;
+ static
+ {
+ _analyzerClasses = new HashMap<String,Class<? extends Analyzer>>();
+
+ storeAnalyzerClass( org.apache.lucene.analysis.ar.ArabicAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.hy.ArmenianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.eu.BasqueAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.br.BrazilianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.bg.BulgarianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.ca.CatalanAnalyzer.class );
+ // deprecated, use StandardAnalyzer instead: storeAnalyzerClass( org.apache.lucene.analysis.cn.ChineseAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.cz.CzechAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.da.DanishAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.nl.DutchAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.en.EnglishAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.fi.FinnishAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.fr.FrenchAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.gl.GalicianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.de.GermanAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.el.GreekAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.hi.HindiAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.hu.HungarianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.id.IndonesianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.ga.IrishAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.it.ItalianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.lv.LatvianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.no.NorwegianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.fa.PersianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.pt.PortugueseAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.ro.RomanianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.ru.RussianAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.es.SpanishAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.sv.SwedishAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.th.ThaiAnalyzer.class );
+ storeAnalyzerClass( org.apache.lucene.analysis.tr.TurkishAnalyzer.class );
+ }
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // PUBLIC BEHAVIOR
+ //
+ /////////////////////////////////////////////////////////////////
+
+ /** Get the version of the Lucene library on the classpath. */
+ @SuppressWarnings("deprecation")
+ public static Version currentVersion()
+ {
+ Version retval = null;
+
+ // the current version is the highest one
+ for ( Version current : Version.values() )
+ {
+ if ( current == Version.LUCENE_CURRENT ) { continue; }
+
+ if ( retval == null ) { retval = current; }
+ else
+ {
+ if ( current.onOrAfter( retval ) ) { retval = current; }
+ }
+ }
+
+ return retval;
+ }
+
+ /**
+ * <p>
+ * Get the default Analyzer associated with the database Locale.
+ * </p>
+ */
+ public static Analyzer defaultAnalyzer()
+ throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, SQLException
+ {
+ return getAnalyzerForLocale( ConnectionUtil.getCurrentLCC().getDatabase().getLocale() );
+ }
+
+ /**
+ * <p>
+ * Get the Analyzer associated with the given Locale.
+ * </p>
+ */
+ public static Analyzer getAnalyzerForLocale( Locale locale )
+ throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException
+ {
+ String language = locale.getLanguage();
+
+ Class<? extends Analyzer> analyzerClass = _analyzerClasses.get( language );
+
+ if ( analyzerClass == null ) { return standardAnalyzer(); }
+ else
+ {
+ Constructor<? extends Analyzer> constructor = analyzerClass.getConstructor( Version.class );
+
+ return constructor.newInstance( currentVersion() );
+ }
+ }
+
+ /**
+ * <p>
+ * Get the StandardAnalyzer for parsing text.
+ * </p>
+ */
+ public static Analyzer standardAnalyzer()
+ {
+ return new StandardAnalyzer( currentVersion() );
+ }
+
+ /////////////////////////////////////////////////////////////////
+ //
+ // MINIONS
+ //
+ /////////////////////////////////////////////////////////////////
+
+ /** Store an Analyzer class in the HashMap of Analyzers, keyed by language code */
+ private static void storeAnalyzerClass( Class<? extends Analyzer> analyzerClass )
+ {
+ _analyzerClasses.put( getLanguageCode( analyzerClass ), analyzerClass );
+ }
+
+ /**
+ * <p>
+ * Get the language code for a Lucene Analyzer. Each of the Analyzers
+ * lives in a package whose last leg is the language code.
+ * </p>
+ */
+ private static String getLanguageCode( Class<? extends Analyzer> analyzerClass )
+ {
+ String className = analyzerClass.getName();
+ String packageName = className.substring( 0, className.lastIndexOf( "." ) );
+ String languageCode = packageName.substring( packageName.lastIndexOf( "." ) + 1, packageName.length() );
+
+ return languageCode;
+ }
+
+}
Propchange: db/derby/code/trunk/java/engine/org/apache/derby/optional/LuceneUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: db/derby/code/trunk/java/engine/org/apache/derby/optional/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/optional/build.xml?rev=1583032&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/optional/build.xml (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/optional/build.xml Sat Mar 29 17:32:18 2014
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project default="optional" basedir="../../../../../..">
+
+<!-- Set Properties -->
+ <!-- User settings -->
+ <property file="${user.home}/ant.properties"/>
+ <!-- Set property lib dir -->
+ <property name="properties.dir" value="tools/ant/properties"/>
+ <!-- Significant dirs -->
+ <property file="${properties.dir}/dirs.properties"/>
+ <!-- Compiler settings -->
+<property file="${properties.dir}/defaultcompiler.properties"/>
+ <property file="${properties.dir}/${build.compiler}.properties"/>
+ <!-- Compile-time classpath properties files -->
+ <property file="${properties.dir}/extrapath.properties"/>
+ <property file="${properties.dir}/compilepath.properties"/>
+ <property name="cur.dir" value="optional"/>
+
+<!-- Targets -->
+
+ <target name="optional">
+ <javac
+ source="1.6"
+ target="1.6"
+ bootclasspath="${empty}"
+ nowarn="on"
+ debug="${debug}"
+ depend="${depend}"
+ deprecation="${deprecation}"
+ optimize="${optimize}"
+ proceed="${proceed}"
+ verbose="${verbose}"
+ srcdir="${derby.engine.src.dir}:${generated.src.dir}"
+ destdir="${out.dir}">
+ <classpath>
+ <pathelement path="${java16compile.classpath}"/>
+ <pathelement path="${lucene_core}"/>
+ <pathelement path="${lucene_a_co}"/>
+ <pathelement path="${lucene_qp}"/>
+ </classpath>
+ <include name="${derby.dir}/${cur.dir}/**"/>
+ <compilerarg value="-Xlint:unchecked"/>
+ </javac>
+ </target>
+</project>
+
Propchange: db/derby/code/trunk/java/engine/org/apache/derby/optional/build.xml
------------------------------------------------------------------------------
svn:eol-style = native
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCollationTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCollationTest.java?rev=1583032&r1=1583031&r2=1583032&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCollationTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCollationTest.java Sat Mar 29 17:32:18 2014
@@ -53,8 +53,8 @@ public class LuceneCollationTest extends
private static final String LOAD_TOOL = "call syscs_util.syscs_register_tool( 'luceneSupport', true )";
private static final String UNLOAD_TOOL = "call syscs_util.syscs_register_tool( 'luceneSupport', false )";
- private static final String INDEX_POEMS = "call LuceneSupport.createIndex( 'ruth', 'poems', 'poemText' )";
- private static final String UPDATE_POEMS_INDEX = "call LuceneSupport.updateIndex( 'ruth', 'poems', 'poemText' )";
+ private static final String INDEX_POEMS = "call LuceneSupport.createIndex( 'ruth', 'poems', 'poemText', null )";
+ private static final String UPDATE_POEMS_INDEX = "call LuceneSupport.updateIndex( 'ruth', 'poems', 'poemText', null )";
private static final String DROP_POEMS_INDEX = "call LuceneSupport.dropIndex( 'ruth', 'poems', 'poemText' )";
///////////////////////////////////////////////////////////////////////////////////
@@ -150,11 +150,12 @@ public class LuceneCollationTest extends
assertResults
(
conn,
- "select * from table ( ruth.poems__poemText( 'star', 0 ) ) luceneResults",
+ "select * from table ( ruth.poems__poemText( 'star', 0 ) ) luceneResults order by poemID",
new String[][]
{
- { "5", "5", "4", "0.3304931" },
- { "3", "3", "2", "0.2832798" },
+ { "3", "3", "2", "0.22933942" },
+ { "4", "4", "3", "0.22933942" },
+ { "5", "5", "4", "0.26756266" },
},
false
);
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java?rev=1583032&r1=1583031&r2=1583032&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportPermsTest.java Sat Mar 29 17:32:18 2014
@@ -39,11 +39,14 @@ import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Locale;
import junit.framework.Test;
import junit.framework.TestSuite;
+import org.apache.derby.iapi.sql.conn.ConnectionUtil;
import org.apache.derbyTesting.junit.BaseJDBCTestCase;
import org.apache.derbyTesting.junit.JDBC;
import org.apache.derbyTesting.junit.DatabasePropertyTestSetup;
+import org.apache.derbyTesting.junit.LocaleTestSetup;
import org.apache.derbyTesting.junit.SecurityManagerSetup;
import org.apache.derbyTesting.junit.TestConfiguration;
import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
@@ -85,13 +88,17 @@ public class LuceneSupportPermsTest exte
private static final String LOAD_TOOL = "call syscs_util.syscs_register_tool( 'luceneSupport', true )";
private static final String UNLOAD_TOOL = "call syscs_util.syscs_register_tool( 'luceneSupport', false )";
- private static final String INDEX_POEMS = "call LuceneSupport.createIndex( 'ruth', 'poems', 'poemText' )";
- private static final String UPDATE_POEMS_INDEX = "call LuceneSupport.updateIndex( 'ruth', 'poems', 'poemText' )";
+ private static final String INDEX_POEMS = "call LuceneSupport.createIndex( 'ruth', 'poems', 'poemText', null )";
+ private static final String UPDATE_POEMS_INDEX = "call LuceneSupport.updateIndex( 'ruth', 'poems', 'poemText', null )";
private static final String DROP_POEMS_INDEX = "call LuceneSupport.dropIndex( 'ruth', 'poems', 'poemText' )";
private static final long MILLIS_IN_HOUR = 1000L * 60L * 60L;
private static final long MILLIS_IN_DAY = MILLIS_IN_HOUR * 24L;
+ private static final String LUCENE_VERSION = "LUCENE_45";
+ private static final String LANGUAGE = "en";
+ private static final String COUNTRY = "US";
+
///////////////////////////////////////////////////////////////////////////////////
//
// STATE
@@ -127,7 +134,8 @@ public class LuceneSupportPermsTest exte
{
TestSuite suite = (TestSuite) TestConfiguration.embeddedSuite(LuceneSupportPermsTest.class);
- Test secureTest = new SecurityManagerSetup( suite, POLICY_FILE );
+ Test localizedTest = new LocaleTestSetup( suite, new Locale( LANGUAGE, COUNTRY ) );
+ Test secureTest = new SecurityManagerSetup( localizedTest, POLICY_FILE );
Test authenticatedTest = DatabasePropertyTestSetup.builtinAuthentication
( secureTest, LEGAL_USERS, "LuceneSupportPermissions" );
Test authorizedTest = TestConfiguration.sqlAuthorizationDecorator( authenticatedTest );
@@ -162,7 +170,8 @@ public class LuceneSupportPermsTest exte
goodStatement( dboConnection, LOAD_TOOL );
// can't update a non-existent index
- expectExecutionError( ruthConnection, NONEXISTENT_INDEX, "call LuceneSupport.updateIndex( 'ruth', 'poems', 'poemText' )" );
+ expectExecutionError
+ ( ruthConnection, NONEXISTENT_INDEX, "call LuceneSupport.updateIndex( 'ruth', 'poems', 'poemText', null )" );
// alice does not have permission to index a table owned by ruth
expectExecutionError( aliceConnection, LACK_COLUMN_PRIV, INDEX_POEMS );
@@ -174,11 +183,12 @@ public class LuceneSupportPermsTest exte
expectExecutionError( ruthConnection, FUNCTION_EXISTS, INDEX_POEMS );
// can't update a non-existent index
- expectExecutionError( ruthConnection, NONEXISTENT_INDEX, "call LuceneSupport.updateIndex( 'ruth', 'poems', 'foo' )" );
- expectExecutionError( ruthConnection, NONEXISTENT_INDEX, "call LuceneSupport.updateIndex( 'ruth', 'poems', 'originalAuthor' )" );
+ expectExecutionError( ruthConnection, NONEXISTENT_INDEX, "call LuceneSupport.updateIndex( 'ruth', 'poems', 'foo', null )" );
+ expectExecutionError
+ ( ruthConnection, NONEXISTENT_INDEX, "call LuceneSupport.updateIndex( 'ruth', 'poems', 'originalAuthor', null )" );
// alice can't view an index created by ruth
- String viewPoemsIndex = "select * from table ( ruth.poems__poemText( 'star', 0 ) ) luceneResults";
+ String viewPoemsIndex = "select * from table ( ruth.poems__poemText( 'star', 0 ) ) luceneResults order by poemID";
expectExecutionError( aliceConnection, LACK_EXECUTE_PRIV, viewPoemsIndex );
// but ruth can
@@ -188,8 +198,9 @@ public class LuceneSupportPermsTest exte
viewPoemsIndex,
new String[][]
{
- { "5", "5", "4", "0.3304931" },
- { "3", "3", "2", "0.2832798" },
+ { "3", "3", "2", "0.22933942" },
+ { "4", "4", "3", "0.22933942" },
+ { "5", "5", "4", "0.26756266" },
},
false
);
@@ -275,11 +286,12 @@ public class LuceneSupportPermsTest exte
}
// but alice still needs select privilege on the base table columns
- String viewPoemsIndex = "select * from table ( ruth.poems__poemText( 'star', 0 ) ) luceneResults";
+ String viewPoemsIndex = "select * from table ( ruth.poems__poemText( 'star', 0 ) ) luceneResults order by poemid";
String[][] viewPoemsIndexResults = new String[][]
{
- { "5", "5", "4", "0.3304931" },
- { "3", "3", "2", "0.2832798" },
+ { "3", "3", "2", "0.22933942" },
+ { "4", "4", "3", "0.22933942" },
+ { "5", "5", "4", "0.26756266" },
};
// now alice can view the index
@@ -353,9 +365,9 @@ public class LuceneSupportPermsTest exte
expectExecutionError( dboConnection, DOUBLE_LOAD_ILLEGAL, LOAD_TOOL );
// cannot index non-existent table or column
- expectExecutionError( ruthConnection, NOT_INDEXABLE, "call LuceneSupport.createIndex( 'ruth', 'foo', 'poemText' )" );
- expectExecutionError( ruthConnection, NOT_INDEXABLE, "call LuceneSupport.createIndex( 'ruth', 'poems', 'fooText' )" );
- expectExecutionError( ruthConnection, NOT_INDEXABLE, "call LuceneSupport.createIndex( 'ruth', 'poems', 'versionStamp' )" );
+ expectExecutionError( ruthConnection, NOT_INDEXABLE, "call LuceneSupport.createIndex( 'ruth', 'foo', 'poemText', null )" );
+ expectExecutionError( ruthConnection, NOT_INDEXABLE, "call LuceneSupport.createIndex( 'ruth', 'poems', 'fooText', null )" );
+ expectExecutionError( ruthConnection, NOT_INDEXABLE, "call LuceneSupport.createIndex( 'ruth', 'poems', 'versionStamp', null )" );
// cannot drop non-existent index
expectExecutionError( ruthConnection, NONEXISTENT_OBJECT, "call LuceneSupport.dropIndex( 'ruth', 'foo', 'poemText' )" );
@@ -423,8 +435,9 @@ public class LuceneSupportPermsTest exte
"order by i.rank desc\n",
new String[][]
{
- { "Walt Whitman", "0.3304931" },
- { "John Milton", "0.2832798" },
+ { "Walt Whitman", "0.26756266" },
+ { "Lord Byron", "0.22933942" },
+ { "John Milton", "0.22933942" },
},
false
);
@@ -469,6 +482,102 @@ public class LuceneSupportPermsTest exte
dropSchema( ruthConnection );
}
+ /**
+ * <p>
+ * Test that you can change the Analyzer.
+ * </p>
+ */
+ public void test_006_changeAnalyzer()
+ throws Exception
+ {
+ Connection dboConnection = openUserConnection( TEST_DBO );
+ Connection ruthConnection = openUserConnection( RUTH );
+
+ createSchema( ruthConnection, Types.INTEGER );
+ goodStatement( dboConnection, LOAD_TOOL );
+ goodStatement( ruthConnection, INDEX_POEMS );
+
+ // verify that we are the correct locale
+ assertResults
+ (
+ ruthConnection,
+ "values ( getDatabaseLocale() )",
+ new String[][]
+ {
+ { LANGUAGE + "_" + COUNTRY },
+ },
+ false
+ );
+
+
+ String query =
+ "select p.originalAuthor, i.rank\n" +
+ "from ruth.poems p, table ( ruth.poems__poemText( 'star', 0 ) ) i\n" +
+ "where p.poemID = i.poemID and p.versionStamp = i.versionStamp\n" +
+ "order by i.rank desc\n";
+
+ assertResults
+ (
+ ruthConnection,
+ query,
+ new String[][]
+ {
+ { "Walt Whitman", "0.26756266" },
+ { "Lord Byron", "0.22933942" },
+ { "John Milton", "0.22933942" },
+ },
+ false
+ );
+
+ // now switch the Analyzer and re-run the query
+ goodStatement
+ ( ruthConnection,
+ "call LuceneSupport.updateIndex( 'ruth', 'poems', 'poemText', 'org.apache.derby.optional.LuceneUtils.standardAnalyzer' )" );
+
+ assertResults
+ (
+ ruthConnection,
+ query,
+ new String[][]
+ {
+ { "Walt Whitman", "0.3304931" },
+ { "John Milton", "0.2832798" },
+ },
+ false
+ );
+
+ //
+ // Add another index and inspect the values of listIndexes()
+ //
+ goodStatement( ruthConnection, "call LuceneSupport.createIndex( 'ruth', 'poems', 'originalAuthor', null )" );
+ assertResults
+ (
+ ruthConnection,
+ "select schemaName, tableName, columnName, luceneVersion, analyzer, analyzerMaker\n" +
+ "from table( LuceneSupport.listIndexes() ) l\n" +
+ "order by schemaName, tableName, columnName\n",
+ new String[][]
+ {
+ {
+ "RUTH", "POEMS", "ORIGINALAUTHOR", LUCENE_VERSION,
+ "org.apache.lucene.analysis.en.EnglishAnalyzer",
+ "org.apache.derby.optional.LuceneUtils.defaultAnalyzer",
+ },
+ {
+ "RUTH", "POEMS", "POEMTEXT", LUCENE_VERSION,
+ "org.apache.lucene.analysis.standard.StandardAnalyzer",
+ "org.apache.derby.optional.LuceneUtils.standardAnalyzer",
+ },
+ },
+ false
+ );
+
+ goodStatement( ruthConnection, DROP_POEMS_INDEX );
+ goodStatement( ruthConnection, "call LuceneSupport.dropIndex( 'ruth', 'poems', 'originalAuthor' )" );
+ goodStatement( dboConnection, UNLOAD_TOOL );
+ dropSchema( ruthConnection );
+ }
+
///////////////////////////////////////////////////////////////////////////////////
//
// MINIONS
@@ -478,6 +587,7 @@ public class LuceneSupportPermsTest exte
private void createSchema( Connection ruthConnection, int jdbcType ) throws Exception
{
createPoemsTable( ruthConnection, jdbcType );
+ createLocaleFunction( ruthConnection );
}
private void createPoemsTable( Connection conn, int jdbcType )
throws Exception
@@ -539,6 +649,18 @@ public class LuceneSupportPermsTest exte
ps.close();
}
+ private void createLocaleFunction( Connection conn )
+ throws Exception
+ {
+ goodStatement
+ (
+ conn,
+ "create function getDatabaseLocale() returns varchar( 20 )\n" +
+ "language java parameter style java reads sql data\n" +
+ "external name 'org.apache.derbyTesting.functionTests.tests.lang.LuceneSupportPermsTest.getDatabaseLocale()'\n"
+ );
+ }
+
private String getType( int jdbcType ) throws Exception
{
switch( jdbcType )
@@ -636,6 +758,7 @@ public class LuceneSupportPermsTest exte
private void dropSchema( Connection ruthConnection ) throws Exception
{
goodStatement( ruthConnection, "drop table poems" );
+ goodStatement( ruthConnection, "drop function getDatabaseLocale" );
}
///////////////////////////////////////////////////////////////////////////////////
@@ -644,6 +767,13 @@ public class LuceneSupportPermsTest exte
//
///////////////////////////////////////////////////////////////////////////////////
+ /** Get the database locale */
+ public static String getDatabaseLocale()
+ throws SQLException
+ {
+ return ConnectionUtil.getCurrentLCC().getDatabase().getLocale().toString();
+ }
+
public static String toString( byte[] value )
{
if ( value == null ) { return null; }
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportTest.java?rev=1583032&r1=1583031&r2=1583032&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSupportTest.java Sat Mar 29 17:32:18 2014
@@ -60,7 +60,7 @@ public class LuceneSupportTest extends B
Statement s = createStatement();
cSt = prepareCall
- ( "call LuceneSupport.createIndex('lucenetest','titles','title')" );
+ ( "call LuceneSupport.createIndex('lucenetest','titles','title', null )" );
assertUpdateCount(cSt, 0);
String[][] expectedRows = new String[][]
@@ -125,7 +125,7 @@ public class LuceneSupportTest extends B
Statement s = createStatement();
cSt = prepareCall
- ( "call LuceneSupport.createIndex('lucenetest','titles','title')" );
+ ( "call LuceneSupport.createIndex('lucenetest','titles','title', null)" );
assertUpdateCount(cSt, 0);
JDBC.assertEmpty
@@ -150,7 +150,7 @@ public class LuceneSupportTest extends B
);
cSt = prepareCall
- ( "call LuceneSupport.updateIndex('lucenetest','titles','title')" );
+ ( "call LuceneSupport.updateIndex('lucenetest','titles','title', null)" );
assertUpdateCount(cSt, 0);
String[][] expectedRows = new String[][]
@@ -178,11 +178,11 @@ public class LuceneSupportTest extends B
Statement s = createStatement();
cSt = prepareCall
- ( "call LuceneSupport.createIndex('lucenetest','titles','title')" );
+ ( "call LuceneSupport.createIndex('lucenetest','titles','title', null)" );
assertUpdateCount(cSt, 0);
cSt = prepareCall
- ( "call LuceneSupport.createIndex('lucenetest','titles','author')" );
+ ( "call LuceneSupport.createIndex('lucenetest','titles','author', null)" );
assertUpdateCount(cSt, 0);
// leave out lastmodified as the date will change