diff --git a/.ci/e2e-expected/backslash-dt.txt b/.ci/e2e-expected/backslash-dt.txt index 35c3ccfa7..c795abd69 100644 --- a/.ci/e2e-expected/backslash-dt.txt +++ b/.ci/e2e-expected/backslash-dt.txt @@ -72,11 +72,12 @@ testdb_e2e_psql_v?? | spanner_sys | table_operations_stats_hour | VIEW | | | | | | | | | | | | | testdb_e2e_psql_v?? | spanner_sys | table_operations_stats_minute | VIEW | | | | | | | | | | | | | testdb_e2e_psql_v?? | spanner_sys | table_sizes_stats_1hour | VIEW | | | | | | | | | | | | | + testdb_e2e_psql_v?? | spanner_sys | tasks | VIEW | | | | | | | | | | | | | testdb_e2e_psql_v?? | spanner_sys | txn_stats_top_10minute | VIEW | | | | | | | | | | | | | testdb_e2e_psql_v?? | spanner_sys | txn_stats_top_hour | VIEW | | | | | | | | | | | | | testdb_e2e_psql_v?? | spanner_sys | txn_stats_top_minute | VIEW | | | | | | | | | | | | | testdb_e2e_psql_v?? | spanner_sys | txn_stats_total_10minute | VIEW | | | | | | | | | | | | | testdb_e2e_psql_v?? | spanner_sys | txn_stats_total_hour | VIEW | | | | | | | | | | | | | testdb_e2e_psql_v?? | spanner_sys | txn_stats_total_minute | VIEW | | | | | | | | | | | | | -(77 rows) +(78 rows) diff --git a/README.md b/README.md index 5fe3d8255..4de81bd9b 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ PGAdapter can be used with the following drivers and clients: 1. `psql`: Versions 11, 12, 13 and 14 are supported. See [psql support](docs/psql.md) for more details. 1. `IntelliJ`, `DataGrip` and other `JetBrains` IDEs. See [Connect Cloud Spanner PostgreSQL to JetBrains](docs/intellij.md) for more details. 1. `JDBC`: Versions 42.x and higher are supported. See [JDBC support](docs/jdbc.md) for more details. +1. `R2DBC`: Versions 1.0.7 and higher are supported. See [R2DBC sample](samples/java/r2dbc) for a small sample application. 1. `pgx`: Version 4.15 and higher are supported. See [pgx support](docs/pgx.md) for more details. 1. `psycopg2`: Version 2.9.3 and higher are supported. See [psycopg2](docs/psycopg2.md) for more details. 1. `psycopg3`: Version 3.1.x and higher are supported. See [psycopg3 support](docs/psycopg3.md) for more details. diff --git a/src/test/java/com/google/cloud/spanner/pgadapter/csharp/ITNpgsqlTest.java b/src/test/java/com/google/cloud/spanner/pgadapter/csharp/ITNpgsqlTest.java index 4eeb970d7..9581dcdc5 100644 --- a/src/test/java/com/google/cloud/spanner/pgadapter/csharp/ITNpgsqlTest.java +++ b/src/test/java/com/google/cloud/spanner/pgadapter/csharp/ITNpgsqlTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import com.google.cloud.ByteArray; @@ -157,34 +158,39 @@ public void clearTestData() { databaseId, Collections.singletonList(Mutation.delete("all_types", KeySet.all()))); } + static void assertEqualsIgnoreControlCharacters(String expected, String actual) { + assertNotNull(actual); + assertTrue("Expected: %s\n" + " Got: %s\n", actual.endsWith(expected)); + } + @Test public void testShowServerVersion() throws IOException, InterruptedException { String result = execute("TestShowServerVersion", createConnectionString()); - assertEquals("14.1\n", result); + assertEqualsIgnoreControlCharacters("14.1\n", result); } @Test public void testSelect1() throws IOException, InterruptedException { String result = execute("TestSelect1", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); } @Test public void testSelectArray() throws IOException, InterruptedException { String result = execute("TestSelectArray", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); } @Test public void testQueryAllDataTypes() throws IOException, InterruptedException { String result = execute("TestQueryAllDataTypes", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); } @Test public void testUpdateAllDataTypes() throws IOException, InterruptedException { String result = execute("TestUpdateAllDataTypes", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); } @Test @@ -195,7 +201,7 @@ public void testInsertAllDataTypes() throws IOException, InterruptedException { databaseId, Collections.singletonList(Mutation.delete("all_types", Key.of(100L)))); String result = execute("TestInsertAllDataTypes", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); } @Test @@ -206,7 +212,7 @@ public void testInsertNullsAllDataTypes() throws IOException, InterruptedExcepti databaseId, Collections.singletonList(Mutation.delete("all_types", Key.of(100L)))); String result = execute("TestInsertNullsAllDataTypes", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); } @Test @@ -216,7 +222,7 @@ public void testInsertAllDataTypesReturning() throws IOException, InterruptedExc testEnv.write(databaseId, Collections.singletonList(Mutation.delete("all_types", Key.of(1)))); String result = execute("TestInsertAllDataTypesReturning", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); } @Test @@ -234,7 +240,7 @@ public void testInsertBatch() throws IOException, InterruptedException { } String result = execute("TestInsertBatch", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); // Verify that we really received 10 rows. final long batchSize = 10L; @@ -261,7 +267,7 @@ public void testMixedBatch() throws IOException, InterruptedException { } String result = execute("TestMixedBatch", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); final long batchSize = 5L; try (ResultSet resultSet = @@ -332,7 +338,7 @@ private void testCopyIn(String testMethod) throws IOException, InterruptedExcept databaseId, Collections.singletonList(Mutation.delete("all_types", KeySet.all()))); String result = execute(testMethod, createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); DatabaseClient client = testEnv.getSpanner().getDatabaseClient(database.getId()); try (ResultSet resultSet = @@ -372,7 +378,7 @@ public void testBinaryCopyOut() throws IOException, InterruptedException { // Add an extra NULL-row to the table. addNullRow(); String result = execute("TestBinaryCopyOut", createConnectionString()); - assertEquals( + assertEqualsIgnoreControlCharacters( "1\tTrue\tdGVzdA==\t3.14\t3.14\t100\t6.626\t20220216T131802123456\t20220329\ttest\t{\"key\": \"value\"}\t[1, , 2]\t[True, , False]\t[Ynl0ZXMx, , Ynl0ZXMy]\t[3.14, , -99.99]\t[3.14, , -99.99]\t[-100, , -200]\t[6.626, , -3.14]\t[20220216T161802123456, , 20000101T000000]\t[20230220, , 20000101]\t[string1, , string2]\t[{\"key\": \"value1\"}, , {\"key\": \"value2\"}]\n" + "2\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\tNULL\n" + "Success\n", @@ -384,7 +390,7 @@ public void testTextCopyOut() throws IOException, InterruptedException { // Add an extra NULL-row to the table. addNullRow(); String result = execute("TestTextCopyOut", createConnectionString()); - assertEquals( + assertEqualsIgnoreControlCharacters( "1\tt\t\\\\x74657374\t3.14\t3.14\t100\t6.626\t2022-02-16 14:18:02.123456+01\t2022-03-29\ttest\t{\"key\": \"value\"}\t{1,NULL,2}\t{t,NULL,f}\t{\"\\\\\\\\x627974657331\",NULL,\"\\\\\\\\x627974657332\"}\t{3.14,NULL,-99.99}\t{3.14,NULL,-99.99}\t{-100,NULL,-200}\t{6.626,NULL,-3.14}\t{\"2022-02-16 17:18:02.123456+01\",NULL,\"2000-01-01 01:00:00+01\"}\t{\"2023-02-20\",NULL,\"2000-01-01\"}\t{\"string1\",NULL,\"string2\"}\t{\"{\\\\\"key\\\\\": \\\\\"value1\\\\\"}\",NULL,\"{\\\\\"key\\\\\": \\\\\"value2\\\\\"}\"}\n" + "2\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\t\\N\n" + "Success\n", @@ -447,19 +453,19 @@ private void addNullRow() { @Test public void testSimplePrepare() throws IOException, InterruptedException { String result = execute("TestSimplePrepare", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); } @Test public void testPrepareAndExecute() throws IOException, InterruptedException { String result = execute("TestPrepareAndExecute", createConnectionString()); - assertEquals("Success\n", result); + assertEqualsIgnoreControlCharacters("Success\n", result); } @Test public void testReadWriteTransaction() throws IOException, InterruptedException { String result = execute("TestReadWriteTransaction", createConnectionString()); - assertEquals("Row: 1\n" + "Success\n", result); + assertEqualsIgnoreControlCharacters("Row: 1\n" + "Success\n", result); DatabaseClient client = testEnv.getSpanner().getDatabaseClient(database.getId()); try (ResultSet resultSet = client.singleUse().executeQuery(Statement.of("SELECT COUNT(*) FROM all_types"))) { @@ -472,6 +478,6 @@ public void testReadWriteTransaction() throws IOException, InterruptedException @Test public void testReadOnlyTransaction() throws IOException, InterruptedException { String result = execute("TestReadOnlyTransaction", createConnectionString()); - assertEquals("Row: 1\n" + "Row: 2\n" + "Success\n", result); + assertEqualsIgnoreControlCharacters("Row: 1\n" + "Row: 2\n" + "Success\n", result); } }