| /* |
| * 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.calcite.avatica.util; |
| |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import java.sql.SQLException; |
| import java.sql.Time; |
| import java.sql.Timestamp; |
| import java.util.Calendar; |
| import java.util.Locale; |
| import java.util.SimpleTimeZone; |
| import java.util.TimeZone; |
| |
| import static org.hamcrest.CoreMatchers.is; |
| import static org.hamcrest.MatcherAssert.assertThat; |
| |
| /** |
| * Test conversions from SQL TIME as the number of milliseconds since 1970-01-01 00:00:00 to JDBC |
| * types in {@link AbstractCursor.TimeFromNumberAccessor}. |
| */ |
| public class TimeFromNumberAccessorTest { |
| |
| private Cursor.Accessor instance; |
| private Calendar localCalendar; |
| private Object value; |
| |
| /** |
| * Setup test environment by creating a {@link AbstractCursor.TimeFromNumberAccessor} that reads |
| * from the instance variable {@code value}. |
| */ |
| @Before public void before() { |
| final AbstractCursor.Getter getter = new LocalGetter(); |
| localCalendar = Calendar.getInstance(TimeZone.getDefault(), Locale.ROOT); |
| instance = new AbstractCursor.TimeFromNumberAccessor(getter, |
| localCalendar, 0); |
| } |
| |
| /** |
| * Test {@code getString()} returns the same value as the input time. |
| */ |
| @Test public void testString() throws SQLException { |
| value = 0; |
| assertThat(instance.getString(), is("00:00:00")); |
| |
| value = DateTimeUtils.MILLIS_PER_DAY - 1000; |
| assertThat(instance.getString(), is("23:59:59")); |
| } |
| |
| /** |
| * Test {@code getTime()} returns the same value as the input time for the local calendar. |
| */ |
| @Test public void testTime() throws SQLException { |
| value = 0; |
| assertThat(instance.getTime(localCalendar), is(Time.valueOf("00:00:00"))); |
| |
| value = DateTimeUtils.MILLIS_PER_DAY - 1000; |
| assertThat(instance.getTime(localCalendar), is(Time.valueOf("23:59:59"))); |
| } |
| |
| /** |
| * Test {@code getTime()} handles time zone conversions relative to the local calendar and not |
| * UTC. |
| */ |
| @Test public void testTimeWithCalendar() throws SQLException { |
| final int offset = localCalendar.getTimeZone().getOffset(0); |
| final TimeZone east = new SimpleTimeZone( |
| offset + (int) DateTimeUtils.MILLIS_PER_HOUR, |
| "EAST"); |
| final TimeZone west = new SimpleTimeZone( |
| offset - (int) DateTimeUtils.MILLIS_PER_HOUR, |
| "WEST"); |
| |
| value = 0; |
| assertThat(instance.getTime(Calendar.getInstance(east, Locale.ROOT)), |
| is(Timestamp.valueOf("1969-12-31 23:00:00"))); |
| assertThat(instance.getTime(Calendar.getInstance(west, Locale.ROOT)), |
| is(Timestamp.valueOf("1970-01-01 01:00:00"))); |
| } |
| |
| /** |
| * Test no time zone conversion occurs if the given calendar is {@code null}. |
| */ |
| @Test public void testTimeWithNullCalendar() throws SQLException { |
| value = 0; |
| assertThat(instance.getTime(null).getTime(), |
| is(0L)); |
| } |
| |
| /** |
| * Test {@code getTimestamp()} returns the same value as the input time. |
| */ |
| @Test public void testTimestamp() throws SQLException { |
| value = 0; |
| assertThat(instance.getTimestamp(localCalendar), |
| is(Timestamp.valueOf("1970-01-01 00:00:00.0"))); |
| |
| value = DateTimeUtils.MILLIS_PER_DAY - 1000; |
| assertThat(instance.getTimestamp(localCalendar), |
| is(Timestamp.valueOf("1970-01-01 23:59:59.0"))); |
| } |
| |
| /** |
| * Test {@code getTimestamp()} handles time zone conversions relative to the local calendar and |
| * not UTC. |
| */ |
| @Test public void testTimestampWithCalendar() throws SQLException { |
| final int offset = localCalendar.getTimeZone().getOffset(0); |
| final TimeZone east = new SimpleTimeZone( |
| offset + (int) DateTimeUtils.MILLIS_PER_HOUR, |
| "EAST"); |
| final TimeZone west = new SimpleTimeZone( |
| offset - (int) DateTimeUtils.MILLIS_PER_HOUR, |
| "WEST"); |
| |
| value = 0; |
| assertThat(instance.getTimestamp(Calendar.getInstance(east, Locale.ROOT)), |
| is(Timestamp.valueOf("1969-12-31 23:00:00.0"))); |
| assertThat(instance.getTimestamp(Calendar.getInstance(west, Locale.ROOT)), |
| is(Timestamp.valueOf("1970-01-01 01:00:00.0"))); |
| } |
| |
| /** |
| * Test no time zone conversion occurs if the given calendar is {@code null}. |
| */ |
| @Test public void testTimestampWithNullCalendar() throws SQLException { |
| value = 0; |
| assertThat(instance.getTimestamp(null).getTime(), |
| is(0L)); |
| } |
| |
| /** |
| * Returns the value from the test instance to the accessor. |
| */ |
| private class LocalGetter implements AbstractCursor.Getter { |
| @Override public Object getObject() { |
| return value; |
| } |
| |
| @Override public boolean wasNull() { |
| return value == null; |
| } |
| } |
| |
| /** |
| * Test case for <a href="https://issues.apache.org/jira/browse/CALCITE-6282">[CALCITE-6282] |
| * Avatica ignores time precision when returning TIME results</a>. */ |
| @Test public void testPrecision() throws SQLException { |
| final AbstractCursor.Getter getter = new AbstractCursor.Getter() { |
| @Override |
| public Object getObject() throws SQLException { |
| // This is the representation of TIME '12:42:25.34' |
| return 45745340; |
| } |
| |
| @Override |
| public boolean wasNull() throws SQLException { |
| return false; |
| } |
| }; |
| AbstractCursor.TimeFromNumberAccessor accessor = new AbstractCursor.TimeFromNumberAccessor( |
| getter, null, 2); |
| String string = accessor.getString(); |
| assertThat(string, is("12:42:25.34")); |
| } |
| } |