You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/05/31 07:35:41 UTC
[10/19] ignite git commit: ignite-5203 Simple BLOB support added
ignite-5203 Simple BLOB support added
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/64ab5cdf
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/64ab5cdf
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/64ab5cdf
Branch: refs/heads/ignite-5075
Commit: 64ab5cdfe9297ed819d269166a3d1a3b489d03ec
Parents: 618a448
Author: agura <ag...@apache.org>
Authored: Thu May 18 19:40:09 2017 +0300
Committer: agura <ag...@apache.org>
Committed: Tue May 30 00:33:46 2017 +0300
----------------------------------------------------------------------
.../jdbc2/JdbcAbstractDmlStatementSelfTest.java | 50 +-
.../JdbcAbstractUpdateStatementSelfTest.java | 11 +-
.../ignite/internal/jdbc2/JdbcBlobTest.java | 485 +++++++++++++++++++
.../jdbc2/JdbcInsertStatementSelfTest.java | 16 +-
.../jdbc2/JdbcMergeStatementSelfTest.java | 16 +-
.../jdbc2/JdbcPreparedStatementSelfTest.java | 47 ++
.../jdbc/suite/IgniteJdbcDriverTestSuite.java | 7 +-
.../apache/ignite/internal/jdbc2/JdbcBlob.java | 191 ++++++++
.../ignite/internal/jdbc2/JdbcConnection.java | 2 +-
.../internal/jdbc2/JdbcPreparedStatement.java | 4 +-
.../ignite/internal/jdbc2/JdbcResultSet.java | 8 +-
11 files changed, 808 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractDmlStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractDmlStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractDmlStatementSelfTest.java
index 6ef86d3..81c913d 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractDmlStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractDmlStatementSelfTest.java
@@ -18,8 +18,11 @@
package org.apache.ignite.internal.jdbc2;
import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
+import java.sql.SQLException;
import java.util.Collections;
import org.apache.ignite.cache.QueryEntity;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
@@ -35,6 +38,9 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
* Statement test.
*/
public abstract class JdbcAbstractDmlStatementSelfTest extends GridCommonAbstractTest {
+ /** UTF 16 character set name. */
+ private static final String UTF_16 = "UTF-16"; // RAWTOHEX function use UTF-16 for conversion strings to byte arrays.
+
/** JDBC URL. */
private static final String BASE_URL = CFG_URL_PREFIX + "cache=" + DEFAULT_CACHE_NAME + "@modules/clients/src/test/config/jdbc-config.xml";
@@ -42,7 +48,7 @@ public abstract class JdbcAbstractDmlStatementSelfTest extends GridCommonAbstrac
static final String BASE_URL_BIN = CFG_URL_PREFIX + "cache=" + DEFAULT_CACHE_NAME + "@modules/clients/src/test/config/jdbc-bin-config.xml";
/** SQL SELECT query for verification. */
- static final String SQL_SELECT = "select _key, id, firstName, lastName, age from Person";
+ static final String SQL_SELECT = "select _key, id, firstName, lastName, age, data from Person";
/** Alias for _key */
private static final String KEY_ALIAS = "key";
@@ -107,6 +113,7 @@ public abstract class JdbcAbstractDmlStatementSelfTest extends GridCommonAbstrac
e.addQueryField("age", Integer.class.getName(), null);
e.addQueryField("firstName", String.class.getName(), null);
e.addQueryField("lastName", String.class.getName(), null);
+ e.addQueryField("data", byte[].class.getName(), null);
cache.setQueryEntities(Collections.singletonList(e));
@@ -136,6 +143,42 @@ public abstract class JdbcAbstractDmlStatementSelfTest extends GridCommonAbstrac
}
/**
+ * @param str String.
+ */
+ static byte[] getBytes(String str) {
+ try {
+ return str.getBytes(UTF_16);
+ }
+ catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * @param blob Blob.
+ */
+ static byte[] getBytes(Blob blob) {
+ try {
+ return blob.getBytes(1, (int)blob.length());
+ }
+ catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * @param arr Array.
+ */
+ static String str(byte[] arr) {
+ try {
+ return new String(arr, UTF_16);
+ }
+ catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* Person.
*/
@SuppressWarnings("UnusedDeclaration")
@@ -156,6 +199,10 @@ public abstract class JdbcAbstractDmlStatementSelfTest extends GridCommonAbstrac
@QuerySqlField
private final int age;
+ /** Binary data. */
+ @QuerySqlField
+ private final byte[] data;
+
/**
* @param id ID.
* @param firstName First name.
@@ -171,6 +218,7 @@ public abstract class JdbcAbstractDmlStatementSelfTest extends GridCommonAbstrac
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
+ this.data = getBytes(lastName);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractUpdateStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractUpdateStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractUpdateStatementSelfTest.java
index a20b815..ace1be6 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractUpdateStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcAbstractUpdateStatementSelfTest.java
@@ -19,12 +19,15 @@ package org.apache.ignite.internal.jdbc2;
import java.sql.Statement;
+/**
+ *
+ */
public abstract class JdbcAbstractUpdateStatementSelfTest extends JdbcAbstractDmlStatementSelfTest {
/** SQL query to populate cache. */
- private static final String ITEMS_SQL = "insert into Person(_key, id, firstName, lastName, age) values " +
- "('p1', 1, 'John', 'White', 25), " +
- "('p2', 2, 'Joe', 'Black', 35), " +
- "('p3', 3, 'Mike', 'Green', 40)";
+ private static final String ITEMS_SQL = "insert into Person(_key, id, firstName, lastName, age, data) values " +
+ "('p1', 1, 'John', 'White', 25, RAWTOHEX('White')), " +
+ "('p2', 2, 'Joe', 'Black', 35, RAWTOHEX('Black')), " +
+ "('p3', 3, 'Mike', 'Green', 40, RAWTOHEX('Green'))";
/** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcBlobTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcBlobTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcBlobTest.java
new file mode 100644
index 0000000..9e0e0d2
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcBlobTest.java
@@ -0,0 +1,485 @@
+/*
+ * 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.jdbc2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.SQLException;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+/**
+ *
+ */
+public class JdbcBlobTest extends TestCase {
+ /**
+ * @throws Exception If failed.
+ */
+ public void testLength() throws Exception {
+ JdbcBlob blob = new JdbcBlob(new byte[16]);
+
+ assertEquals(16, (int)blob.length());
+
+ blob.free();
+
+ try {
+ blob.length();
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testGetBytes() throws Exception {
+ byte[] arr = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+ JdbcBlob blob = new JdbcBlob(arr);
+
+ try {
+ blob.getBytes(0, 16);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+
+ try {
+ blob.getBytes(17, 16);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+
+ try {
+ blob.getBytes(1, -1);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+
+ byte[] res = blob.getBytes(1, 0);
+ assertEquals(0, res.length);
+
+ assertTrue(Arrays.equals(arr, blob.getBytes(1, 16)));
+
+ res = blob.getBytes(1, 20);
+ assertEquals(16, res.length);
+ assertTrue(Arrays.equals(arr, res));
+
+ res = blob.getBytes(1, 10);
+ assertEquals(10, res.length);
+ assertEquals(0, res[0]);
+ assertEquals(9, res[9]);
+
+ res = blob.getBytes(7, 10);
+ assertEquals(10, res.length);
+ assertEquals(6, res[0]);
+ assertEquals(15, res[9]);
+
+ res = blob.getBytes(7, 20);
+ assertEquals(10, res.length);
+ assertEquals(6, res[0]);
+ assertEquals(15, res[9]);
+
+ res = blob.getBytes(1, 0);
+ assertEquals(0, res.length);
+
+ blob.free();
+
+ try {
+ blob.getBytes(1, 16);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testGetBinaryStream() throws Exception {
+ byte[] arr = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+ JdbcBlob blob = new JdbcBlob(arr);
+
+ InputStream is = blob.getBinaryStream();
+
+ byte[] res = readBytes(is);
+
+ assertTrue(Arrays.equals(arr, res));
+
+ blob.free();
+
+ try {
+ blob.getBinaryStream();
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testGetBinaryStreamWithParams() throws Exception {
+ byte[] arr = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+ JdbcBlob blob = new JdbcBlob(arr);
+
+ try {
+ blob.getBinaryStream(0, arr.length);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+
+ try {
+ blob.getBinaryStream(1, 0);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+
+ try {
+ blob.getBinaryStream(17, arr.length);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+
+ try {
+ blob.getBinaryStream(1, arr.length + 1);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+
+ InputStream is = blob.getBinaryStream(1, arr.length);
+ byte[] res = readBytes(is);
+ assertTrue(Arrays.equals(arr, res));
+
+ is = blob.getBinaryStream(1, 10);
+ res = readBytes(is);
+ assertEquals(10, res.length);
+ assertEquals(0, res[0]);
+ assertEquals(9, res[9]);
+
+ is = blob.getBinaryStream(6, 10);
+ res = readBytes(is);
+ assertEquals(10, res.length);
+ assertEquals(5, res[0]);
+ assertEquals(14, res[9]);
+
+ blob.free();
+
+ try {
+ blob.getBinaryStream(1, arr.length);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testPositionBytePattern() throws Exception {
+ byte[] arr = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+ JdbcBlob blob = new JdbcBlob(arr);
+
+ assertEquals(-1, blob.position(new byte[] {1, 2, 3}, 0));
+ assertEquals(-1, blob.position(new byte[] {1, 2, 3}, arr.length + 1));
+ assertEquals(-1, blob.position(new byte[0], 1));
+ assertEquals(-1, blob.position(new byte[17], 1));
+ assertEquals(-1, blob.position(new byte[] {3, 2, 1}, 1));
+ assertEquals(1, blob.position(new byte[] {0, 1, 2}, 1));
+ assertEquals(2, blob.position(new byte[] {1, 2, 3}, 1));
+ assertEquals(2, blob.position(new byte[] {1, 2, 3}, 2));
+ assertEquals(-1, blob.position(new byte[] {1, 2, 3}, 3));
+ assertEquals(14, blob.position(new byte[] {13, 14, 15}, 3));
+ assertEquals(-1, blob.position(new byte[] {0, 1, 3}, 1));
+ assertEquals(-1, blob.position(new byte[] {0, 2, 3}, 1));
+ assertEquals(-1, blob.position(new byte[] {1, 2, 4}, 1));
+
+ blob.free();
+
+ try {
+ blob.position(new byte[] {0, 1, 2}, 1);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testPositionBlobPattern() throws Exception {
+ byte[] arr = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+ JdbcBlob blob = new JdbcBlob(arr);
+
+ assertEquals(-1, blob.position(new JdbcBlob(new byte[] {1, 2, 3}), 0));
+ assertEquals(-1, blob.position(new JdbcBlob(new byte[] {1, 2, 3}), arr.length + 1));
+ assertEquals(-1, blob.position(new JdbcBlob(new byte[0]), 1));
+ assertEquals(-1, blob.position(new JdbcBlob(new byte[17]), 1));
+ assertEquals(-1, blob.position(new JdbcBlob(new byte[] {3, 2, 1}), 1));
+ assertEquals(1, blob.position(new JdbcBlob(new byte[] {0, 1, 2}), 1));
+ assertEquals(2, blob.position(new JdbcBlob(new byte[] {1, 2, 3}), 1));
+ assertEquals(2, blob.position(new JdbcBlob(new byte[] {1, 2, 3}), 2));
+ assertEquals(-1, blob.position(new JdbcBlob(new byte[] {1, 2, 3}), 3));
+ assertEquals(14, blob.position(new JdbcBlob(new byte[] {13, 14, 15}), 3));
+ assertEquals(-1, blob.position(new JdbcBlob(new byte[] {0, 1, 3}), 1));
+ assertEquals(-1, blob.position(new JdbcBlob(new byte[] {0, 2, 3}), 1));
+ assertEquals(-1, blob.position(new JdbcBlob(new byte[] {1, 2, 4}), 1));
+
+ blob.free();
+
+ try {
+ blob.position(new JdbcBlob(new byte[] {0, 1, 2}), 1);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testSetBytes() throws Exception {
+ byte[] arr = new byte[] {0, 1, 2, 3, 4, 5, 6, 7};
+
+ JdbcBlob blob = new JdbcBlob(arr);
+
+ try {
+ blob.setBytes(0, new byte[4]);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+
+ try {
+ blob.setBytes(17, new byte[4]);
+
+ fail();
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ // No-op.
+ }
+
+ assertEquals(4, blob.setBytes(1, new byte[] {3, 2, 1, 0}));
+ assertTrue(Arrays.equals(new byte[] {3, 2, 1, 0, 4, 5, 6, 7}, blob.getBytes(1, arr.length)));
+
+ assertEquals(4, blob.setBytes(5, new byte[] {7, 6, 5, 4}));
+ assertTrue(Arrays.equals(new byte[] {3, 2, 1, 0, 7, 6, 5, 4}, blob.getBytes(1, arr.length)));
+
+ assertEquals(4, blob.setBytes(7, new byte[] {8, 9, 10, 11}));
+ assertTrue(Arrays.equals(new byte[] {3, 2, 1, 0, 7, 6, 8, 9, 10, 11}, blob.getBytes(1, (int)blob.length())));
+
+ blob = new JdbcBlob(new byte[] {15, 16});
+ assertEquals(8, blob.setBytes(1, new byte[] {0, 1, 2, 3, 4, 5, 6, 7}));
+ assertTrue(Arrays.equals(new byte[] {0, 1, 2, 3, 4, 5, 6, 7}, blob.getBytes(1, (int)blob.length())));
+
+ blob.free();
+
+ try {
+ blob.setBytes(1, new byte[] {0, 1, 2});
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testSetBytesWithOffsetAndLength() throws Exception {
+ byte[] arr = new byte[] {0, 1, 2, 3, 4, 5, 6, 7};
+
+ JdbcBlob blob = new JdbcBlob(arr);
+
+ try {
+ blob.setBytes(0, new byte[4], 0, 2);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+
+ try {
+ blob.setBytes(17, new byte[4], 0, 2);
+
+ fail();
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ // No-op.
+ }
+
+ try {
+ blob.setBytes(1, new byte[4], -1, 2);
+
+ fail();
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ // No-op.
+ }
+
+ try {
+ blob.setBytes(1, new byte[4], 0, 5);
+
+ fail();
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ // No-op.
+ }
+
+ assertEquals(4, blob.setBytes(1, new byte[] {3, 2, 1, 0}, 0, 4));
+ assertTrue(Arrays.equals(new byte[] {3, 2, 1, 0, 4, 5, 6, 7}, blob.getBytes(1, arr.length)));
+
+ assertEquals(4, blob.setBytes(5, new byte[] {7, 6, 5, 4}, 0, 4));
+ assertTrue(Arrays.equals(new byte[] {3, 2, 1, 0, 7, 6, 5, 4}, blob.getBytes(1, arr.length)));
+
+ assertEquals(4, blob.setBytes(7, new byte[] {8, 9, 10, 11}, 0, 4));
+ assertTrue(Arrays.equals(new byte[] {3, 2, 1, 0, 7, 6, 8, 9, 10, 11}, blob.getBytes(1, (int)blob.length())));
+
+ assertEquals(2, blob.setBytes(1, new byte[] {3, 2, 1, 0}, 2, 2));
+ assertTrue(Arrays.equals(new byte[] {1, 0, 1, 0, 7, 6, 8, 9, 10, 11}, blob.getBytes(1, (int)blob.length())));
+
+ assertEquals(2, blob.setBytes(9, new byte[] {3, 2, 1, 0}, 1, 2));
+ assertTrue(Arrays.equals(new byte[] {1, 0, 1, 0, 7, 6, 8, 9, 2, 1}, blob.getBytes(1, (int)blob.length())));
+
+ assertEquals(3, blob.setBytes(9, new byte[] {3, 2, 1, 0}, 0, 3));
+ assertTrue(Arrays.equals(new byte[] {1, 0, 1, 0, 7, 6, 8, 9, 3, 2, 1}, blob.getBytes(1, (int)blob.length())));
+
+ blob = new JdbcBlob(new byte[] {15, 16});
+ assertEquals(8, blob.setBytes(1, new byte[] {0, 1, 2, 3, 4, 5, 6, 7}, 0, 8));
+ assertTrue(Arrays.equals(new byte[] {0, 1, 2, 3, 4, 5, 6, 7}, blob.getBytes(1, (int)blob.length())));
+
+ blob.free();
+
+ try {
+ blob.setBytes(1, new byte[] {0, 1, 2}, 0, 2);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTruncate() throws Exception {
+ byte[] arr = new byte[] {0, 1, 2, 3, 4, 5, 6, 7};
+
+ JdbcBlob blob = new JdbcBlob(arr);
+
+ try {
+ blob.truncate(-1);
+
+ fail();
+ }
+ catch(SQLException e) {
+ // No-op.
+ }
+
+ try {
+ blob.truncate(arr.length + 1);
+
+ fail();
+ }
+ catch(SQLException e) {
+ // No-op.
+ }
+
+ blob.truncate(4);
+ assertTrue(Arrays.equals(new byte[] {0, 1, 2, 3}, blob.getBytes(1, (int)blob.length())));
+
+ blob.truncate(0);
+ assertEquals(0, (int)blob.length());
+
+ blob.free();
+
+ try {
+ blob.truncate(0);
+
+ fail();
+ }
+ catch (SQLException e) {
+ // No-op.
+ System.out.println();
+ }
+ }
+
+ /**
+ * @param is Input stream.
+ */
+ private static byte[] readBytes(InputStream is) throws IOException {
+ byte[] tmp = new byte[16];
+
+ int i = 0;
+ int read;
+ int cnt = 0;
+
+ while ((read = is.read()) != -1) {
+ tmp[i++] = (byte)read;
+ cnt++;
+ }
+
+ byte[] res = new byte[cnt];
+
+ System.arraycopy(tmp, 0, res, 0, cnt);
+
+ return res;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java
index b23f947..0e7539f 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java
@@ -33,14 +33,14 @@ import org.apache.ignite.testframework.GridTestUtils;
*/
public class JdbcInsertStatementSelfTest extends JdbcAbstractDmlStatementSelfTest {
/** SQL query. */
- private static final String SQL = "insert into Person(_key, id, firstName, lastName, age) values " +
- "('p1', 1, 'John', 'White', 25), " +
- "('p2', 2, 'Joe', 'Black', 35), " +
- "('p3', 3, 'Mike', 'Green', 40)";
+ private static final String SQL = "insert into Person(_key, id, firstName, lastName, age, data) values " +
+ "('p1', 1, 'John', 'White', 25, RAWTOHEX('White')), " +
+ "('p2', 2, 'Joe', 'Black', 35, RAWTOHEX('Black')), " +
+ "('p3', 3, 'Mike', 'Green', 40, RAWTOHEX('Green'))";
/** SQL query. */
- private static final String SQL_PREPARED = "insert into Person(_key, id, firstName, lastName, age) values " +
- "(?, ?, ?, ?, ?), (?, ?, ?, ?, ?)";
+ private static final String SQL_PREPARED = "insert into Person(_key, id, firstName, lastName, age, data) values " +
+ "(?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?)";
/** Statement. */
private Statement stmt;
@@ -79,6 +79,7 @@ public class JdbcInsertStatementSelfTest extends JdbcAbstractDmlStatementSelfTes
assertEquals("John", rs.getString("firstName"));
assertEquals("White", rs.getString("lastName"));
assertEquals(25, rs.getInt("age"));
+ assertEquals("White", str(getBytes(rs.getBlob("data"))));
break;
case 2:
@@ -86,6 +87,7 @@ public class JdbcInsertStatementSelfTest extends JdbcAbstractDmlStatementSelfTes
assertEquals("Joe", rs.getString("firstName"));
assertEquals("Black", rs.getString("lastName"));
assertEquals(35, rs.getInt("age"));
+ assertEquals("Black", str(getBytes(rs.getBlob("data"))));
break;
case 3:
@@ -93,6 +95,7 @@ public class JdbcInsertStatementSelfTest extends JdbcAbstractDmlStatementSelfTes
assertEquals("Mike", rs.getString("firstName"));
assertEquals("Green", rs.getString("lastName"));
assertEquals(40, rs.getInt("age"));
+ assertEquals("Green", str(getBytes(rs.getBlob("data"))));
break;
case 4:
@@ -100,6 +103,7 @@ public class JdbcInsertStatementSelfTest extends JdbcAbstractDmlStatementSelfTes
assertEquals("Leah", rs.getString("firstName"));
assertEquals("Grey", rs.getString("lastName"));
assertEquals(22, rs.getInt("age"));
+ assertEquals("Grey", str(getBytes(rs.getBlob("data"))));
break;
default:
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMergeStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMergeStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMergeStatementSelfTest.java
index f4577f5..1432a78 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMergeStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcMergeStatementSelfTest.java
@@ -28,14 +28,14 @@ import org.apache.ignite.cache.CachePeekMode;
*/
public class JdbcMergeStatementSelfTest extends JdbcAbstractDmlStatementSelfTest {
/** SQL query. */
- private static final String SQL = "merge into Person(_key, id, firstName, lastName, age) values " +
- "('p1', 1, 'John', 'White', 25), " +
- "('p2', 2, 'Joe', 'Black', 35), " +
- "('p3', 3, 'Mike', 'Green', 40)";
+ private static final String SQL = "merge into Person(_key, id, firstName, lastName, age, data) values " +
+ "('p1', 1, 'John', 'White', 25, RAWTOHEX('White')), " +
+ "('p2', 2, 'Joe', 'Black', 35, RAWTOHEX('Black')), " +
+ "('p3', 3, 'Mike', 'Green', 40, RAWTOHEX('Green'))";
/** SQL query. */
- protected static final String SQL_PREPARED = "merge into Person(_key, id, firstName, lastName, age) values " +
- "(?, ?, ?, ?, ?), (?, ?, ?, ?, ?)";
+ protected static final String SQL_PREPARED = "merge into Person(_key, id, firstName, lastName, age, data) values " +
+ "(?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?)";
/** Statement. */
protected Statement stmt;
@@ -74,6 +74,7 @@ public class JdbcMergeStatementSelfTest extends JdbcAbstractDmlStatementSelfTest
assertEquals("John", rs.getString("firstName"));
assertEquals("White", rs.getString("lastName"));
assertEquals(25, rs.getInt("age"));
+ assertEquals("White", str(getBytes(rs.getBlob("data"))));
break;
case 2:
@@ -81,6 +82,7 @@ public class JdbcMergeStatementSelfTest extends JdbcAbstractDmlStatementSelfTest
assertEquals("Joe", rs.getString("firstName"));
assertEquals("Black", rs.getString("lastName"));
assertEquals(35, rs.getInt("age"));
+ assertEquals("Black", str(getBytes(rs.getBlob("data"))));
break;
case 3:
@@ -88,6 +90,7 @@ public class JdbcMergeStatementSelfTest extends JdbcAbstractDmlStatementSelfTest
assertEquals("Mike", rs.getString("firstName"));
assertEquals("Green", rs.getString("lastName"));
assertEquals(40, rs.getInt("age"));
+ assertEquals("Green", str(getBytes(rs.getBlob("data"))));
break;
case 4:
@@ -95,6 +98,7 @@ public class JdbcMergeStatementSelfTest extends JdbcAbstractDmlStatementSelfTest
assertEquals("Leah", rs.getString("firstName"));
assertEquals("Grey", rs.getString("lastName"));
assertEquals(22, rs.getInt("age"));
+ assertEquals("Grey", str(getBytes(rs.getBlob("data"))));
break;
default:
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatementSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatementSelfTest.java
index 5e402ff..30bd018 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatementSelfTest.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.jdbc2;
import java.io.Serializable;
import java.math.BigDecimal;
import java.net.URL;
+import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
@@ -117,6 +118,7 @@ public class JdbcPreparedStatementSelfTest extends GridCommonAbstractTest {
o.bigVal = new BigDecimal(1);
o.strVal = "str";
o.arrVal = new byte[] {1};
+ o.blobVal = new byte[] {1};
o.dateVal = new Date(1);
o.timeVal = new Time(1);
o.tsVal = new Timestamp(1);
@@ -529,6 +531,47 @@ public class JdbcPreparedStatementSelfTest extends GridCommonAbstractTest {
/**
* @throws Exception If failed.
*/
+ public void testBlob() throws Exception {
+ stmt = conn.prepareStatement("select * from TestObject where blobVal is not distinct from ?");
+
+ Blob blob = conn.createBlob();
+
+ blob.setBytes(1, new byte[] {1});
+
+ stmt.setBlob(1, blob);
+
+ ResultSet rs = stmt.executeQuery();
+
+ int cnt = 0;
+
+ while (rs.next()) {
+ if (cnt == 0)
+ assert rs.getInt("id") == 1;
+
+ cnt++;
+ }
+
+ assertEquals(1, cnt);
+
+ stmt.setNull(1, BINARY);
+
+ rs = stmt.executeQuery();
+
+ cnt = 0;
+
+ while (rs.next()) {
+ if (cnt == 0)
+ assert rs.getInt("id") == 2;
+
+ cnt++;
+ }
+
+ assert cnt == 1;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testDate() throws Exception {
stmt = conn.prepareStatement("select * from TestObject where dateVal is not distinct from ?");
@@ -725,6 +768,10 @@ public class JdbcPreparedStatementSelfTest extends GridCommonAbstractTest {
/** */
@QuerySqlField
+ private byte[] blobVal;
+
+ /** */
+ @QuerySqlField
private Date dateVal;
/** */
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
index e2f09ba..abfdf90 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
@@ -18,6 +18,8 @@
package org.apache.ignite.jdbc.suite;
import junit.framework.TestSuite;
+import org.apache.ignite.internal.jdbc2.JdbcBlobTest;
+import org.apache.ignite.internal.jdbc2.JdbcDistributedJoinsQueryTest;
import org.apache.ignite.jdbc.JdbcComplexQuerySelfTest;
import org.apache.ignite.jdbc.JdbcConnectionSelfTest;
import org.apache.ignite.jdbc.JdbcEmptyCacheSelfTest;
@@ -41,7 +43,7 @@ public class IgniteJdbcDriverTestSuite extends TestSuite {
public static TestSuite suite() throws Exception {
TestSuite suite = new TestSuite("Ignite JDBC Driver Test Suite");
- // Thin client based driver tests
+ // Thin client based driver tests.
suite.addTest(new TestSuite(JdbcConnectionSelfTest.class));
suite.addTest(new TestSuite(JdbcStatementSelfTest.class));
suite.addTest(new TestSuite(JdbcPreparedStatementSelfTest.class));
@@ -61,7 +63,7 @@ public class IgniteJdbcDriverTestSuite extends TestSuite {
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcPreparedStatementSelfTest.class));
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcResultSetSelfTest.class));
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcComplexQuerySelfTest.class));
- suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcDistributedJoinsQueryTest.class));
+ suite.addTest(new TestSuite(JdbcDistributedJoinsQueryTest.class));
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcMetadataSelfTest.class));
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcEmptyCacheSelfTest.class));
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcLocalCachesSelfTest.class));
@@ -71,6 +73,7 @@ public class IgniteJdbcDriverTestSuite extends TestSuite {
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcInsertStatementSelfTest.class));
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcBinaryMarshallerInsertStatementSelfTest.class));
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcDeleteStatementSelfTest.class));
+ suite.addTest(new TestSuite(JdbcBlobTest.class));
suite.addTest(new TestSuite(org.apache.ignite.internal.jdbc2.JdbcStreamingSelfTest.class));
// DDL tests.
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcBlob.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcBlob.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcBlob.java
new file mode 100644
index 0000000..d1610d1
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcBlob.java
@@ -0,0 +1,191 @@
+/*
+ * 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.jdbc2;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Arrays;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * Simple BLOB implementation. Actually there is no such entity as BLOB in Ignite. So using arrays is preferable way
+ * to work with binary objects.
+ *
+ * This implementation can be useful for reading binary fields of objects through JDBC.
+ */
+public class JdbcBlob implements Blob {
+ /** Byte array. */
+ private byte[] arr;
+
+ /**
+ * @param arr Byte array.
+ */
+ public JdbcBlob(byte[] arr) {
+ this.arr = arr;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long length() throws SQLException {
+ ensureNotClosed();
+
+ return arr.length;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte[] getBytes(long pos, int len) throws SQLException {
+ ensureNotClosed();
+
+ if (pos < 1 || arr.length - pos < 0 || len < 0)
+ throw new SQLException("Invalid argument. Position can't be less than 1 or " +
+ "greater than size of underlying byte array. Requested length also can't be negative " + "" +
+ "[pos=" + pos + ", len=" + len +']');
+
+ int idx = (int)(pos - 1);
+
+ int size = len > arr.length - idx ? arr.length - idx : len;
+
+ byte[] res = new byte[size];
+
+ U.arrayCopy(arr, idx, res, 0, size);
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public InputStream getBinaryStream() throws SQLException {
+ ensureNotClosed();
+
+ return new ByteArrayInputStream(arr);
+ }
+
+ /** {@inheritDoc} */
+ @Override public InputStream getBinaryStream(long pos, long len) throws SQLException {
+ ensureNotClosed();
+
+ if (pos < 1 || len < 1 || pos > arr.length || len > arr.length - pos + 1)
+ throw new SQLException("Invalid argument. Position can't be less than 1 or " +
+ "greater than size of underlying byte array. Requested length can't be negative and can't be " +
+ "greater than available bytes from given position [pos=" + pos + ", len=" + len +']');
+
+
+ return new ByteArrayInputStream(arr, (int)(pos - 1), (int)len);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long position(byte[] ptrn, long start) throws SQLException {
+ ensureNotClosed();
+
+ if (start < 1 || start > arr.length || ptrn.length == 0 || ptrn.length > arr.length)
+ return -1;
+
+ for(int i = 0, pos = (int)(start - 1); pos < arr.length;) {
+ if (arr[pos] == ptrn[i]) {
+ pos++;
+
+ i++;
+
+ if (i == ptrn.length)
+ return pos - ptrn.length + 1;
+ }
+ else {
+ pos = pos - i + 1;
+
+ i = 0;
+ }
+ }
+
+ return -1;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long position(Blob ptrn, long start) throws SQLException {
+ ensureNotClosed();
+
+ if (start < 1 || start > arr.length || ptrn.length() == 0 || ptrn.length() > arr.length)
+ return -1;
+
+ return position(ptrn.getBytes(1, (int)ptrn.length()), start);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int setBytes(long pos, byte[] bytes) throws SQLException {
+ return setBytes(pos, bytes, 0, bytes.length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int setBytes(long pos, byte[] bytes, int off, int len) throws SQLException {
+ ensureNotClosed();
+
+ if (pos < 1)
+ throw new SQLException("Invalid argument. Position can't be less than 1 [pos=" + pos + ']');
+
+ int idx = (int)(pos - 1);
+
+ if (pos - 1 > arr.length || off < 0 || off >= bytes.length || off + len > bytes.length)
+ throw new ArrayIndexOutOfBoundsException();
+
+ byte[] dst = arr;
+
+ if (idx + len > arr.length) {
+ dst = new byte[arr.length + (len - (arr.length - idx))];
+
+ U.arrayCopy(arr, 0, dst, 0, idx);
+
+ arr = dst;
+ }
+
+ U.arrayCopy(bytes, off, dst, idx, len);
+
+ return len;
+ }
+
+ /** {@inheritDoc} */
+ @Override public OutputStream setBinaryStream(long pos) throws SQLException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void truncate(long len) throws SQLException {
+ ensureNotClosed();
+
+ if (len < 0 || len > arr.length)
+ throw new SQLException("Invalid argument. Length can't be " +
+ "less than zero or greater than Blob length [len=" + len + ']');
+
+ arr = Arrays.copyOf(arr, (int)len);
+
+ }
+
+ /** {@inheritDoc} */
+ @Override public void free() throws SQLException {
+ if (arr != null)
+ arr = null;
+ }
+
+ /**
+ *
+ */
+ private void ensureNotClosed() throws SQLException {
+ if (arr == null)
+ throw new SQLException("Blob instance can't be used after free() has been called.");
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
index f6f79fb..ee8b605 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
@@ -597,7 +597,7 @@ public class JdbcConnection implements Connection {
@Override public Blob createBlob() throws SQLException {
ensureNotClosed();
- throw new SQLFeatureNotSupportedException("SQL-specific types are not supported.");
+ return new JdbcBlob(new byte[0]);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatement.java
index 54e58e9..1a66ced 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatement.java
@@ -239,9 +239,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
/** {@inheritDoc} */
@Override public void setBlob(int paramIdx, Blob x) throws SQLException {
- ensureNotClosed();
-
- throw new SQLFeatureNotSupportedException("SQL-specific types are not supported.");
+ setBytes(paramIdx, x.getBytes(1, (int)x.length()));
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/64ab5cdf/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
index 0f91bd8..10cf17a 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
@@ -952,9 +952,7 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override public Blob getBlob(int colIdx) throws SQLException {
- ensureNotClosed();
-
- throw new SQLFeatureNotSupportedException("SQL-specific types are not supported.");
+ return new JdbcBlob(getBytes(colIdx));
}
/** {@inheritDoc} */
@@ -985,9 +983,7 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override public Blob getBlob(String colLb) throws SQLException {
- ensureNotClosed();
-
- throw new SQLFeatureNotSupportedException("SQL-specific types are not supported.");
+ return new JdbcBlob(getBytes(colLb));
}
/** {@inheritDoc} */