/**
* 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.jena.jdbc;
import java.math.BigDecimal ;
import java.sql.* ;
import java.util.Calendar ;
import org.apache.jena.datatypes.TypeMapper ;
import org.apache.jena.datatypes.xsd.XSDDatatype ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.jdbc.results.metadata.columns.ColumnInfo ;
import org.apache.jena.rdf.model.Model ;
import org.apache.jena.rdf.model.ModelFactory ;
import org.apache.jena.sparql.util.NodeFactoryExtra ;
import org.junit.Assert ;
import org.junit.Test ;
/**
* Tests for the various helper methods of {@link JdbcCompatibility}
*/
public class TestCompatibility {
/**
* Tests constants are not normalized to different values
*/
@Test
public void test_level_normalization_01() {
Assert.assertEquals(JdbcCompatibility.LOW, JdbcCompatibility.normalizeLevel(JdbcCompatibility.LOW));
Assert.assertEquals(JdbcCompatibility.MEDIUM, JdbcCompatibility.normalizeLevel(JdbcCompatibility.MEDIUM));
Assert.assertEquals(JdbcCompatibility.HIGH, JdbcCompatibility.normalizeLevel(JdbcCompatibility.HIGH));
Assert.assertEquals(JdbcCompatibility.MEDIUM, JdbcCompatibility.normalizeLevel(JdbcCompatibility.DEFAULT));
}
/**
* Test values outside range are normalized to range ends
*/
@Test
public void test_level_normalization_02() {
Assert.assertEquals(JdbcCompatibility.LOW, JdbcCompatibility.normalizeLevel(Integer.MIN_VALUE));
Assert.assertEquals(JdbcCompatibility.HIGH, JdbcCompatibility.normalizeLevel(Integer.MAX_VALUE));
}
/**
* Test all values in acceptable range are left as is
*/
@Test
public void test_level_normalization_03() {
for (int i = 1; i <= 9; i++) {
Assert.assertEquals(i, JdbcCompatibility.normalizeLevel(i));
}
}
/**
* Test that with low compatibility columns will not be typed as strings/detected types
*/
@Test
public void test_level_behaviours_columns_01() {
Assert.assertFalse(JdbcCompatibility.shouldTypeColumnsAsString(JdbcCompatibility.LOW));
Assert.assertFalse(JdbcCompatibility.shouldDetectColumnTypes(JdbcCompatibility.LOW));
}
/**
* Test that with medium compatibility columns will be typed as strings but not detected types
*/
@Test
public void test_level_behaviours_columns_02() {
Assert.assertTrue(JdbcCompatibility.shouldTypeColumnsAsString(JdbcCompatibility.MEDIUM));
Assert.assertFalse(JdbcCompatibility.shouldDetectColumnTypes(JdbcCompatibility.MEDIUM));
// This also applies to DEFAULT level
Assert.assertTrue(JdbcCompatibility.shouldTypeColumnsAsString(JdbcCompatibility.DEFAULT));
Assert.assertFalse(JdbcCompatibility.shouldDetectColumnTypes(JdbcCompatibility.DEFAULT));
}
/**
* Test that with high compatibility columns will not be typed as strings but with detected types
*/
@Test
public void test_level_behaviours_columns_03() {
Assert.assertFalse(JdbcCompatibility.shouldTypeColumnsAsString(JdbcCompatibility.HIGH));
Assert.assertTrue(JdbcCompatibility.shouldDetectColumnTypes(JdbcCompatibility.HIGH));
}
/**
* Detects a columns types and checks basic information from the detected type, returns the detected column information so tests can make further assertions on this
* @param var Variable Name i.e. Column Label
* @param value Example value to detect from
* @param allowNulls Whether the column allows nulls
* @param jdbcType Expected detected JDBC type
* @param className Expected detected class name
* @return Column Information
* @throws SQLException
*/
private ColumnInfo testColumnTypeDetection(String var, Node value, boolean allowNulls, int jdbcType, String className) throws SQLException {
ColumnInfo info = JdbcCompatibility.detectColumnType(var, value, allowNulls);
Assert.assertEquals(var, info.getLabel());
if (allowNulls) {
Assert.assertEquals(ResultSetMetaData.columnNullable, info.getNullability());
} else {
Assert.assertEquals(ResultSetMetaData.columnNoNulls, info.getNullability());
}
Assert.assertEquals(jdbcType, info.getType());
Assert.assertEquals(className, info.getClassName());
Assert.assertEquals(Node.class.getCanonicalName(), info.getTypeName());
return info;
}
/**
* Expect xsd:integer to be typed as integers
* @throws SQLException
*/
@Test
public void test_column_type_detection_integer_01() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactoryExtra.intToNode(1234), true, Types.BIGINT, Long.class.getCanonicalName());
Assert.assertEquals(0, info.getScale());
Assert.assertTrue(info.isSigned());
}
/**
* Expect xsd:int to be typed as integers
* @throws SQLException
*/
@Test
public void test_column_type_detection_integer_02() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("1234", XSDDatatype.XSDint), true, Types.BIGINT, Long.class.getCanonicalName());
Assert.assertEquals(0, info.getScale());
Assert.assertTrue(info.isSigned());
}
/**
* Expect xsd:long to be typed as integers
* @throws SQLException
*/
@Test
public void test_column_type_detection_integer_03() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("1234", XSDDatatype.XSDlong), true, Types.BIGINT, Long.class.getCanonicalName());
Assert.assertEquals(0, info.getScale());
Assert.assertTrue(info.isSigned());
}
/**
* Expect xsd:unsignedInteger to be typed as integers
* @throws SQLException
*/
@Test
public void test_column_type_detection_integer_04() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("1234", XSDDatatype.XSDunsignedInt), true, Types.BIGINT, Long.class.getCanonicalName());
Assert.assertEquals(0, info.getScale());
Assert.assertFalse(info.isSigned());
}
/**
* Expect xsd:unsignedLong to be typed as integers
* @throws SQLException
*/
@Test
public void test_column_type_detection_integer_05() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("1234", XSDDatatype.XSDunsignedLong), true, Types.BIGINT, Long.class.getCanonicalName());
Assert.assertEquals(0, info.getScale());
Assert.assertFalse(info.isSigned());
}
/**
* Expect xsd:short to be typed as integers
* @throws SQLException
*/
@Test
public void test_column_type_detection_integer_06() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("1234", XSDDatatype.XSDshort), true, Types.INTEGER, Integer.class.getCanonicalName());
Assert.assertEquals(0, info.getScale());
Assert.assertTrue(info.isSigned());
}
/**
* Expect xsd:unsignedShort to be typed as integers
* @throws SQLException
*/
@Test
public void test_column_type_detection_integer_07() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("1234", XSDDatatype.XSDunsignedShort), true, Types.INTEGER, Integer.class.getCanonicalName());
Assert.assertEquals(0, info.getScale());
Assert.assertFalse(info.isSigned());
}
/**
* Expect xsd:byte to be typed as bytes
* @throws SQLException
*/
@Test
public void test_column_type_detection_byte_01() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("123", XSDDatatype.XSDbyte), true, Types.TINYINT, Byte.class.getCanonicalName());
Assert.assertEquals(0, info.getScale());
Assert.assertTrue(info.isSigned());
}
/**
* Expect xsd:unsignedByte to be typed as bytes
* @throws SQLException
*/
@Test
public void test_column_type_detection_byte_02() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("123", XSDDatatype.XSDunsignedByte), true, Types.TINYINT, Byte.class.getCanonicalName());
Assert.assertEquals(0, info.getScale());
Assert.assertFalse(info.isSigned());
}
/**
* Expect xsd:boolean to be typed as booleans
* @throws SQLException
*/
@Test
public void test_column_type_detection_boolean() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createLiteral("true", XSDDatatype.XSDboolean), true, Types.BOOLEAN, Boolean.class.getCanonicalName());
}
/**
* Expect xsd:decimal to be typed as decimal
* @throws SQLException
*/
@Test
public void test_column_type_detection_decimal() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("123.4", XSDDatatype.XSDdecimal), true, Types.DECIMAL, BigDecimal.class.getCanonicalName());
Assert.assertEquals(16, info.getScale());
Assert.assertEquals(16, info.getPrecision());
Assert.assertTrue(info.isSigned());
}
/**
* Expect xsd:double to be typed as double
* @throws SQLException
*/
@Test
public void test_column_type_detection_double() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("12.3e4", XSDDatatype.XSDdouble), true, Types.DOUBLE, Double.class.getCanonicalName());
Assert.assertEquals(16, info.getScale());
Assert.assertEquals(16, info.getPrecision());
Assert.assertTrue(info.isSigned());
}
/**
* Expect xsd:float to be typed as float
* @throws SQLException
*/
@Test
public void test_column_type_detection_float() throws SQLException {
ColumnInfo info = testColumnTypeDetection("x", NodeFactory.createLiteral("12.3e4", XSDDatatype.XSDfloat), true, Types.FLOAT, Float.class.getCanonicalName());
Assert.assertEquals(7, info.getScale());
Assert.assertEquals(15, info.getPrecision());
Assert.assertTrue(info.isSigned());
}
/**
* Tests that xsd:dateTime is typed as Date
* @throws SQLException
*/
@Test
public void test_column_type_detection_datetimes_01() throws SQLException {
Model m = ModelFactory.createDefaultModel();
testColumnTypeDetection("x", m.createTypedLiteral(Calendar.getInstance()).asNode(), true, Types.TIMESTAMP, Timestamp.class.getCanonicalName());
}
/**
* Tests that xsd:date is typed as Date
* @throws SQLException
*/
@Test
public void test_column_type_detection_datetimes_02() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createLiteral("2013-04-08", XSDDatatype.XSDdate), true, Types.DATE, Date.class.getCanonicalName());
}
/**
* Tests that xsd:time is typed as Time
* @throws SQLException
*/
@Test
public void test_column_type_detection_datetimes_03() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createLiteral("13:15:00", XSDDatatype.XSDtime), true, Types.TIME, Time.class.getCanonicalName());
}
/**
* Tests that xsd:time is typed as Time
* @throws SQLException
*/
@Test
public void test_column_type_detection_datetimes_04() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createLiteral("13:15:00.123", XSDDatatype.XSDtime), true, Types.TIME, Time.class.getCanonicalName());
}
/**
* Test that simple literals are typed as strings
* @throws SQLException
*/
@Test
public void test_column_type_detection_strings_01() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createLiteral("simple"), true, Types.NVARCHAR, String.class.getCanonicalName());
}
/**
* Test that literals with languages are typed as strings
* @throws SQLException
*/
@Test
public void test_column_type_detection_strings_02() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createLiteral("simple", "en", false), true, Types.NVARCHAR, String.class.getCanonicalName());
}
/**
* Test that xsd:string literals are typed as strings
* @throws SQLException
*/
@Test
public void test_column_type_detection_strings_03() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createLiteral("simple", XSDDatatype.XSDstring), true, Types.NVARCHAR, String.class.getCanonicalName());
}
/**
* Test that custom typed literals are typed as strings
* @throws SQLException
*/
@Test
public void test_column_type_detection_strings_04() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createLiteral("simple", TypeMapper.getInstance().getSafeTypeByName("http://datatypes/custom")), true, Types.NVARCHAR, String.class.getCanonicalName());
}
/**
* Test that URI are typed as strings
* @throws SQLException
*/
@Test
public void test_column_type_detection_strings_05() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createURI("http://example.org"), true, Types.NVARCHAR, String.class.getCanonicalName());
}
/**
* Test that blank nodes are typed as strings
* @throws SQLException
*/
@Test
public void test_column_type_detection_strings_06() throws SQLException {
testColumnTypeDetection("x", NodeFactory.createAnon(), true, Types.NVARCHAR, String.class.getCanonicalName());
}
/**
* Tests treatment of nulls in type detection
* @throws SQLException
*/
@Test
public void test_column_type_detection_nulls_01() throws SQLException {
testColumnTypeDetection("x", null, true, Types.NVARCHAR, String.class.getCanonicalName());
}
/**
* Tests treatment of nulls in type detection
* @throws SQLException
*/
@Test(expected=SQLException.class)
public void test_column_type_detection_nulls_02() throws SQLException {
// Expect an error to be thrown if a null is provided when the column should not allow nulls
testColumnTypeDetection("x", null, false, Types.NVARCHAR, String.class.getCanonicalName());
}
}