blob: 82acac917c9fdfefaedc9a3412aeb448fc871e1d [file] [log] [blame]
/*
* 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.jdbc;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.affinity.AffinityKey;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.ConnectorConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.binary.BinaryMarshaller;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
import static java.sql.Types.DATE;
import static java.sql.Types.DECIMAL;
import static java.sql.Types.INTEGER;
import static java.sql.Types.OTHER;
import static java.sql.Types.VARCHAR;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
/**
* Metadata tests.
*/
public class JdbcMetadataSelfTest extends GridCommonAbstractTest {
/** URL. */
private static final String URL = "jdbc:ignite://127.0.0.1/pers";
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
cfg.setConnectorConfiguration(new ConnectorConfiguration());
return cfg;
}
/**
* @return Cache configuration.
*/
protected CacheConfiguration cacheConfiguration() {
CacheConfiguration<?,?> cache = defaultCacheConfiguration();
cache.setCacheMode(PARTITIONED);
cache.setBackups(1);
cache.setWriteSynchronizationMode(FULL_SYNC);
return cache;
}
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
startGridsMultiThreaded(3);
IgniteCache<String, Organization> orgCache = jcache(grid(0), cacheConfiguration(), "org",
String.class, Organization.class);
assert orgCache != null;
orgCache.put("o1", new Organization(1, "A"));
orgCache.put("o2", new Organization(2, "B"));
IgniteCache<AffinityKey, Person> personCache = jcache(grid(0), cacheConfiguration(), "pers",
AffinityKey.class, Person.class);
assert personCache != null;
personCache.put(new AffinityKey<>("p1", "o1"), new Person("John White", 25, 1));
personCache.put(new AffinityKey<>("p2", "o1"), new Person("Joe Black", 35, 1));
personCache.put(new AffinityKey<>("p3", "o2"), new Person("Mike Green", 40, 2));
jcache(grid(0), cacheConfiguration(), "metaTest", AffinityKey.class, MetaTest.class);
}
/**
* @throws Exception If failed.
*/
@Test
public void testResultSetMetaData() throws Exception {
Statement stmt = DriverManager.getConnection(URL).createStatement();
ResultSet rs = stmt.executeQuery(
"select p.name, o.id as orgId from \"pers\".Person p, \"org\".Organization o where p.orgId = o.id");
assert rs != null;
ResultSetMetaData meta = rs.getMetaData();
assert meta != null;
assert meta.getColumnCount() == 2;
assert "Person".equalsIgnoreCase(meta.getTableName(1));
assert "name".equalsIgnoreCase(meta.getColumnName(1));
assert "name".equalsIgnoreCase(meta.getColumnLabel(1));
assert meta.getColumnType(1) == VARCHAR;
assert "VARCHAR".equals(meta.getColumnTypeName(1));
assert "java.lang.String".equals(meta.getColumnClassName(1));
assert "Organization".equalsIgnoreCase(meta.getTableName(2));
assert "orgId".equalsIgnoreCase(meta.getColumnName(2));
assert "orgId".equalsIgnoreCase(meta.getColumnLabel(2));
assert meta.getColumnType(2) == INTEGER;
assert "INTEGER".equals(meta.getColumnTypeName(2));
assert "java.lang.Integer".equals(meta.getColumnClassName(2));
}
/**
* @throws Exception If failed.
*/
@Test
public void testDecimalAndDateTypeMetaData() throws Exception {
try (Connection conn = DriverManager.getConnection(URL)) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(
"select t.decimal, t.date from \"metaTest\".MetaTest as t");
assert rs != null;
ResultSetMetaData meta = rs.getMetaData();
assert meta != null;
assert meta.getColumnCount() == 2;
assert "METATEST".equalsIgnoreCase(meta.getTableName(1));
assert "DECIMAL".equalsIgnoreCase(meta.getColumnName(1));
assert "DECIMAL".equalsIgnoreCase(meta.getColumnLabel(1));
assert meta.getColumnType(1) == DECIMAL;
assert "DECIMAL".equals(meta.getColumnTypeName(1));
assert "java.math.BigDecimal".equals(meta.getColumnClassName(1));
assert "METATEST".equalsIgnoreCase(meta.getTableName(2));
assert "DATE".equalsIgnoreCase(meta.getColumnName(2));
assert "DATE".equalsIgnoreCase(meta.getColumnLabel(2));
assert meta.getColumnType(2) == DATE;
assert "DATE".equals(meta.getColumnTypeName(2));
assert "java.sql.Date".equals(meta.getColumnClassName(2));
}
}
/**
* @throws Exception If failed.
*/
@Test
public void testGetTables() throws Exception {
try (Connection conn = DriverManager.getConnection(URL)) {
DatabaseMetaData meta = conn.getMetaData();
ResultSet rs = meta.getTables("", "pers", "%", new String[]{"TABLE"});
assertNotNull(rs);
assertTrue(rs.next());
assertEquals("TABLE", rs.getString("TABLE_TYPE"));
assertEquals("PERSON", rs.getString("TABLE_NAME"));
rs = meta.getTables("", "org", "%", new String[]{"TABLE"});
assertNotNull(rs);
assertTrue(rs.next());
assertEquals("TABLE", rs.getString("TABLE_TYPE"));
assertEquals("ORGANIZATION", rs.getString("TABLE_NAME"));
rs = meta.getTables("", "pers", "%", null);
assertNotNull(rs);
assertTrue(rs.next());
assertEquals("TABLE", rs.getString("TABLE_TYPE"));
assertEquals("PERSON", rs.getString("TABLE_NAME"));
rs = meta.getTables("", "org", "%", null);
assertNotNull(rs);
assertTrue(rs.next());
assertEquals("TABLE", rs.getString("TABLE_TYPE"));
assertEquals("ORGANIZATION", rs.getString("TABLE_NAME"));
rs = meta.getTables("", "PUBLIC", "", new String[]{"WRONG"});
assertFalse(rs.next());
}
}
/**
* @throws Exception If failed.
*/
@Test
public void testGetColumns() throws Exception {
final boolean primitivesInformationIsLostAfterStore = ignite(0).configuration().getMarshaller() instanceof BinaryMarshaller;
try (Connection conn = DriverManager.getConnection(URL)) {
DatabaseMetaData meta = conn.getMetaData();
ResultSet rs = meta.getColumns("", "pers", "Person", "%");
assert rs != null;
Collection<String> names = new ArrayList<>(2);
names.add("NAME");
names.add("AGE");
names.add("ORGID");
int cnt = 0;
while (rs.next()) {
String name = rs.getString("COLUMN_NAME");
assert names.remove(name);
if ("NAME".equals(name)) {
assert rs.getInt("DATA_TYPE") == VARCHAR;
assert "VARCHAR".equals(rs.getString("TYPE_NAME"));
assert rs.getInt("NULLABLE") == 1;
} else if ("AGE".equals(name) || "ORGID".equals(name)) {
assert rs.getInt("DATA_TYPE") == INTEGER;
assert "INTEGER".equals(rs.getString("TYPE_NAME"));
assert rs.getInt("NULLABLE") == (primitivesInformationIsLostAfterStore ? 1 : 0);
}
if ("_KEY".equals(name)) {
assert rs.getInt("DATA_TYPE") == OTHER;
assert "OTHER".equals(rs.getString("TYPE_NAME"));
assert rs.getInt("NULLABLE") == 0;
}
if ("_VAL".equals(name)) {
assert rs.getInt("DATA_TYPE") == OTHER;
assert "OTHER".equals(rs.getString("TYPE_NAME"));
assert rs.getInt("NULLABLE") == 0;
}
cnt++;
}
assert names.isEmpty();
assert cnt == 3;
rs = meta.getColumns("", "org", "Organization", "%");
assert rs != null;
names.add("ID");
names.add("NAME");
cnt = 0;
while (rs.next()) {
String name = rs.getString("COLUMN_NAME");
assert names.remove(name);
if ("id".equals(name)) {
assert rs.getInt("DATA_TYPE") == INTEGER;
assert "INTEGER".equals(rs.getString("TYPE_NAME"));
assert rs.getInt("NULLABLE") == 0;
} else if ("name".equals(name)) {
assert rs.getInt("DATA_TYPE") == VARCHAR;
assert "VARCHAR".equals(rs.getString("TYPE_NAME"));
assert rs.getInt("NULLABLE") == 1;
}
if ("_KEY".equals(name)) {
assert rs.getInt("DATA_TYPE") == VARCHAR;
assert "VARCHAR".equals(rs.getString("TYPE_NAME"));
assert rs.getInt("NULLABLE") == 0;
}
if ("_VAL".equals(name)) {
assert rs.getInt("DATA_TYPE") == OTHER;
assert "OTHER".equals(rs.getString("TYPE_NAME"));
assert rs.getInt("NULLABLE") == 0;
}
cnt++;
}
assert names.isEmpty();
assert cnt == 2;
}
}
/**
* @throws Exception If failed.
*/
@Test
public void testMetadataResultSetClose() throws Exception {
try (Connection conn = DriverManager.getConnection(URL);
ResultSet tbls = conn.getMetaData().getTables(null, null, "%", null)) {
int colCnt = tbls.getMetaData().getColumnCount();
while (tbls.next()) {
for (int i = 0; i < colCnt; i++)
tbls.getObject(i + 1);
}
}
catch (Exception ignored) {
fail();
}
}
/**
* Person.
*/
private static class Person implements Serializable {
/** Name. */
@QuerySqlField(index = false)
private final String name;
/** Age. */
@QuerySqlField
private final int age;
/** Organization ID. */
@QuerySqlField
private final int orgId;
/**
* @param name Name.
* @param age Age.
* @param orgId Organization ID.
*/
private Person(String name, int age, int orgId) {
assert !F.isEmpty(name);
assert age > 0;
assert orgId > 0;
this.name = name;
this.age = age;
this.orgId = orgId;
}
}
/**
* Organization.
*/
private static class Organization implements Serializable {
/** ID. */
@QuerySqlField
private final int id;
/** Name. */
@QuerySqlField(index = false)
private final String name;
/**
* @param id ID.
* @param name Name.
*/
private Organization(int id, String name) {
this.id = id;
this.name = name;
}
}
/**
* Meta Test.
*/
private static class MetaTest implements Serializable {
/** ID. */
@QuerySqlField
private final int id;
/** Date. */
@QuerySqlField
private final Date date;
/** decimal. */
@QuerySqlField
private final BigDecimal decimal;
/**
* @param id ID.
* @param date Date.
*/
private MetaTest(int id, Date date, BigDecimal decimal) {
this.id = id;
this.date = date;
this.decimal = decimal;
}
}
}