Search in sources :

Example 1 with SessionFactory

use of com.mysql.cj.xdevapi.SessionFactory in project aws-mysql-jdbc by awslabs.

the class DevApiSample method main.

public static void main(String[] args) {
    Session session = new SessionFactory().getSession("mysqlx://localhost:33060/test?user=user&password=password1234");
    System.err.println("Connected!");
    Schema schema = session.getDefaultSchema();
    System.err.println("Default schema is: " + schema);
    documentWalkthrough(schema);
}
Also used : SessionFactory(com.mysql.cj.xdevapi.SessionFactory) Schema(com.mysql.cj.xdevapi.Schema) Session(com.mysql.cj.xdevapi.Session)

Example 2 with SessionFactory

use of com.mysql.cj.xdevapi.SessionFactory in project aws-mysql-jdbc by awslabs.

the class SessionTest method urlWithoutDefaultSchema.

@Test
public void urlWithoutDefaultSchema() {
    try {
        // Create user with mysql_native_password authentication plugin as it can be used with any of the authentication mechanisms.
        this.session.sql("CREATE USER IF NOT EXISTS 'testUserN'@'%' IDENTIFIED WITH mysql_native_password BY 'testUserN'").execute();
        this.session.sql("GRANT SELECT ON *.* TO 'testUserN'@'%'").execute();
        final SessionFactory testSessionFactory = new SessionFactory();
        final String testUriPattern1 = "mysqlx://testUserN:testUserN@%s:%s/?xdevapi.auth=%s";
        final String testUriPattern2 = "mysqlx://testUserN:testUserN@%s:%s?xdevapi.auth=%s";
        final String testUriPattern3 = "mysqlx://testUserN:testUserN@address=(host=%s)(port=%s)(xdevapi.auth=%s)";
        // Check if not setting a default schema works correctly when using different authentication mechanisms.
        String[] authMechs = mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.4")) ? new String[] { "PLAIN", "MYSQL41", "SHA256_MEMORY" } : new String[] { "PLAIN", "MYSQL41" };
        for (String authMech : authMechs) {
            for (String testUriPattern : new String[] { testUriPattern1, testUriPattern2, testUriPattern3 }) {
                // Test using a connection String.
                final String testUri = String.format(testUriPattern, getTestHost(), getTestPort(), authMech);
                final String testCase = "Testing no default schema with authentication mecanism '" + authMech + "' and URI '" + testUri + "'.";
                Session testSession = testSessionFactory.getSession(testUri);
                assertTrue(testSession.getUri().contains("/?"), testCase);
                assertEquals("", testSession.getDefaultSchemaName(), testCase);
                assertNull(testSession.getDefaultSchema(), testCase);
                assertNull(testSession.sql("SELECT database()").execute().fetchOne().getString(0), testCase);
                testSession.close();
            }
            // Test using a properties map.
            final String testCase = "Testing no default schema with authentication mecanism '" + authMech + "'.";
            final Properties testProps = new Properties();
            testProps.setProperty(PropertyKey.USER.getKeyName(), "testUserN");
            testProps.setProperty(PropertyKey.PASSWORD.getKeyName(), "testUserN");
            testProps.setProperty(PropertyKey.HOST.getKeyName(), getTestHost());
            testProps.setProperty(PropertyKey.PORT.getKeyName(), String.valueOf(getTestPort()));
            testProps.setProperty(PropertyKey.xdevapiAuth.getKeyName(), authMech);
            Session testSession = testSessionFactory.getSession(testProps);
            assertTrue(testSession.getUri().contains("/?"), testCase);
            assertEquals("", testSession.getDefaultSchemaName(), testCase);
            assertNull(testSession.getDefaultSchema(), testCase);
            assertNull(testSession.sql("SELECT database()").execute().fetchOne().getString(0), testCase);
            testSession.close();
        }
    } finally {
        this.session.sql("DROP USER IF EXISTS testUserN").execute();
    }
}
Also used : SessionFactory(com.mysql.cj.xdevapi.SessionFactory) JsonString(com.mysql.cj.xdevapi.JsonString) Properties(java.util.Properties) CoreSession(com.mysql.cj.CoreSession) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 3 with SessionFactory

use of com.mysql.cj.xdevapi.SessionFactory in project aws-mysql-jdbc by awslabs.

the class SessionTest method testPreparedStatementsCleanup.

@Test
public void testPreparedStatementsCleanup() {
    assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.14")), "MySQL 8.0.14+ is required to run this test.");
    try {
        // Prepare test data.
        this.schema.createCollection("testPrepStmtClean", true).add("{\"_id\":\"1\"}").execute();
        SessionFactory sf = new SessionFactory();
        /*
             * Test common usage.
             */
        Session testSession = sf.getSession(this.testProperties);
        int sessionThreadId = getThreadId(testSession);
        assertPreparedStatementsCount(sessionThreadId, 0, 1);
        assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
        // Initialize several *Statement objects.
        FindStatement testFind1 = testSession.getDefaultSchema().getCollection("testPrepStmtClean").find();
        SelectStatement testSelect1 = testSession.getDefaultSchema().getCollectionAsTable("testPrepStmtClean").select("_id");
        FindStatement testFind2 = testSession.getDefaultSchema().getCollection("testPrepStmtClean").find();
        SelectStatement testSelect2 = testSession.getDefaultSchema().getCollectionAsTable("testPrepStmtClean").select("_id");
        // 1st execute -> don't prepare.
        testFind1.execute();
        assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
        testSelect1.execute();
        assertPreparedStatementsCountsAndId(testSession, 0, testSelect1, 0, -1);
        testFind2.execute();
        assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
        testSelect2.execute();
        assertPreparedStatementsCountsAndId(testSession, 0, testSelect2, 0, -1);
        assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
        // 2nd execute -> prepare + execute.
        testFind1.execute();
        assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
        testSelect1.execute();
        assertPreparedStatementsCountsAndId(testSession, 2, testSelect1, 2, 1);
        testFind2.execute();
        assertPreparedStatementsCountsAndId(testSession, 3, testFind2, 3, 1);
        testSelect2.execute();
        assertPreparedStatementsCountsAndId(testSession, 4, testSelect2, 4, 1);
        assertPreparedStatementsStatusCounts(testSession, 4, 4, 0);
        assertPreparedStatementsCount(sessionThreadId, 4, 1);
        /*
             * The following verifications are non-deterministic as System.gc() only hints the JVM to perform a garbage collection. This approach allows some
             * time for the JVM to execute the GC. In case of failure the repeats or wait times may have to be adjusted.
             * The test can be deleted entirely if no reasonable setup can be found.
             */
        // Nullify first statement.
        testFind1 = null;
        System.gc();
        int psCount, countdown = 10;
        do {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            testSession.sql("SELECT 1").execute();
            psCount = getPreparedStatementsCount(sessionThreadId);
        } while (psCount != 3 && --countdown > 0);
        assertPreparedStatementsStatusCounts(testSession, 4, 4, 1);
        assertPreparedStatementsCount(sessionThreadId, 3, 1);
        // Nullify second and third statements.
        testSelect1 = null;
        testFind2 = null;
        System.gc();
        countdown = 10;
        do {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            testSession.sql("SELECT 1").execute();
            psCount = getPreparedStatementsCount(sessionThreadId);
        } while (psCount != 1 && --countdown > 0);
        assertPreparedStatementsStatusCounts(testSession, 4, 4, 3);
        assertPreparedStatementsCount(sessionThreadId, 1, 1);
        // Nullify last statement.
        testSelect2 = null;
        System.gc();
        countdown = 10;
        do {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            testSession.sql("SELECT 1").execute();
            psCount = getPreparedStatementsCount(sessionThreadId);
        } while (psCount != 0 && --countdown > 0);
        assertPreparedStatementsStatusCounts(testSession, 4, 4, 4);
        assertPreparedStatementsCount(sessionThreadId, 0, 1);
        testSession.close();
        assertPreparedStatementsCount(sessionThreadId, 0, 1);
    } finally {
        this.schema.dropCollection("testPrepStmtClean");
    }
}
Also used : SessionFactory(com.mysql.cj.xdevapi.SessionFactory) SelectStatement(com.mysql.cj.xdevapi.SelectStatement) FindStatement(com.mysql.cj.xdevapi.FindStatement) CoreSession(com.mysql.cj.CoreSession) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 4 with SessionFactory

use of com.mysql.cj.xdevapi.SessionFactory in project aws-mysql-jdbc by awslabs.

the class CollectionFindTest method testCollectionRowLockOptions.

@Test
public void testCollectionRowLockOptions() throws Exception {
    assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.5")), "MySQL 8.0.5+ is required to run this test.");
    Function<DocResult, List<String>> asStringList = rr -> rr.fetchAll().stream().map(d -> ((JsonString) d.get("_id")).getString()).collect(Collectors.toList());
    this.collection.add("{\"_id\":\"1\", \"a\":1}").add("{\"_id\":\"2\", \"a\":1}").add("{\"_id\":\"3\", \"a\":1}").execute();
    Session session1 = null;
    Session session2 = null;
    try {
        session1 = new SessionFactory().getSession(this.testProperties);
        Collection col1 = session1.getDefaultSchema().getCollection(this.collectionName);
        session2 = new SessionFactory().getSession(this.testProperties);
        Collection col2 = session2.getDefaultSchema().getCollection(this.collectionName);
        DocResult res;
        CompletableFuture<DocResult> futRes;
        /*
             * 1. Shared Lock in both sessions.
             */
        // session2.lockShared() returns data immediately.
        session1.startTransaction();
        col1.find("_id = '1'").lockShared().execute();
        session2.startTransaction();
        res = col2.find("_id < '3'").lockShared().execute();
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), hasItems("1", "2"));
        session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockShared().executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("1", "2"));
        session2.rollback();
        session1.rollback();
        // session2.lockShared(NOWAIT) returns data immediately.
        session1.startTransaction();
        col1.find("_id = '1'").lockShared().execute();
        session2.startTransaction();
        res = col2.find("_id < '3'").lockShared(Statement.LockContention.NOWAIT).execute();
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("1", "2"));
        session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockShared(Statement.LockContention.NOWAIT).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("1", "2"));
        session2.rollback();
        session1.rollback();
        // session2.lockShared(SKIP_LOCK) returns data immediately.
        session1.startTransaction();
        col1.find("_id = '1'").lockShared().execute();
        session2.startTransaction();
        res = col2.find("_id < '3'").lockShared(Statement.LockContention.SKIP_LOCKED).execute();
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("1", "2"));
        session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockShared(Statement.LockContention.SKIP_LOCKED).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("1", "2"));
        session2.rollback();
        session1.rollback();
        /*
             * 2. Shared Lock in first session and exclusive lock in second.
             */
        // session2.lockExclusive() blocks until session1 ends.
        session1.startTransaction();
        col1.find("_id = '1'").lockShared().execute();
        // session2.startTransaction();
        // res = col2.find("_id < '3'").lockExclusive().execute(); (Can't test)
        // session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockExclusive().executeAsync();
        final CompletableFuture<DocResult> fr1 = futRes;
        assertThrows(TimeoutException.class, () -> fr1.get(3, TimeUnit.SECONDS));
        // Unlocks session2.
        session1.rollback();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("1", "2"));
        session2.rollback();
        // session2.lockExclusive(NOWAIT) should return locking error.
        session1.startTransaction();
        col1.find("_id = '1'").lockShared().execute();
        session2.startTransaction();
        assertThrows(XProtocolError.class, "ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> col2.find("_id < '3'").lockExclusive(Statement.LockContention.NOWAIT).execute());
        session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockExclusive(Statement.LockContention.NOWAIT).executeAsync();
        final CompletableFuture<DocResult> fr2 = futRes;
        assertThrows(ExecutionException.class, ".*XProtocolError: ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> fr2.get(3, TimeUnit.SECONDS));
        session2.rollback();
        session1.rollback();
        // session2.lockExclusive(SKIP_LOCK) should return (unlocked) data immediately.
        session1.startTransaction();
        col1.find("_id = '1'").lockShared().execute();
        session2.startTransaction();
        res = col2.find("_id < '3'").lockExclusive(Statement.LockContention.SKIP_LOCKED).execute();
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("2"));
        session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockExclusive(Statement.LockContention.SKIP_LOCKED).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("2"));
        session2.rollback();
        session1.rollback();
        /*
             * 3. Exclusive Lock in first session and shared lock in second.
             */
        // session2.lockShared() blocks until session1 ends.
        session1.startTransaction();
        col1.find("_id = '1'").lockExclusive().execute();
        // session2.startTransaction();
        // res = col2.find("_id < '3'").lockShared().execute(); (Can't test)
        // session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockShared().executeAsync();
        final CompletableFuture<DocResult> fr3 = futRes;
        assertThrows(TimeoutException.class, () -> fr3.get(3, TimeUnit.SECONDS));
        // Unlocks session2.
        session1.rollback();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("1", "2"));
        session2.rollback();
        // session2.lockShared(NOWAIT) should return locking error.
        session1.startTransaction();
        col1.find("_id = '1'").lockExclusive().execute();
        session2.startTransaction();
        assertThrows(XProtocolError.class, "ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> col2.find("_id < '3'").lockShared(Statement.LockContention.NOWAIT).execute());
        session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockShared(Statement.LockContention.NOWAIT).executeAsync();
        final CompletableFuture<DocResult> fr4 = futRes;
        assertThrows(ExecutionException.class, ".*XProtocolError: ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> fr4.get(3, TimeUnit.SECONDS));
        session2.rollback();
        session1.rollback();
        // session2.lockShared(SKIP_LOCK) should return (unlocked) data immediately.
        session1.startTransaction();
        col1.find("_id = '1'").lockExclusive().execute();
        session2.startTransaction();
        res = col2.find("_id < '3'").lockShared(Statement.LockContention.SKIP_LOCKED).execute();
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("2"));
        session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockShared(Statement.LockContention.SKIP_LOCKED).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("2"));
        session2.rollback();
        session1.rollback();
        /*
             * 4. Exclusive Lock in both sessions.
             */
        // session2.lockExclusive() blocks until session1 ends.
        session1.startTransaction();
        col1.find("_id = '1'").lockExclusive().execute();
        // session2.startTransaction();
        // res = col2.find("_id < '3'").lockExclusive().execute(); (Can't test)
        // session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockExclusive().executeAsync();
        final CompletableFuture<DocResult> fr5 = futRes;
        assertThrows(TimeoutException.class, () -> fr5.get(3, TimeUnit.SECONDS));
        // Unlocks session2.
        session1.rollback();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(2, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("1", "2"));
        session2.rollback();
        // session2.lockExclusive(NOWAIT) should return locking error.
        session1.startTransaction();
        col1.find("_id = '1'").lockExclusive().execute();
        session2.startTransaction();
        assertThrows(XProtocolError.class, "ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> col2.find("_id < '3'").lockExclusive(Statement.LockContention.NOWAIT).execute());
        session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockExclusive(Statement.LockContention.NOWAIT).executeAsync();
        final CompletableFuture<DocResult> fr6 = futRes;
        assertThrows(ExecutionException.class, ".*XProtocolError: ERROR 3572 \\(HY000\\) Statement aborted because lock\\(s\\) could not be acquired immediately and NOWAIT is set\\.", () -> fr6.get(3, TimeUnit.SECONDS));
        session2.rollback();
        session1.rollback();
        // session2.lockExclusive(SKIP_LOCK) should return (unlocked) data immediately.
        session1.startTransaction();
        col1.find("_id = '1'").lockExclusive().execute();
        session2.startTransaction();
        res = col2.find("_id < '3'").lockExclusive(Statement.LockContention.SKIP_LOCKED).execute();
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("2"));
        session2.rollback();
        session2.startTransaction();
        futRes = col2.find("_id < '3'").lockExclusive(Statement.LockContention.SKIP_LOCKED).executeAsync();
        res = futRes.get(3, TimeUnit.SECONDS);
        assertTrue(futRes.isDone());
        assertEquals(1, asStringList.apply(res).size());
        assertThat(asStringList.apply(res), CoreMatchers.hasItems("2"));
        session2.rollback();
        session1.rollback();
    } finally {
        if (session1 != null) {
            session1.close();
        }
        if (session2 != null) {
            session2.close();
        }
    }
}
Also used : CoreMatchers(org.hamcrest.CoreMatchers) RowResult(com.mysql.cj.xdevapi.RowResult) JsonNumber(com.mysql.cj.xdevapi.JsonNumber) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) TimeoutException(java.util.concurrent.TimeoutException) Collection(com.mysql.cj.xdevapi.Collection) Statement(com.mysql.cj.xdevapi.Statement) BigDecimal(java.math.BigDecimal) Expression.expr(com.mysql.cj.xdevapi.Expression.expr) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) FindStatementImpl(com.mysql.cj.xdevapi.FindStatementImpl) Map(java.util.Map) Table(com.mysql.cj.xdevapi.Table) ServerVersion(com.mysql.cj.ServerVersion) WrongArgumentException(com.mysql.cj.exceptions.WrongArgumentException) Warning(com.mysql.cj.xdevapi.Warning) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) List(java.util.List) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) FindStatement(com.mysql.cj.xdevapi.FindStatement) Assertions.fail(org.junit.jupiter.api.Assertions.fail) MysqlErrorNumbers(com.mysql.cj.exceptions.MysqlErrorNumbers) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Result(com.mysql.cj.xdevapi.Result) DbDocImpl(com.mysql.cj.xdevapi.DbDocImpl) JsonArray(com.mysql.cj.xdevapi.JsonArray) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) HashMap(java.util.HashMap) Callable(java.util.concurrent.Callable) CompletableFuture(java.util.concurrent.CompletableFuture) JsonString(com.mysql.cj.xdevapi.JsonString) Function(java.util.function.Function) ArrayList(java.util.ArrayList) AddResult(com.mysql.cj.xdevapi.AddResult) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) SessionImpl(com.mysql.cj.xdevapi.SessionImpl) Session(com.mysql.cj.xdevapi.Session) Iterator(java.util.Iterator) CoreMatchers.hasItems(org.hamcrest.CoreMatchers.hasItems) DbDoc(com.mysql.cj.xdevapi.DbDoc) DocResult(com.mysql.cj.xdevapi.DocResult) XProtocolError(com.mysql.cj.protocol.x.XProtocolError) SessionFactory(com.mysql.cj.xdevapi.SessionFactory) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Row(com.mysql.cj.xdevapi.Row) SqlResult(com.mysql.cj.xdevapi.SqlResult) JsonLiteral(com.mysql.cj.xdevapi.JsonLiteral) SessionFactory(com.mysql.cj.xdevapi.SessionFactory) Collection(com.mysql.cj.xdevapi.Collection) List(java.util.List) ArrayList(java.util.ArrayList) JsonString(com.mysql.cj.xdevapi.JsonString) DocResult(com.mysql.cj.xdevapi.DocResult) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Example 5 with SessionFactory

use of com.mysql.cj.xdevapi.SessionFactory in project aws-mysql-jdbc by awslabs.

the class CollectionFindTest method testPreparedStatements.

@Test
public void testPreparedStatements() {
    assumeTrue(mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.14")), "MySQL 8.0.14+ is required to run this test.");
    // Prepare test data.
    this.collection.add("{\"_id\":\"1\", \"ord\": 1}", "{\"_id\":\"2\", \"ord\": 2}", "{\"_id\":\"3\", \"ord\": 3}", "{\"_id\":\"4\", \"ord\": 4}", "{\"_id\":\"5\", \"ord\": 5}", "{\"_id\":\"6\", \"ord\": 6}", "{\"_id\":\"7\", \"ord\": 7}", "{\"_id\":\"8\", \"ord\": 8}").execute();
    SessionFactory sf = new SessionFactory();
    /*
         * Test common usage.
         */
    Session testSession = sf.getSession(this.testProperties);
    int sessionThreadId = getThreadId(testSession);
    assertPreparedStatementsCount(sessionThreadId, 0, 1);
    assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
    Collection testCol = testSession.getDefaultSchema().getCollection(this.collectionName);
    // Initialize several FindStatement objects.
    // Find all.
    FindStatement testFind1 = testCol.find();
    // Criteria with one placeholder.
    FindStatement testFind2 = testCol.find("$.ord >= :n");
    // Criteria with same placeholder repeated.
    FindStatement testFind3 = testCol.find("$.ord >= :n AND $.ord <= :n + 3");
    // Criteria with multiple placeholders.
    FindStatement testFind4 = testCol.find("$.ord >= :n AND $.ord <= :m");
    assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind3, 0, -1);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
    assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
    // A. Set binds: 1st execute -> non-prepared.
    assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
    assertTestPreparedStatementsResult(testFind2.bind("n", 2).execute(), 2, 8);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
    assertTestPreparedStatementsResult(testFind3.bind("n", 2).execute(), 2, 5);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind3, 0, -1);
    assertTestPreparedStatementsResult(testFind4.bind("n", 2).bind("m", 5).execute(), 2, 5);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
    assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
    // B. Set sort resets execution count: 1st execute -> non-prepared.
    assertTestPreparedStatementsResult(testFind1.sort("$._id").execute(), 1, 8);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
    assertTestPreparedStatementsResult(testFind2.sort("$._id").execute(), 2, 8);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
    assertTestPreparedStatementsResult(testFind3.sort("$._id").execute(), 2, 5);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind3, 0, -1);
    assertTestPreparedStatementsResult(testFind4.sort("$._id").execute(), 2, 5);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
    assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
    // C. Set binds reuse statement: 2nd execute -> prepare + execute.
    assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
    assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
    assertTestPreparedStatementsResult(testFind2.bind("n", 3).execute(), 3, 8);
    assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 2, 1);
    assertTestPreparedStatementsResult(testFind3.bind("n", 3).execute(), 3, 6);
    assertPreparedStatementsCountsAndId(testSession, 3, testFind3, 3, 1);
    assertTestPreparedStatementsResult(testFind4.bind("m", 6).execute(), 2, 6);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 1);
    assertPreparedStatementsStatusCounts(testSession, 4, 4, 0);
    // D. Set binds reuse statement: 3rd execute -> execute.
    assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind1, 1, 2);
    assertTestPreparedStatementsResult(testFind2.bind("n", 4).execute(), 4, 8);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind2, 2, 2);
    assertTestPreparedStatementsResult(testFind3.bind("n", 4).execute(), 4, 7);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind3, 3, 2);
    assertTestPreparedStatementsResult(testFind4.bind("n", 3).bind("m", 7).execute(), 3, 7);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 2);
    assertPreparedStatementsStatusCounts(testSession, 4, 8, 0);
    // E. Set sort deallocates and resets execution count: 1st execute -> deallocate + non-prepared.
    assertTestPreparedStatementsResult(testFind1.sort("$._id").execute(), 1, 8);
    assertPreparedStatementsCountsAndId(testSession, 3, testFind1, 0, -1);
    assertTestPreparedStatementsResult(testFind2.sort("$._id").bind("n", 4).execute(), 4, 8);
    assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 0, -1);
    assertTestPreparedStatementsResult(testFind3.sort("$._id").bind("n", 4).execute(), 4, 7);
    assertPreparedStatementsCountsAndId(testSession, 1, testFind3, 0, -1);
    assertTestPreparedStatementsResult(testFind4.sort("$._id").bind("n", 3).bind("m", 7).execute(), 3, 7);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
    assertPreparedStatementsStatusCounts(testSession, 4, 8, 4);
    // F. No Changes: 2nd execute -> prepare + execute.
    assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
    assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
    assertTestPreparedStatementsResult(testFind2.bind("n", 4).execute(), 4, 8);
    assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 2, 1);
    assertTestPreparedStatementsResult(testFind3.bind("n", 4).execute(), 4, 7);
    assertPreparedStatementsCountsAndId(testSession, 3, testFind3, 3, 1);
    assertTestPreparedStatementsResult(testFind4.bind("n", 3).bind("m", 7).execute(), 3, 7);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 1);
    assertPreparedStatementsStatusCounts(testSession, 8, 12, 4);
    // G. Set limit for the first time deallocates and re-prepares: 1st execute -> re-prepare + execute.
    assertTestPreparedStatementsResult(testFind1.limit(2).execute(), 1, 2);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind1, 1, 1);
    assertTestPreparedStatementsResult(testFind2.limit(2).execute(), 4, 5);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind2, 2, 1);
    assertTestPreparedStatementsResult(testFind3.limit(2).execute(), 4, 5);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind3, 3, 1);
    assertTestPreparedStatementsResult(testFind4.limit(2).execute(), 3, 4);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 1);
    assertPreparedStatementsStatusCounts(testSession, 12, 16, 8);
    // H. Set limit and offset reuse prepared statement: 2nd execute -> execute.
    assertTestPreparedStatementsResult(testFind1.limit(1).offset(1).execute(), 2, 2);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind1, 1, 2);
    assertTestPreparedStatementsResult(testFind2.limit(1).offset(1).execute(), 5, 5);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind2, 2, 2);
    assertTestPreparedStatementsResult(testFind3.limit(1).offset(1).execute(), 5, 5);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind3, 3, 2);
    assertTestPreparedStatementsResult(testFind4.limit(1).offset(1).execute(), 4, 4);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 2);
    assertPreparedStatementsStatusCounts(testSession, 12, 20, 8);
    // I. Set sort deallocates and resets execution count, set limit and bind has no effect: 1st execute -> deallocate + non-prepared.
    assertTestPreparedStatementsResult(testFind1.sort("$._id").limit(2).execute(), 2, 3);
    assertPreparedStatementsCountsAndId(testSession, 3, testFind1, 0, -1);
    assertTestPreparedStatementsResult(testFind2.sort("$._id").limit(2).bind("n", 4).execute(), 5, 6);
    assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 0, -1);
    assertTestPreparedStatementsResult(testFind3.sort("$._id").limit(2).bind("n", 4).execute(), 5, 6);
    assertPreparedStatementsCountsAndId(testSession, 1, testFind3, 0, -1);
    assertTestPreparedStatementsResult(testFind4.sort("$._id").limit(2).bind("n", 3).bind("m", 7).execute(), 4, 5);
    assertPreparedStatementsCountsAndId(testSession, 0, testFind4, 0, -1);
    assertPreparedStatementsStatusCounts(testSession, 12, 20, 12);
    // J. Set offset reuse statement: 2nd execute -> prepare + execute.
    assertTestPreparedStatementsResult(testFind1.offset(0).execute(), 1, 2);
    assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
    assertTestPreparedStatementsResult(testFind2.offset(0).execute(), 4, 5);
    assertPreparedStatementsCountsAndId(testSession, 2, testFind2, 2, 1);
    assertTestPreparedStatementsResult(testFind3.offset(0).execute(), 4, 5);
    assertPreparedStatementsCountsAndId(testSession, 3, testFind3, 3, 1);
    assertTestPreparedStatementsResult(testFind4.offset(0).execute(), 3, 4);
    assertPreparedStatementsCountsAndId(testSession, 4, testFind4, 4, 1);
    assertPreparedStatementsStatusCounts(testSession, 16, 24, 12);
    testSession.close();
    // Prepared statements won't live past the closing of the session.
    assertPreparedStatementsCount(sessionThreadId, 0, 10);
    /*
         * Test falling back onto non-prepared statements.
         */
    testSession = sf.getSession(this.testProperties);
    int origMaxPrepStmtCount = this.session.sql("SELECT @@max_prepared_stmt_count").execute().fetchOne().getInt(0);
    try {
        // Allow preparing only one more statement.
        this.session.sql("SET GLOBAL max_prepared_stmt_count = ?").bind(getPreparedStatementsCount() + 1).execute();
        sessionThreadId = getThreadId(testSession);
        assertPreparedStatementsCount(sessionThreadId, 0, 1);
        assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
        testCol = testSession.getDefaultSchema().getCollection(this.collectionName);
        testFind1 = testCol.find();
        testFind2 = testCol.find();
        // 1st execute -> don't prepare.
        assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
        assertPreparedStatementsCountsAndId(testSession, 0, testFind1, 0, -1);
        assertTestPreparedStatementsResult(testFind2.execute(), 1, 8);
        assertPreparedStatementsCountsAndId(testSession, 0, testFind2, 0, -1);
        assertPreparedStatementsStatusCounts(testSession, 0, 0, 0);
        // 2nd execute -> prepare + execute.
        assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
        assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 1);
        // Fails preparing, execute as non-prepared.
        assertTestPreparedStatementsResult(testFind2.execute(), 1, 8);
        assertPreparedStatementsCountsAndId(testSession, 1, testFind2, 0, -1);
        // Failed prepare also counts.
        assertPreparedStatementsStatusCounts(testSession, 2, 1, 0);
        // 3rd execute -> execute.
        assertTestPreparedStatementsResult(testFind1.execute(), 1, 8);
        assertPreparedStatementsCountsAndId(testSession, 1, testFind1, 1, 2);
        // Execute as non-prepared.
        assertTestPreparedStatementsResult(testFind2.execute(), 1, 8);
        assertPreparedStatementsCountsAndId(testSession, 1, testFind2, 0, -1);
        assertPreparedStatementsStatusCounts(testSession, 2, 2, 0);
        testSession.close();
        // Prepared statements won't live past the closing of the session.
        assertPreparedStatementsCount(sessionThreadId, 0, 10);
    } finally {
        this.session.sql("SET GLOBAL max_prepared_stmt_count = ?").bind(origMaxPrepStmtCount).execute();
    }
}
Also used : SessionFactory(com.mysql.cj.xdevapi.SessionFactory) FindStatement(com.mysql.cj.xdevapi.FindStatement) Collection(com.mysql.cj.xdevapi.Collection) Session(com.mysql.cj.xdevapi.Session) Test(org.junit.jupiter.api.Test)

Aggregations

SessionFactory (com.mysql.cj.xdevapi.SessionFactory)37 Session (com.mysql.cj.xdevapi.Session)35 Test (org.junit.jupiter.api.Test)33 JsonString (com.mysql.cj.xdevapi.JsonString)23 Collection (com.mysql.cj.xdevapi.Collection)21 ExecutionException (java.util.concurrent.ExecutionException)20 WrongArgumentException (com.mysql.cj.exceptions.WrongArgumentException)17 Schema (com.mysql.cj.xdevapi.Schema)16 DocResult (com.mysql.cj.xdevapi.DocResult)8 CoreSession (com.mysql.cj.CoreSession)7 Table (com.mysql.cj.xdevapi.Table)7 DbDoc (com.mysql.cj.xdevapi.DbDoc)6 Row (com.mysql.cj.xdevapi.Row)6 SqlResult (com.mysql.cj.xdevapi.SqlResult)6 RowResult (com.mysql.cj.xdevapi.RowResult)4 SessionImpl (com.mysql.cj.xdevapi.SessionImpl)4 Properties (java.util.Properties)4 DbDocImpl (com.mysql.cj.xdevapi.DbDocImpl)3 FindStatement (com.mysql.cj.xdevapi.FindStatement)3 SelectStatement (com.mysql.cj.xdevapi.SelectStatement)3