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 <[email protected]>
Authored: Fri Nov 3 14:12:21 2017 +0300
Committer: devozerov <[email protected]>
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;
+    }
+}

Reply via email to