Repository: incubator-ignite Updated Branches: refs/heads/ignite-962 [created] 406395443
# ignite-962 Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/40639544 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/40639544 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/40639544 Branch: refs/heads/ignite-962 Commit: 4063954438f30c5f9f99d48e879b5216ec505fa4 Parents: b1e557c Author: sboikov <sboi...@gridgain.com> Authored: Tue Jul 14 15:43:49 2015 +0300 Committer: sboikov <sboi...@gridgain.com> Committed: Tue Jul 14 16:53:11 2015 +0300 ---------------------------------------------------------------------- modules/core/pom.xml | 6 + .../src/main/java/org/apache/ignite/Ignite.java | 3 + .../cache/json/CacheJsonQueryTest.java | 248 +++++++++++++++++++ 3 files changed, 257 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/40639544/modules/core/pom.xml ---------------------------------------------------------------------- diff --git a/modules/core/pom.xml b/modules/core/pom.xml index 5ac49ae..4a592b5 100644 --- a/modules/core/pom.xml +++ b/modules/core/pom.xml @@ -41,6 +41,12 @@ </dependency> <dependency> + <groupId>javax.json</groupId> + <artifactId>javax.json-api</artifactId> + <version>1.0</version> + </dependency> + + <dependency> <groupId>mx4j</groupId> <artifactId>mx4j-tools</artifactId> <version>3.0.1</version> http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/40639544/modules/core/src/main/java/org/apache/ignite/Ignite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/Ignite.java b/modules/core/src/main/java/org/apache/ignite/Ignite.java index 7103b1b..30a16b5 100644 --- a/modules/core/src/main/java/org/apache/ignite/Ignite.java +++ b/modules/core/src/main/java/org/apache/ignite/Ignite.java @@ -26,6 +26,7 @@ import org.apache.ignite.lang.*; import org.apache.ignite.plugin.*; import org.jetbrains.annotations.*; +import javax.json.spi.*; import java.util.*; import java.util.concurrent.*; @@ -473,4 +474,6 @@ public interface Ignite extends AutoCloseable { * @return Affinity. */ public <K> Affinity<K> affinity(String cacheName); + + JsonProvider json(); } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/40639544/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/json/CacheJsonQueryTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/json/CacheJsonQueryTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/json/CacheJsonQueryTest.java new file mode 100644 index 0000000..e44635d --- /dev/null +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/json/CacheJsonQueryTest.java @@ -0,0 +1,248 @@ +/* + * 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.cache.json; + +import netscape.javascript.*; +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.affinity.*; +import org.apache.ignite.cache.query.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; +import org.apache.ignite.testframework.junits.common.*; + +import javax.json.*; +import javax.json.spi.*; +import java.sql.*; +import java.util.*; + +/** + * + */ +public class CacheJsonQueryTest extends GridCommonAbstractTest { + /** */ + private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true); + + /** */ + private static final String ORG_CACHE = "orgCache"; + + /** */ + private static final String PERSON_CACHE = "personCache"; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER); + + CacheConfiguration<Long, JsonObject> orgCache = new CacheConfiguration<>(); + + orgCache.setName(ORG_CACHE); + + orgCache.setTypeMetadata(Collections.singleton(organizationMetadata())); + + CacheConfiguration<JsonObject, JsonObject> personCache = new CacheConfiguration<>(); + + personCache.setName(PERSON_CACHE); + + personCache.setTypeMetadata(Collections.singleton(personMetadata())); + + personCache.setAffinityMapper(new AffinityKeyMapper() { + @Override public Object affinityKey(Object key) { + assert key instanceof JsonObject : key; + + return ((JsonObject)key).getJsonNumber("orgId").longValue(); + } + + @Override public void reset() { + // No-op. + } + }); + + cfg.setCacheConfiguration(orgCache, personCache); + + return cfg; + } + + /** + * @return Organization type metadata. + */ + private CacheTypeMetadata organizationMetadata() { + CacheTypeMetadata orgMeta = new CacheTypeMetadata(); + + orgMeta.setKeyType(Long.class); + orgMeta.setValueType(JsonObject.class); + + Map<String, Class<?>> ascFields = new HashMap<>(); + + ascFields.put("id", Long.class); + ascFields.put("name", String.class); + + orgMeta.setAscendingFields(ascFields); + + return orgMeta; + } + + /** + * @return Person type metadata. + */ + private CacheTypeMetadata personMetadata() { + CacheTypeMetadata personMeta = new CacheTypeMetadata(); + + personMeta.setKeyType(JsonObject.class); + personMeta.setValueType(JsonObject.class); + + Map<String, Class<?>> ascFields = new HashMap<>(); + + ascFields.put("name", String.class); + ascFields.put("salary", Long.class); + ascFields.put("orgId", Long.class); + + personMeta.setAscendingFields(ascFields); + + return personMeta; + } + + /** + * @throws Exception If failed. + */ + public void test() throws Exception { + Ignite ignite = grid(0); + + JsonProvider provider = ignite.json(); + + IgniteCache<Long, JsonObject> orgCache = ignite.cache(ORG_CACHE); + + JsonObject org1 = provider.createObjectBuilder().add("id", 1L).add("name", "ApacheIgnite").build(); + JsonObject org2 = provider.createObjectBuilder().add("id", 2L).add("name", "Other").build(); + + orgCache.put(org1.getJsonNumber("id").longValue(), org1); + orgCache.put(org1.getJsonNumber("id").longValue(), org2); + + IgniteCache<JsonObject, JsonObject> personCache = ignite.cache(PERSON_CACHE); + + JsonObject person1 = provider.createObjectBuilder().add("name", "John Doe").add("salary", 1000).build(); + JsonObject key1 = provider.createObjectBuilder().add("orgId", 1L).add("id", 1000L).build(); + + personCache.put(key1, person1); + + sqlQuery(); + + sqlQueryWithJoin(); + + sqlQueryWithAggregation(); + + sqlFieldsQuery(); + + sqlFieldsQueryWithJoin(); + } + + /** + * Example for SQL queries based on salary ranges. + */ + private void sqlQuery() { + IgniteCache<JsonObject, JsonObject> cache = Ignition.ignite().cache(PERSON_CACHE); + + // SQL clause which selects salaries based on range. + String sql = "salary > ? and salary <= ?"; + + // Execute queries for salary ranges. + log.info("People with salaries between 0 and 1000 (queried with SQL query): " + + cache.query(new SqlQuery<JsonObject, JsonObject>(JsonObject.class, sql). + setArgs(0, 1000)).getAll()); + } + + /** + * Example for SQL queries based on all employees working for a specific organization. + */ + private void sqlQueryWithJoin() { + IgniteCache<JsonObject, JsonObject> cache = Ignition.ignite().cache(PERSON_CACHE); + + String joinSql = + "from Person, \"" + ORG_CACHE + "\".Organization as org " + + "where Person.orgId = org.id " + + "and lower(org.name) = lower(?)"; + + // Execute queries for find employees for different organizations. + log.info("Following people are 'ApacheIgnite' employees: " + + cache.query(new SqlQuery<JsonObject, JsonObject>(JsonObject.class, joinSql). + setArgs("ApacheIgnite")).getAll()); + } + + /** + * Example for SQL queries to calculate average salary for a specific organization. + */ + private void sqlQueryWithAggregation() { + IgniteCache<JsonObject, JsonObject> cache = Ignition.ignite().cache(PERSON_CACHE); + + // Calculate average of salary of all persons in ApacheIgnite. + // Note that we also join on Organization cache as well. + String sql = + "select avg(salary) " + + "from Person, \"" + ORG_CACHE + "\".Organization as org " + + "where Person.orgId = org.id " + + "and lower(org.name) = lower(?)"; + + QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery(sql).setArgs("ApacheIgnite")); + + // Calculate average salary for a specific organization. + log.info("Average salary for 'ApacheIgnite' employees: " + cursor.getAll()); + } + + /** + * Example for SQL-based fields queries that return only required + * fields instead of whole key-value pairs. + */ + private void sqlFieldsQuery() { + IgniteCache<JsonObject, JsonObject> cache = Ignition.ignite().cache(PERSON_CACHE); + + // Execute query to get names of all employees. + QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery( + "select concat(firstName, ' ', lastName) from Person")); + + // In this particular case each row will have one element with full name of an employees. + List<List<?>> res = cursor.getAll(); + + // Print names. + log.info("Names of all employees:" + res); + } + + /** + * Example for SQL-based fields queries that return only required + * fields instead of whole key-value pairs. + */ + private void sqlFieldsQueryWithJoin() { + IgniteCache<JsonObject, JsonObject> cache = Ignition.ignite().cache(PERSON_CACHE); + + // Execute query to get names of all employees. + String sql = + "select concat(firstName, ' ', lastName), org.name " + + "from Person, \"" + ORG_CACHE + "\".Organization as org " + + "where Person.orgId = org.id"; + + QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery(sql)); + + // In this particular case each row will have one element with full name of an employees. + List<List<?>> res = cursor.getAll(); + + // Print persons' names and organizations' names. + log.info("Names of all employees and organizations they belong to:" + res); + } +}