You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2017/11/03 11:12:32 UTC
ignite git commit: IGNITE-4172: SQL: Added support for Java 8 Time
API classes in date\time functions. This closes #2438.
Repository: ignite
Updated Branches:
refs/heads/master 9bf3558c3 -> a3ef23a0d
IGNITE-4172: SQL: Added support for Java 8 Time API classes in date\time functions. This closes #2438.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a3ef23a0
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a3ef23a0
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a3ef23a0
Branch: refs/heads/master
Commit: a3ef23a0d4a4b030294231bee6985f8757aae1a7
Parents: 9bf3558
Author: Alexander Fedotov <al...@gmail.com>
Authored: Fri Nov 3 14:12:21 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Nov 3 14:12:21 2017 +0300
----------------------------------------------------------------------
.../processors/query/GridQueryProcessor.java | 2 +-
.../internal/processors/query/QueryUtils.java | 53 ++-
.../util/Jsr310Java8DateTimeApiUtils.java | 80 +++++
modules/indexing/pom.xml | 48 +++
...ityWithJsr310Java8DateTimeApiFieldsTest.java | 351 +++++++++++++++++++
...acheQueryJsr310Java8DateTimeApiBaseTest.java | 88 +++++
...yJsr310Java8DateTimeApiSupportTestSuite.java | 38 ++
7 files changed, 641 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/a3ef23a0/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index aa947ff..8b3d832 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -1381,7 +1381,7 @@ public class GridQueryProcessor extends GridProcessorAdapter {
if (ccfg == null) {
if (QueryUtils.TEMPLATE_PARTITIONED.equalsIgnoreCase(templateName))
ccfg = new CacheConfiguration<>().setCacheMode(CacheMode.PARTITIONED);
- else if (QueryUtils.TEMPLATE_REPLICÄTED.equalsIgnoreCase(templateName))
+ else if (QueryUtils.TEMPLATE_REPLICATED.equalsIgnoreCase(templateName))
ccfg = new CacheConfiguration<>().setCacheMode(CacheMode.REPLICATED);
else
throw new SchemaOperationException(SchemaOperationException.CODE_CACHE_NOT_FOUND, templateName);
http://git-wip-us.apache.org/repos/asf/ignite/blob/a3ef23a0/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
index 1b61ce9..9584e05 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/QueryUtils.java
@@ -21,7 +21,9 @@ import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -54,9 +56,11 @@ import org.apache.ignite.internal.processors.query.property.QueryMethodsAccessor
import org.apache.ignite.internal.processors.query.property.QueryPropertyAccessor;
import org.apache.ignite.internal.processors.query.property.QueryReadOnlyMethodsAccessor;
import org.apache.ignite.internal.processors.query.schema.SchemaOperationException;
+import org.apache.ignite.internal.util.Jsr310Java8DateTimeApiUtils;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_INDEXING_DISCOVERY_HISTORY_SIZE;
@@ -82,7 +86,7 @@ public class QueryUtils {
public static final String TEMPLATE_PARTITIONED = "PARTITIONED";
/** Well-known template name for REPLICATED cache. */
- public static final String TEMPLATE_REPLICÄTED = "REPLICATED";
+ public static final String TEMPLATE_REPLICATED = "REPLICATED";
/** Discovery history size. */
private static final int DISCO_HIST_SIZE = getInteger(IGNITE_INDEXING_DISCOVERY_HISTORY_SIZE, 1000);
@@ -91,23 +95,36 @@ public class QueryUtils {
private static final Class<?> GEOMETRY_CLASS = U.classForName("com.vividsolutions.jts.geom.Geometry", null);
/** */
- private static final Set<Class<?>> SQL_TYPES = new HashSet<>(F.<Class<?>>asList(
- Integer.class,
- Boolean.class,
- Byte.class,
- Short.class,
- Long.class,
- BigDecimal.class,
- Double.class,
- Float.class,
- Time.class,
- Timestamp.class,
- java.util.Date.class,
- java.sql.Date.class,
- String.class,
- UUID.class,
- byte[].class
- ));
+ private static final Set<Class<?>> SQL_TYPES = createSqlTypes();
+
+ /**
+ * Creates SQL types set.
+ *
+ * @return SQL types set.
+ */
+ @NotNull private static Set<Class<?>> createSqlTypes() {
+ Set<Class<?>> sqlClasses = new HashSet<>(Arrays.<Class<?>>asList(
+ Integer.class,
+ Boolean.class,
+ Byte.class,
+ Short.class,
+ Long.class,
+ BigDecimal.class,
+ Double.class,
+ Float.class,
+ Time.class,
+ Timestamp.class,
+ Date.class,
+ java.sql.Date.class,
+ String.class,
+ UUID.class,
+ byte[].class
+ ));
+
+ sqlClasses.addAll(Jsr310Java8DateTimeApiUtils.jsr310ApiClasses());
+
+ return sqlClasses;
+ }
/**
* Get table name for entity.
http://git-wip-us.apache.org/repos/asf/ignite/blob/a3ef23a0/modules/core/src/main/java/org/apache/ignite/internal/util/Jsr310Java8DateTimeApiUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/Jsr310Java8DateTimeApiUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/Jsr310Java8DateTimeApiUtils.java
new file mode 100644
index 0000000..9febf19
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/Jsr310Java8DateTimeApiUtils.java
@@ -0,0 +1,80 @@
+/*
+ * 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.util;
+
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Provides utility functions for JSR-310 Java 8 Date and Time API types
+ * based on reflection.
+ */
+public final class Jsr310Java8DateTimeApiUtils {
+ /** Class<java.time.LocalTime>. */
+ private static final Class<?> LOCAL_TIME_CLASS = U.classForName("java.time.LocalTime", null);
+
+ /** Class<java.time.LocalDate>. */
+ private static final Class<?> LOCAL_DATE_CLASS = U.classForName("java.time.LocalDate", null);
+
+ /** Class<java.time.LocalDateTime>. */
+ private static final Class<?> LOCAL_DATE_TIME_CLASS = U.classForName("java.time.LocalDateTime", null);
+
+ /** JSR-310 API classes. */
+ private static final Collection<Class<?>> JSR_310_API_CLASSES = createJsr310ApiClassesCollection();
+
+ /**
+ * Creates a collection of the available JSR-310 classes.
+ *
+ * @return Collection of the available JSR-310 classes.
+ */
+ @NotNull private static Collection<Class<?>> createJsr310ApiClassesCollection() {
+ Collection<Class<?>> res = new ArrayList<>(3);
+
+ if (LOCAL_DATE_CLASS != null)
+ res.add(LOCAL_DATE_CLASS);
+
+ if (LOCAL_TIME_CLASS != null)
+ res.add(LOCAL_TIME_CLASS);
+
+ if (LOCAL_DATE_TIME_CLASS != null)
+ res.add(LOCAL_DATE_TIME_CLASS);
+
+ return res;
+ }
+
+ /**
+ * Default private constructor.
+ *
+ * <p>Prevents creation of instances of this class.</p>
+ */
+ private Jsr310Java8DateTimeApiUtils() {
+ // No-op
+ }
+
+ /**
+ * Returns the available JSR-310 classes.
+ *
+ * @return Available JSR-310 classes.
+ */
+ @NotNull public static Collection<Class<?>> jsr310ApiClasses() {
+ return JSR_310_API_CLASSES;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a3ef23a0/modules/indexing/pom.xml
----------------------------------------------------------------------
diff --git a/modules/indexing/pom.xml b/modules/indexing/pom.xml
index cd310fd..a279285 100644
--- a/modules/indexing/pom.xml
+++ b/modules/indexing/pom.xml
@@ -34,6 +34,10 @@
<version>2.3.0-SNAPSHOT</version>
<url>http://ignite.apache.org</url>
+ <properties>
+ <java8.test.folder>${project.build.testSourceDirectory}</java8.test.folder>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.apache.ignite</groupId>
@@ -121,9 +125,53 @@
</dependency>
</dependencies>
+ <profiles>
+ <profile>
+ <id>java8</id>
+ <activation>
+ <jdk>[1.8,)</jdk>
+ </activation>
+ <properties>
+ <javadoc.opts>-Xdoclint:none</javadoc.opts>
+ <java8.test.folder>${project.build.testSourceDirectory}/../java8</java8.test.folder>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
<build>
<plugins>
<plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.9.1</version>
+ <executions>
+ <execution>
+ <id>add-tests</id>
+ <phase>generate-test-sources</phase>
+ <goals>
+ <goal>add-test-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${java8.test.folder}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
http://git-wip-us.apache.org/repos/asf/ignite/blob/a3ef23a0/modules/indexing/src/test/java8/org/apache/ignite/internal/processors/query/h2/CacheQueryEntityWithJsr310Java8DateTimeApiFieldsTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java8/org/apache/ignite/internal/processors/query/h2/CacheQueryEntityWithJsr310Java8DateTimeApiFieldsTest.java b/modules/indexing/src/test/java8/org/apache/ignite/internal/processors/query/h2/CacheQueryEntityWithJsr310Java8DateTimeApiFieldsTest.java
new file mode 100644
index 0000000..903b8dc
--- /dev/null
+++ b/modules/indexing/src/test/java8/org/apache/ignite/internal/processors/query/h2/CacheQueryEntityWithJsr310Java8DateTimeApiFieldsTest.java
@@ -0,0 +1,351 @@
+/*
+ * 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.query.h2;
+
+import java.io.Serializable;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.List;
+import java.util.Objects;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.configuration.CacheConfiguration;
+
+/**
+ * Tests queries against entities with JSR-310 Java 8 Date and Time API fields.
+ */
+public class CacheQueryEntityWithJsr310Java8DateTimeApiFieldsTest extends CacheQueryJsr310Java8DateTimeApiBaseTest {
+ /**
+ * Entity containing JSR-310 fields.
+ */
+ private static class EntityWithJsr310Fields implements Serializable {
+
+ /** Serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** ID. */
+ @QuerySqlField(index = true)
+ private Long id;
+
+ /** {@link LocalTime} field. */
+ @QuerySqlField(index = true)
+ private LocalTime locTime;
+
+ /** {@link LocalDate} field. */
+ @QuerySqlField(index = true)
+ private LocalDate locDate;
+
+ /** {@link LocalDateTime} field. */
+ @QuerySqlField(index = true)
+ private LocalDateTime locDateTime;
+
+ /**
+ * Default constructor.
+ */
+ EntityWithJsr310Fields() {
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param entity Entity to copy from.
+ */
+ EntityWithJsr310Fields(EntityWithJsr310Fields entity) {
+ id = entity.id;
+ locTime = LocalTime.from(entity.locTime);
+ locDate = LocalDate.from(entity.locDate);
+ locDateTime = LocalDateTime.from(entity.locDateTime);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param id ID.
+ * @param locTime {@link LocalTime} value.
+ * @param locDate {@link LocalDate} value.
+ * @param locDateTime {@link LocalDateTime} value.
+ */
+ EntityWithJsr310Fields(Long id, LocalTime locTime, LocalDate locDate, LocalDateTime locDateTime) {
+ this.id = id;
+ this.locTime = locTime;
+ this.locDate = locDate;
+ this.locDateTime = locDateTime;
+ }
+
+ /**
+ * Returns the ID.
+ *
+ * @return ID.
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * Sets the ID.
+ *
+ * @param id ID.
+ */
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns the {@link LocalDateTime} field value
+ *
+ * @return {@link LocalDateTime} field value;
+ */
+ public LocalDateTime getLocalDateTime() {
+ return locDateTime;
+ }
+
+ /**
+ * Returns the {@link LocalDateTime} field value.
+ *
+ * @param locDateTime {@link LocalDateTime} value.
+ */
+ public void setLocalDateTime(LocalDateTime locDateTime) {
+ this.locDateTime = locDateTime;
+ }
+
+ /**
+ * Returns the {@link LocalDate} field value.
+ *
+ * @return {@link LocalDate} field value.
+ */
+ public LocalDate getLocalDate() {
+ return locDate;
+ }
+
+ /**
+ * Sets the {@link LocalDate} field value.
+ *
+ * @param locDate {@link LocalDate} value.
+ */
+ public void setLocalDate(LocalDate locDate) {
+ this.locDate = locDate;
+ }
+
+ /**
+ * Returns the {@link LocalTime} field value.
+ *
+ * @return {@link LocalTime} field value.
+ */
+ public LocalTime getLocalTime() {
+ return locTime;
+ }
+
+ /**
+ * Sets the {@link LocalTime} field value.
+ *
+ * @param locTime {@link LocalTime} value.
+ */
+ public void setLocalTime(LocalTime locTime) {
+ this.locTime = locTime;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ EntityWithJsr310Fields fields = (EntityWithJsr310Fields)o;
+
+ return Objects.equals(id, fields.id) && Objects.equals(locDateTime, fields.locDateTime) &&
+ Objects.equals(locDate, fields.locDate) && Objects.equals(locTime, fields.locTime);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return Objects.hash(id, locDateTime, locDate, locTime);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return "EntityWithJsr310Fields{" + "id=" + id + ", locDateTime=" + locDateTime + ", locDate=" + locDate +
+ ", locTime=" + locTime + '}';
+ }
+ }
+
+ /** Cache. */
+ private IgniteCache<Long, EntityWithJsr310Fields> cache;
+
+ /** Entity with JSR-310 fields instance. */
+ private final EntityWithJsr310Fields entity =
+ new EntityWithJsr310Fields(1L, LOCAL_TIME, LOCAL_DATE, LOCAL_DATE_TIME);
+
+ /**
+ * Creates a cache configuration.
+ *
+ * @return Cache configuration.
+ */
+ private static CacheConfiguration<Long, EntityWithJsr310Fields> createCacheConfig() {
+ return createCacheConfig(
+ "entityWithJava8DataTimeFields", Long.class, EntityWithJsr310Fields.class
+ );
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ Ignite ignite = startGridsMultiThreaded(1, true);
+ cache = ignite.getOrCreateCache(createCacheConfig());
+
+ cache.put(entity.getId(), entity);
+ }
+
+ /**
+ * Tests insertion of an entity.
+ *
+ * @throws Exception If failed.
+ */
+ public void testInsertEntityFields() throws Exception {
+ cache.remove(entity.getId());
+
+ assertEquals(0, cache.size());
+
+ SqlFieldsQuery qry = new SqlFieldsQuery(
+ "insert into EntityWithJsr310Fields(_key, id, locTime, locDate, locDateTime) values(?, ?, ?, ?, ?)"
+ ).setArgs(
+ entity.getId(), entity.getId(), entity.getLocalTime(), entity.getLocalDate(), entity.getLocalDateTime()
+ );
+
+ List<List<?>> qryResults = cache.query(qry).getAll();
+
+ assertEquals(1, qryResults.size());
+ assertEquals(1L, qryResults.get(0).get(0));
+ assertEquals(1, cache.size());
+ assertEquals(entity, cache.get(entity.getId()));
+ }
+
+ /**
+ * Tests that DATEDIFF SQL function works for {@link LocalDateTime}
+ * fields with the time part set to midnight.
+ *
+ * @throws Exception If failed.
+ */
+ public void testDateDiffForLocalDateTimeFieldAtMidnight() throws Exception {
+ SqlFieldsQuery qry =
+ new SqlFieldsQuery("select DATEDIFF('DAY', locDateTime, CURRENT_DATE ()) from EntityWithJsr310Fields");
+
+ List<List<?>> qryResults = cache.query(qry).getAll();
+
+ assertEquals(1, qryResults.size());
+ assertTrue((Long)qryResults.get(0).get(0) >= DAYS_BEFORE_NOW);
+ }
+
+ /**
+ * Tests that selection for a {@link LocalTime} field returns {@link Time}.
+ *
+ * @throws Exception If failed.
+ */
+ public void testSelectLocalTimeFieldReturnsTime() throws Exception {
+ SqlFieldsQuery qry = new SqlFieldsQuery("select locTime from EntityWithJsr310Fields");
+
+ List<List<?>> qryResults = cache.query(qry).getAll();
+
+ assertEquals(1, qryResults.size());
+ assertEquals(Time.class, qryResults.get(0).get(0).getClass());
+ }
+
+ /**
+ * Tests that selection for a {@link LocalDate} field returns {@link Date}.
+ *
+ * @throws Exception If failed.
+ */
+ public void testSelectLocalDateFieldReturnsDate() throws Exception {
+ SqlFieldsQuery qry = new SqlFieldsQuery("select locDate from EntityWithJsr310Fields");
+
+ List<List<?>> qryResults = cache.query(qry).getAll();
+
+ assertEquals(1, qryResults.size());
+ assertEquals(Date.class, qryResults.get(0).get(0).getClass());
+ }
+
+ /**
+ * Tests that selection for a {@link LocalDateTime} field returns {@link Timestamp}.
+ *
+ * @throws Exception If failed.
+ */
+ public void testSelectLocalDateTimeFieldReturnsTimestamp() throws Exception {
+ SqlFieldsQuery qry = new SqlFieldsQuery("select locDateTime from EntityWithJsr310Fields");
+
+ List<List<?>> qryResults = cache.query(qry).getAll();
+
+ assertEquals(1, qryResults.size());
+ assertEquals(Timestamp.class, qryResults.get(0).get(0).getClass());
+ }
+
+ /**
+ * Tests selection of an entity by a {@link LocalTime} field.
+ */
+ public void testSelectByAllJsr310Fields() {
+ SqlFieldsQuery qry = new SqlFieldsQuery(
+ "select locDate from EntityWithJsr310Fields where locTime = ? and locDate = ? and locDateTime = ?"
+ ).setArgs(entity.getLocalTime(), entity.getLocalDate(), entity.getLocalDateTime());
+
+ List<List<?>> qryResults = cache.query(qry).getAll();
+
+ assertEquals(1, qryResults.size());
+ assertEquals(Date.valueOf(entity.getLocalDate()), qryResults.get(0).get(0));
+ }
+
+ /**
+ * Tests updating of all JSR-310 fields.
+ */
+ public void testUpdateAllJsr310Fields() {
+ EntityWithJsr310Fields expEntity = new EntityWithJsr310Fields(entity);
+
+ expEntity.setLocalTime(expEntity.getLocalTime().plusHours(1));
+ expEntity.setLocalDate(expEntity.getLocalDate().plusDays(1));
+ expEntity.setLocalDateTime(LocalDateTime.of(expEntity.getLocalDate(), expEntity.getLocalTime()));
+
+ SqlFieldsQuery qry = new SqlFieldsQuery(
+ "update EntityWithJsr310Fields set locTime = ?, locDate = ?, locDateTime = ? where id = ?"
+ ).setArgs(expEntity.getLocalTime(), expEntity.getLocalDate(), expEntity.getLocalDateTime(), entity.getId());
+
+ List<List<?>> qryResults = cache.query(qry).getAll();
+
+ assertEquals(1, qryResults.size());
+ assertEquals(1L, qryResults.get(0).get(0));
+ assertEquals(expEntity, cache.get(expEntity.getId()));
+ }
+
+ /**
+ * Tests deleting by all JSR-310 fields.
+ */
+ public void testDeleteByAllJsr310Fields() {
+ SqlFieldsQuery qry = new SqlFieldsQuery(
+ "delete from EntityWithJsr310Fields where locTime = ? and locDate = ? and locDateTime = ?"
+ ).setArgs(entity.getLocalTime(), entity.getLocalDate(), entity.getLocalDateTime());
+
+ List<List<?>> qryResults = cache.query(qry).getAll();
+
+ assertEquals(1, qryResults.size());
+ assertEquals(1L, qryResults.get(0).get(0));
+ assertEquals(0, cache.size());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a3ef23a0/modules/indexing/src/test/java8/org/apache/ignite/internal/processors/query/h2/CacheQueryJsr310Java8DateTimeApiBaseTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java8/org/apache/ignite/internal/processors/query/h2/CacheQueryJsr310Java8DateTimeApiBaseTest.java b/modules/indexing/src/test/java8/org/apache/ignite/internal/processors/query/h2/CacheQueryJsr310Java8DateTimeApiBaseTest.java
new file mode 100644
index 0000000..6f643b4
--- /dev/null
+++ b/modules/indexing/src/test/java8/org/apache/ignite/internal/processors/query/h2/CacheQueryJsr310Java8DateTimeApiBaseTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.query.h2;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Base class for JSR-310 Java 8 Date and Time API queries tests.
+ */
+public abstract class CacheQueryJsr310Java8DateTimeApiBaseTest extends GridCommonAbstractTest {
+ /** IP finder. */
+ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+ /** {@link LocalTime} instance. */
+ protected static final LocalTime LOCAL_TIME = LocalTime.now().minusHours(10);
+
+ /**
+ * The number of days subtracted from the current time when constructing
+ * {@link LocalDate} and {@link LocalDateTime}
+ * instances.
+ */
+ protected static final long DAYS_BEFORE_NOW = 10;
+
+ /** {@link LocalDate} instance. */
+ protected static final LocalDate LOCAL_DATE = LocalDate.now().minusDays(DAYS_BEFORE_NOW);
+
+ /** {@link LocalDateTime} instance. */
+ protected static final LocalDateTime LOCAL_DATE_TIME = LocalDateTime.of(LOCAL_DATE, LocalTime.MIDNIGHT);
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+ TcpDiscoverySpi discoverySpi = (TcpDiscoverySpi)cfg.getDiscoverySpi();
+
+ discoverySpi.setIpFinder(IP_FINDER);
+
+ return cfg;
+ }
+
+ /**
+ * Creates a cache configuration with the specified cache name
+ * and indexed type key/value pairs.
+ *
+ * @param cacheName Cache name
+ * @param indexedTypes key/value pairs according to {@link CacheConfiguration#setIndexedTypes(Class[])}.
+ * @param <K> Key type.
+ * @param <V> Value type.
+ * @return Cache configuration.
+ */
+ protected static <K, V> CacheConfiguration<K, V> createCacheConfig(String cacheName, Class<?>... indexedTypes) {
+ return new CacheConfiguration<K, V>(cacheName)
+ .setCacheMode(CacheMode.REPLICATED)
+ .setAtomicityMode(CacheAtomicityMode.ATOMIC)
+ .setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC)
+ .setIndexedTypes(indexedTypes);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ stopAllGrids();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/a3ef23a0/modules/indexing/src/test/java8/org/apache/ignite/testsuites/CacheQueryJsr310Java8DateTimeApiSupportTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java8/org/apache/ignite/testsuites/CacheQueryJsr310Java8DateTimeApiSupportTestSuite.java b/modules/indexing/src/test/java8/org/apache/ignite/testsuites/CacheQueryJsr310Java8DateTimeApiSupportTestSuite.java
new file mode 100644
index 0000000..aa7aed8
--- /dev/null
+++ b/modules/indexing/src/test/java8/org/apache/ignite/testsuites/CacheQueryJsr310Java8DateTimeApiSupportTestSuite.java
@@ -0,0 +1,38 @@
+/*
+ * 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.testsuites;
+
+import junit.framework.TestSuite;
+import org.apache.ignite.internal.processors.query.h2.CacheQueryEntityWithJsr310Java8DateTimeApiFieldsTest;
+
+/**
+ * Test suite for JSR-310 Java 8 Date and Time API queries.
+ */
+public class CacheQueryJsr310Java8DateTimeApiSupportTestSuite extends TestSuite {
+ /**
+ * @return Test suite.
+ * @throws Exception If failed.
+ */
+ public static TestSuite suite() throws Exception {
+ TestSuite suite = new TestSuite("JSR-310 Java 8 Date and Time API Cache Queries Test Suite");
+
+ suite.addTestSuite(CacheQueryEntityWithJsr310Java8DateTimeApiFieldsTest.class);
+
+ return suite;
+ }
+}