<commit_before>/*
 * Hibernate OGM, Domain model persistence for NoSQL datastores
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.ogm.datastore.neo4j.test.query.nativequery;

import static org.fest.assertions.Assertions.assertThat;
import static org.hibernate.ogm.datastore.neo4j.test.query.nativequery.OscarWildePoem.TABLE_NAME;

import java.util.GregorianCalendar;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.ogm.backendtck.jpa.Poem;
import org.hibernate.ogm.datastore.impl.DatastoreProviderType;
import org.hibernate.ogm.utils.PackagingRule;
import org.hibernate.ogm.utils.TestForIssue;
import org.hibernate.ogm.utils.TestHelper;
import org.hibernate.ogm.utils.jpa.OgmJpaTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

/**
 * Test the execution of native queries on Neo4j using the {@link EntityManager}
 *
 * @author <NAME> &lt;<EMAIL>&gt;
 */
public class Neo4jEntityManagerNativeQueryTest extends OgmJpaTestCase {

	/*
	 *  The only purpose of this constant is to keep track of the nodes created using a native query via the
	 *	executeUpdate method. This is just a Label (not a table or entity).
	 */
	private static final String UPDATE_LABEL = "UPDATE";

	@Rule
	public PackagingRule packaging = new PackagingRule( "persistencexml/ogm.xml", Poem.class );

	private final Critic critic = new Critic( new CriticId( "de", "764" ), "Roger" );
	private final OscarWildePoem portia = new OscarWildePoem( 1L, "Portia", "<NAME>", new GregorianCalendar( 1808, 3, 10, 12, 45 ).getTime(), critic );
	private final OscarWildePoem athanasia = new OscarWildePoem( 2L, "Athanasia", "<NAME>", new GregorianCalendar( 1810, 3, 10 ).getTime(), null );

	private EntityManager em;

	@Before
	public void init() throws Exception {
		em = createEntityManager();
		persist( critic, portia, athanasia );
	}

	@After
	public void tearDown() throws Exception {
		delete( portia, athanasia, critic );
		em.close();
	}

	@Test
	public void testIteratorSingleResultQuery() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { name:'Portia', author:'<NAME>' } ) RETURN n";
		OscarWildePoem poem = (OscarWildePoem) em.createNativeQuery( nativeQuery, OscarWildePoem.class ).getSingleResult();

		assertAreEquals( portia, poem );

		em.getTransaction().commit();
	}

	@Test
	public void testIteratorSingleResultFromNamedNativeQuery() throws Exception {
		em.getTransaction().begin();

		OscarWildePoem poem = (OscarWildePoem) em.createNamedQuery( "AthanasiaQuery" ).getSingleResult();

		assertAreEquals( athanasia, poem );

		em.getTransaction().commit();
	}



	@Test
	public void testListMultipleResultQuery() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { author:'<NAME>' } ) RETURN n ORDER BY n.name";
		@SuppressWarnings("unchecked")
		List<OscarWildePoem> results = em.createNativeQuery( nativeQuery, OscarWildePoem.class ).getResultList();

		assertThat( results ).as( "Unexpected number of results" ).hasSize( 2 );
		assertAreEquals( athanasia, results.get( 0 ) );
		assertAreEquals( portia, results.get( 1 ) );

		em.getTransaction().commit();
	}

	@Test
	public void testSingleResultQueryUsingParameter() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { name:{name}, author:'<NAME>' } ) RETURN n";
		Query query = em.createNativeQuery( nativeQuery, OscarWildePoem.class );
		query.setParameter( "name", "Portia" );
		OscarWildePoem poem = (OscarWildePoem) query.getSingleResult();

		assertAreEquals( portia, poem );

		em.getTransaction().commit();
	}

	@Test
	public void testSingleResultQueryUsingDateParameter() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { dateOfCreation:{creationDate}, author:'<NAME>' } ) RETURN n";
		Query query = em.createNativeQuery( nativeQuery, OscarWildePoem.class );
		query.setParameter( "creationDate", new GregorianCalendar( 1810, 3, 10 ).getTime() );
		OscarWildePoem poem = (OscarWildePoem) query.getSingleResult();

		assertAreEquals( athanasia, poem );

		em.getTransaction().commit();
	}

	@Test
	@TestForIssue(jiraKey = "OGM-702")
	public void testQueryWithCompositeId() throws Exception {
		em.getTransaction().begin();

		@SuppressWarnings("unchecked")
		List<Critic> critics = em.createNativeQuery( "MATCH ( n:Critic ) RETURN n", Critic.class ).getResultList();

		assertThat( critics ).onProperty( "id" ).containsExactly( new CriticId( "de", "764" ) );

		em.getTransaction().commit();
	}

	@Test
	@TestForIssue(jiraKey = "OGM-854")
	public void testToOneInitializedByQuery() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { name:'Portia', author:'<NAME>' } ) RETURN n";
		OscarWildePoem poem = (OscarWildePoem) em.createNativeQuery( nativeQuery, OscarWildePoem.class ).getSingleResult();

		assertThat( poem.getCritic() ).isNotNull();
		assertThat( poem.getCritic().getName() ).as( "Wrong critic name" ).isEqualTo( "Roger" );

		em.getTransaction().commit();
	}

	@Test
	@SuppressWarnings("unchecked")
	public void testNativeQueryExecuteUpdate() throws Exception {
		em.getTransaction().begin();

		String findQueryString = "MATCH (n:" + UPDATE_LABEL + ") RETURN n";
		Query findQuery = em.createNativeQuery( findQueryString );

		String createQuery = "CREATE (n:" + UPDATE_LABEL + " { author:'<NAME>' })";
		int updates = em.createNativeQuery( createQuery ).executeUpdate();
		if ( TestHelper.getCurrentDatastoreProviderType() != DatastoreProviderType.NEO4J_HTTP ) {
			assertThat( updates ).isEqualTo( 3 ); // 1 node + 1 label + 1 property set
		}
		List<Object> createdNode = (List<Object>) findQuery.getResultList();
		assertThat( createdNode ).hasSize( 1 );

		String deleteQuery = "MATCH (n:" + UPDATE_LABEL + ") DELETE n ";
		int deletes = em.createNativeQuery( deleteQuery ).executeUpdate();
		if ( TestHelper.getCurrentDatastoreProviderType() != DatastoreProviderType.NEO4J_HTTP ) {
			assertThat( deletes ).isEqualTo( 1 ); // 1 node
		}
		List<Object> uniqueResult = (List<Object>) findQuery.getResultList();
		assertThat( uniqueResult ).isEmpty();

		em.getTransaction().commit();
	}

	private void persist(Object... entities) {
		EntityManager em = createEntityManager();
		em.getTransaction().begin();
		for ( Object object : entities ) {
			em.persist( object );
		}
		em.getTransaction().commit();
		em.clear();
	}

	private void assertAreEquals(OscarWildePoem expectedPoem, OscarWildePoem poem) {
		assertThat( poem ).isNotNull();
		assertThat( poem.getId() ).as( "Wrong Id" ).isEqualTo( expectedPoem.getId() );
		assertThat( poem.getName() ).as( "Wrong Name" ).isEqualTo( expectedPoem.getName() );
		assertThat( poem.getAuthor() ).as( "Wrong Author" ).isEqualTo( expectedPoem.getAuthor() );
	}<commit_msg>OGM-1407 Add test for positional parameters with native Cypher queries<commit_after>/*
 * Hibernate OGM, Domain model persistence for NoSQL datastores
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.ogm.datastore.neo4j.test.query.nativequery;

import static org.fest.assertions.Assertions.assertThat;
import static org.hibernate.ogm.datastore.neo4j.test.query.nativequery.OscarWildePoem.TABLE_NAME;

import java.util.GregorianCalendar;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.ogm.backendtck.jpa.Poem;
import org.hibernate.ogm.datastore.impl.DatastoreProviderType;
import org.hibernate.ogm.utils.PackagingRule;
import org.hibernate.ogm.utils.TestForIssue;
import org.hibernate.ogm.utils.TestHelper;
import org.hibernate.ogm.utils.jpa.OgmJpaTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

/**
 * Test the execution of native queries on Neo4j using the {@link EntityManager}
 *
 * @author <NAME> &lt;<EMAIL>&gt;
 */
public class Neo4jEntityManagerNativeQueryTest extends OgmJpaTestCase {

	/*
	 *  The only purpose of this constant is to keep track of the nodes created using a native query via the
	 *	executeUpdate method. This is just a Label (not a table or entity).
	 */
	private static final String UPDATE_LABEL = "UPDATE";

	@Rule
	public PackagingRule packaging = new PackagingRule( "persistencexml/ogm.xml", Poem.class );

	private final Critic critic = new Critic( new CriticId( "de", "764" ), "Roger" );
	private final OscarWildePoem portia = new OscarWildePoem( 1L, "Portia", "<NAME>", new GregorianCalendar( 1808, 3, 10, 12, 45 ).getTime(), critic );
	private final OscarWildePoem athanasia = new OscarWildePoem( 2L, "Athanasia", "<NAME>", new GregorianCalendar( 1810, 3, 10 ).getTime(), null );

	private EntityManager em;

	@Before
	public void init() throws Exception {
		em = createEntityManager();
		persist( critic, portia, athanasia );
	}

	@After
	public void tearDown() throws Exception {
		delete( portia, athanasia, critic );
		em.close();
	}

	@Test
	public void testIteratorSingleResultQuery() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { name:'Portia', author:'<NAME>' } ) RETURN n";
		OscarWildePoem poem = (OscarWildePoem) em.createNativeQuery( nativeQuery, OscarWildePoem.class ).getSingleResult();

		assertAreEquals( portia, poem );

		em.getTransaction().commit();
	}

	@Test
	public void testIteratorSingleResultFromNamedNativeQuery() throws Exception {
		em.getTransaction().begin();

		OscarWildePoem poem = (OscarWildePoem) em.createNamedQuery( "AthanasiaQuery" ).getSingleResult();

		assertAreEquals( athanasia, poem );

		em.getTransaction().commit();
	}



	@Test
	public void testListMultipleResultQuery() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { author:'<NAME>' } ) RETURN n ORDER BY n.name";
		@SuppressWarnings("unchecked")
		List<OscarWildePoem> results = em.createNativeQuery( nativeQuery, OscarWildePoem.class ).getResultList();

		assertThat( results ).as( "Unexpected number of results" ).hasSize( 2 );
		assertAreEquals( athanasia, results.get( 0 ) );
		assertAreEquals( portia, results.get( 1 ) );

		em.getTransaction().commit();
	}

	@Test
	public void testSingleResultQueryUsingParameter() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { name:{name}, author:'<NAME>' } ) RETURN n";
		Query query = em.createNativeQuery( nativeQuery, OscarWildePoem.class );
		query.setParameter( "name", "Portia" );
		OscarWildePoem poem = (OscarWildePoem) query.getSingleResult();

		assertAreEquals( portia, poem );

		em.getTransaction().commit();
	}

	@Test
	public void testSingleResultQueryUsingDateParameter() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { dateOfCreation:{creationDate}, author:'<NAME>' } ) RETURN n";
		Query query = em.createNativeQuery( nativeQuery, OscarWildePoem.class );
		query.setParameter( "creationDate", new GregorianCalendar( 1810, 3, 10 ).getTime() );
		OscarWildePoem poem = (OscarWildePoem) query.getSingleResult();

		assertAreEquals( athanasia, poem );

		em.getTransaction().commit();
	}

	@Test
	@TestForIssue(jiraKey = "OGM-702")
	public void testQueryWithCompositeId() throws Exception {
		em.getTransaction().begin();

		@SuppressWarnings("unchecked")
		List<Critic> critics = em.createNativeQuery( "MATCH ( n:Critic ) RETURN n", Critic.class ).getResultList();

		assertThat( critics ).onProperty( "id" ).containsExactly( new CriticId( "de", "764" ) );

		em.getTransaction().commit();
	}

	@Test
	@TestForIssue(jiraKey = "OGM-854")
	public void testToOneInitializedByQuery() throws Exception {
		em.getTransaction().begin();

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { name:'Portia', author:'<NAME>' } ) RETURN n";
		OscarWildePoem poem = (OscarWildePoem) em.createNativeQuery( nativeQuery, OscarWildePoem.class ).getSingleResult();

		assertThat( poem.getCritic() ).isNotNull();
		assertThat( poem.getCritic().getName() ).as( "Wrong critic name" ).isEqualTo( "Roger" );

		em.getTransaction().commit();
	}

	@Test
	@SuppressWarnings("unchecked")
	public void testNativeQueryExecuteUpdate() throws Exception {
		em.getTransaction().begin();

		String findQueryString = "MATCH (n:" + UPDATE_LABEL + ") RETURN n";
		Query findQuery = em.createNativeQuery( findQueryString );

		String createQuery = "CREATE (n:" + UPDATE_LABEL + " { author:'<NAME>' })";
		int updates = em.createNativeQuery( createQuery ).executeUpdate();
		if ( TestHelper.getCurrentDatastoreProviderType() != DatastoreProviderType.NEO4J_HTTP ) {
			assertThat( updates ).isEqualTo( 3 ); // 1 node + 1 label + 1 property set
		}
		List<Object> createdNode = (List<Object>) findQuery.getResultList();
		assertThat( createdNode ).hasSize( 1 );

		String deleteQuery = "MATCH (n:" + UPDATE_LABEL + ") DELETE n ";
		int deletes = em.createNativeQuery( deleteQuery ).executeUpdate();
		if ( TestHelper.getCurrentDatastoreProviderType() != DatastoreProviderType.NEO4J_HTTP ) {
			assertThat( deletes ).isEqualTo( 1 ); // 1 node
		}
		List<Object> uniqueResult = (List<Object>) findQuery.getResultList();
		assertThat( uniqueResult ).isEmpty();

		em.getTransaction().commit();
	}

	@Test
	public void testQueryWithPositionalParams() {
		em.getTransaction().begin();

		long id = 1L;
		String author = "<NAME>";

		String nativeQuery = "MATCH ( n:" + TABLE_NAME + " { id: {0}, author: { 1 }} ) RETURN n";
		Query query = em.createNativeQuery( nativeQuery, OscarWildePoem.class );
		query.setParameter( 0, id );
		query.setParameter( 1, author );
		OscarWildePoem result = (OscarWildePoem) query.getSingleResult();
		assertAreEquals( portia, result );

		em.getTransaction().commit();
	}

	private void persist(Object... entities) {
		EntityManager em = createEntityManager();
		em.getTransaction().begin();
		for ( Object object : entities ) {
			em.persist( object );
		}
		em.getTransaction().commit();
		em.clear();
	}

	private void assertAreEquals(OscarWildePoem expectedPoem, OscarWildePoem poem) {
		assertThat( poem ).isNotNull();
		assertThat( poem.getId() ).as( "Wrong Id" ).isEqualTo( expectedPoem.getId() );
		assertThat( poem.getName() ).as( "Wrong Name" ).isEqualTo( expectedPoem.getName() );
		assertThat( poem.getAuthor() ).as( "Wrong Author" ).isEqualTo( expectedPoem.getAuthor() );
	}
{'fraction_non_alphanumeric': 0.13586332635559456, 'fraction_numerical': 0.00857586602741576, 'mean_word_length': 4.9935248887090244, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, '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': '2776262', 'n_tokens_mistral': 5075, 'n_tokens_neox': 4646, 'n_words': 1154}