You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by se...@apache.org on 2014/12/09 17:33:15 UTC
[05/13] incubator-ignite git commit: ignite-qry - merged
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/922a2bab/modules/indexing/src/main/java/org/gridgain/grid/spi/indexing/h2/GridH2IndexingSpi.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/gridgain/grid/spi/indexing/h2/GridH2IndexingSpi.java b/modules/indexing/src/main/java/org/gridgain/grid/spi/indexing/h2/GridH2IndexingSpi.java
deleted file mode 100644
index 9d42582..0000000
--- a/modules/indexing/src/main/java/org/gridgain/grid/spi/indexing/h2/GridH2IndexingSpi.java
+++ /dev/null
@@ -1,2398 +0,0 @@
-/* @java.file.header */
-
-/* _________ _____ __________________ _____
-* __ ____/___________(_)______ /__ ____/______ ____(_)_______
-* _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
-* / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
-* \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
-*/
-
-package org.gridgain.grid.spi.indexing.h2;
-
-import org.apache.ignite.*;
-import org.apache.ignite.marshaller.*;
-import org.apache.ignite.resources.*;
-import org.apache.ignite.spi.*;
-import org.apache.ignite.spi.indexing.*;
-import org.gridgain.grid.*;
-import org.gridgain.grid.cache.query.*;
-import org.gridgain.grid.spi.indexing.h2.opt.*;
-import org.gridgain.grid.util.*;
-import org.gridgain.grid.util.offheap.unsafe.*;
-import org.gridgain.grid.util.typedef.*;
-import org.gridgain.grid.util.typedef.internal.*;
-import org.h2.api.*;
-import org.h2.command.*;
-import org.h2.constant.*;
-import org.h2.index.*;
-import org.h2.jdbc.*;
-import org.h2.message.*;
-import org.h2.mvstore.cache.*;
-import org.h2.server.web.*;
-import org.h2.table.*;
-import org.h2.tools.*;
-import org.h2.util.*;
-import org.h2.value.*;
-import org.jdk8.backport.*;
-import org.jetbrains.annotations.*;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.math.*;
-import java.sql.*;
-import java.text.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import static org.apache.ignite.IgniteSystemProperties.*;
-import static org.apache.ignite.spi.indexing.IndexType.*;
-import static org.gridgain.grid.spi.indexing.h2.opt.GridH2AbstractKeyValueRow.*;
-import static org.h2.result.SortOrder.*;
-
-/**
- * Indexing SPI implementation based on H2 database engine. In this implementation main query language is SQL,
- * fulltext indexing can be performed using Lucene or using embedded H2 mechanism. For each registered space
- * the SPI will create respective schema, for default space (where space name is null) schema
- * with name {@code PUBLIC} will be used. To avoid name conflicts user should not explicitly name
- * a schema {@code PUBLIC}.
- * <p>
- * For each registered {@link org.apache.ignite.spi.indexing.IndexingTypeDescriptor} this SPI will create respective SQL table with
- * {@code '_key'} and {@code '_val'} fields for key and value, and fields from
- * {@link org.apache.ignite.spi.indexing.IndexingTypeDescriptor#keyFields()} and {@link org.apache.ignite.spi.indexing.IndexingTypeDescriptor#valueFields()}.
- * For each table it will create indexes declared in {@link org.apache.ignite.spi.indexing.IndexingTypeDescriptor#indexes()}.
- * <p>
- * Note that you can monitor longer queries by setting {@link #setLongQueryExplain(boolean)} to {@code true}.
- * In this case a warning and execution plan are printed out if query exceeds certain time threshold. The
- * time threshold for long queries is configured via {@link #setLongQueryExecutionTimeout(long)} parameter.
- * <h1 class="header">Configuration</h1>
- * <h2 class="header">Mandatory</h2>
- * This SPI has no mandatory configuration parameters.
- * <h2 class="header">Optional</h2>
- * The following configuration parameters are optional:
- * <ul>
- * <li>Whether SPI will convert key type to SQL type or store keys in binary form
- * (see {@link #setDefaultIndexFixedTyping(boolean)})</li>
- * <li>Whether SPI will create tables for each primitive key-value pair
- * (see {@link #setDefaultIndexPrimitiveKey(boolean)})</li>
- * <li>Whether SPI will create indexes for each primitive value
- * (see {@link #setDefaultIndexPrimitiveValue(boolean)})</li>
- * <li>Search path for SQL objects (see {@link #setSearchPath(String...)})</li>
- * <li>Off-heap memory (see {@link #setMaxOffHeapMemory(long)})</li>
- * <li>Deserialized off-heap rows cache size (see {@link #setMaxOffheapRowsCacheSize(int)})</li>
- * <li>Name (see {@link #setName(String)})</li>
- * <li>SPI will issue a warning if query execution takes longer than specified period in milliseconds (see
- * {@link #setLongQueryExecutionTimeout(long)})</li>
- * <li>Whether SPI will print execution plan for slow queries (see {@link #setLongQueryExplain(boolean)})</li>
- * <li>Classes containing user defined functions (see {@link #setIndexCustomFunctionClasses(Class[])})</li>
- * <li>Per-space configurations (see {@link #setSpaceConfigurations(GridH2IndexingSpaceConfiguration...)})</li>
- * </ul>
- * <h1 class="header">Some important defaults.</h1>
- * <ul>
- * <li>All the data will be kept in memory</li>
- * <li>Primitive types will not be indexed (e.g. java types which can be directly converted to SQL types)</li>
- * <li>
- * Key types will be converted to SQL types, so it is impossible to store one value type with
- * different key types
- * </li>
- * </ul>
- * Here is a Java example on how to configure grid with {@code GridH2IndexingSpi}.
- * <pre name="code" class="java">
- * GridH2IndexingSpi spi = new GridH2IndexingSpi();
- *
- * // Set SPI name.
- * spi.setName(name);
- *
- * spi.setDefaultIndexPrimitiveKey(true);
- * spi.setDefaultIndexPrimitiveValue(true);
- *
- * GridConfiguration cfg = new GridConfiguration();
- *
- * // Overrides default indexing SPI.
- * cfg.setIndexingSpi(spi);
- *
- * // Starts grid.
- * G.start(cfg);
- * </pre>
- * Here is an example of how to configure {@code GridH2IndexingSpi} from Spring XML configuration file.
- * <pre name="code" class="xml">
- * <property name="indexingSpi">
- * <list>
- * <bean class="org.gridgain.grid.spi.indexing.h2.GridH2IndexingSpi">
- * <!-- Index primitives. -->
- * <property name="defaultIndexPrimitiveKey" value="true"/>
- *
- * <!-- Allow different key types for one value type. -->
- * <property name="defaultIndexFixedTyping" value="false"/>
- * </bean>
- * </list>
- * </property>
- * </pre>
- * <p>
- * <img src="http://www.gridgain.com/images/spring-small.png">
- * <br>
- * For information about Spring framework visit <a href="http://www.springframework.org/">www.springframework.org</a>
- * @see org.apache.ignite.spi.indexing.IndexingSpi
- */
-@IgniteSpiMultipleInstancesSupport(true)
-@SuppressWarnings({"UnnecessaryFullyQualifiedName", "NonFinalStaticVariableUsedInClassInitialization"})
-public class GridH2IndexingSpi extends IgniteSpiAdapter implements IndexingSpi, GridH2IndexingSpiMBean {
- /** Default query execution time interpreted as long query (3 seconds). */
- public static final long DFLT_LONG_QRY_EXEC_TIMEOUT = 3000;
-
- /** Default index write lock wait time in milliseconds. */
- private static final long DFLT_IDX_WRITE_LOCK_WAIT_TIME = 100;
-
- /** Default value for {@link #setUseOptimizedSerializer(boolean)} flag. */
- public static final boolean DFLT_USE_OPTIMIZED_SERIALIZER = true;
-
- /** Default DB name. */
- private static final String DFLT_DB_NAME = "gridgain_indexes";
-
- /** Default DB options. */
- private static final String DFLT_DB_OPTIONS = ";LOCK_MODE=3;MULTI_THREADED=1;DB_CLOSE_ON_EXIT=FALSE" +
- ";DEFAULT_LOCK_TIMEOUT=10000";
-
- /** Options for optimized mode to work properly. */
- private static final String OPTIMIZED_DB_OPTIONS = ";OPTIMIZE_REUSE_RESULTS=0;QUERY_CACHE_SIZE=0;" +
- "RECOMPILE_ALWAYS=1;MAX_OPERATION_MEMORY=0";
-
- /** Field name for key. */
- public static final String KEY_FIELD_NAME = "_key";
-
- /** Field name for value. */
- public static final String VAL_FIELD_NAME = "_val";
-
- /** */
- private static final Field COMMAND_FIELD;
-
- /**
- * Command in H2 prepared statement.
- */
- static {
- try {
- COMMAND_FIELD = JdbcPreparedStatement.class.getDeclaredField("command");
-
- COMMAND_FIELD.setAccessible(true);
- }
- catch (NoSuchFieldException e) {
- throw new IllegalStateException("Check H2 version in classpath.", e);
- }
- }
-
- /** */
- private static final ThreadLocal<GridH2IndexingSpi> localSpi = new ThreadLocal<>();
-
- /** */
- private Class<?>[] idxCustomFuncClss;
-
- /** */
- private String[] searchPath;
-
- /** */
- private volatile String cachedSearchPathCmd;
-
- /** */
- private String initScriptPath;
-
- /** */
- private boolean dfltIdxPrimitiveKey;
-
- /** */
- private boolean dfltIdxPrimitiveVal;
-
- /** */
- private boolean dfltIdxFixedTyping = true;
-
- /** */
- private long maxOffHeapMemory = -1;
-
- /** */
- private long longQryExecTimeout = DFLT_LONG_QRY_EXEC_TIMEOUT;
-
- /** */
- private long idxWriteLockWaitTime = DFLT_IDX_WRITE_LOCK_WAIT_TIME;
-
- /** */
- private boolean longQryExplain;
-
- /** */
- private boolean dfltEscapeAll;
-
- /** */
- private boolean useOptimizedSerializer = DFLT_USE_OPTIMIZED_SERIALIZER;
-
- /** Cache for deserialized offheap rows. */
- private CacheLongKeyLIRS<GridH2KeyValueRowOffheap> rowCache = new CacheLongKeyLIRS<>(32 * 1024, 1, 128, 256);
-
- /** */
- private Map<String, GridH2IndexingSpaceConfiguration> spaceCfgs =
- new LinkedHashMap<>();
-
- /** Logger. */
- @IgniteLoggerResource
- private IgniteLogger log;
-
- /** Node ID. */
- @IgniteLocalNodeIdResource
- private UUID nodeId;
-
- /** */
- @IgniteMarshallerResource
- private IgniteMarshaller igniteMarshaller;
-
- /** */
- private final CountDownLatch ctxInitLatch = new CountDownLatch(1);
-
- /** Marshaller. */
- private IndexingMarshaller marshaller;
-
- /** */
- private GridUnsafeMemory offheap;
-
- /** */
- private final Collection<String> schemaNames = new GridConcurrentHashSet<>();
-
- /** Collection of schemaNames and registered tables. */
- private final ConcurrentMap<String, Schema> schemas = new ConcurrentHashMap8<>();
-
- /** */
- private String dbUrl = "jdbc:h2:mem:";
-
- /** */
- private final Collection<Connection> conns = Collections.synchronizedCollection(new ArrayList<Connection>());
-
- /** */
- private ThreadLocal<ConnectionWrapper> connCache = new ThreadLocal<ConnectionWrapper>() {
- @Nullable @Override public ConnectionWrapper get() {
- ConnectionWrapper c = super.get();
-
- boolean reconnect = true;
-
- try {
- reconnect = c == null || c.connection().isClosed();
- }
- catch (SQLException e) {
- U.warn(log, "Failed to check connection status.", e);
- }
-
- if (reconnect) {
- c = initialValue();
-
- set(c);
- }
-
- return c;
- }
-
- @Nullable @Override protected ConnectionWrapper initialValue() {
- Connection c = null;
-
- try {
- c = DriverManager.getConnection(dbUrl);
-
- if (!F.isEmpty(searchPath)) {
- try (Statement s = c.createStatement()) {
- String cmd = cachedSearchPathCmd;
-
- if (cmd == null) {
- SB b = new SB("SET SCHEMA_SEARCH_PATH ");
-
- for (int i = 0; i < searchPath.length; i++) {
- if (i != 0)
- b.a(',');
-
- b.a('"').a(schema(searchPath[i])).a('"');
- }
-
- cachedSearchPathCmd = cmd = b.toString();
- }
-
- s.executeUpdate(cmd);
- }
- }
-
- conns.add(c);
-
- return new ConnectionWrapper(c);
- }
- catch (SQLException e) {
- U.close(c, log);
-
- throw new GridRuntimeException("Failed to initialize DB connection: " + dbUrl, e);
- }
- }
- };
-
- /**
- * Gets DB connection.
- *
- * @param schema Whether to set schema for connection or not.
- * @return DB connection.
- * @throws org.apache.ignite.spi.IgniteSpiException In case of error.
- */
- private Connection connectionForThread(@Nullable String schema) throws IgniteSpiException {
- ConnectionWrapper c = connCache.get();
-
- if (c == null)
- throw new IgniteSpiException("Failed to get DB connection for thread (check log for details).");
-
- if (schema != null && !F.eq(c.schema(), schema)) {
- Statement stmt = null;
-
- try {
- stmt = c.connection().createStatement();
-
- stmt.executeUpdate("SET SCHEMA \"" + schema + '"');
-
- if (log.isDebugEnabled())
- log.debug("Initialized H2 schema for queries on space: " + schema);
-
- c.schema(schema);
- }
- catch (SQLException e) {
- throw new IgniteSpiException("Failed to set schema for DB connection for thread [schema=" +
- schema + "]", e);
- }
- finally {
- U.close(stmt, log);
- }
- }
-
- return c.connection();
- }
-
- /**
- * Creates DB schema if it has not been created yet.
- *
- * @param schema Schema name.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed to create db schema.
- */
- private void createSchemaIfAbsent(String schema) throws IgniteSpiException {
- executeStatement("CREATE SCHEMA IF NOT EXISTS \"" + schema + '"');
-
- if (log.isDebugEnabled())
- log.debug("Created H2 schema for index database: " + schema);
- }
-
- /**
- * @param sql SQL statement.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- private void executeStatement(String sql) throws IgniteSpiException {
- Statement stmt = null;
-
- try {
- Connection c = connectionForThread(null);
-
- stmt = c.createStatement();
-
- stmt.executeUpdate(sql);
- }
- catch (SQLException e) {
- onSqlException();
-
- throw new IgniteSpiException("Failed to execute statement: " + sql, e);
- }
- finally {
- U.close(stmt, log);
- }
- }
-
- /**
- * Removes entry with specified key from any tables (if exist).
- *
- * @param spaceName Space name.
- * @param k Key entity.
- * @param tblToUpdate Table to update.
- * @throws org.apache.ignite.spi.IgniteSpiException In case of error.
- */
- private <K> void removeKey(@Nullable String spaceName, IndexingEntity<K> k, TableDescriptor tblToUpdate)
- throws IgniteSpiException {
- K key = k.value();
-
- try {
- Collection<TableDescriptor> tbls = tables(schema(spaceName));
-
- if (tbls.size() > 1) {
- boolean fixedTyping = isIndexFixedTyping(spaceName);
-
- for (TableDescriptor tbl : tbls) {
- if (tbl != tblToUpdate && (tbl.type().keyClass().equals(key.getClass()) ||
- !fixedTyping)) {
- if (tbl.tbl.update(key, null, 0)) {
- if (tbl.luceneIdx != null)
- tbl.luceneIdx.remove(k);
-
- return;
- }
- }
- }
- }
- }
- catch (Exception e) {
- throw new IgniteSpiException("Failed to remove key: " + key, e);
- }
- }
-
- /**
- * Binds object to prepared statement.
- *
- * @param stmt SQL statement.
- * @param idx Index.
- * @param obj Value to store.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- private void bindObject(PreparedStatement stmt, int idx, @Nullable Object obj) throws IgniteSpiException {
- try {
- if (obj == null)
- stmt.setNull(idx, Types.VARCHAR);
- else
- stmt.setObject(idx, obj);
- }
- catch (SQLException e) {
- throw new IgniteSpiException("Failed to bind parameter [idx=" + idx + ", obj=" + obj + ']', e);
- }
- }
-
- /**
- * Handles SQL exception.
- */
- private void onSqlException() {
- Connection conn = connCache.get().connection();
-
- connCache.set(null);
-
- if (conn != null) {
- conns.remove(conn);
-
- // Reset connection to receive new one at next call.
- U.close(conn, log);
- }
- }
-
- /** {@inheritDoc} */
- @Override public <K, V> void store(@Nullable String spaceName, IndexingTypeDescriptor type,
- IndexingEntity<K> k, IndexingEntity<V> v, byte[] ver, long expirationTime)
- throws IgniteSpiException {
- TableDescriptor tbl = tableDescriptor(spaceName, type);
-
- if (tbl == null)
- return; // Type was rejected.
-
- localSpi.set(this);
-
- try {
- removeKey(spaceName, k, tbl);
-
- if (expirationTime == 0)
- expirationTime = Long.MAX_VALUE;
-
- tbl.tbl.update(k.value(), v.value(), expirationTime);
-
- if (tbl.luceneIdx != null)
- tbl.luceneIdx.store(k, v, ver, expirationTime);
- }
- finally {
- localSpi.remove();
- }
- }
-
- /** {@inheritDoc} */
- @Override public <K> boolean remove(@Nullable String spaceName, IndexingEntity<K> k) throws IgniteSpiException {
- assert k != null;
-
- K key = k.value();
-
- if (log.isDebugEnabled())
- log.debug("Removing key from cache query index [locId=" + nodeId + ", key=" + key + ']');
-
- localSpi.set(this);
-
- try {
- for (TableDescriptor tbl : tables(schema(spaceName))) {
- if (tbl.type().keyClass().equals(key.getClass()) || !isIndexFixedTyping(spaceName)) {
- if (tbl.tbl.update(key, null, 0)) {
- if (tbl.luceneIdx != null)
- tbl.luceneIdx.remove(k);
-
- return true;
- }
- }
- }
- }
- finally {
- localSpi.remove();
- }
-
- return false;
- }
-
- /** {@inheritDoc} */
- @Override protected void onContextInitialized0(IgniteSpiContext spiCtx) throws IgniteSpiException {
- ctxInitLatch.countDown();
-
- if (log.isDebugEnabled())
- log.debug("Context has been initialized.");
- }
-
- /** {@inheritDoc} */
- @Override public IgniteSpiContext getSpiContext() {
- if (ctxInitLatch.getCount() != 0) {
- try {
- U.await(ctxInitLatch);
- }
- catch (GridInterruptedException ignored) {
- U.warn(log, "Thread has been interrupted while waiting for SPI context initialization.");
- }
- }
-
- return super.getSpiContext();
- }
-
- /** {@inheritDoc} */
- @Override public <K> void onSwap(@Nullable String spaceName, String swapSpaceName, K key) throws IgniteSpiException {
- Schema schema = schemas.get(schema(spaceName));
-
- if (schema == null)
- return;
-
- localSpi.set(this);
-
- try {
- for (TableDescriptor tbl : schema.values()) {
- if (tbl.type().keyClass().equals(key.getClass()) || !isIndexFixedTyping(spaceName)) {
- try {
- if (tbl.tbl.onSwap(key))
- return;
- }
- catch (GridException e) {
- throw new IgniteSpiException(e);
- }
- }
- }
- }
- finally {
- localSpi.remove();
- }
- }
-
- /** {@inheritDoc} */
- @Override public <K, V> void onUnswap(@Nullable String spaceName, K key, V val, byte[] valBytes)
- throws IgniteSpiException {
- localSpi.set(this);
-
- try {
- for (TableDescriptor tbl : tables(schema(spaceName))) {
- if (tbl.type().keyClass().equals(key.getClass()) || !isIndexFixedTyping(spaceName)) {
- try {
- if (tbl.tbl.onUnswap(key, val))
- return;
- }
- catch (GridException e) {
- throw new IgniteSpiException(e);
- }
- }
- }
- }
- finally {
- localSpi.remove();
- }
- }
-
- /**
- * Drops table form h2 database and clear all related indexes (h2 text, lucene).
- *
- * @param tbl Table to unregister.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed to unregister.
- */
- private void removeTable(TableDescriptor tbl) throws IgniteSpiException {
- assert tbl != null;
-
- if (log.isDebugEnabled())
- log.debug("Removing query index table: " + tbl.fullTableName());
-
- Connection c = connectionForThread(null);
-
- Statement stmt = null;
-
- try {
- // NOTE: there is no method dropIndex() for lucene engine correctly working.
- // So we have to drop all lucene index.
- // FullTextLucene.dropAll(c); TODO: GG-4015: fix this
-
- stmt = c.createStatement();
-
- String sql = "DROP TABLE IF EXISTS " + tbl.fullTableName();
-
- if (log.isDebugEnabled())
- log.debug("Dropping database index table with SQL: " + sql);
-
- stmt.executeUpdate(sql);
- }
- catch (SQLException e) {
- onSqlException();
-
- throw new IgniteSpiException("Failed to drop database index table [type=" + tbl.type().name() +
- ", table=" + tbl.fullTableName() + "]", e);
- }
- finally {
- U.close(stmt, log);
- }
-
- tbl.tbl.close();
-
- if (tbl.luceneIdx != null)
- U.closeQuiet(tbl.luceneIdx);
-
- ConcurrentMap<String, TableDescriptor> tbls = schemas.get(tbl.schema());
-
- if (!F.isEmpty(tbls))
- tbls.remove(tbl.name());
- }
-
- /** {@inheritDoc} */
- @SuppressWarnings("unchecked")
- @Override public <K, V> IgniteSpiCloseableIterator<IndexingKeyValueRow<K, V>> queryText(
- @Nullable String spaceName, String qry, IndexingTypeDescriptor type,
- IndexingQueryFilter filters) throws IgniteSpiException {
- TableDescriptor tbl = tableDescriptor(spaceName, type);
-
- if (tbl != null && tbl.luceneIdx != null)
- return tbl.luceneIdx.query(qry, filters);
-
- return new GridEmptyCloseableIterator<>();
- }
-
- /** {@inheritDoc} */
- @Override public void unregisterType(@Nullable String spaceName, IndexingTypeDescriptor type)
- throws IgniteSpiException {
- TableDescriptor tbl = tableDescriptor(spaceName, type);
-
- if (tbl != null)
- removeTable(tbl);
- }
-
- /** {@inheritDoc} */
- @SuppressWarnings("unchecked")
- @Override public <K, V> IndexingFieldsResult queryFields(@Nullable final String spaceName, final String qry,
- @Nullable final Collection<Object> params, final IndexingQueryFilter filters)
- throws IgniteSpiException {
- localSpi.set(this);
-
- setFilters(filters);
-
- try {
- Connection conn = connectionForThread(schema(spaceName));
-
- ResultSet rs = executeSqlQueryWithTimer(conn, qry, params);
-
- List<IndexingFieldMetadata> meta = null;
-
- if (rs != null) {
- try {
- ResultSetMetaData rsMeta = rs.getMetaData();
-
- meta = new ArrayList<>(rsMeta.getColumnCount());
-
- for (int i = 1; i <= rsMeta.getColumnCount(); i++) {
- String schemaName = rsMeta.getSchemaName(i);
- String typeName = rsMeta.getTableName(i);
- String name = rsMeta.getColumnLabel(i);
- String type = rsMeta.getColumnClassName(i);
-
- meta.add(new SqlFieldMetadata(schemaName, typeName, name, type));
- }
- }
- catch (SQLException e) {
- throw new IgniteSpiException("Failed to get meta data.", e);
- }
- }
-
- return new IndexingFieldsResultAdapter(meta, new FieldsIterator(rs));
- }
- finally {
- setFilters(null);
-
- localSpi.remove();
- }
- }
-
- /**
- * @param stmt Prepared statement.
- * @return Command type.
- */
- private static int commandType(PreparedStatement stmt) {
- try {
- return ((CommandInterface)COMMAND_FIELD.get(stmt)).getCommandType();
- }
- catch (IllegalAccessException e) {
- throw new IllegalStateException(e);
- }
- }
-
- /**
- * Executes sql query.
- *
- * @param conn Connection,.
- * @param sql Sql query.
- * @param params Parameters.
- * @return Result.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- @Nullable private ResultSet executeSqlQuery(Connection conn, String sql,
- @Nullable Collection<Object> params) throws IgniteSpiException {
- PreparedStatement stmt;
-
- try {
- stmt = conn.prepareStatement(sql);
- }
- catch (SQLException e) {
- if (e.getErrorCode() == ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1)
- return null;
-
- throw new IgniteSpiException("Failed to parse SQL query: " + sql, e);
- }
-
- switch (commandType(stmt)) {
- case CommandInterface.SELECT:
- case CommandInterface.CALL:
- case CommandInterface.EXPLAIN:
- case CommandInterface.ANALYZE:
- break;
- default:
- throw new IgniteSpiException("Failed to execute non-query SQL statement: " + sql);
- }
-
- bindParameters(stmt, params);
-
- try {
- return stmt.executeQuery();
- }
- catch (SQLException e) {
- throw new IgniteSpiException("Failed to execute SQL query.", e);
- }
- }
-
- /**
- * Executes sql query and prints warning if query is too slow..
- *
- * @param conn Connection,.
- * @param sql Sql query.
- * @param params Parameters.
- * @return Result.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- private ResultSet executeSqlQueryWithTimer(Connection conn, String sql,
- @Nullable Collection<Object> params) throws IgniteSpiException {
- long start = U.currentTimeMillis();
-
- try {
- ResultSet rs = executeSqlQuery(conn, sql, params);
-
- long time = U.currentTimeMillis() - start;
-
- if (time > longQryExecTimeout) {
- String msg = "Query execution is too long (" + time + " ms): " + sql;
-
- String longMsg = msg;
-
- if (longQryExplain) {
- ResultSet plan = executeSqlQuery(conn, "EXPLAIN " + sql, params);
-
- if (plan == null)
- longMsg = "Failed to explain plan because required table does not exist: " + sql;
- else {
- plan.next();
-
- // Add SQL explain result message into log.
- longMsg = "Query execution is too long [time=" + time + " ms, sql='" + sql + '\'' +
- ", plan=" + U.nl() + plan.getString(1) + U.nl() + ", parameters=" + params + "]";
- }
- }
-
- LT.warn(log, null, longMsg, msg);
- }
-
- return rs;
- }
- catch (SQLException e) {
- onSqlException();
-
- throw new IgniteSpiException(e);
- }
- }
-
- /**
- * Executes query.
- *
- * @param qry Query.
- * @param params Query parameters.
- * @param tbl Target table of query to generate select.
- * @return Result set.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- private ResultSet executeQuery(String qry, @Nullable Collection<Object> params,
- @Nullable TableDescriptor tbl) throws IgniteSpiException {
- Connection conn = connectionForThread(tbl != null ? tbl.schema() : "PUBLIC");
-
- String sql = generateQuery(qry, tbl);
-
- return executeSqlQueryWithTimer(conn, sql, params);
- }
-
- /**
- * Binds parameters to prepared statement.
- *
- * @param stmt Prepared statement.
- * @param params Parameters collection.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- private void bindParameters(PreparedStatement stmt, @Nullable Collection<Object> params) throws IgniteSpiException {
- if (!F.isEmpty(params)) {
- int idx = 1;
-
- for (Object arg : params)
- bindObject(stmt, idx++, arg);
- }
- }
-
- /**
- * Executes regular query.
- * Note that SQL query can not refer to table alias, so use full table name instead.
- *
- * @param spaceName Space name.
- * @param qry Query.
- * @param params Query parameters.
- * @param type Query return type.
- * @param filters Space name and key filters.
- * @return Queried rows.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- @SuppressWarnings("unchecked")
- @Override public <K, V> IgniteSpiCloseableIterator<IndexingKeyValueRow<K, V>> query(@Nullable String spaceName,
- final String qry, @Nullable final Collection<Object> params, IndexingTypeDescriptor type,
- final IndexingQueryFilter filters) throws IgniteSpiException {
- final TableDescriptor tbl = tableDescriptor(spaceName, type);
-
- if (tbl == null)
- return new GridEmptyCloseableIterator<>();
-
- setFilters(filters);
-
- localSpi.set(this);
-
- try {
- ResultSet rs = executeQuery(qry, params, tbl);
-
- return new KeyValIterator(rs);
- }
- finally {
- setFilters(null);
-
- localSpi.remove();
- }
- }
-
- /**
- * Sets filters for current thread. Must be set to not null value
- * before executeQuery and reset to null after in finally block since it signals
- * to table that it should return content without expired values.
- *
- * @param filters Filters.
- */
- private void setFilters(@Nullable IndexingQueryFilter filters) {
- GridH2IndexBase.setFiltersForThread(filters);
- }
-
- /**
- * Prepares statement for query.
- *
- * @param qry Query string.
- * @param tbl Table to use.
- * @return Prepared statement.
- * @throws org.apache.ignite.spi.IgniteSpiException In case of error.
- */
- private String generateQuery(String qry, @Nullable TableDescriptor tbl) throws IgniteSpiException {
- boolean needSelect = tbl != null;
-
- String str = qry.trim().toUpperCase();
-
- if (!str.startsWith("FROM")) {
- if (str.startsWith("SELECT")) {
- if (needSelect) {
- StringTokenizer st = new StringTokenizer(str, " ");
-
- String errMsg = "Wrong query format, query must start with 'select * from' " +
- "or 'from' or without such keywords.";
-
- if (st.countTokens() > 3) {
- st.nextToken();
- String wildcard = st.nextToken();
- String from = st.nextToken();
-
- if (!"*".equals(wildcard) || !"FROM".equals(from))
- throw new IgniteSpiException(errMsg);
-
- needSelect = false;
- }
- else
- throw new IgniteSpiException(errMsg);
- }
- }
- else {
- boolean needWhere = !str.startsWith("ORDER") && !str.startsWith("LIMIT");
-
- qry = needWhere ? "FROM " + tbl.fullTableName() + " WHERE " + qry :
- "FROM " + tbl.fullTableName() + ' ' + qry;
- }
- }
-
- GridStringBuilder ptrn = new SB("SELECT {0}.").a(KEY_FIELD_NAME);
-
- ptrn.a(", {0}.").a(VAL_FIELD_NAME);
-
- return needSelect ? MessageFormat.format(ptrn.toString(), tbl.fullTableName()) + ' ' + qry : qry;
- }
-
- /**
- * Registers new class description.
- *
- * This implementation doesn't support type reregistration.
- *
- * @param type Type description.
- * @throws org.apache.ignite.spi.IgniteSpiException In case of error.
- */
- @Override public boolean registerType(@Nullable String spaceName, IndexingTypeDescriptor type)
- throws IgniteSpiException {
- if (!validateTypeDescriptor(spaceName, type))
- return false;
-
- for (TableDescriptor table : tables(schema(spaceName)))
- // Need to compare class names rather than classes to define
- // whether a class was previously undeployed.
- if (table.type().valueClass().getClass().getName().equals(type.valueClass().getName()))
- throw new IgniteSpiException("Failed to register type in query index because" +
- " class is already registered (most likely that class with the same name" +
- " was not properly undeployed): " + type);
-
- TableDescriptor tbl = new TableDescriptor(spaceName, type);
-
- try {
- Connection conn = connectionForThread(null);
-
- Schema schema = schemas.get(tbl.schema());
-
- if (schema == null) {
- schema = new Schema(spaceName);
-
- Schema existing = schemas.putIfAbsent(tbl.schema(), schema);
-
- if (existing != null)
- schema = existing;
- }
-
- createTable(schema, tbl, conn);
-
- schema.put(tbl.name(), tbl);
- }
- catch (SQLException e) {
- onSqlException();
-
- throw new IgniteSpiException("Failed to register query type: " + type, e);
- }
-
- return true;
- }
-
- /**
- * @param cls Class.
- * @return True if given class has primitive respective sql type.
- */
- private boolean isPrimitive(Class<?> cls) {
- DBTypeEnum valType = DBTypeEnum.fromClass(cls);
-
- return valType != DBTypeEnum.BINARY && valType != DBTypeEnum.OTHER &&
- valType != DBTypeEnum.ARRAY;
- }
-
- /**
- * Validates properties described by query types.
- *
- * @param spaceName Space name.
- * @param type Type descriptor.
- * @return True if type is valid.
- * @throws org.apache.ignite.spi.IgniteSpiException If validation failed.
- */
- private boolean validateTypeDescriptor(@Nullable String spaceName, IndexingTypeDescriptor type)
- throws IgniteSpiException {
- assert type != null;
-
- boolean keyPrimitive = isPrimitive(type.keyClass());
- boolean valPrimitive = isPrimitive(type.valueClass());
-
- // Do not register if value is not primitive and
- // there are no indexes or fields defined.
- if (!type.valueTextIndex() && type.indexes().isEmpty() &&
- type.keyFields().isEmpty() && type.valueFields().isEmpty())
- return keyPrimitive && isIndexPrimitiveKey(spaceName) || valPrimitive && isIndexPrimitiveValue(spaceName);
-
- Collection<String> names = new HashSet<>();
-
- names.addAll(type.keyFields().keySet());
- names.addAll(type.valueFields().keySet());
-
- if (names.size() < type.keyFields().size() + type.valueFields().size())
- throw new IgniteSpiException("Found duplicated properties with the same name [keyType=" +
- type.keyClass().getName() + ", valueType=" + type.valueClass().getName() + "]");
-
- String ptrn = "Name ''{0}'' is reserved and cannot be used as a field name [class=" + type + "]";
-
- for (String name : names) {
- if (name.equals(KEY_FIELD_NAME) || name.equals(VAL_FIELD_NAME))
- throw new IgniteSpiException(MessageFormat.format(ptrn, name));
- }
-
- return true;
- }
-
- /**
- * Escapes name to be valid SQL identifier. Currently just replaces '.' and '$' sign with '_'.
- *
- * @param name Name.
- * @param escapeAll Escape flag.
- * @return Escaped name.
- */
- private static String escapeName(String name, boolean escapeAll) {
- if (escapeAll)
- return "\"" + name + "\"";
-
- SB sb = null;
-
- for (int i = 0; i < name.length(); i++) {
- char ch = name.charAt(i);
-
- if (!Character.isLetter(ch) && !Character.isDigit(ch) && ch != '_' &&
- !(ch == '"' && (i == 0 || i == name.length() - 1)) && ch != '-') {
- // Class name can also contain '$' or '.' - these should be escaped.
- assert ch == '$' || ch == '.';
-
- if (sb == null)
- sb = new SB();
-
- sb.a(name.substring(sb.length(), i));
-
- // Replace illegal chars with '_'.
- sb.a('_');
- }
- }
-
- if (sb == null)
- return name;
-
- sb.a(name.substring(sb.length(), name.length()));
-
- return sb.toString();
- }
-
- /**
- * Create db table by using given table descriptor.
- *
- * @param schema Schema.
- * @param tbl Table descriptor.
- * @param conn Connection.
- * @throws SQLException If failed to create db table.
- */
- private void createTable(Schema schema, TableDescriptor tbl, Connection conn) throws SQLException {
- assert tbl != null;
-
- boolean keyAsObj = !isIndexFixedTyping(schema.spaceName);
-
- boolean escapeAll = isEscapeAll(schema.spaceName);
-
- String keyType = keyAsObj ? "OTHER" : dbTypeFromClass(tbl.type().keyClass());
- String valTypeStr = dbTypeFromClass(tbl.type().valueClass());
-
- SB sql = new SB();
-
- sql.a("CREATE TABLE ").a(tbl.fullTableName()).a(" (")
- .a(KEY_FIELD_NAME).a(' ').a(keyType).a(" NOT NULL");
-
- sql.a(',').a(VAL_FIELD_NAME).a(' ').a(valTypeStr);
-
- for (Map.Entry<String, Class<?>> e: tbl.type().keyFields().entrySet())
- sql.a(',').a(escapeName(e.getKey(), escapeAll)).a(' ').a(dbTypeFromClass(e.getValue()));
-
- for (Map.Entry<String, Class<?>> e: tbl.type().valueFields().entrySet())
- sql.a(',').a(escapeName(e.getKey(), escapeAll)).a(' ').a(dbTypeFromClass(e.getValue()));
-
- sql.a(')');
-
- if (log.isDebugEnabled())
- log.debug("Creating DB table with SQL: " + sql);
-
- GridH2RowDescriptor desc = new RowDescriptor(tbl.type(), schema, keyAsObj);
-
- GridH2Table.Engine.createTable(conn, sql.toString(), desc, tbl, tbl.spaceName);
- }
-
- /**
- * Gets corresponding DB type from java class.
- *
- * @param cls Java class.
- * @return DB type name.
- */
- private String dbTypeFromClass(Class<?> cls) {
- return DBTypeEnum.fromClass(cls).dBTypeAsString();
- }
-
- /**
- * Gets table descriptor by value type.
- *
- * @param spaceName Space name.
- * @param type Value type descriptor.
- * @return Table descriptor or {@code null} if not found.
- */
- @Nullable private TableDescriptor tableDescriptor(@Nullable String spaceName, IndexingTypeDescriptor type) {
- return tableDescriptor(type.name(), spaceName);
- }
-
- /**
- * Gets table descriptor by type and space names.
- *
- * @param type Type name.
- * @param space Space name.
- * @return Table descriptor.
- */
- @Nullable private TableDescriptor tableDescriptor(String type, @Nullable String space) {
- ConcurrentMap<String, TableDescriptor> tbls = schemas.get(schema(space));
-
- if (tbls == null)
- return null;
-
- return tbls.get(type);
- }
-
- /**
- * Gets collection of table for given schema name.
- *
- * @param schema Schema name.
- * @return Collection of table descriptors.
- */
- private Collection<TableDescriptor> tables(String schema) {
- ConcurrentMap<String, TableDescriptor> tbls = schemas.get(schema);
-
- if (tbls == null)
- return Collections.emptySet();
-
- return tbls.values();
- }
-
- /**
- * Gets database schema from space.
- *
- * @param space Space name.
- * @return Schema name.
- */
- private static String schema(@Nullable String space) {
- if (F.isEmpty(space))
- return "PUBLIC";
-
- return space;
- }
-
- /** {@inheritDoc} */
- @Override public void rebuildIndexes(@Nullable String spaceName, IndexingTypeDescriptor type) {
- if (offheap != null)
- throw new UnsupportedOperationException("Index rebuilding is not supported when off-heap memory is used");
-
- TableDescriptor tbl = tableDescriptor(spaceName, type);
-
- if (tbl == null)
- return;
-
- tbl.tbl.rebuildIndexes();
- }
-
- /** {@inheritDoc} */
- @Override public long size(@Nullable String spaceName, IndexingTypeDescriptor type) throws IgniteSpiException {
- TableDescriptor tbl = tableDescriptor(spaceName, type);
-
- if (tbl == null)
- return -1;
-
- IgniteSpiCloseableIterator<List<IndexingEntity<?>>> iter = queryFields(spaceName,
- "SELECT COUNT(*) FROM " + tbl.fullTableName(), null, null).iterator();
-
- if (!iter.hasNext())
- throw new IllegalStateException();
-
- return ((IndexingEntityAdapter<Number>)iter.next().get(0)).value().longValue();
- }
-
- /** {@inheritDoc} */
- @SuppressWarnings("NonThreadSafeLazyInitialization")
- @Override public void spiStart(@Nullable String gridName) throws IgniteSpiException {
- if (log.isDebugEnabled())
- log.debug("Starting cache query index...");
-
- assertParameter(idxWriteLockWaitTime > 0, "'idxWriteLockWaitTime' must be positive.");
-
- startStopwatch();
-
- System.setProperty("h2.serializeJavaObject", "false");
-
- if (SysProperties.serializeJavaObject) {
- U.warn(log, "Serialization of Java objects in H2 was enabled.");
-
- SysProperties.serializeJavaObject = false;
- }
-
- if (useOptimizedSerializer)
- Utils.serializer = h2Serializer();
-
- if (maxOffHeapMemory != -1) {
- assert maxOffHeapMemory >= 0 : maxOffHeapMemory;
-
- offheap = new GridUnsafeMemory(maxOffHeapMemory);
- }
-
- SB opt = new SB();
-
- opt.a(DFLT_DB_OPTIONS).a(OPTIMIZED_DB_OPTIONS);
-
- String dbName = UUID.randomUUID() + "_" + gridName + "_" + getName();
-
- dbUrl = "jdbc:h2:mem:" + DFLT_DB_NAME + "_" + dbName + opt;
-
- try {
- Class.forName("org.h2.Driver");
- }
- catch (ClassNotFoundException e) {
- throw new IgniteSpiException("Failed to find org.h2.Driver class", e);
- }
-
- for (String schema : schemaNames)
- createSchemaIfAbsent(schema);
-
- try {
- createSqlFunctions();
- runInitScript();
-
- if (getString(GG_H2_DEBUG_CONSOLE) != null) {
- Connection c = DriverManager.getConnection(dbUrl);
-
- WebServer webSrv = new WebServer();
- Server web = new Server(webSrv, "-webPort", "0");
- web.start();
- String url = webSrv.addSession(c);
-
- try {
- Server.openBrowser(url);
- }
- catch (Exception e) {
- U.warn(log, "Failed to open browser: " + e.getMessage());
- }
- }
- }
- catch (SQLException e) {
- throw new IgniteSpiException(e);
- }
-
- registerMBean(gridName, this, GridH2IndexingSpiMBean.class);
-
- if (log.isDebugEnabled())
- log.debug("Cache query index started [grid=" + gridName + ", cache=" + getName() + "]");
- }
-
- /**
- * @return Serializer.
- */
- protected JavaObjectSerializer h2Serializer() {
- return new H2Serializer();
- }
-
- /**
- * Runs initial script.
- *
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- * @throws SQLException If failed.
- */
- private void runInitScript() throws IgniteSpiException, SQLException {
- if (initScriptPath == null)
- return;
-
- try (PreparedStatement p = connectionForThread(null).prepareStatement("RUNSCRIPT FROM ? CHARSET 'UTF-8'")) {
- p.setString(1, initScriptPath);
-
- p.execute();
- }
- }
-
- /**
- * Registers SQL functions.
- *
- * @throws SQLException If failed.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- private void createSqlFunctions() throws SQLException, IgniteSpiException {
- if (F.isEmpty(idxCustomFuncClss))
- return;
-
- for (Class<?> cls : idxCustomFuncClss) {
- for (Method m : cls.getDeclaredMethods()) {
- GridCacheQuerySqlFunction ann = m.getAnnotation(GridCacheQuerySqlFunction.class);
-
- if (ann != null) {
- int modifiers = m.getModifiers();
-
- if (!Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers))
- throw new IgniteSpiException("Method " + m.getName() + " must be public static.");
-
- String alias = ann.alias().isEmpty() ? m.getName() : ann.alias();
-
- String clause = "CREATE ALIAS " + alias + (ann.deterministic() ? " DETERMINISTIC FOR \"" :
- " FOR \"") + cls.getName() + '.' + m.getName() + '"';
-
- Collection<String> schemas = new ArrayList<>(schemaNames);
-
- if (!schemaNames.contains(schema(null)))
- schemas.add(schema(null));
-
- for (String schema : schemas) {
- Connection c = connectionForThread(schema);
-
- Statement s = c.createStatement();
-
- s.execute(clause);
-
- s.close();
- }
- }
- }
- }
- }
-
- /** {@inheritDoc} */
- @Override public void spiStop() throws IgniteSpiException {
- if (log.isDebugEnabled())
- log.debug("Stopping cache query index...");
-
- if (ctxInitLatch.getCount() != 0)
- ctxInitLatch.countDown();
-
- unregisterMBean();
-
- Connection conn = connectionForThread(null);
-
- for (ConcurrentMap<String, TableDescriptor> m : schemas.values()) {
- for (TableDescriptor desc : m.values()) {
- desc.tbl.close();
-
- if (desc.luceneIdx != null)
- U.closeQuiet(desc.luceneIdx);
- }
- }
-
- if (conn != null) {
- Statement stmt = null;
-
- try {
- stmt = conn.createStatement();
-
- stmt.execute("DROP ALL OBJECTS DELETE FILES");
- stmt.execute("SHUTDOWN");
- }
- catch (SQLException e) {
- throw new IgniteSpiException("Failed to shutdown database.", e);
- }
- finally {
- U.close(stmt, log);
- }
- }
-
- for (Connection c : conns)
- U.close(c, log);
-
- conns.clear();
- schemas.clear();
- rowCache.clear();
-
- if (log.isDebugEnabled())
- log.debug("Cache query index stopped [cache=" + getName() + "]");
- }
-
- /**
- * Sets classes with methods annotated by {@link GridCacheQuerySqlFunction}
- * to be used as user-defined functions from SQL queries.
- *
- * @param idxCustomFuncClss List of classes.
- */
- public void setIndexCustomFunctionClasses(Class<?>... idxCustomFuncClss) {
- this.idxCustomFuncClss = idxCustomFuncClss;
- }
-
- /** {@inheritDoc} */
- @Override public String getSpaceNames() {
- return StringUtils.arrayCombine(spaceCfgs.keySet().toArray(new String[spaceCfgs.size()]), ',');
- }
-
- /**
- * The flag indicating that {@link JavaObjectSerializer} for H2 database will be set to optimized version.
- * This setting usually makes sense for offheap indexing only.
- * <p>
- * Default is {@link #DFLT_USE_OPTIMIZED_SERIALIZER}.
- *
- * @param useOptimizedSerializer Flag value.
- */
- public void setUseOptimizedSerializer(boolean useOptimizedSerializer) {
- this.useOptimizedSerializer = useOptimizedSerializer;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isUseOptimizedSerializer() {
- return useOptimizedSerializer;
- }
-
- /** {@inheritDoc} */
- @Override public long getLongQueryExecutionTimeout() {
- return longQryExecTimeout;
- }
-
- /**
- * Set query execution time threshold. If queries exceed this threshold,
- * then a warning will be printed out. If {@link #setLongQueryExplain(boolean)} is
- * set to {@code true}, then execution plan will be printed out as well.
- * <p>
- * If not provided, default value is defined by {@link #DFLT_LONG_QRY_EXEC_TIMEOUT}.
- *
- * @param longQryExecTimeout Long query execution timeout.
- * @see #setLongQueryExplain(boolean)
- */
- @IgniteSpiConfiguration(optional = true)
- public void setLongQueryExecutionTimeout(long longQryExecTimeout) {
- this.longQryExecTimeout = longQryExecTimeout;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isLongQueryExplain() {
- return longQryExplain;
- }
-
- /**
- * If {@code true}, SPI will print SQL execution plan for long queries (explain SQL query).
- * The time threshold of long queries is controlled via {@link #setLongQueryExecutionTimeout(long)}
- * parameter.
- * <p>
- * If not provided, default value is {@code false}.
- *
- * @param longQryExplain Flag marking SPI should print SQL execution plan for long queries (explain SQL query).
- * @see #setLongQueryExecutionTimeout(long)
- */
- @IgniteSpiConfiguration(optional = true)
- public void setLongQueryExplain(boolean longQryExplain) {
- this.longQryExplain = longQryExplain;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isIndexPrimitiveKey(@Nullable String spaceName) {
- GridH2IndexingSpaceConfiguration cfg = spaceCfgs.get(spaceName);
-
- if (cfg != null)
- return cfg.isIndexPrimitiveKey();
-
- return dfltIdxPrimitiveKey;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isIndexPrimitiveValue(String spaceName) {
- GridH2IndexingSpaceConfiguration cfg = spaceCfgs.get(spaceName);
-
- if (cfg != null)
- return cfg.isIndexPrimitiveValue();
-
- return dfltIdxPrimitiveVal;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isIndexFixedTyping(String spaceName) {
- GridH2IndexingSpaceConfiguration cfg = spaceCfgs.get(spaceName);
-
- if (cfg != null)
- return cfg.isIndexFixedTyping();
-
- return dfltIdxFixedTyping;
- }
-
- /**
- * Sets if SPI will index primitive key-value pairs by value. Makes sense only if
- * {@link #setDefaultIndexPrimitiveKey(boolean)} set to true.
- *
- * @param dfltIdxPrimitiveVal Flag value.
- */
- @IgniteSpiConfiguration(optional = true)
- public void setDefaultIndexPrimitiveValue(boolean dfltIdxPrimitiveVal) {
- this.dfltIdxPrimitiveVal = dfltIdxPrimitiveVal;
- }
-
- /**
- * Gets if SPI will index primitive key-value pairs by value. Makes sense only if
- * {@link #setDefaultIndexPrimitiveKey(boolean)} set to true.
- *
- * @return Flag value.
- */
- @Override public boolean isDefaultIndexPrimitiveValue() {
- return dfltIdxPrimitiveVal;
- }
-
- /**
- * Sets if SPI will index primitive key-value pairs by key.
- *
- * @param dfltIdxPrimitiveKey Flag value.
- */
- @IgniteSpiConfiguration(optional = true)
- public void setDefaultIndexPrimitiveKey(boolean dfltIdxPrimitiveKey) {
- this.dfltIdxPrimitiveKey = dfltIdxPrimitiveKey;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isDefaultIndexPrimitiveKey() {
- return dfltIdxPrimitiveKey;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isDefaultIndexFixedTyping() {
- return dfltIdxFixedTyping;
- }
-
- /**
- * This flag essentially controls whether all values of the same type have
- * identical key type.
- * <p>
- * If {@code false}, SPI will store all keys in BINARY form to make it possible to store
- * the same value type with different key types. If {@code true}, key type will be converted
- * to respective SQL type if it is possible, hence, improving performance of queries.
- * <p>
- * Setting this value to {@code false} also means that {@code '_key'} column cannot be indexed and
- * cannot participate in query where clauses. The behavior of using '_key' column in where
- * clauses with this flag set to {@code false} is undefined.
- * <p>
- * This property can be overridden on per-space level via {@link GridH2IndexingSpaceConfiguration}.
- *
- * @param dfltIdxFixedTyping FLag value.
- */
- @IgniteSpiConfiguration(optional = true)
- public void setDefaultIndexFixedTyping(boolean dfltIdxFixedTyping) {
- this.dfltIdxFixedTyping = dfltIdxFixedTyping;
- }
-
- /**
- * Sets maximum amount of memory available to off-heap storage. Possible values are
- * <ul>
- * <li>{@code -1} - Means that off-heap storage is disabled.</li>
- * <li>
- * {@code 0} - GridGain will not limit off-heap storage (it's up to user to properly
- * add and remove entries from cache to ensure that off-heap storage does not grow
- * indefinitely.
- * </li>
- * <li>Any positive value specifies the limit of off-heap storage in bytes.</li>
- * </ul>
- * Default value is {@code -1}, which means that off-heap storage is disabled by default.
- * <p>
- * Use off-heap storage to load gigabytes of data in memory without slowing down
- * Garbage Collection. Essentially in this case you should allocate very small amount
- * of memory to JVM and GridGain will cache most of the data in off-heap space
- * without affecting JVM performance at all.
- *
- * @param maxOffHeapMemory Maximum memory in bytes available to off-heap memory space.
- */
- @IgniteSpiConfiguration(optional = true)
- public void setMaxOffHeapMemory(long maxOffHeapMemory) {
- this.maxOffHeapMemory = maxOffHeapMemory;
- }
-
- /** {@inheritDoc} */
- @Override public long getMaxOffHeapMemory() {
- return maxOffHeapMemory;
- }
-
- /**
- * Sets index write lock wait time in milliseconds. This parameter can affect query performance under high
- * thread contention. Default value is {@code 100}.
- *
- * @param idxWriteLockWaitTime Index write lock wait time.
- */
- public void setIndexWriteLockWaitTime(long idxWriteLockWaitTime) {
- this.idxWriteLockWaitTime = idxWriteLockWaitTime;
- }
-
- /** {@inheritDoc} */
- @Override public long getIndexWriteLockWaitTime() {
- return idxWriteLockWaitTime;
- }
-
- /**
- * Specifies max allowed size of cache for deserialized offheap rows to avoid deserialization costs for most
- * frequently used ones. In general performance is better with greater cache size. Must be more than 128 items.
- *
- * @param size Cache size in items.
- */
- @IgniteSpiConfiguration(optional = true)
- public void setMaxOffheapRowsCacheSize(int size) {
- A.ensure(size >= 128, "Offheap rows cache size must be not less than 128.");
-
- rowCache = new CacheLongKeyLIRS<>(size, 1, 128, 256);
- }
-
- /**
- * Sets the optional search path consisting of space names to search SQL schema objects. Useful for cross cache
- * queries to avoid writing fully qualified table names.
- *
- * @param searchPath Search path.
- */
- @IgniteSpiConfiguration(optional = true)
- public void setSearchPath(String... searchPath) {
- this.searchPath = searchPath;
- }
-
- /** {@inheritDoc} */
- @Nullable @Override public String[] getSearchPath() {
- return searchPath;
- }
-
- /** {@inheritDoc} */
- @Nullable @Override public String getInitialScriptPath() {
- return initScriptPath;
- }
-
- /**
- * Sets script path to be ran against H2 database after opening.
- * The script must be UTF-8 encoded file.
- *
- * @param initScriptPath Script path.
- */
- @IgniteSpiConfiguration(optional = true)
- public void setInitialScriptPath(String initScriptPath) {
- this.initScriptPath = initScriptPath;
- }
-
- /**
- * This flag controls generation of 'create table' SQL.
- * <p>
- * If {@code true}, then table name and all column names in 'create table' SQL
- * generated by SPI are escaped with double quotes. This flag should be set if table name of
- * column name is H2 reserved word or is not valid H2 identifier (e.g. contains space or hyphen).
- * <p>
- * Note if this flag is set then table and column name in SQL queries also must be escaped with double quotes.
- * <p>
- * This property can be overridden on per-space level via {@link GridH2IndexingSpaceConfiguration}.
- *
- * @param dfltEscapeAll Default flag value.
- */
- @IgniteSpiConfiguration(optional = true)
- public void setDefaultEscapeAll(boolean dfltEscapeAll) {
- this.dfltEscapeAll = dfltEscapeAll;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isDefaultEscapeAll() {
- return dfltEscapeAll;
- }
-
- /** {@inheritDoc} */
- @Override public boolean isEscapeAll(String spaceName) {
- GridH2IndexingSpaceConfiguration cfg = spaceCfgs.get(spaceName);
-
- if (cfg != null)
- return cfg.isEscapeAll();
-
- return dfltEscapeAll;
- }
-
- /** {@inheritDoc} */
- @Override public int getMaxOffheapRowsCacheSize() {
- return (int)rowCache.getMaxMemory();
- }
-
- /** {@inheritDoc} */
- @Override public int getOffheapRowsCacheSize() {
- return (int)rowCache.getUsedMemory();
- }
-
- /** {@inheritDoc} */
- @Override public long getAllocatedOffHeapMemory() {
- return offheap == null ? -1 : offheap.allocatedSize();
- }
-
- /** {@inheritDoc} */
- @Override public void registerMarshaller(IndexingMarshaller marshaller) {
- this.marshaller = marshaller;
- }
-
- /** {@inheritDoc} */
- @Override public void registerSpace(String spaceName) throws IgniteSpiException {
- schemaNames.add(schema(spaceName));
-
- if (!spaceCfgs.containsKey(spaceName))
- spaceCfgs.put(spaceName, null);
- }
-
- /**
- * Sets per-space configurations.
- *
- * @param spaceCfgs Space configurations list.
- */
- @IgniteSpiConfiguration(optional = true)
- public void setSpaceConfigurations(GridH2IndexingSpaceConfiguration... spaceCfgs) {
- Map<String , GridH2IndexingSpaceConfiguration> map = new HashMap<>();
-
- for (GridH2IndexingSpaceConfiguration cfg : spaceCfgs) {
- GridH2IndexingSpaceConfiguration old = map.put(cfg.getName(), cfg);
-
- if (old != null)
- throw new IllegalArgumentException("Space configured twice: " + cfg.getName());
- }
-
- this.spaceCfgs = map;
- }
-
- /**
- * Wrapper to store connection and flag is schema set or not.
- */
- private static class ConnectionWrapper {
- /** */
- private Connection conn;
-
- /** */
- private volatile String schema;
-
- /**
- * @param conn Connection to use.
- */
- ConnectionWrapper(Connection conn) {
- this.conn = conn;
- }
-
- /**
- * @return Schema name if schema is set, null otherwise.
- */
- public String schema() {
- return schema;
- }
-
- /**
- * @param schema Schema name set on this connection.
- */
- public void schema(@Nullable String schema) {
- this.schema = schema;
- }
-
- /**
- * @return Connection.
- */
- public Connection connection() {
- return conn;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(ConnectionWrapper.class, this);
- }
- }
-
- /**
- * Enum that helps to map java types to database types.
- */
- private enum DBTypeEnum {
- /** */
- INT("INT"),
-
- /** */
- BOOL("BOOL"),
-
- /** */
- TINYINT("TINYINT"),
-
- /** */
- SMALLINT("SMALLINT"),
-
- /** */
- BIGINT("BIGINT"),
-
- /** */
- DECIMAL("DECIMAL"),
-
- /** */
- DOUBLE("DOUBLE"),
-
- /** */
- REAL("REAL"),
-
- /** */
- TIME("TIME"),
-
- /** */
- TIMESTAMP("TIMESTAMP"),
-
- /** */
- DATE("DATE"),
-
- /** */
- VARCHAR("VARCHAR"),
-
- /** */
- CHAR("CHAR"),
-
- /** */
- BINARY("BINARY"),
-
- /** */
- UUID("UUID"),
-
- /** */
- ARRAY("ARRAY"),
-
- /** */
- GEOMETRY("GEOMETRY"),
-
- /** */
- OTHER("OTHER");
-
- /** Map of Class to enum. */
- private static final Map<Class<?>, DBTypeEnum> map = new HashMap<>();
-
- /**
- * Initialize map of DB types.
- */
- static {
- map.put(int.class, INT);
- map.put(Integer.class, INT);
- map.put(boolean.class, BOOL);
- map.put(Boolean.class, BOOL);
- map.put(byte.class, TINYINT);
- map.put(Byte.class, TINYINT);
- map.put(short.class, SMALLINT);
- map.put(Short.class, SMALLINT);
- map.put(long.class, BIGINT);
- map.put(Long.class, BIGINT);
- map.put(BigDecimal.class, DECIMAL);
- map.put(double.class, DOUBLE);
- map.put(Double.class, DOUBLE);
- map.put(float.class, REAL);
- map.put(Float.class, REAL);
- map.put(Time.class, TIME);
- map.put(Timestamp.class, TIMESTAMP);
- map.put(java.util.Date.class, TIMESTAMP);
- map.put(java.sql.Date.class, DATE);
- map.put(char.class, CHAR);
- map.put(Character.class, CHAR);
- map.put(String.class, VARCHAR);
- map.put(UUID.class, UUID);
- map.put(byte[].class, BINARY);
- }
-
- /** */
- private final String dbType;
-
- /**
- * Constructs new instance.
- *
- * @param dbType DB type name.
- */
- DBTypeEnum(String dbType) {
- this.dbType = dbType;
- }
-
- /**
- * Resolves enum by class.
- *
- * @param cls Class.
- * @return Enum value.
- */
- public static DBTypeEnum fromClass(Class<?> cls) {
- DBTypeEnum res = map.get(cls);
-
- if (res != null)
- return res;
-
- if (DataType.isGeometryClass(cls))
- return GEOMETRY;
-
- return cls.isArray() && !cls.getComponentType().isPrimitive() ? ARRAY : OTHER;
- }
-
- /**
- * Gets DB type name.
- *
- * @return DB type name.
- */
- public String dBTypeAsString() {
- return dbType;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(DBTypeEnum.class, this);
- }
- }
-
- /**
- * Information about table in database.
- */
- private class TableDescriptor implements GridH2Table.IndexesFactory {
- /** */
- private final String fullTblName;
-
- /** */
- private final IndexingTypeDescriptor type;
-
- /** */
- private final String spaceName;
-
- /** */
- private final String schema;
-
- /** */
- private GridH2Table tbl;
-
- /** */
- private GridLuceneIndex luceneIdx;
-
- /**
- * @param spaceName Space name.
- * @param type Type descriptor.
- */
- TableDescriptor(@Nullable String spaceName, IndexingTypeDescriptor type) {
- this.spaceName = spaceName;
- this.type = type;
-
- schema = GridH2IndexingSpi.schema(spaceName);
-
- fullTblName = '\"' + schema + "\"." + escapeName(type.name(), isEscapeAll(spaceName));
- }
-
- /**
- * @return Schema name.
- */
- public String schema() {
- return schema;
- }
-
- /**
- * @return Database table name.
- */
- String fullTableName() {
- return fullTblName;
- }
-
- /**
- * @return Database table name.
- */
- String name() {
- return type.name();
- }
-
- /**
- * @return Type.
- */
- IndexingTypeDescriptor type() {
- return type;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(TableDescriptor.class, this);
- }
-
- /** {@inheritDoc} */
- @Override public ArrayList<Index> createIndexes(GridH2Table tbl) {
- this.tbl = tbl;
-
- ArrayList<Index> idxs = new ArrayList<>();
-
- idxs.add(new GridH2TreeIndex("_key_PK", tbl, true, KEY_COL, VAL_COL, tbl.indexColumn(0, ASCENDING)));
-
- if (type().valueClass() == String.class) {
- try {
- luceneIdx = new GridLuceneIndex(marshaller, offheap, spaceName, type, true);
- }
- catch (IgniteSpiException e1) {
- throw new GridRuntimeException(e1);
- }
- }
-
- for (Map.Entry<String, IndexDescriptor> e : type.indexes().entrySet()) {
- String name = e.getKey();
- IndexDescriptor idx = e.getValue();
-
- if (idx.type() == FULLTEXT) {
- try {
- luceneIdx = new GridLuceneIndex(marshaller, offheap, spaceName, type, true);
- }
- catch (IgniteSpiException e1) {
- throw new GridRuntimeException(e1);
- }
- }
- else {
- IndexColumn[] cols = new IndexColumn[idx.fields().size()];
-
- int i = 0;
-
- boolean escapeAll = isEscapeAll(spaceName);
-
- for (String field : idx.fields()) {
- // H2 reserved keywords used as column name is case sensitive.
- String fieldName = escapeAll ? field : escapeName(field, escapeAll).toUpperCase();
-
- Column col = tbl.getColumn(fieldName);
-
- cols[i++] = tbl.indexColumn(col.getColumnId(), idx.descending(field) ? DESCENDING : ASCENDING);
- }
-
- if (idx.type() == SORTED)
- idxs.add(new GridH2TreeIndex(name, tbl, false, KEY_COL, VAL_COL, cols));
- else if (idx.type() == GEO_SPATIAL)
- idxs.add(new GridH2SpatialIndex(tbl, name, cols, KEY_COL, VAL_COL));
- else
- throw new IllegalStateException();
- }
- }
-
- return idxs;
- }
- }
-
- /**
- * Special field set iterator based on database result set.
- */
- private static class FieldsIterator extends GridH2ResultSetIterator<List<IndexingEntity<?>>> {
- /** */
- private static final long serialVersionUID = 0L;
-
- /**
- * @param data Data.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- protected FieldsIterator(ResultSet data) throws IgniteSpiException {
- super(data);
- }
-
- /** {@inheritDoc} */
- @Override protected List<IndexingEntity<?>> createRow() {
- List<IndexingEntity<?>> res = new ArrayList<>(row.length);
-
- for (Object val : row) {
- res.add(val instanceof IndexingEntity ? (IndexingEntity<?>)val :
- new IndexingEntityAdapter<>(val, null));
- }
-
- return res;
- }
- }
-
- /**
- * Special key/value iterator based on database result set.
- */
- private static class KeyValIterator<K, V> extends GridH2ResultSetIterator<IndexingKeyValueRow<K, V>> {
- /** */
- private static final long serialVersionUID = 0L;
-
- /**
- * @param data Data array.
- * @throws org.apache.ignite.spi.IgniteSpiException If failed.
- */
- protected KeyValIterator(ResultSet data) throws IgniteSpiException {
- super(data);
- }
-
- /** {@inheritDoc} */
- @Override protected IndexingKeyValueRow<K, V> createRow() {
- K key = (K)row[0];
- V val = (V)row[1];
-
- return new IndexingKeyValueRowAdapter<>(new IndexingEntityAdapter<>(key, null),
- new IndexingEntityAdapter<>(val, null), null);
- }
- }
-
- /**
- * Field descriptor.
- */
- private static class SqlFieldMetadata implements IndexingFieldMetadata {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** Schema name. */
- private String schemaName;
-
- /** Type name. */
- private String typeName;
-
- /** Name. */
- private String name;
-
- /** Type. */
- private String type;
-
- /**
- * Required by {@link Externalizable}.
- */
- public SqlFieldMetadata() {
- // No-op
- }
-
- /**
- * @param schemaName Schema name.
- * @param typeName Type name.
- * @param name Name.
- * @param type Type.
- */
- SqlFieldMetadata(@Nullable String schemaName, @Nullable String typeName, String name, String type) {
- assert name != null;
- assert type != null;
-
- this.schemaName = schemaName;
- this.typeName = typeName;
- this.name = name;
- this.type = type;
- }
-
- /** {@inheritDoc} */
- @Override public String schemaName() {
- return schemaName;
- }
-
- /** {@inheritDoc} */
- @Override public String typeName() {
- return typeName;
- }
-
- /** {@inheritDoc} */
- @Override public String fieldName() {
- return name;
- }
-
- /** {@inheritDoc} */
- @Override public String fieldTypeName() {
- return type;
- }
-
- /** {@inheritDoc} */
- @Override public void writeExternal(ObjectOutput out) throws IOException {
- U.writeString(out, schemaName);
- U.writeString(out, typeName);
- U.writeString(out, name);
- U.writeString(out, type);
- }
-
- /** {@inheritDoc} */
- @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- schemaName = U.readString(in);
- typeName = U.readString(in);
- name = U.readString(in);
- type = U.readString(in);
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(SqlFieldMetadata.class, this);
- }
- }
-
- /**
- * Database schema object.
- */
- private static class Schema extends ConcurrentHashMap8<String, TableDescriptor> {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** */
- private final String spaceName;
-
- /**
- * @param spaceName Space name.
- */
- private Schema(@Nullable String spaceName) {
- this.spaceName = spaceName;
- }
- }
-
- /**
- * Row descriptor.
- */
- private class RowDescriptor implements GridH2RowDescriptor {
- /** */
- private final IndexingTypeDescriptor type;
-
- /** */
- private final String[] fields;
-
- /** */
- private final int[] fieldTypes;
-
- /** */
- private final int keyType;
-
- /** */
- private final int valType;
-
- /** */
- private final Schema schema;
-
- /** */
- private final ClassLoader valClsLdr;
-
- /** */
- private final int keyCols;
-
- /** */
- private final GridUnsafeGuard guard = offheap == null ? null : new GridUnsafeGuard();
-
- /**
- * @param type Type descriptor.
- * @param schema Schema.
- * @param keyAsObj Store key as java object.
- */
- RowDescriptor(IndexingTypeDescriptor type, Schema schema, boolean keyAsObj) {
- assert type != null;
- assert schema != null;
-
- this.type = type;
- this.schema = schema;
-
- keyCols = type.keyFields().size();
-
- valClsLdr = type.valueClass().getClassLoader();
-
- Map<String, Class<?>> allFields = new LinkedHashMap<>();
-
- allFields.putAll(type.keyFields());
- allFields.putAll(type.valueFields());
-
- fields = allFields.keySet().toArray(new String[allFields.size()]);
-
- fieldTypes = new int[fields.length];
-
- Class[] classes = allFields.values().toArray(new Class[fields.length]);
-
- for (int i = 0; i < fieldTypes.length; i++)
- fieldTypes[i] = DataType.getTypeFromClass(classes[i]);
-
- keyType = keyAsObj ? Value.JAVA_OBJECT : DataType.getTypeFromClass(type.keyClass());
- valType = DataType.getTypeFromClass(type.valueClass());
- }
-
- /** {@inheritDoc} */
- @Override public GridUnsafeGuard guard() {
- return guard;
- }
-
- /** {@inheritDoc} */
- @Override public void cache(GridH2KeyValueRowOffheap row) {
- long ptr = row.pointer();
-
- assert ptr > 0 : ptr;
-
- rowCache.put(ptr, row);
- }
-
- /** {@inheritDoc} */
- @Override public void uncache(long ptr) {
- rowCache.remove(ptr);
- }
-
- /** {@inheritDoc} */
- @Override public GridUnsafeMemory memory() {
- return offheap;
- }
-
- /** {@inheritDoc} */
- @Override public GridH2IndexingSpi spi() {
- return GridH2IndexingSpi.this;
- }
-
- /** {@inheritDoc} */
- @Override public GridH2AbstractKeyValueRow createRow(Object key, @Nullable Object val, long expirationTime)
- throws IgniteSpiException {
- try {
- return offheap == null ?
- new GridH2KeyValueRowOnheap(this, key, keyType, val, valType, expirationTime) :
- new GridH2KeyValueRowOffheap(this, key, keyType, val, valType, expirationTime);
- }
- catch (ClassCastException e) {
- throw new IgniteSpiException("Failed to convert key to SQL type. " +
- "Please make sure that you always store each value type with the same key type or disable " +
- "'defaultIndexFixedTyping' property on GridH2IndexingSpi.", e);
- }
- }
-
- /** {@inheritDoc} */
- @Override public Object readFromSwap(Object key) throws GridException {
- IgniteSpiContext ctx = getSpiContext();
-
- return ctx.readValueFromOffheapAndSwap(schema.spaceName, key, valClsLdr);
- }
-
- /** {@inheritDoc} */
- @Override public int valueType() {
- return valType;
- }
-
- /** {@inheritDoc} */
- @Override public int fieldsCount() {
- return fields.length;
- }
-
- /** {@inheritDoc} */
- @Override public int fieldType(int col) {
- return fieldTypes[col];
- }
-
- /** {@inheritDoc} */
- @Override public Object columnValue(Object obj, int col) {
- try {
- return type.value(obj, fields[col]);
- }
- catch (IgniteSpiException e) {
- throw DbException.convert(e);
- }
- }
-
- /** {@inheritDoc} */
- @Override public boolean isKeyColumn(int col) {
- return keyCols > col;
- }
-
- /** {@inheritDoc} */
- @Override public boolean valueToString() {
- return type.valueTextIndex();
- }
-
- /** {@inheritDoc} */
- @Override public GridH2KeyValueRowOffheap createPointer(long ptr) {
- GridH2KeyValueRowOffheap row = rowCache.get(ptr);
-
- if (row != null) {
- assert row.pointer() == ptr : ptr + " " + row.pointer();
-
- return row;
- }
-
- return new GridH2KeyValueRowOffheap(this, ptr);
- }
- }
-
- /**
- * Object serializer.
- */
- private static class H2Serializer implements JavaObjectSerializer {
- /** {@inheritDoc} */
- @Override public byte[] serialize(Object o) throws Exception {
- return localSpi.get().marshaller.marshal(new IndexingEntityAdapter<>(o, null));
- }
-
- /** {@inheritDoc} */
- @Override public Object deserialize(byte[] bytes) throws Exception {
- return localSpi.get().marshaller.unmarshal(bytes).value();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/922a2bab/modules/indexing/src/main/java/org/gridgain/grid/spi/indexing/h2/GridH2IndexingSpiMBean.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/gridgain/grid/spi/indexing/h2/GridH2IndexingSpiMBean.java b/modules/indexing/src/main/java/org/gridgain/grid/spi/indexing/h2/GridH2IndexingSpiMBean.java
deleted file mode 100644
index f9cc010..0000000
--- a/modules/indexing/src/main/java/org/gridgain/grid/spi/indexing/h2/GridH2IndexingSpiMBean.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/* @java.file.header */
-
-/* _________ _____ __________________ _____
- * __ ____/___________(_)______ /__ ____/______ ____(_)_______
- * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
- * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
- * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
- */
-
-package org.gridgain.grid.spi.indexing.h2;
-
-import org.apache.ignite.mbean.*;
-import org.apache.ignite.spi.*;
-import org.h2.api.*;
-import org.jetbrains.annotations.*;
-
-/**
- * Management bean for {@link GridH2IndexingSpi}.
- */
-@IgniteMBeanDescription("MBean that provides access to H2 indexing SPI configuration.")
-public interface GridH2IndexingSpiMBean extends IgniteSpiManagementMBean {
- /**
- * Gets if SPI will index primitive key-value pairs by key.
- *
- * @return Flag value.
- */
- @IgniteMBeanDescription("Index primitive key-value pairs by key by default in all schemas.")
- public boolean isDefaultIndexPrimitiveKey();
-
- /**
- * Gets if SPI will index primitive key-value pairs by value. Makes sense only if
- * {@link GridH2IndexingSpi#setDefaultIndexPrimitiveKey(boolean)} set to true.
- *
- * @return Flag value.
- */
- @IgniteMBeanDescription("Index primitive key-value pairs by value by default in all schemas.")
- public boolean isDefaultIndexPrimitiveValue();
-
- /**
- * If false, SPI will store all keys in BINARY form to make it possible to store
- * the same value type with different key types. If true, key type will be converted
- * to respective SQL type if it is possible.
- *
- * @return Flag value.
- */
- @IgniteMBeanDescription("If false, SPI will store all keys in BINARY form, otherwise it will try to convert key " +
- "type to respective SQL type.")
- public boolean isDefaultIndexFixedTyping();
-
- /**
- * Gets maximum amount of memory available to off-heap storage. Possible values are
- * <ul>
- * <li>{@code -1} - Means that off-heap storage is disabled.</li>
- * <li>
- * {@code 0} - GridGain will not limit off-heap storage (it's up to user to properly
- * add and remove entries from cache to ensure that off-heap storage does not grow
- * indefinitely.
- * </li>
- * <li>Any positive value specifies the limit of off-heap storage in bytes.</li>
- * </ul>
- * Default value is {@code -1}, which means that off-heap storage is disabled by default.
- * <p>
- * Use off-heap storage to load gigabytes of data in memory without slowing down
- * Garbage Collection. Essentially in this case you should allocate very small amount
- * of memory to JVM and GridGain will cache most of the data in off-heap space
- * without affecting JVM performance at all.
- *
- * @return Maximum memory in bytes available to off-heap memory space.
- */
- @IgniteMBeanDescription("Maximum off-heap memory for indexes.")
- public long getMaxOffHeapMemory();
-
- /**
- * Gets index write lock wait time in milliseconds. This parameter can affect query performance under high
- * thread contention. Default value is {@code 100}.
- *
- * @return Index write lock wait time in milliseconds.
- */
- @IgniteMBeanDescription("Index write lock wait time in milliseconds.")
- public long getIndexWriteLockWaitTime();
-
- /**
- * Gets maximum allowed off-heap rows cache size in items.
- *
- * @return Maximum allowed off-heap rows cache size.
- */
- @IgniteMBeanDescription("Maximum allowed off-heap rows cache size.")
- public int getMaxOffheapRowsCacheSize();
-
- /**
- * Gets current off-heap rows cache size in items.
- *
- * @return Current off-heap rows cache size.
- */
- @IgniteMBeanDescription("Current off-heap rows cache size.")
- public int getOffheapRowsCacheSize();
-
- /**
- * Gets currently allocated offheap memory.
- *
- * @return Allocated memory in bytes.
- */
- @IgniteMBeanDescription("Allocated off-heap memory for indexes.")
- public long getAllocatedOffHeapMemory();
-
- /**
- * Gets all registered in this SPI spaces comma separated.
- *
- * @return Collection of space names.
- */
- @IgniteMBeanDescription("All registered in this SPI spaces.")
- public String getSpaceNames();
-
- /**
- * Gets the optional search path consisting of space names to search SQL schema objects. Useful for cross cache
- * queries to avoid writing fully qualified table names.
- *
- * @return Array of space names.
- */
- @Nullable public String[] getSearchPath();
-
- /**
- * The flag indicating that {@link JavaObjectSerializer} for H2 database will be set to optimized version.
- *
- * @return Flag value.
- */
- public boolean isUseOptimizedSerializer();
-
- /**
- * Gets script path to be ran against H2 database after opening.
- *
- * @return Script path.
- */
- @Nullable public String getInitialScriptPath();
-
- /**
- * Get query execution time interpreted by SPI as long query for additional handling (e.g. print warning).
- *
- * @return Long query execution time.
- * @see #isLongQueryExplain()
- */
- @IgniteMBeanDescription("Query execution time interpreted by SPI as long query.")
- public long getLongQueryExecutionTimeout();
-
- /**
- * If {@code true}, SPI prints SQL execution plan for long queries (explain SQL query).
- *
- * @return Flag marking SPI should print SQL execution plan for long queries (explain SQL query).
- * @see #getLongQueryExecutionTimeout()
- */
- @IgniteMBeanDescription("If true, SPI will print SQL execution plan for long queries (explain SQL query).")
- public boolean isLongQueryExplain();
-
- /**
- * Defines whether indexing SPI will index by key entries where key and value are primitive types in given space.
- *
- * @param spaceName Space name.
- * @return Flag value.
- */
- @IgniteMBeanDescription("Index by key entries where key and value are primitive types in given space.")
- @IgniteMBeanParametersNames("spaceName")
- @IgniteMBeanParametersDescriptions("Space name.")
- public boolean isIndexPrimitiveKey(@Nullable String spaceName);
-
- /**
- * Defines whether indexing SPI will index by value entries where key and value are primitive types in given space.
- *
- * @param spaceName Space name.
- * @return Flag value.
- */
- @IgniteMBeanDescription("Index by value entries where key and value are primitive types in given space.")
- @IgniteMBeanParametersNames("spaceName")
- @IgniteMBeanParametersDescriptions("Space name.")
- public boolean isIndexPrimitiveValue(@Nullable String spaceName);
-
- /**
- * If {@code false}, SPI will store all keys in BINARY form to make it possible to store
- * the same value type with different key types. If {@code true}, key type will be converted
- * to respective SQL type if it is possible.
- * <p>
- * Setting this value to {@code false} also means that {@code '_key'} column cannot be indexed and
- * cannot participate in query where clauses. The behavior of using '_key' column in where
- * clauses with this flag set to {@code false} is undefined.
- *
- * @param spaceName Space name.
- * @return Flag value.
- */
- @IgniteMBeanDescription("If false, SPI will store all keys in BINARY form, otherwise it will try to convert key " +
- "type to respective SQL type.")
- @IgniteMBeanParametersNames("spaceName")
- @IgniteMBeanParametersDescriptions("Space name.")
- public boolean isIndexFixedTyping(@Nullable String spaceName);
-
- /**
- * If {@code true}, then table name and all column names in 'create table' SQL
- * generated by SPI are escaped with double quotes. This flag should be set if table name of
- * column name is H2 reserved word or is not valid H2 identifier (e.g. contains space or hyphen).
- * <p>
- * Note if this flag is set then table and column name in SQL queries also must be escaped with double quotes.
- *
- * @return Flag value.
- */
- @IgniteMBeanDescription("If true, then table name and all column names in 'create table' SQL generated by " +
- "SPI are escaped with double quotes.")
- public boolean isDefaultEscapeAll();
-
- /**
- * If {@code true}, then table name and all column names in 'create table' SQL
- * generated by SPI are escaped with double quotes. This flag should be set if table name of
- * column name is H2 reserved word or is not valid H2 identifier (e.g. contains space or hyphen).
- * <p>
- * Note if this flag is set then table and column name in SQL queries also must be escaped with double quotes.
- *
- * @param spaceName Space name.
- * @return Flag value.
- */
- @IgniteMBeanDescription("If true, then table name and all column names in 'create table' SQL generated by " +
- "SPI are escaped with double quotes.")
- @IgniteMBeanParametersNames("spaceName")
- @IgniteMBeanParametersDescriptions("Space name.")
- public boolean isEscapeAll(@Nullable String spaceName);
-}