http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerRequestHandlerImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerRequestHandlerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerRequestHandlerImpl.java deleted file mode 100644 index 1230bb4..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerRequestHandlerImpl.java +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.odbc; - -import java.sql.ParameterMetaData; -import java.sql.PreparedStatement; -import java.sql.Types; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; -import org.apache.ignite.IgniteCache; -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.GridBinaryMarshaller; -import org.apache.ignite.internal.processors.cache.QueryCursorImpl; -import org.apache.ignite.internal.processors.odbc.odbc.escape.OdbcEscapeUtils; -import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; -import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; -import org.apache.ignite.internal.util.GridSpinBusyLock; -import org.apache.ignite.internal.util.typedef.F; -import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.lang.IgniteBiTuple; - -import static org.apache.ignite.internal.processors.odbc.SqlListenerRequest.META_COLS; -import static org.apache.ignite.internal.processors.odbc.SqlListenerRequest.META_PARAMS; -import static org.apache.ignite.internal.processors.odbc.SqlListenerRequest.META_TBLS; -import static org.apache.ignite.internal.processors.odbc.SqlListenerRequest.QRY_CLOSE; -import static org.apache.ignite.internal.processors.odbc.SqlListenerRequest.QRY_EXEC; -import static org.apache.ignite.internal.processors.odbc.SqlListenerRequest.QRY_FETCH; - -/** - * SQL query handler. - */ -public class SqlListenerRequestHandlerImpl implements SqlListenerRequestHandler { - /** Query ID sequence. */ - private static final AtomicLong QRY_ID_GEN = new AtomicLong(); - - /** Kernel context. */ - private final GridKernalContext ctx; - - /** Logger. */ - private final IgniteLogger log; - - /** Busy lock. */ - private final GridSpinBusyLock busyLock; - - /** Maximum allowed cursors. */ - private final int maxCursors; - - /** Current queries cursors. */ - private final ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCursors = new ConcurrentHashMap<>(); - - /** Distributed joins flag. */ - private final boolean distributedJoins; - - /** Enforce join order flag. */ - private final boolean enforceJoinOrder; - - /** - * Constructor. - * - * @param ctx Context. - * @param busyLock Shutdown latch. - * @param maxCursors Maximum allowed cursors. - * @param distributedJoins Distributed joins flag. - * @param enforceJoinOrder Enforce join order flag. - */ - public SqlListenerRequestHandlerImpl(GridKernalContext ctx, GridSpinBusyLock busyLock, int maxCursors, - boolean distributedJoins, boolean enforceJoinOrder) { - this.ctx = ctx; - this.busyLock = busyLock; - this.maxCursors = maxCursors; - this.distributedJoins = distributedJoins; - this.enforceJoinOrder = enforceJoinOrder; - - log = ctx.log(getClass()); - } - - /** {@inheritDoc} */ - @Override public SqlListenerResponse handle(SqlListenerRequest req) { - assert req != null; - - if (!busyLock.enterBusy()) - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, - "Failed to handle ODBC request because node is stopping: " + req); - - try { - switch (req.command()) { - case QRY_EXEC: - return executeQuery((SqlListenerQueryExecuteRequest)req); - - case QRY_FETCH: - return fetchQuery((SqlListenerQueryFetchRequest)req); - - case QRY_CLOSE: - return closeQuery((SqlListenerQueryCloseRequest)req); - - case META_COLS: - return getColumnsMeta((OdbcQueryGetColumnsMetaRequest)req); - - case META_TBLS: - return getTablesMeta((OdbcQueryGetTablesMetaRequest)req); - - case META_PARAMS: - return getParamsMeta((OdbcQueryGetParamsMetaRequest)req); - } - - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, "Unsupported ODBC request: " + req); - } - finally { - busyLock.leaveBusy(); - } - } - - /** - * {@link SqlListenerQueryExecuteRequest} command handler. - * - * @param req Execute query request. - * @return Response. - */ - private SqlListenerResponse executeQuery(SqlListenerQueryExecuteRequest req) { - int cursorCnt = qryCursors.size(); - - if (maxCursors > 0 && cursorCnt >= maxCursors) - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, "Too many opened cursors (either close other " + - "opened cursors or increase the limit through OdbcConfiguration.setMaxOpenCursors()) " + - "[maximum=" + maxCursors + ", current=" + cursorCnt + ']'); - - long qryId = QRY_ID_GEN.getAndIncrement(); - - try { - String sql = OdbcEscapeUtils.parse(req.sqlQuery()); - - if (log.isDebugEnabled()) - log.debug("ODBC query parsed [reqId=" + req.requestId() + ", original=" + req.sqlQuery() + - ", parsed=" + sql + ']'); - - SqlFieldsQuery qry = new SqlFieldsQuery(sql); - - qry.setArgs(req.arguments()); - - qry.setDistributedJoins(distributedJoins); - qry.setEnforceJoinOrder(enforceJoinOrder); - - IgniteCache<Object, Object> cache0 = ctx.grid().cache(req.cacheName()); - - if (cache0 == null) - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, - "Cache doesn't exist (did you configure it?): " + req.cacheName()); - - IgniteCache<Object, Object> cache = cache0.withKeepBinary(); - - if (cache == null) - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, - "Can not get cache with keep binary: " + req.cacheName()); - - QueryCursor qryCur = cache.query(qry); - - qryCursors.put(qryId, new IgniteBiTuple<QueryCursor, Iterator>(qryCur, null)); - - List<?> fieldsMeta = ((QueryCursorImpl) qryCur).fieldsMeta(); - - SqlListenerQueryExecuteResult res = new SqlListenerQueryExecuteResult(qryId, convertMetadata(fieldsMeta)); - - return new SqlListenerResponse(res); - } - catch (Exception e) { - qryCursors.remove(qryId); - - U.error(log, "Failed to execute SQL query [reqId=" + req.requestId() + ", req=" + req + ']', e); - - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); - } - } - - /** - * {@link SqlListenerQueryCloseRequest} command handler. - * - * @param req Execute query request. - * @return Response. - */ - private SqlListenerResponse closeQuery(SqlListenerQueryCloseRequest req) { - try { - IgniteBiTuple<QueryCursor, Iterator> tuple = qryCursors.get(req.queryId()); - - if (tuple == null) - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, - "Failed to find query with ID: " + req.queryId()); - - QueryCursor cur = tuple.get1(); - - assert(cur != null); - - cur.close(); - - qryCursors.remove(req.queryId()); - - SqlListenerQueryCloseResult res = new SqlListenerQueryCloseResult(req.queryId()); - - return new SqlListenerResponse(res); - } - catch (Exception e) { - qryCursors.remove(req.queryId()); - - U.error(log, "Failed to close SQL query [reqId=" + req.requestId() + ", req=" + req.queryId() + ']', e); - - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); - } - } - - /** - * {@link SqlListenerQueryFetchRequest} command handler. - * - * @param req Execute query request. - * @return Response. - */ - private SqlListenerResponse fetchQuery(SqlListenerQueryFetchRequest req) { - try { - IgniteBiTuple<QueryCursor, Iterator> tuple = qryCursors.get(req.queryId()); - - if (tuple == null) - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, - "Failed to find query with ID: " + req.queryId()); - - Iterator iter = tuple.get2(); - - if (iter == null) { - QueryCursor cur = tuple.get1(); - - iter = cur.iterator(); - - tuple.put(cur, iter); - } - - List<Object> items = new ArrayList<>(); - - for (int i = 0; i < req.pageSize() && iter.hasNext(); ++i) - items.add(iter.next()); - - SqlListenerQueryFetchResult res = new SqlListenerQueryFetchResult(req.queryId(), items, !iter.hasNext()); - - return new SqlListenerResponse(res); - } - catch (Exception e) { - U.error(log, "Failed to fetch SQL query result [reqId=" + req.requestId() + ", req=" + req + ']', e); - - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); - } - } - - /** - * {@link OdbcQueryGetColumnsMetaRequest} command handler. - * - * @param req Get columns metadata request. - * @return Response. - */ - private SqlListenerResponse getColumnsMeta(OdbcQueryGetColumnsMetaRequest req) { - try { - List<SqlListenerColumnMeta> meta = new ArrayList<>(); - - String cacheName; - String tableName; - - if (req.tableName().contains(".")) { - // Parsing two-part table name. - String[] parts = req.tableName().split("\\."); - - cacheName = OdbcUtils.removeQuotationMarksIfNeeded(parts[0]); - - tableName = parts[1]; - } - else { - cacheName = OdbcUtils.removeQuotationMarksIfNeeded(req.cacheName()); - - tableName = req.tableName(); - } - - Collection<GridQueryTypeDescriptor> tablesMeta = ctx.query().types(cacheName); - - for (GridQueryTypeDescriptor table : tablesMeta) { - if (!matches(table.name(), tableName)) - continue; - - for (Map.Entry<String, Class<?>> field : table.fields().entrySet()) { - if (!matches(field.getKey(), req.columnName())) - continue; - - SqlListenerColumnMeta columnMeta = new SqlListenerColumnMeta(req.cacheName(), table.name(), - field.getKey(), field.getValue()); - - if (!meta.contains(columnMeta)) - meta.add(columnMeta); - } - } - - OdbcQueryGetColumnsMetaResult res = new OdbcQueryGetColumnsMetaResult(meta); - - return new SqlListenerResponse(res); - } - catch (Exception e) { - U.error(log, "Failed to get columns metadata [reqId=" + req.requestId() + ", req=" + req + ']', e); - - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); - } - } - - /** - * {@link OdbcQueryGetTablesMetaRequest} command handler. - * - * @param req Get tables metadata request. - * @return Response. - */ - private SqlListenerResponse getTablesMeta(OdbcQueryGetTablesMetaRequest req) { - try { - List<OdbcTableMeta> meta = new ArrayList<>(); - - String realSchema = OdbcUtils.removeQuotationMarksIfNeeded(req.schema()); - - for (String cacheName : ctx.cache().cacheNames()) - { - if (!matches(cacheName, realSchema)) - continue; - - Collection<GridQueryTypeDescriptor> tablesMeta = ctx.query().types(cacheName); - - for (GridQueryTypeDescriptor table : tablesMeta) { - if (!matches(table.name(), req.table())) - continue; - - if (!matches("TABLE", req.tableType())) - continue; - - OdbcTableMeta tableMeta = new OdbcTableMeta(null, cacheName, table.name(), "TABLE"); - - if (!meta.contains(tableMeta)) - meta.add(tableMeta); - } - } - - OdbcQueryGetTablesMetaResult res = new OdbcQueryGetTablesMetaResult(meta); - - return new SqlListenerResponse(res); - } - catch (Exception e) { - U.error(log, "Failed to get tables metadata [reqId=" + req.requestId() + ", req=" + req + ']', e); - - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); - } - } - - /** - * {@link OdbcQueryGetParamsMetaRequest} command handler. - * - * @param req Get params metadata request. - * @return Response. - */ - private SqlListenerResponse getParamsMeta(OdbcQueryGetParamsMetaRequest req) { - try { - PreparedStatement stmt = ctx.query().prepareNativeStatement(req.cacheName(), req.query()); - - ParameterMetaData pmd = stmt.getParameterMetaData(); - - byte[] typeIds = new byte[pmd.getParameterCount()]; - - for (int i = 1; i <= pmd.getParameterCount(); ++i) { - int sqlType = pmd.getParameterType(i); - - typeIds[i - 1] = sqlTypeToBinary(sqlType); - } - - OdbcQueryGetParamsMetaResult res = new OdbcQueryGetParamsMetaResult(typeIds); - - return new SqlListenerResponse(res); - } - catch (Exception e) { - U.error(log, "Failed to get params metadata [reqId=" + req.requestId() + ", req=" + req + ']', e); - - return new SqlListenerResponse(SqlListenerResponse.STATUS_FAILED, e.toString()); - } - } - - /** - * Convert {@link java.sql.Types} to binary type constant (See {@link GridBinaryMarshaller} constants). - * - * @param sqlType SQL type. - * @return Binary type. - */ - private static byte sqlTypeToBinary(int sqlType) { - switch (sqlType) { - case Types.BIGINT: - return GridBinaryMarshaller.LONG; - - case Types.BOOLEAN: - return GridBinaryMarshaller.BOOLEAN; - - case Types.DATE: - return GridBinaryMarshaller.DATE; - - case Types.DOUBLE: - return GridBinaryMarshaller.DOUBLE; - - case Types.FLOAT: - case Types.REAL: - return GridBinaryMarshaller.FLOAT; - - case Types.NUMERIC: - case Types.DECIMAL: - return GridBinaryMarshaller.DECIMAL; - - case Types.INTEGER: - return GridBinaryMarshaller.INT; - - case Types.SMALLINT: - return GridBinaryMarshaller.SHORT; - - case Types.TIME: - return GridBinaryMarshaller.TIME; - - case Types.TIMESTAMP: - return GridBinaryMarshaller.TIMESTAMP; - - case Types.TINYINT: - return GridBinaryMarshaller.BYTE; - - case Types.CHAR: - case Types.VARCHAR: - case Types.LONGNVARCHAR: - return GridBinaryMarshaller.STRING; - - case Types.NULL: - return GridBinaryMarshaller.NULL; - - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - default: - return GridBinaryMarshaller.BYTE_ARR; - } - } - - /** - * Convert metadata in collection from {@link GridQueryFieldMetadata} to - * {@link SqlListenerColumnMeta}. - * - * @param meta Internal query field metadata. - * @return Odbc query field metadata. - */ - private static Collection<SqlListenerColumnMeta> convertMetadata(Collection<?> meta) { - List<SqlListenerColumnMeta> res = new ArrayList<>(); - - if (meta != null) { - for (Object info : meta) { - assert info instanceof GridQueryFieldMetadata; - - res.add(new SqlListenerColumnMeta((GridQueryFieldMetadata)info)); - } - } - - return res; - } - - /** - * 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.toUpperCase().matches(ptrn.toUpperCase().replace("%", ".*").replace("_", "."))); - } -}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerResponse.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerResponse.java index 84c1e26..e35d8f2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerResponse.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerResponse.java @@ -17,14 +17,12 @@ package org.apache.ignite.internal.processors.odbc; -import org.apache.ignite.internal.util.tostring.GridToStringInclude; -import org.apache.ignite.internal.util.typedef.internal.S; import org.jetbrains.annotations.Nullable; /** * SQL listener response. */ -public class SqlListenerResponse { +public abstract class SqlListenerResponse { /** Command succeeded. */ public static final int STATUS_SUCCESS = 0; @@ -32,26 +30,10 @@ public class SqlListenerResponse { public static final int STATUS_FAILED = 1; /** Success status. */ - private final int status; + private int status; /** Error. */ - private final String err; - - /** Response object. */ - @GridToStringInclude - private final Object obj; - - /** - * Constructs successful rest response. - * - * @param obj Response object. - */ - public SqlListenerResponse(Object obj) { - this.status = STATUS_SUCCESS; - - this.obj = obj; - this.err = null; - } + private String err; /** * Constructs failed rest response. @@ -60,11 +42,7 @@ public class SqlListenerResponse { * @param err Error, {@code null} if success is {@code true}. */ public SqlListenerResponse(int status, @Nullable String err) { - assert status != STATUS_SUCCESS; - this.status = status; - - this.obj = null; this.err = err; } @@ -76,10 +54,10 @@ public class SqlListenerResponse { } /** - * @return Response object. + * @param status Status. */ - public Object response() { - return obj; + public void status(int status) { + this.status = status; } /** @@ -89,8 +67,10 @@ public class SqlListenerResponse { return err; } - /** {@inheritDoc} */ - @Override public String toString() { - return S.toString(SqlListenerResponse.class, this); + /** + * @param err Error message. + */ + public void error(String err) { + this.err = err; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerUtils.java new file mode 100644 index 0000000..196eafa --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlListenerUtils.java @@ -0,0 +1,250 @@ +/* + * 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; + +import java.math.BigDecimal; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.UUID; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.internal.binary.BinaryReaderExImpl; +import org.apache.ignite.internal.binary.BinaryUtils; +import org.apache.ignite.internal.binary.BinaryWriterExImpl; +import org.apache.ignite.internal.binary.GridBinaryMarshaller; +import org.jetbrains.annotations.Nullable; + +/** + * Binary reader with marshaling non-primitive and non-embedded objects with JDK marshaller. + */ +@SuppressWarnings("unchecked") +public abstract class SqlListenerUtils { + /** + * @param reader Reader. + * @param binObjAllow Allow to read non plaint objects. + * @return Read object. + * @throws BinaryObjectException On error. + */ + @Nullable public static Object readObject(BinaryReaderExImpl reader, boolean binObjAllow) + throws BinaryObjectException { + byte type = reader.readByte(); + + switch (type) { + case GridBinaryMarshaller.NULL: + return null; + + case GridBinaryMarshaller.BOOLEAN: + return reader.readBoolean(); + + case GridBinaryMarshaller.BYTE: + return reader.readByte(); + + case GridBinaryMarshaller.CHAR: + return reader.readChar(); + + case GridBinaryMarshaller.SHORT: + return reader.readShort(); + + case GridBinaryMarshaller.INT: + return reader.readInt(); + + case GridBinaryMarshaller.LONG: + return reader.readLong(); + + case GridBinaryMarshaller.FLOAT: + return reader.readFloat(); + + case GridBinaryMarshaller.DOUBLE: + return reader.readDouble(); + + case GridBinaryMarshaller.STRING: + return BinaryUtils.doReadString(reader.in()); + + case GridBinaryMarshaller.DECIMAL: + return BinaryUtils.doReadDecimal(reader.in()); + + case GridBinaryMarshaller.UUID: + return BinaryUtils.doReadUuid(reader.in()); + + case GridBinaryMarshaller.TIME: + return BinaryUtils.doReadTime(reader.in()); + + case GridBinaryMarshaller.TIMESTAMP: + return BinaryUtils.doReadTimestamp(reader.in()); + + case GridBinaryMarshaller.DATE: + return BinaryUtils.doReadDate(reader.in()); + + case GridBinaryMarshaller.BOOLEAN_ARR: + return BinaryUtils.doReadBooleanArray(reader.in()); + + case GridBinaryMarshaller.BYTE_ARR: + return BinaryUtils.doReadByteArray(reader.in()); + + case GridBinaryMarshaller.CHAR_ARR: + return BinaryUtils.doReadCharArray(reader.in()); + + case GridBinaryMarshaller.SHORT_ARR: + return BinaryUtils.doReadShortArray(reader.in()); + + case GridBinaryMarshaller.INT_ARR: + return BinaryUtils.doReadIntArray(reader.in()); + + case GridBinaryMarshaller.FLOAT_ARR: + return BinaryUtils.doReadFloatArray(reader.in()); + + case GridBinaryMarshaller.DOUBLE_ARR: + return BinaryUtils.doReadDoubleArray(reader.in()); + + case GridBinaryMarshaller.STRING_ARR: + return BinaryUtils.doReadStringArray(reader.in()); + + case GridBinaryMarshaller.DECIMAL_ARR: + return BinaryUtils.doReadDecimalArray(reader.in()); + + case GridBinaryMarshaller.UUID_ARR: + return BinaryUtils.doReadUuidArray(reader.in()); + + case GridBinaryMarshaller.TIME_ARR: + return BinaryUtils.doReadTimeArray(reader.in()); + + case GridBinaryMarshaller.TIMESTAMP_ARR: + return BinaryUtils.doReadTimestampArray(reader.in()); + + case GridBinaryMarshaller.DATE_ARR: + return BinaryUtils.doReadDateArray(reader.in()); + + default: + reader.in().position(reader.in().position() - 1); + + if (binObjAllow) + return reader.readObjectDetached(); + else + throw new BinaryObjectException("Custom objects are not supported"); + } + } + + /** + * @param writer Writer. + * @param obj Object to write. + * @param binObjAllow Allow to write non plain objects. + * @throws BinaryObjectException On error. + */ + public static void writeObject(BinaryWriterExImpl writer, @Nullable Object obj, boolean binObjAllow) + throws BinaryObjectException { + if (obj == null) { + writer.writeByte(GridBinaryMarshaller.NULL); + + return; + } + + Class<?> cls = obj.getClass(); + + if (cls == Boolean.class) + writer.writeBooleanFieldPrimitive((Boolean)obj); + else if (cls == Byte.class) + writer.writeByteFieldPrimitive((Byte)obj); + else if (cls == Character.class) + writer.writeCharFieldPrimitive((Character)obj); + else if (cls == Short.class) + writer.writeShortFieldPrimitive((Short)obj); + else if (cls == Integer.class) + writer.writeIntFieldPrimitive((Integer)obj); + else if (cls == Long.class) + writer.writeLongFieldPrimitive((Long)obj); + else if (cls == Float.class) + writer.writeFloatFieldPrimitive((Float)obj); + else if (cls == Double.class) + writer.writeDoubleFieldPrimitive((Double)obj); + else if (cls == String.class) + writer.doWriteString((String)obj); + else if (cls == BigDecimal.class) + writer.doWriteDecimal((BigDecimal)obj); + else if (cls == UUID.class) + writer.writeUuid((UUID)obj); + else if (cls == Time.class) + writer.writeTime((Time)obj); + else if (cls == Timestamp.class) + writer.writeTimestamp((Timestamp)obj); + else if (cls == java.sql.Date.class || cls == java.util.Date.class) + writer.writeDate((java.util.Date)obj); + else if (cls == boolean[].class) + writer.writeBooleanArray((boolean[])obj); + else if (cls == byte[].class) + writer.writeByteArray((byte[])obj); + else if (cls == char[].class) + writer.writeCharArray((char[])obj); + else if (cls == short[].class) + writer.writeShortArray((short[])obj); + else if (cls == int[].class) + writer.writeIntArray((int[])obj); + else if (cls == float[].class) + writer.writeFloatArray((float[])obj); + else if (cls == double[].class) + writer.writeDoubleArray((double[])obj); + else if (cls == String[].class) + writer.writeStringArray((String[])obj); + else if (cls == BigDecimal[].class) + writer.writeDecimalArray((BigDecimal[])obj); + else if (cls == UUID[].class) + writer.writeUuidArray((UUID[])obj); + else if (cls == Time[].class) + writer.writeTimeArray((Time[])obj); + else if (cls == Timestamp[].class) + writer.writeTimestampArray((Timestamp[])obj); + else if (cls == java.util.Date[].class || cls == java.sql.Date[].class) + writer.writeDateArray((java.util.Date[])obj); + else if (binObjAllow) + writer.writeObjectDetached(obj); + else + throw new BinaryObjectException("Custom objects are not supported"); + } + + /** + * @param cls Class. + * @return {@code true} is the type is plain (not user's custom class). + */ + public static boolean isPlainType(Class<?> cls) { + return cls == Boolean.class + || cls == Byte.class + || cls == Character.class + || cls == Short.class + || cls == Integer.class + || cls == Long.class + || cls == Float.class + || cls == Double.class + || cls == String.class + || cls == BigDecimal.class + || cls == UUID.class + || cls == Time.class + || cls == Timestamp.class + || cls == java.sql.Date.class || cls == java.util.Date.class + || cls == boolean[].class + || cls == byte[].class + || cls == char[].class + || cls == short[].class + || cls == int[].class + || cls == float[].class + || cls == double[].class + || cls == String[].class + || cls == BigDecimal[].class + || cls == UUID[].class + || cls == Time[].class + || cls == Timestamp[].class + || cls == java.util.Date[].class || cls == java.sql.Date[].class; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java new file mode 100644 index 0000000..07cbabe --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcColumnMeta.java @@ -0,0 +1,129 @@ +/* + * 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.internal.binary.BinaryReaderExImpl; +import org.apache.ignite.internal.binary.BinaryWriterExImpl; +import org.apache.ignite.internal.jdbc.thin.JdbcThinUtils; +import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; + +/** + * SQL listener column metadata. + */ +public class JdbcColumnMeta implements JdbcRawBinarylizable { + /** Cache name. */ + private String schemaName; + + /** Table name. */ + private String tableName; + + /** Column name. */ + private String columnName; + + /** Data type. */ + private int dataType; + + /** Data type. */ + private String dataTypeName; + + /** Data type. */ + private String dataTypeClass; + + /** + * Default constructor is used for serialization. + */ + public JdbcColumnMeta() { + } + + /** + * @param info Field metadata. + */ + public JdbcColumnMeta(GridQueryFieldMetadata info) { + this.schemaName = info.schemaName(); + this.tableName = info.typeName(); + this.columnName = info.fieldName(); + + dataType = JdbcThinUtils.type(info.fieldTypeName()); + dataTypeName = JdbcThinUtils.typeName(info.fieldTypeName()); + dataTypeClass = info.fieldTypeName(); + } + + /** + * @return Schema name. + */ + public String schemaName() { + return schemaName; + } + + /** + * @return Table name. + */ + public String tableName() { + return tableName; + } + + /** + * @return Column name. + */ + public String columnName() { + return columnName; + } + + /** + * @return Column's data type. + */ + public int dataType() { + return dataType; + } + + /** + * @return Column's data type name. + */ + public String dataTypeName() { + return dataTypeName; + } + + /** + * @return Column's data type class. + */ + public String dataTypeClass() { + return dataTypeClass; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) { + writer.writeString(schemaName); + writer.writeString(tableName); + writer.writeString(columnName); + + writer.writeInt(dataType); + writer.writeString(dataTypeName); + writer.writeString(dataTypeClass); + } + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) { + schemaName = reader.readString(); + tableName = reader.readString(); + columnName = reader.readString(); + + dataType = reader.readInt(); + dataTypeName = reader.readString(); + dataTypeClass = reader.readString(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMessageParser.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMessageParser.java index cf87712..0f8a3ef 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMessageParser.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcMessageParser.java @@ -23,28 +23,65 @@ import org.apache.ignite.internal.binary.BinaryWriterExImpl; import org.apache.ignite.internal.binary.streams.BinaryHeapInputStream; import org.apache.ignite.internal.binary.streams.BinaryHeapOutputStream; import org.apache.ignite.internal.binary.streams.BinaryInputStream; -import org.apache.ignite.internal.processors.odbc.SqlListenerAbstractMessageParser; +import org.apache.ignite.internal.processors.odbc.SqlListenerMessageParser; +import org.apache.ignite.internal.processors.odbc.SqlListenerRequest; +import org.apache.ignite.internal.processors.odbc.SqlListenerResponse; /** * JDBC message parser. */ -public class JdbcMessageParser extends SqlListenerAbstractMessageParser { +public class JdbcMessageParser implements SqlListenerMessageParser { + /** Kernal context. */ + private final GridKernalContext ctx; + + /** Initial output stream capacity. */ + protected static final int INIT_CAP = 1024; + /** * @param ctx Context. */ public JdbcMessageParser(GridKernalContext ctx) { - super(ctx, new JdbcObjectReader(), new JdbcObjectWriter()); + this.ctx = ctx; } - /** {@inheritDoc} */ - @Override protected BinaryReaderExImpl createReader(byte[] msg) { + /** + * @param msg Message. + * @return Reader. + */ + protected BinaryReaderExImpl createReader(byte[] msg) { BinaryInputStream stream = new BinaryHeapInputStream(msg); return new BinaryReaderExImpl(null, stream, ctx.config().getClassLoader(), true); } - /** {@inheritDoc} */ - @Override protected BinaryWriterExImpl createWriter(int cap) { + /** + * @param cap Capacisty + * @return Writer. + */ + protected BinaryWriterExImpl createWriter(int cap) { return new BinaryWriterExImpl(null, new BinaryHeapOutputStream(cap), null, null); } -} + + /** {@inheritDoc} */ + @Override public SqlListenerRequest decode(byte[] msg) { + assert msg != null; + + BinaryReaderExImpl reader = createReader(msg); + + return JdbcRequest.readRequest(reader); + } + + /** {@inheritDoc} */ + @Override public byte[] encode(SqlListenerResponse msg) { + assert msg != null; + + assert msg instanceof JdbcResponse; + + JdbcResponse res = (JdbcResponse)msg; + + BinaryWriterExImpl writer = createWriter(INIT_CAP); + + res.writeBinary(writer); + + return writer.array(); + }} http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcObjectReader.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcObjectReader.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcObjectReader.java deleted file mode 100644 index 81c8c10..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcObjectReader.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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.processors.odbc.SqlListenerAbstractObjectReader; - -/** - * Binary reader with marshaling non-primitive and non-embedded objects with JDK marshaller. - */ -@SuppressWarnings("unchecked") -public class JdbcObjectReader extends SqlListenerAbstractObjectReader { - /** {@inheritDoc} */ - @Override protected Object readCustomObject(BinaryReaderExImpl reader) throws BinaryObjectException { - throw new BinaryObjectException("JDBC doesn't support custom objects."); - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcObjectWriter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcObjectWriter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcObjectWriter.java deleted file mode 100644 index e87ef50..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcObjectWriter.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.odbc.jdbc; - -import org.apache.ignite.binary.BinaryObjectException; -import org.apache.ignite.internal.binary.BinaryWriterExImpl; -import org.apache.ignite.internal.processors.odbc.SqlListenerAbstractObjectWriter; - -/** - * Binary writer with marshaling non-primitive and non-embedded objects with JDK marshaller.. - */ -public class JdbcObjectWriter extends SqlListenerAbstractObjectWriter { - /** {@inheritDoc} */ - @Override protected void writeCustomObject(BinaryWriterExImpl writer, Object obj) - throws BinaryObjectException { - throw new BinaryObjectException("JDBC doesn't support custom objects."); - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCloseRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCloseRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCloseRequest.java new file mode 100644 index 0000000..411d1e0 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCloseRequest.java @@ -0,0 +1,72 @@ +/* + * 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; + +/** + * SQL listener query close request. + */ +public class JdbcQueryCloseRequest extends JdbcRequest { + /** Query ID. */ + private long queryId; + + /** + */ + public JdbcQueryCloseRequest() { + super(QRY_CLOSE); + } + + /** + * @param queryId Query ID. + */ + public JdbcQueryCloseRequest(long queryId) { + super(QRY_CLOSE); + + this.queryId = queryId; + } + + /** + * @return Query ID. + */ + public long queryId() { + return queryId; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { + super.writeBinary(writer); + + writer.writeLong(queryId); + } + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { + super.readBinary(reader); + + queryId = reader.readLong(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(JdbcQueryCloseRequest.class, this); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCursor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCursor.java new file mode 100644 index 0000000..b8edb8d --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryCursor.java @@ -0,0 +1,132 @@ +/* + * 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 java.sql.ResultSet; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.apache.ignite.internal.processors.cache.QueryCursorImpl; +import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata; + +/** + * SQL listener query fetch result. + */ +class JdbcQueryCursor { + /** Query ID. */ + private final long queryId; + + /** Fetch size. */ + private int pageSize; + + /** Max rows. */ + private final long maxRows; + + /** Number of fetched rows. */ + private long fetched; + + /** Query result rows. */ + private final QueryCursorImpl<List<Object>> cur; + + /** Query results iterator. */ + private final Iterator<List<Object>> iter; + + /** + * @param queryId Query ID. + * @param pageSize Fetch size. + * @param maxRows Max rows. + * @param cur Query cursor. + */ + JdbcQueryCursor(long queryId, int pageSize, int maxRows, QueryCursorImpl<List<Object>> cur) { + this.queryId = queryId; + this.pageSize = pageSize; + this.maxRows = maxRows; + this.cur = cur; + + iter = cur.iterator(); + } + + /** + * @return List of the rows. + */ + List<List<Object>> fetchRows() { + List<List<Object>> items = new ArrayList<>(); + + int fetchSize0 = (maxRows > 0) ? (int)Math.min(pageSize, maxRows - fetched) : pageSize; + + for (; fetched < fetchSize0 && iter.hasNext(); ++fetched) + items.add(iter.next()); + + return items; + } + + /** + * @return Query metadata. + */ + List<JdbcColumnMeta> meta() { + List<?> meta = cur.fieldsMeta(); + + List<JdbcColumnMeta> res = new ArrayList<>(); + + if (meta != null) { + for (Object info : meta) { + assert info instanceof GridQueryFieldMetadata; + + res.add(new JdbcColumnMeta((GridQueryFieldMetadata)info)); + } + } + + return res; + } + + /** + * @return {@code true} if the cursor has more rows + */ + boolean hasNext() { + return iter.hasNext() && !(maxRows > 0 && fetched >= maxRows); + } + + /** + * @return Query ID. + */ + public long queryId() { + return queryId; + } + + /** + * Close the cursor. + */ + public void close() { + cur.close(); + } + + /** + * @param pageSize New fetch size. + */ + public void pageSize(int pageSize) { + this.pageSize = pageSize; + } + + /** + * @return {@code true} if this cursor corresponds to a {@link ResultSet} as a result of query, + * {@code false} if query was modifying operation like INSERT, UPDATE, or DELETE. + */ + public boolean isQuery() { + return cur.isQuery(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/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 new file mode 100644 index 0000000..f132366 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java @@ -0,0 +1,147 @@ +/* + * 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.processors.odbc.SqlListenerUtils; +import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.jetbrains.annotations.Nullable; + +/** + * SQL listener query execute request. + */ +public class JdbcQueryExecuteRequest extends JdbcRequest { + /** Cache name. */ + private String schemaName; + + /** Fetch size. */ + private int pageSize; + + /** Max rows. */ + private int maxRows; + + /** Sql query. */ + @GridToStringInclude(sensitive = true) + private String sqlQry; + + /** Sql query arguments. */ + @GridToStringInclude(sensitive = true) + private Object[] args; + + /** + */ + public JdbcQueryExecuteRequest() { + super(QRY_EXEC); + } + + /** + * @param schemaName Cache name. + * @param pageSize Fetch size. + * @param maxRows Max rows. + * @param sqlQry SQL query. + * @param args Arguments list. + */ + public JdbcQueryExecuteRequest(String schemaName, int pageSize, int maxRows, String sqlQry, + Object[] args) { + super(QRY_EXEC); + + this.schemaName = F.isEmpty(schemaName) ? null : schemaName; + this.pageSize = pageSize; + this.maxRows = maxRows; + this.sqlQry = sqlQry; + this.args = args; + } + + /** + * @return Fetch size. + */ + public int pageSize() { + return pageSize; + } + + /** + * @return Max rows. + */ + public int maxRows() { + return maxRows; + } + + /** + * @return Sql query. + */ + public String sqlQuery() { + return sqlQry; + } + + /** + * @return Sql query arguments. + */ + public Object[] arguments() { + return args; + } + + /** + * @return Cache name. + */ + @Nullable public String schemaName() { + return schemaName; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { + super.writeBinary(writer); + + writer.writeString(schemaName); + writer.writeInt(pageSize); + writer.writeInt(maxRows); + writer.writeString(sqlQry); + + writer.writeInt(args == null ? 0 : args.length); + + if (args != null) { + for (Object arg : args) + SqlListenerUtils.writeObject(writer, arg, false); + } + } + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { + super.readBinary(reader); + + schemaName = reader.readString(); + pageSize = reader.readInt(); + maxRows = reader.readInt(); + sqlQry = reader.readString(); + + int argsNum = reader.readInt(); + + args = new Object[argsNum]; + + for (int i = 0; i < argsNum; ++i) + args[i] = SqlListenerUtils.readObject(reader, false); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(JdbcQueryExecuteRequest.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/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 new file mode 100644 index 0000000..a935215 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteResult.java @@ -0,0 +1,150 @@ +/* + * 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 java.util.List; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.internal.binary.BinaryReaderExImpl; +import org.apache.ignite.internal.binary.BinaryWriterExImpl; + +/** + * SQL listener query execute result. + */ +public class JdbcQueryExecuteResult extends JdbcResult { + /** Query ID. */ + private long queryId; + + /** Query result rows. */ + private List<List<Object>> items; + + /** Flag indicating the query has no unfetched results. */ + private boolean last; + + /** Flag indicating the query is SELECT query. {@code false} for DML/DDL queries. */ + private boolean isQuery; + + /** Update count. */ + private long updateCnt; + + /** + * Condtructor. + */ + public JdbcQueryExecuteResult() { + super(QRY_EXEC); + } + + /** + * @param queryId Query ID. + * @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) { + super(QRY_EXEC); + + this.queryId = queryId; + this.items = items; + this.last = last; + this.isQuery = true; + } + + /** + * @param queryId Query ID. + * @param updateCnt Update count for DML queries. + */ + public JdbcQueryExecuteResult(long queryId, long updateCnt) { + super(QRY_EXEC); + + this.queryId = queryId; + this.last = true; + this.isQuery = false; + this.updateCnt = updateCnt; + } + + /** + * @return Query ID. + */ + public long getQueryId() { + return queryId; + } + + /** + * @return Query result rows. + */ + public List<List<Object>> items() { + return items; + } + + /** + * @return Flag indicating the query has no unfetched results. + */ + public boolean last() { + return last; + } + + /** + * @return Flag indicating the query is SELECT query. {@code false} for DML/DDL queries. + */ + public boolean isQuery() { + return isQuery; + } + + /** + * @return Update count for DML queries. + */ + public long updateCount() { + return updateCnt; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { + super.writeBinary(writer); + + writer.writeLong(queryId); + writer.writeBoolean(isQuery); + + if (isQuery) { + assert items != null; + + writer.writeBoolean(last); + + JdbcUtils.writeItems(writer, items); + } + else + writer.writeLong(updateCnt); + } + + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { + super.readBinary(reader); + + queryId = reader.readLong(); + isQuery = reader.readBoolean(); + + if (isQuery) { + last = reader.readBoolean(); + + items = JdbcUtils.readItems(reader); + } + else { + last = true; + + updateCnt = reader.readLong(); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/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 new file mode 100644 index 0000000..2e1f551 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchRequest.java @@ -0,0 +1,87 @@ +/* + * 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; + +/** + * SQL listener query fetch request. + */ +public class JdbcQueryFetchRequest extends JdbcRequest { + /** Query ID. */ + private long queryId; + + /** Fetch size. */ + private int pageSize; + + /** + * Constructor. + */ + public JdbcQueryFetchRequest() { + super(QRY_FETCH); + } + + /** + * @param queryId Query ID. + * @param pageSize Fetch size. + */ + public JdbcQueryFetchRequest(long queryId, int pageSize) { + super(QRY_FETCH); + + this.queryId = queryId; + this.pageSize = pageSize; + } + + /** + * @return Query ID. + */ + public long queryId() { + return queryId; + } + + /** + * @return Fetch page size. + */ + public int pageSize() { + return pageSize; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { + super.writeBinary(writer); + + writer.writeLong(queryId); + writer.writeInt(pageSize); + } + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { + super.readBinary(reader); + + queryId = reader.readLong(); + pageSize = reader.readInt(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(JdbcQueryFetchRequest.class, this); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/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 new file mode 100644 index 0000000..6735c6b --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryFetchResult.java @@ -0,0 +1,84 @@ +/* + * 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 java.util.List; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.internal.binary.BinaryReaderExImpl; +import org.apache.ignite.internal.binary.BinaryWriterExImpl; + +/** + * SQL listener query fetch result. + */ +public class JdbcQueryFetchResult extends JdbcResult { + /** Query result rows. */ + private List<List<Object>> items; + + /** Flag indicating the query has no unfetched results. */ + private boolean last; + + /** + * Default constructor is used for deserialization. + */ + public JdbcQueryFetchResult() { + super(QRY_FETCH); + } + + /** + * @param items Query result rows. + * @param last Flag indicating the query has no unfetched results. + */ + public JdbcQueryFetchResult(List<List<Object>> items, boolean last){ + super(QRY_FETCH); + + this.items = items; + this.last = last; + } + + /** + * @return Query result rows. + */ + public List<List<Object>> items() { + return items; + } + + /** + * @return Flag indicating the query has no unfetched results. + */ + public boolean last() { + return last; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { + super.writeBinary(writer); + + writer.writeBoolean(last); + + JdbcUtils.writeItems(writer, items); + } + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { + super.readBinary(reader); + + last = reader.readBoolean(); + + items = JdbcUtils.readItems(reader); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/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 new file mode 100644 index 0000000..d14c9df --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataRequest.java @@ -0,0 +1,73 @@ +/* + * 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; + +/** + * SQL listener query metadata request. + */ +public class JdbcQueryMetadataRequest extends JdbcRequest { + /** Query ID. */ + private long queryId; + + /** + * Constructor. + */ + public JdbcQueryMetadataRequest() { + super(QRY_META); + } + + /** + * @param queryId Query ID. + */ + public JdbcQueryMetadataRequest(long queryId) { + super(QRY_META); + + this.queryId = queryId; + } + + /** + * @return Query ID. + */ + public long queryId() { + return queryId; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { + super.writeBinary(writer); + + writer.writeLong(queryId); + } + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { + super.readBinary(reader); + + queryId = reader.readLong(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(JdbcQueryMetadataRequest.class, this); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/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 new file mode 100644 index 0000000..cc193e3 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryMetadataResult.java @@ -0,0 +1,93 @@ +/* + * 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 java.util.ArrayList; +import java.util.Collections; +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.F; + +/** + * SQL listener query metadata result. + */ +public class JdbcQueryMetadataResult extends JdbcResult { + /** Fields metadata. */ + private List<JdbcColumnMeta> meta; + + /** + * Default constructor is used for deserialization. + */ + public JdbcQueryMetadataResult() { + super(QRY_META); + } + + /** + * @param queryId Query ID. + * @param meta Query metadata. + */ + public JdbcQueryMetadataResult(long queryId, List<JdbcColumnMeta> meta){ + super(QRY_META); + + this.meta = meta; + } + + /** + * @return Query result rows. + */ + public List<JdbcColumnMeta> meta() { + return meta; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { + super.writeBinary(writer); + + if (F.isEmpty(meta)) + writer.writeInt(0); + else { + writer.writeInt(meta.size()); + + for (JdbcColumnMeta m : meta) + m.writeBinary(writer); + } + } + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { + super.readBinary(reader); + + int size = reader.readInt(); + + if (size == 0) + meta = Collections.emptyList(); + else { + meta = new ArrayList<>(size); + + for (int i = 0; i < size; ++i) { + JdbcColumnMeta m = new JdbcColumnMeta(); + + m.readBinary(reader); + + meta.add(m); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRawBinarylizable.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRawBinarylizable.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRawBinarylizable.java new file mode 100644 index 0000000..c3f1874 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRawBinarylizable.java @@ -0,0 +1,44 @@ +/* + * 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; + +/** + * Interface that allows to implement custom serialization + * logic to raw binary streams. + */ +public interface JdbcRawBinarylizable { + /** + * Writes fields to provided writer. + * + * @param writer Binary object writer. + * @throws BinaryObjectException In case of error. + */ + public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException; + + /** + * Reads fields from provided reader. + * + * @param reader Binary object reader. + * @throws BinaryObjectException In case of error. + */ + public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/e92707b6/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 new file mode 100644 index 0000000..d6f8fd3 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java @@ -0,0 +1,108 @@ +/* + * 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.IgniteException; +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.processors.odbc.SqlListenerRequest; + +/** + * SQL listener command request. + */ +public class JdbcRequest extends SqlListenerRequest implements JdbcRawBinarylizable { + /** Execute sql query. */ + public static final byte QRY_EXEC = 2; + + /** Fetch query results. */ + public static final byte QRY_FETCH = 3; + + /** Close query. */ + public static final byte QRY_CLOSE = 4; + + /** Get columns meta query. */ + public static final byte QRY_META = 5; + + /** Request type. */ + private byte type; + + /** + * @param type Command type. + */ + public JdbcRequest(byte type) { + this.type = type; + } + + /** {@inheritDoc} */ + @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException { + writer.writeByte(type); + } + + /** {@inheritDoc} */ + @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException { + // No-op. + } + + /** + * @return Request type. + */ + public byte type() { + return type; + } + + /** + * @param reader Binary reader. + * @return Request object. + * @throws BinaryObjectException On error. + */ + public static JdbcRequest readRequest(BinaryReaderExImpl reader) throws BinaryObjectException { + int reqType = reader.readByte(); + + JdbcRequest req; + + switch(reqType) { + case QRY_EXEC: + req = new JdbcQueryExecuteRequest(); + + break; + + case QRY_FETCH: + req = new JdbcQueryFetchRequest(); + + break; + + case QRY_META: + req = new JdbcQueryMetadataRequest(); + + break; + + case QRY_CLOSE: + req = new JdbcQueryCloseRequest(); + + break; + + default: + throw new IgniteException("Unknown SQL listener request ID: [request ID=" + reqType + ']'); + } + + req.readBinary(reader); + + return req; + } +}
