http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java index f132366..0b26dce 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java @@ -27,10 +27,10 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.jetbrains.annotations.Nullable; /** - * SQL listener query execute request. + * JDBC query execute request. */ public class JdbcQueryExecuteRequest extends JdbcRequest { - /** Cache name. */ + /** Schema name. */ private String schemaName; /** Fetch size. */ @@ -49,7 +49,7 @@ public class JdbcQueryExecuteRequest extends JdbcRequest { /** */ - public JdbcQueryExecuteRequest() { + JdbcQueryExecuteRequest() { super(QRY_EXEC); } @@ -100,7 +100,7 @@ public class JdbcQueryExecuteRequest extends JdbcRequest { } /** - * @return Cache name. + * @return Schema name. */ @Nullable public String schemaName() { return schemaName;
http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteResult.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteResult.java index a935215..fdebdb8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteResult.java @@ -21,9 +21,10 @@ import java.util.List; import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.internal.binary.BinaryReaderExImpl; import org.apache.ignite.internal.binary.BinaryWriterExImpl; +import org.apache.ignite.internal.util.typedef.internal.S; /** - * SQL listener query execute result. + * JDBC query execute result. */ public class JdbcQueryExecuteResult extends JdbcResult { /** Query ID. */ @@ -44,7 +45,7 @@ public class JdbcQueryExecuteResult extends JdbcResult { /** * Condtructor. */ - public JdbcQueryExecuteResult() { + JdbcQueryExecuteResult() { super(QRY_EXEC); } @@ -53,7 +54,7 @@ public class JdbcQueryExecuteResult extends JdbcResult { * @param items Query result rows. * @param last Flag indicates the query has no unfetched results. */ - public JdbcQueryExecuteResult(long queryId, List<List<Object>> items, boolean last) { + JdbcQueryExecuteResult(long queryId, List<List<Object>> items, boolean last) { super(QRY_EXEC); this.queryId = queryId; @@ -147,4 +148,9 @@ public class JdbcQueryExecuteResult extends JdbcResult { updateCnt = reader.readLong(); } } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(JdbcQueryExecuteResult.class, this); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchRequest.java index 2e1f551..776c3bf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchRequest.java @@ -23,7 +23,7 @@ import org.apache.ignite.internal.binary.BinaryWriterExImpl; import org.apache.ignite.internal.util.typedef.internal.S; /** - * SQL listener query fetch request. + * JDBC query fetch request. */ public class JdbcQueryFetchRequest extends JdbcRequest { /** Query ID. */ @@ -35,7 +35,7 @@ public class JdbcQueryFetchRequest extends JdbcRequest { /** * Constructor. */ - public JdbcQueryFetchRequest() { + JdbcQueryFetchRequest() { super(QRY_FETCH); } http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchResult.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchResult.java index 6735c6b..ac4a603 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchResult.java @@ -21,9 +21,10 @@ import java.util.List; import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.internal.binary.BinaryReaderExImpl; import org.apache.ignite.internal.binary.BinaryWriterExImpl; +import org.apache.ignite.internal.util.typedef.internal.S; /** - * SQL listener query fetch result. + * JDBC query fetch result. */ public class JdbcQueryFetchResult extends JdbcResult { /** Query result rows. */ @@ -35,7 +36,7 @@ public class JdbcQueryFetchResult extends JdbcResult { /** * Default constructor is used for deserialization. */ - public JdbcQueryFetchResult() { + JdbcQueryFetchResult() { super(QRY_FETCH); } @@ -43,7 +44,7 @@ public class JdbcQueryFetchResult extends JdbcResult { * @param items Query result rows. * @param last Flag indicating the query has no unfetched results. */ - public JdbcQueryFetchResult(List<List<Object>> items, boolean last){ + JdbcQueryFetchResult(List<List<Object>> items, boolean last){ super(QRY_FETCH); this.items = items; @@ -81,4 +82,9 @@ public class JdbcQueryFetchResult extends JdbcResult { items = JdbcUtils.readItems(reader); } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(JdbcQueryFetchResult.class, this); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataRequest.java index d14c9df..bdef321 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataRequest.java @@ -23,47 +23,47 @@ import org.apache.ignite.internal.binary.BinaryWriterExImpl; import org.apache.ignite.internal.util.typedef.internal.S; /** - * SQL listener query metadata request. + * JDBC query metadata request. */ public class JdbcQueryMetadataRequest extends JdbcRequest { /** Query ID. */ - private long queryId; + private long qryId; /** * Constructor. */ - public JdbcQueryMetadataRequest() { + JdbcQueryMetadataRequest() { super(QRY_META); } /** - * @param queryId Query ID. + * @param qryId Query ID. */ - public JdbcQueryMetadataRequest(long queryId) { + public JdbcQueryMetadataRequest(long qryId) { super(QRY_META); - this.queryId = queryId; + this.qryId = qryId; } /** * @return Query ID. */ public long queryId() { - return queryId; + return qryId; } /** {@inheritDoc} */ @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { super.writeBinary(writer); - writer.writeLong(queryId); + writer.writeLong(qryId); } /** {@inheritDoc} */ @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { super.readBinary(reader); - queryId = reader.readLong(); + qryId = reader.readLong(); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataResult.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataResult.java index cc193e3..c8c0991 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataResult.java @@ -24,9 +24,10 @@ import org.apache.ignite.binary.BinaryObjectException; import org.apache.ignite.internal.binary.BinaryReaderExImpl; import org.apache.ignite.internal.binary.BinaryWriterExImpl; import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.S; /** - * SQL listener query metadata result. + * JDBC query metadata result. */ public class JdbcQueryMetadataResult extends JdbcResult { /** Fields metadata. */ @@ -35,7 +36,7 @@ public class JdbcQueryMetadataResult extends JdbcResult { /** * Default constructor is used for deserialization. */ - public JdbcQueryMetadataResult() { + JdbcQueryMetadataResult() { super(QRY_META); } @@ -43,14 +44,14 @@ public class JdbcQueryMetadataResult extends JdbcResult { * @param queryId Query ID. * @param meta Query metadata. */ - public JdbcQueryMetadataResult(long queryId, List<JdbcColumnMeta> meta){ + JdbcQueryMetadataResult(long queryId, List<JdbcColumnMeta> meta){ super(QRY_META); this.meta = meta; } /** - * @return Query result rows. + * @return Query result metadata. */ public List<JdbcColumnMeta> meta() { return meta; @@ -90,4 +91,9 @@ public class JdbcQueryMetadataResult extends JdbcResult { } } } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(JdbcQueryMetadataResult.class, this); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java index 0e144cc..4ef75f6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java @@ -24,24 +24,43 @@ import org.apache.ignite.internal.binary.BinaryWriterExImpl; import org.apache.ignite.internal.processors.odbc.SqlListenerRequest; /** - * SQL listener command request. + * JDBC request. */ public class JdbcRequest extends SqlListenerRequest implements JdbcRawBinarylizable { - /** Execute sql query. */ - public static final byte QRY_EXEC = 2; + /** Execute sql query request. */ + static final byte QRY_EXEC = 2; - /** Fetch query results. */ - public static final byte QRY_FETCH = 3; + /** Fetch query results request. */ + static final byte QRY_FETCH = 3; - /** Close query. */ - public static final byte QRY_CLOSE = 4; + /** Close query request. */ + static final byte QRY_CLOSE = 4; - /** Get columns meta query. */ - public static final byte QRY_META = 5; + /** Get query columns metadata request. */ + static final byte QRY_META = 5; /** Batch queries. */ public static final byte BATCH_EXEC = 6; + /** Get tables metadata request. */ + static final byte META_TABLES = 7; + + /** Get columns metadata request. */ + static final byte META_COLUMNS = 8; + + /** Get indexes metadata request. */ + static final byte META_INDEXES = 9; + + /** Get SQL query parameters metadata request. */ + static final byte META_PARAMS = 10; + + /** Get primary keys metadata request. */ + static final byte META_PRIMARY_KEYS = 11; + + /** Get schemas metadata request. */ + static final byte META_SCHEMAS = 12; + + /** Request type. */ private byte type; @@ -105,6 +124,36 @@ public class JdbcRequest extends SqlListenerRequest implements JdbcRawBinaryliza break; + case META_TABLES: + req = new JdbcMetaTablesRequest(); + + break; + + case META_COLUMNS: + req = new JdbcMetaColumnsRequest(); + + break; + + case META_INDEXES: + req = new JdbcMetaIndexesRequest(); + + break; + + case META_PARAMS: + req = new JdbcMetaParamsRequest(); + + break; + + case META_PRIMARY_KEYS: + req = new JdbcMetaPrimaryKeysRequest(); + + break; + + case META_SCHEMAS: + req = new JdbcMetaSchemasRequest(); + + break; + default: throw new IgniteException("Unknown SQL listener request ID: [request ID=" + reqType + ']'); } http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java index 60c08f9..7e58f99 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java @@ -17,8 +17,15 @@ package org.apache.ignite.internal.processors.odbc.jdbc; +import java.sql.ParameterMetaData; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import org.apache.ignite.IgniteCheckedException; @@ -26,10 +33,15 @@ import org.apache.ignite.IgniteLogger; import org.apache.ignite.cache.query.FieldsQueryCursor; import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.IgniteVersionUtils; +import org.apache.ignite.internal.binary.BinaryWriterExImpl; import org.apache.ignite.internal.processors.cache.QueryCursorImpl; import org.apache.ignite.internal.processors.odbc.SqlListenerRequest; import org.apache.ignite.internal.processors.odbc.SqlListenerRequestHandler; import org.apache.ignite.internal.processors.odbc.SqlListenerResponse; +import org.apache.ignite.internal.processors.odbc.odbc.OdbcQueryGetColumnsMetaRequest; +import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor; +import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; import org.apache.ignite.internal.processors.query.QueryUtils; import org.apache.ignite.internal.util.GridSpinBusyLock; import org.apache.ignite.internal.util.typedef.F; @@ -37,13 +49,19 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.BATCH_EXEC; +import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_COLUMNS; +import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_INDEXES; +import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_PARAMS; +import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_PRIMARY_KEYS; +import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_SCHEMAS; +import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.META_TABLES; import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_CLOSE; import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_EXEC; import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_FETCH; import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_META; /** - * SQL query handler. + * JDBC request handler. */ public class JdbcRequestHandler implements SqlListenerRequestHandler { /** Query ID sequence. */ @@ -92,7 +110,7 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler { * @param autoCloseCursors Flag to automatically close server cursors. */ public JdbcRequestHandler(GridKernalContext ctx, GridSpinBusyLock busyLock, int maxCursors, - boolean distributedJoins, boolean enforceJoinOrder, boolean collocated, boolean replicatedOnly, + boolean distributedJoins, boolean enforceJoinOrder, boolean collocated, boolean replicatedOnly, boolean autoCloseCursors) { this.ctx = ctx; this.busyLock = busyLock; @@ -134,6 +152,24 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler { case BATCH_EXEC: return executeBatch((JdbcBatchExecuteRequest)req); + + case META_TABLES: + return getTablesMeta((JdbcMetaTablesRequest)req); + + case META_COLUMNS: + return getColumnsMeta((JdbcMetaColumnsRequest)req); + + case META_INDEXES: + return getIndexesMeta((JdbcMetaIndexesRequest)req); + + case META_PARAMS: + return getParametersMeta((JdbcMetaParamsRequest)req); + + case META_PRIMARY_KEYS: + return getPrimaryKeys((JdbcMetaPrimaryKeysRequest)req); + + case META_SCHEMAS: + return getSchemas((JdbcMetaSchemasRequest)req); } return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, "Unsupported JDBC request [req=" + req + ']'); @@ -148,6 +184,20 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler { return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); } + /** {@inheritDoc} */ + @Override public void writeHandshake(BinaryWriterExImpl writer) { + // Handshake OK. + writer.writeBoolean(true); + + // Write server version. + writer.writeByte(IgniteVersionUtils.VER.major()); + writer.writeByte(IgniteVersionUtils.VER.minor()); + writer.writeByte(IgniteVersionUtils.VER.maintenance()); + writer.writeString(IgniteVersionUtils.VER.stage()); + writer.writeLong(IgniteVersionUtils.VER.revisionTimestamp()); + writer.writeByteArray(IgniteVersionUtils.VER.revisionHash()); + } + /** * {@link JdbcQueryExecuteRequest} command handler. * @@ -318,7 +368,7 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler { * @return Response. */ private SqlListenerResponse executeBatch(JdbcBatchExecuteRequest req) { - String schemaName = req.schema(); + String schemaName = req.schemaName(); if (F.isEmpty(schemaName)) schemaName = QueryUtils.DFLT_SCHEMA; @@ -365,4 +415,221 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler { SqlListenerResponse.STATUS_FAILED, e.toString())); } } + + /** + * @param req Get tables metadata request. + * @return Response. + */ + private JdbcResponse getTablesMeta(JdbcMetaTablesRequest req) { + try { + List<JdbcTableMeta> meta = new ArrayList<>(); + + for (String cacheName : ctx.cache().publicCacheNames()) { + for (GridQueryTypeDescriptor table : ctx.query().types(cacheName)) { + if (!matches(table.schemaName(), req.schemaName())) + continue; + + if (!matches(table.tableName(), req.tableName())) + continue; + + JdbcTableMeta tableMeta = new JdbcTableMeta(table.schemaName(), table.tableName(), "TABLE"); + + if (!meta.contains(tableMeta)) + meta.add(tableMeta); + } + } + + JdbcMetaTablesResult res = new JdbcMetaTablesResult(meta); + + return new JdbcResponse(res); + } + catch (Exception e) { + U.error(log, "Failed to get tables metadata [reqId=" + req.requestId() + ", req=" + req + ']', e); + + return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); + } + } + + /** + * {@link OdbcQueryGetColumnsMetaRequest} command handler. + * + * @param req Get columns metadata request. + * @return Response. + */ + private JdbcResponse getColumnsMeta(JdbcMetaColumnsRequest req) { + try { + Collection<JdbcColumnMeta> meta = new HashSet<>(); + + for (String cacheName : ctx.cache().publicCacheNames()) { + for (GridQueryTypeDescriptor table : ctx.query().types(cacheName)) { + if (!matches(table.schemaName(), req.schemaName())) + continue; + + if (!matches(table.tableName(), req.tableName())) + continue; + + for (Map.Entry<String, Class<?>> field : table.fields().entrySet()) { + if (!matches(field.getKey(), req.columnName())) + continue; + + JdbcColumnMeta columnMeta = new JdbcColumnMeta(table.schemaName(), table.tableName(), + field.getKey(), field.getValue()); + + if (!meta.contains(columnMeta)) + meta.add(columnMeta); + } + } + } + + JdbcMetaColumnsResult res = new JdbcMetaColumnsResult(meta); + + return new JdbcResponse(res); + } + catch (Exception e) { + U.error(log, "Failed to get columns metadata [reqId=" + req.requestId() + ", req=" + req + ']', e); + + return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); + } + } + + /** + * @param req Request. + * @return Response. + */ + private SqlListenerResponse getIndexesMeta(JdbcMetaIndexesRequest req) { + try { + Collection<JdbcIndexMeta> meta = new HashSet<>(); + + for (String cacheName : ctx.cache().publicCacheNames()) { + for (GridQueryTypeDescriptor table : ctx.query().types(cacheName)) { + if (!matches(table.schemaName(), req.schemaName())) + continue; + + if (!matches(table.tableName(), req.tableName())) + continue; + + for (GridQueryIndexDescriptor idxDesc : table.indexes().values()) + meta.add(new JdbcIndexMeta(table.schemaName(), table.tableName(), idxDesc)); + } + } + + return new JdbcResponse(new JdbcMetaIndexesResult(meta)); + } + catch (Exception e) { + U.error(log, "Failed to get parameters metadata [reqId=" + req.requestId() + ", req=" + req + ']', e); + + return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); + } + } + + /** + * @param req Request. + * @return Response. + */ + private SqlListenerResponse getParametersMeta(JdbcMetaParamsRequest req) { + try { + ParameterMetaData paramMeta = ctx.query().prepareNativeStatement(req.schemaName(), req.sql()) + .getParameterMetaData(); + + int size = paramMeta.getParameterCount(); + + List<JdbcParameterMeta> meta = new ArrayList<>(size); + + for (int i = 0; i < size; i++) + meta.add(new JdbcParameterMeta(paramMeta, i + 1)); + + JdbcMetaParamsResult res = new JdbcMetaParamsResult(meta); + + return new JdbcResponse(res); + } + catch (Exception e) { + U.error(log, "Failed to get parameters metadata [reqId=" + req.requestId() + ", req=" + req + ']', e); + + return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); + } + } + + /** + * @param req Request. + * @return Response. + */ + private SqlListenerResponse getPrimaryKeys(JdbcMetaPrimaryKeysRequest req) { + try { + Collection<JdbcPrimaryKeyMeta> meta = new HashSet<>(); + + for (String cacheName : ctx.cache().publicCacheNames()) { + for (GridQueryTypeDescriptor table : ctx.query().types(cacheName)) { + if (!matches(table.schemaName(), req.schemaName())) + continue; + + if (!matches(table.tableName(), req.tableName())) + continue; + + List<String> fields = new ArrayList<>(); + + for (String field : table.fields().keySet()) { + if (table.property(field).key()) + fields.add(field); + } + + + final String keyName = table.keyFieldName() == null ? + "PK_" + table.schemaName() + "_" + table.tableName() : + table.keyFieldName(); + + if (fields.isEmpty()) { + meta.add(new JdbcPrimaryKeyMeta(table.schemaName(), table.tableName(), keyName, + Collections.singletonList("_KEY"))); + } + else + meta.add(new JdbcPrimaryKeyMeta(table.schemaName(), table.tableName(), keyName, fields)); + } + } + + return new JdbcResponse(new JdbcMetaPrimaryKeysResult(meta)); + } + catch (Exception e) { + U.error(log, "Failed to get parameters metadata [reqId=" + req.requestId() + ", req=" + req + ']', e); + + return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); + } + } + + /** + * @param req Request. + * @return Response. + */ + private SqlListenerResponse getSchemas(JdbcMetaSchemasRequest req) { + try { + String schemaPtrn = req.schemaName(); + + Set<String> schemas = new HashSet<>(); + + for (String cacheName : ctx.cache().publicCacheNames()) { + for (GridQueryTypeDescriptor table : ctx.query().types(cacheName)) { + if (matches(table.schemaName(), schemaPtrn)) + schemas.add(table.schemaName()); + } + } + + return new JdbcResponse(new JdbcMetaSchemasResult(schemas)); + } + catch (Exception e) { + U.error(log, "Failed to get schemas metadata [reqId=" + req.requestId() + ", req=" + req + ']', e); + + return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); + } + } + + /** + * Checks whether string matches SQL pattern. + * + * @param str String. + * @param ptrn Pattern. + * @return Whether string matches pattern. + */ + private static boolean matches(String str, String ptrn) { + return str != null && (F.isEmpty(ptrn) || + str.matches(ptrn.replace("%", ".*").replace("_", "."))); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java index 48affe9..202905b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java @@ -23,21 +23,39 @@ import org.apache.ignite.internal.binary.BinaryReaderExImpl; import org.apache.ignite.internal.binary.BinaryWriterExImpl; /** - * SQL listener response. + * JDBC response result. */ public class JdbcResult implements JdbcRawBinarylizable { /** Execute sql result. */ - public static final byte QRY_EXEC = 2; + static final byte QRY_EXEC = 2; /** Fetch query results. */ - public static final byte QRY_FETCH = 3; + static final byte QRY_FETCH = 3; - /** Get columns meta query result. */ - public static final byte QRY_META = 4; + /** Query result's columns metadata result. */ + static final byte QRY_META = 5; /** Batch queries. */ public static final byte BATCH_EXEC = 6; + /** Tables metadata result. */ + static final byte META_TABLES = 7; + + /** Columns metadata result. */ + static final byte META_COLUMNS = 8; + + /** Indexes metadata result. */ + static final byte META_INDEXES = 9; + + /** SQL query parameters metadata result. */ + static final byte META_PARAMS = 10; + + /** Primary keys metadata result. */ + static final byte META_PRIMARY_KEYS = 11; + + /** Database schemas metadata result. */ + static final byte META_SCHEMAS = 12; + /** Success status. */ private byte type; @@ -91,6 +109,36 @@ public class JdbcResult implements JdbcRawBinarylizable { break; + case META_TABLES: + res = new JdbcMetaTablesResult(); + + break; + + case META_COLUMNS: + res = new JdbcMetaColumnsResult(); + + break; + + case META_INDEXES: + res = new JdbcMetaIndexesResult(); + + break; + + case META_PARAMS: + res = new JdbcMetaParamsResult(); + + break; + + case META_PRIMARY_KEYS: + res = new JdbcMetaPrimaryKeysResult(); + + break; + + case META_SCHEMAS: + res = new JdbcMetaSchemasResult(); + + break; + default: throw new IgniteException("Unknown SQL listener request ID: [request ID=" + resId + ']'); } http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcTableMeta.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcTableMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcTableMeta.java new file mode 100644 index 0000000..b954e97 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcTableMeta.java @@ -0,0 +1,82 @@ +/* + * 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.ignite.internal.processors.odbc.jdbc; + +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.internal.binary.BinaryReaderExImpl; +import org.apache.ignite.internal.binary.BinaryWriterExImpl; +import org.apache.ignite.internal.util.typedef.internal.S; + +/** + * JDBC table metadata. + */ +public class JdbcTableMeta implements JdbcRawBinarylizable { + /** Schema name. */ + private String schemaName; + + /** Table name. */ + private String tblName; + + /** + * Default constructor is used for deserialization. + */ + JdbcTableMeta() { + // No-op. + } + + /** + * @param schemaName Schema name. + * @param tblName Table name. + * @param tblType Table type. + */ + JdbcTableMeta(String schemaName, String tblName, String tblType) { + this.schemaName = schemaName; + this.tblName = tblName; + } + + /** + * @return Schema name. + */ + public String schemaName() { + return schemaName; + } + + /** + * @return Table name. + */ + public String tableName() { + return tblName; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { + writer.writeString(schemaName); + writer.writeString(tblName); + } + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { + schemaName = reader.readString(); + tblName = reader.readString(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(JdbcTableMeta.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcUtils.java index 65efbf5..d556419 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcUtils.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.odbc.jdbc; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import org.apache.ignite.internal.binary.BinaryReaderExImpl; @@ -29,7 +30,7 @@ import org.apache.ignite.internal.processors.odbc.SqlListenerUtils; */ public class JdbcUtils { /** - * @param writer Binari writer. + * @param writer Binary writer. * @param items Query results items. */ public static void writeItems(BinaryWriterExImpl writer, List<List<Object>> items) { @@ -70,4 +71,38 @@ public class JdbcUtils { } else return Collections.emptyList(); } + + /** + * @param writer Binary writer. + * @param lst List to write. + */ + public static void writeStringCollection(BinaryWriterExImpl writer, Collection<String> lst) { + if (lst == null) + writer.writeInt(0); + else { + writer.writeInt(lst.size()); + + for (String s : lst) + writer.writeString(s); + } + } + + /** + * @param reader Binary reader. + * @return List of string. + */ + public static List<String> readStringList(BinaryReaderExImpl reader) { + int size = reader.readInt(); + + if (size > 0) { + List<String> lst = new ArrayList<>(size); + + for (int i = 0; i < size; ++i) + lst.add(reader.readString()); + + return lst; + } + else + return Collections.emptyList(); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java index bb54b59..692043c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java @@ -33,6 +33,7 @@ import org.apache.ignite.IgniteLogger; import org.apache.ignite.cache.query.QueryCursor; import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.binary.BinaryWriterExImpl; import org.apache.ignite.internal.binary.GridBinaryMarshaller; import org.apache.ignite.internal.processors.cache.QueryCursorImpl; import org.apache.ignite.internal.processors.odbc.SqlListenerRequest; @@ -156,6 +157,11 @@ public class OdbcRequestHandler implements SqlListenerRequestHandler { return new OdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); } + /** {@inheritDoc} */ + @Override public void writeHandshake(BinaryWriterExImpl writer) { + writer.writeBoolean(true); + } + /** * {@link OdbcQueryExecuteRequest} command handler. * http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java index baafb1e..1d154d3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java @@ -688,7 +688,7 @@ public class GridQueryProcessor extends GridProcessorAdapter { if (!F.isEmpty(qryEntities)) { for (QueryEntity qryEntity : qryEntities) { - QueryTypeCandidate cand = QueryUtils.typeForQueryEntity(cacheName, cctx, qryEntity, + QueryTypeCandidate cand = QueryUtils.typeForQueryEntity(cacheName, schemaName, cctx, qryEntity, mustDeserializeClss, escape); cands.add(cand); http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java index c1a9e1e..c149335 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryTypeDescriptor.java @@ -33,6 +33,13 @@ public interface GridQueryTypeDescriptor { public String name(); /** + * Gets schema name for type (database schema means here). + * + * @return Schema name. + */ + public String schemaName(); + + /** * Gets table name for type. * * @return Table name. http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java index c0da83f..79b90e5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryTypeDescriptorImpl.java @@ -42,6 +42,9 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor { /** */ private String name; + /** Schema name. */ + private String schemaName; + /** */ private String tblName; @@ -120,6 +123,11 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor { return name; } + /** {@inheritDoc} */ + @Override public String schemaName() { + return schemaName; + } + /** * Sets type name. * @@ -363,6 +371,13 @@ public class QueryTypeDescriptorImpl implements GridQueryTypeDescriptor { fields.put(name, prop.type()); } + /** + * @param schemaName Schema name. + */ + public void schemaName(String schemaName) { + this.schemaName = schemaName; + } + /** {@inheritDoc} */ @Override public boolean valueTextIndex() { return valTextIdx; http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java index 320b25a..26fc776 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java @@ -343,6 +343,7 @@ public class QueryUtils { * Create type candidate for query entity. * * @param cacheName Cache name. + * @param schemaName Schema name. * @param cctx Cache context. * @param qryEntity Query entity. * @param mustDeserializeClss Classes which must be deserialized. @@ -350,8 +351,8 @@ public class QueryUtils { * @return Type candidate. * @throws IgniteCheckedException If failed. */ - public static QueryTypeCandidate typeForQueryEntity(String cacheName, GridCacheContext cctx, QueryEntity qryEntity, - List<Class<?>> mustDeserializeClss, boolean escape) throws IgniteCheckedException { + public static QueryTypeCandidate typeForQueryEntity(String cacheName, String schemaName, GridCacheContext cctx, + QueryEntity qryEntity, List<Class<?>> mustDeserializeClss, boolean escape) throws IgniteCheckedException { GridKernalContext ctx = cctx.kernalContext(); CacheConfiguration<?,?> ccfg = cctx.config(); @@ -361,6 +362,8 @@ public class QueryUtils { QueryTypeDescriptorImpl desc = new QueryTypeDescriptorImpl(cacheName); + desc.schemaName(schemaName); + desc.aliases(qryEntity.getAliases()); // Key and value classes still can be available if they are primitive or JDK part. http://git-wip-us.apache.org/repos/asf/ignite/blob/0e803144/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java index 99246eb..e1ab8e6 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexingSpiAbstractSelfTest.java @@ -104,13 +104,13 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract } /** */ - private static TypeDesc typeAA = new TypeDesc("A", "A", Collections.<String, Class<?>>emptyMap(), null); + private static TypeDesc typeAA = new TypeDesc("A", "A", "A", Collections.<String, Class<?>>emptyMap(), null); /** */ - private static TypeDesc typeAB = new TypeDesc("A", "B", Collections.<String, Class<?>>emptyMap(), textIdx); + private static TypeDesc typeAB = new TypeDesc("A", "A", "B", Collections.<String, Class<?>>emptyMap(), textIdx); /** */ - private static TypeDesc typeBA = new TypeDesc("B", "A", Collections.<String, Class<?>>emptyMap(), null); + private static TypeDesc typeBA = new TypeDesc("B", "B", "A", Collections.<String, Class<?>>emptyMap(), null); /** {@inheritDoc} */ @Override protected void beforeTest() throws Exception { @@ -467,6 +467,9 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract private final String cacheName; /** */ + private final String schemaName; + + /** */ private final Map<String, Class<?>> valFields; /** */ @@ -474,13 +477,15 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract /** * @param cacheName Cache name. + * @param schemaName Schema name. * @param name Type name. * @param valFields Fields. * @param textIdx Fulltext index. */ - private TypeDesc(String cacheName, String name, Map<String, Class<?>> valFields, GridQueryIndexDescriptor textIdx) { + private TypeDesc(String cacheName, String schemaName, String name, Map<String, Class<?>> valFields, GridQueryIndexDescriptor textIdx) { this.name = name; this.cacheName = cacheName; + this.schemaName = schemaName; this.valFields = Collections.unmodifiableMap(valFields); this.textIdx = textIdx; } @@ -496,6 +501,11 @@ public abstract class GridIndexingSpiAbstractSelfTest extends GridCommonAbstract } /** {@inheritDoc} */ + @Override public String schemaName() { + return schemaName; + } + + /** {@inheritDoc} */ @Override public String tableName() { return null; }
