<commit_before>/*
 * Copyright 2014 - 2018 Blazebit.
 *
 * Licensed 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 com.blazebit.persistence.testsuite;

import static com.googlecode.catchexception.CatchException.verifyException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.persistence.EntityManager;
import javax.persistence.Tuple;

import com.blazebit.persistence.testsuite.base.jpa.category.NoDatanucleus;
import com.blazebit.persistence.testsuite.base.jpa.category.NoEclipselink;
import com.blazebit.persistence.testsuite.tx.TxVoidWork;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

import com.blazebit.persistence.CriteriaBuilder;
import com.blazebit.persistence.PagedList;
import com.blazebit.persistence.PaginatedCriteriaBuilder;
import com.blazebit.persistence.testsuite.entity.Document;
import com.blazebit.persistence.testsuite.entity.Person;
import com.blazebit.persistence.testsuite.entity.Workflow;
import com.blazebit.persistence.testsuite.model.DocumentViewModel;
import org.junit.experimental.categories.Category;

/**
 *
 * @author <NAME>
 * @author <NAME>
 * @since 1.0.0
 */
public class PaginationTest extends AbstractCoreTest {

    @Override
    public void setUpOnce() {
        cleanDatabase();
        transactional(new TxVoidWork() {
            @Override
            public void work(EntityManager em) {
                Document doc1 = new Document("doc1");
                Document doc2 = new Document("Doc2");
                Document doc3 = new Document("doC3");
                Document doc4 = new Document("dOc4");
                Document doc5 = new Document("DOC5");
                Document doc6 = new Document("bdoc");
                Document doc7 = new Document("adoc");

                Person o1 = new Person("Karl1");
                Person o2 = new Person("Karl2");
                Person o3 = new Person("Moritz");
                o1.getLocalized().put(1, "abra kadabra");
                o2.getLocalized().put(1, "ass");

                doc1.setOwner(o1);
                doc2.setOwner(o1);
                doc3.setOwner(o1);
                doc4.setOwner(o2);
                doc5.setOwner(o2);
                doc6.setOwner(o2);
                doc7.setOwner(o2);

                doc1.getContacts().put(1, o1);
                doc1.getContacts().put(2, o2);

                doc4.getContacts().put(1, o3);

                em.persist(o1);
                em.persist(o2);
                em.persist(o3);

                em.persist(doc1);
                em.persist(doc2);
                em.persist(doc3);
                em.persist(doc4);
                em.persist(doc5);
                em.persist(doc6);
                em.persist(doc7);
            }
        });
    }

    @Test
    public void simpleTest() {
        CriteriaBuilder<DocumentViewModel> crit = cbf.create(em, Document.class, "d")
                .selectNew(DocumentViewModel.class)
                .with("d.name")
                .with("CONCAT(d.owner.name, ' user')")
                .with("COALESCE(d.owner.localized[1],'no item')")
                .with("d.owner.partnerDocument.name")
                .end();
        crit.where("d.name").like(false).value("doc%").noEscape();
        crit.where("d.owner.name").like().value("%arl%").noEscape();
        crit.where("d.owner.localized[1]").like(false).value("a%").noEscape();
        crit.orderByAsc("d.id");

        // do not include joins that are only needed for the select clause
        String expectedCountQuery = "SELECT " + countPaginated("d.id", false) + " FROM Document d JOIN d.owner owner_1 LEFT JOIN owner_1.localized localized_1_1"
                + onClause("KEY(localized_1_1) = 1")
                + " WHERE UPPER(d.name) LIKE UPPER(:param_0) AND owner_1.name LIKE :param_1 AND UPPER(" + joinAliasValue("localized_1_1")
                + ") LIKE UPPER(:param_2)";

        String expectedObjectQuery = "SELECT d.name, CONCAT(owner_1.name,' user'), COALESCE(" + joinAliasValue("localized_1_1")
                + ",'no item'), partnerDocument_1.name FROM Document d "
                + "JOIN d.owner owner_1 LEFT JOIN owner_1.localized localized_1_1"
                + onClause("KEY(localized_1_1) = 1")
                + " LEFT JOIN owner_1.partnerDocument partnerDocument_1 "
                + "WHERE UPPER(d.name) LIKE UPPER(:param_0) AND owner_1.name LIKE :param_1 AND UPPER(" + joinAliasValue("localized_1_1")
                + ") LIKE UPPER(:param_2) "
                + "ORDER BY d.id ASC";
<commit_msg>Added two tests that show issues with grouping joined entities #194<commit_after>/*
 * Copyright 2014 - 2018 Blazebit.
 *
 * Licensed 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 com.blazebit.persistence.testsuite;

import static com.googlecode.catchexception.CatchException.verifyException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.persistence.EntityManager;
import javax.persistence.Tuple;

import com.blazebit.persistence.testsuite.base.jpa.category.NoDatanucleus;
import com.blazebit.persistence.testsuite.base.jpa.category.NoEclipselink;
import com.blazebit.persistence.testsuite.tx.TxVoidWork;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

import com.blazebit.persistence.CriteriaBuilder;
import com.blazebit.persistence.PagedList;
import com.blazebit.persistence.PaginatedCriteriaBuilder;
import com.blazebit.persistence.testsuite.entity.Document;
import com.blazebit.persistence.testsuite.entity.Person;
import com.blazebit.persistence.testsuite.entity.Workflow;
import com.blazebit.persistence.testsuite.model.DocumentViewModel;
import org.junit.experimental.categories.Category;

/**
 *
 * @author <NAME>
 * @author <NAME>
 * @since 1.0.0
 */
public class PaginationTest extends AbstractCoreTest {

    @Override
    public void setUpOnce() {
        cleanDatabase();
        transactional(new TxVoidWork() {
            @Override
            public void work(EntityManager em) {
                Document doc1 = new Document("doc1");
                Document doc2 = new Document("Doc2");
                Document doc3 = new Document("doC3");
                Document doc4 = new Document("dOc4");
                Document doc5 = new Document("DOC5");
                Document doc6 = new Document("bdoc");
                Document doc7 = new Document("adoc");

                Person o1 = new Person("Karl1");
                Person o2 = new Person("Karl2");
                Person o3 = new Person("Moritz");
                o1.getLocalized().put(1, "<NAME>");
                o2.getLocalized().put(1, "ass");

                doc1.setOwner(o1);
                doc2.setOwner(o1);
                doc3.setOwner(o1);
                doc4.setOwner(o2);
                doc5.setOwner(o2);
                doc6.setOwner(o2);
                doc7.setOwner(o2);

                doc1.getContacts().put(1, o1);
                doc1.getContacts().put(2, o2);

                doc4.getContacts().put(1, o3);

                em.persist(o1);
                em.persist(o2);
                em.persist(o3);

                em.persist(doc1);
                em.persist(doc2);
                em.persist(doc3);
                em.persist(doc4);
                em.persist(doc5);
                em.persist(doc6);
                em.persist(doc7);
            }
        });
    }

    @Test
    public void implicitGroupByImplicitlyJoinedEntityTest() {
        // Not sure if we want to support implicit group by's here
        CriteriaBuilder<Tuple> tupleCriteriaBuilder = cbf.create(em, Tuple.class)
            .from(Document.class, "d")
            .select("d.owner.id", "ownerId")
            .select("d.owner.age", "ownerAge")
            .select("d.owner.name", "ownerName")
            .select("max(d.id)", "latestDocument")
            .orderByAsc("d.owner.name")
            .orderByAsc("d.owner.age")
            .orderByAsc("d.owner.id");

        PaginatedCriteriaBuilder<Tuple> page = tupleCriteriaBuilder
            .page(0, 10);

        page.getResultList();
    }

    @Test
    public void groupByImplicitlyJoinedEntityTest() {
        // Test that shows that its not sufficient to group by / order by all used path expressions
        CriteriaBuilder<Tuple> tupleCriteriaBuilder = cbf.create(em, Tuple.class)
            .from(Document.class, "d")
            .select("d.owner.id", "ownerId")
            .select("d.owner.age", "ownerAge")
            .select("d.owner.name", "ownerName")
            .select("max(d.id)", "latestDocument")
            .groupBy("d.owner.name")
            .groupBy("d.owner.age")
            .groupBy("d.owner.id")
            .orderByAsc("d.owner.name")
            .orderByAsc("d.owner.age")
            .orderByAsc("d.owner.id");

        PaginatedCriteriaBuilder<Tuple> page = tupleCriteriaBuilder
            .page(0, 10);

        page.getResultList();
    }


    @Test
    public void groupByJoinedEntityTest() {
        // Test that shows that a work around with a manual inner join default
        // still fails, because the required join is omitted in the count query
        CriteriaBuilder<Tuple> tupleCriteriaBuilder = cbf.create(em, Tuple.class)
            .from(Document.class, "d")
            .innerJoinDefault("d.owner", "theOwner")
            .select("theOwner.id", "ownerId")
            .select("theOwner.age", "ownerAge")
            .select("theOwner.name", "ownerName")
            .select("max(d.id)", "latestDocument")
            .groupBy("theOwner.name")
            .groupBy("theOwner.age")
            .groupBy("theOwner.id")
            .orderByAsc("theOwner.name")
            .orderByAsc("theOwner.age")
            .orderByAsc("theOwner.id");

        PaginatedCriteriaBuilder<Tuple> page = tupleCriteriaBuilder
            .page(0, 10);

        page.getResultList();
    }

    @Test
    public void simpleTest() {
        CriteriaBuilder<DocumentViewModel> crit = cbf.create(em, Document.class, "d")
                .selectNew(DocumentViewModel.class)
                .with("d.name")
                .with("CONCAT(d.owner.name, ' user')")
                .with("COALESCE(d.owner.localized[1],'no item')")
                .with("d.owner.partnerDocument.name")
                .end();
        crit.where("d.name").like(false).value("doc%").noEscape();
        crit.where("d.owner.name").like().value("%arl%").noEscape();
        crit.where("d.owner.localized[1]").like(false).value("a%").noEscape();
        crit.orderByAsc("d.id");

        // do not include joins that are only needed for the select clause
        String expectedCountQuery = "SELECT " + countPaginated("d.id", false) + " FROM Document d JOIN d.owner owner_1 LEFT JOIN owner_1.localized localized_1_1"
                + onClause("KEY(localized_1_1) = 1")
                + " WHERE UPPER(d.name) LIKE UPPER(:param_0) AND owner_1.name LIKE :param_1 AND UPPER(" + joinAliasValue("localized_1_1")
                + ") LIKE UPPER(:param_2)";

        String expectedObjectQuery = "SELECT d.name, CONCAT(owner_1.name,' user'), COALESCE(" + joinAliasValue("localized_1_1")
                + ",'no item'), partnerDocument_1.name FROM Document d "
                + "JOIN d.owner owner_1 LEFT JOIN owner_1.localized localized_1_1"
                + onClause("KEY(localized_1_1) = 1")
                + " LEFT JOIN owner_1.partnerDocument partnerDocument_1 "
                + "WHERE UPPER(d.name) LIKE UPPER(:param_0) AND owner_1.name LIKE :param_1 AND UPPER(" + joinAliasValue("localized_1_1")
                + ") LIKE UPPER(:param_2) "
                + "ORDER BY d.id ASC";

{'fraction_non_alphanumeric': 0.1223077521188088, 'fraction_numerical': 0.016950470414431228, 'mean_word_length': 2.306426735218509, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4630982', 'n_tokens_mistral': 3956, 'n_tokens_neox': 3775, 'n_words': 810}