/**
   * Query all purchases made at a specific store for 3 specific products. This query uses
   * cross-cache joins between {@link DimStore}, {@link DimProduct} objects stored in {@code
   * 'replicated'} cache and {@link FactPurchase} objects stored in {@code 'partitioned'} cache.
   *
   * @throws IgniteException If failed.
   */
  private static void queryProductPurchases() {
    IgniteCache<Integer, FactPurchase> factCache = Ignition.ignite().cache(PARTITIONED_CACHE_NAME);

    // All purchases for certain product made at store2.
    // =================================================

    DimProduct p1 = rand(dataProduct.values());
    DimProduct p2 = rand(dataProduct.values());
    DimProduct p3 = rand(dataProduct.values());

    System.out.println(
        "IDs of products [p1=" + p1.getId() + ", p2=" + p2.getId() + ", p3=" + p3.getId() + ']');

    // Create cross cache query to get all purchases made at store2
    // for specified products.
    QueryCursor<Cache.Entry<Integer, FactPurchase>> prodPurchases =
        factCache.query(
            new SqlQuery(
                    FactPurchase.class,
                    "from \""
                        + REPLICATED_CACHE_NAME
                        + "\".DimStore, \""
                        + REPLICATED_CACHE_NAME
                        + "\".DimProduct, "
                        + "\""
                        + PARTITIONED_CACHE_NAME
                        + "\".FactPurchase "
                        + "where DimStore.id=FactPurchase.storeId and DimProduct.id=FactPurchase.productId "
                        + "and DimStore.name=? and DimProduct.id in(?, ?, ?)")
                .setArgs("Store2", p1.getId(), p2.getId(), p3.getId()));

    printQueryResults(
        "All purchases made at store2 for 3 specific products:", prodPurchases.getAll());
  }
  /**
   * Executes example.
   *
   * @param args Command line arguments, none required.
   */
  public static void main(String[] args) {
    try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {

      System.out.println();
      System.out.println(">>> Cache star schema example started.");

      CacheConfiguration<Integer, FactPurchase> factCacheCfg =
          new CacheConfiguration<>(PARTITIONED_CACHE_NAME);

      factCacheCfg.setCacheMode(CacheMode.PARTITIONED);
      factCacheCfg.setIndexedTypes(Integer.class, FactPurchase.class);

      CacheConfiguration<Integer, Object> dimCacheCfg =
          new CacheConfiguration<>(REPLICATED_CACHE_NAME);

      dimCacheCfg.setCacheMode(CacheMode.REPLICATED);
      dimCacheCfg.setIndexedTypes(
          Integer.class, DimStore.class,
          Integer.class, DimProduct.class);

      try (IgniteCache<Integer, FactPurchase> factCache = ignite.getOrCreateCache(factCacheCfg);
          IgniteCache<Integer, Object> dimCache = ignite.getOrCreateCache(dimCacheCfg)) {
        populateDimensions(dimCache);
        populateFacts(factCache);

        queryStorePurchases();
        queryProductPurchases();
      }
    }
  }
  /**
   * Query all purchases made at a specific store. This query uses cross-cache joins between {@link
   * DimStore} objects stored in {@code 'replicated'} cache and {@link FactPurchase} objects stored
   * in {@code 'partitioned'} cache.
   *
   * @throws IgniteException If failed.
   */
  private static void queryStorePurchases() {
    IgniteCache<Integer, FactPurchase> factCache = Ignition.ignite().cache(PARTITIONED_CACHE_NAME);

    // All purchases for store1.
    // ========================

    // Create cross cache query to get all purchases made at store1.
    QueryCursor<Cache.Entry<Integer, FactPurchase>> storePurchases =
        factCache.query(
            new SqlQuery(
                    FactPurchase.class,
                    "from \""
                        + REPLICATED_CACHE_NAME
                        + "\".DimStore, \""
                        + PARTITIONED_CACHE_NAME
                        + "\".FactPurchase "
                        + "where DimStore.id=FactPurchase.storeId and DimStore.name=?")
                .setArgs("Store1"));

    printQueryResults("All purchases made at store1:", storePurchases.getAll());
  }