diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 0c8fe7d..643e1d7 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -6,7 +6,7 @@ on:
- master
- develop
pull_request:
- type: [opened, reopened, edited]
+ type: [opened, reopened, edited, synchronize]
jobs:
build:
@@ -44,7 +44,7 @@ jobs:
- name: Checkout YDB Java SDK
if: ${{ env.NEED_SDK }}
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
repository: ydb-platform/ydb-java-sdk
ref: develop
@@ -61,7 +61,7 @@ jobs:
- name: Checkout YDB YC Auth Provider
if: ${{ env.NEED_SDK }}
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
repository: ydb-platform/ydb-java-yc
ref: develop
diff --git a/auth/access_token_credentials/src/main/java/tech/ydb/example/Main.java b/auth/access_token_credentials/src/main/java/tech/ydb/example/Main.java
index 0721050..fd33e59 100644
--- a/auth/access_token_credentials/src/main/java/tech/ydb/example/Main.java
+++ b/auth/access_token_credentials/src/main/java/tech/ydb/example/Main.java
@@ -1,13 +1,12 @@
package tech.ydb.example;
-import java.util.concurrent.CompletableFuture;
import tech.ydb.auth.AuthProvider;
import tech.ydb.auth.TokenAuthProvider;
-import tech.ydb.core.Result;
import tech.ydb.core.grpc.GrpcTransport;
import tech.ydb.table.SessionRetryContext;
import tech.ydb.table.TableClient;
+import tech.ydb.table.query.DataQueryResult;
import tech.ydb.table.result.ResultSetReader;
import tech.ydb.table.transaction.TxControl;
@@ -25,23 +24,20 @@ public static void main(String[] args) {
// Access token credentials
AuthProvider authProvider = new TokenAuthProvider(accessToken);
- try ( GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
- .withAuthProvider(authProvider) // Or this method could not be called at all
+ try (GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
+ .withAuthProvider(authProvider)
.build()) {
- try ( TableClient tableClient = TableClient
- .newClient(transport)
- .build()) {
+ try (TableClient tableClient = TableClient.newClient(transport).build()) {
SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build();
- retryCtx.supplyResult(session -> {
- ResultSetReader rsReader = session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
- .join().getValue().getResultSet(0);
+ DataQueryResult dataQueryResult = retryCtx.supplyResult(
+ session -> session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
+ ).join().getValue();
- rsReader.next();
+ ResultSetReader rsReader = dataQueryResult.getResultSet(0);
+ while (rsReader.next()) {
System.out.println(rsReader.getColumn(0).getInt32());
-
- return CompletableFuture.completedFuture(Result.success(Boolean.TRUE));
- }).join();
+ }
}
}
}
diff --git a/auth/anonymous_credentials/src/main/java/tech/ydb/example/Main.java b/auth/anonymous_credentials/src/main/java/tech/ydb/example/Main.java
index 243ef26..3d54e33 100644
--- a/auth/anonymous_credentials/src/main/java/tech/ydb/example/Main.java
+++ b/auth/anonymous_credentials/src/main/java/tech/ydb/example/Main.java
@@ -1,13 +1,12 @@
package tech.ydb.example;
-import java.util.concurrent.CompletableFuture;
import tech.ydb.auth.AuthProvider;
import tech.ydb.auth.NopAuthProvider;
-import tech.ydb.core.Result;
import tech.ydb.core.grpc.GrpcTransport;
import tech.ydb.table.SessionRetryContext;
import tech.ydb.table.TableClient;
+import tech.ydb.table.query.DataQueryResult;
import tech.ydb.table.result.ResultSetReader;
import tech.ydb.table.transaction.TxControl;
@@ -22,24 +21,20 @@ public static void main(String[] args) {
// Anonymous credentials
AuthProvider authProvider = NopAuthProvider.INSTANCE;
- try ( GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
- .withAuthProvider(authProvider) // Or this method could not be called at all
+ try (GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
+ .withAuthProvider(authProvider)
.build()) {
- try ( TableClient tableClient = TableClient
- .newClient(transport)
- .build()) {
-
+ try (TableClient tableClient = TableClient.newClient(transport).build()) {
SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build();
- retryCtx.supplyResult(session -> {
- ResultSetReader rsReader = session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
- .join().getValue().getResultSet(0);
+ DataQueryResult dataQueryResult = retryCtx.supplyResult(
+ session -> session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
+ ).join().getValue();
- rsReader.next();
+ ResultSetReader rsReader = dataQueryResult.getResultSet(0);
+ while (rsReader.next()) {
System.out.println(rsReader.getColumn(0).getInt32());
-
- return CompletableFuture.completedFuture(Result.success(Boolean.TRUE));
- }).join();
+ }
}
}
}
diff --git a/auth/environ/src/main/java/tech/ydb/example/Main.java b/auth/environ/src/main/java/tech/ydb/example/Main.java
index 21bfec8..3042d3e 100644
--- a/auth/environ/src/main/java/tech/ydb/example/Main.java
+++ b/auth/environ/src/main/java/tech/ydb/example/Main.java
@@ -1,13 +1,12 @@
package tech.ydb.example;
-import java.util.concurrent.CompletableFuture;
import tech.ydb.auth.AuthProvider;
import tech.ydb.auth.iam.CloudAuthHelper;
-import tech.ydb.core.Result;
import tech.ydb.core.grpc.GrpcTransport;
import tech.ydb.table.SessionRetryContext;
import tech.ydb.table.TableClient;
+import tech.ydb.table.query.DataQueryResult;
import tech.ydb.table.result.ResultSetReader;
import tech.ydb.table.transaction.TxControl;
@@ -22,24 +21,20 @@ public static void main(String[] args) {
// Construct authProvider from environment variables
AuthProvider authProvider = CloudAuthHelper.getAuthProviderFromEnviron();
- try ( GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
- .withAuthProvider(authProvider) // Or this method could not be called at all
+ try (GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
+ .withAuthProvider(authProvider)
.build()) {
- try ( TableClient tableClient = TableClient
- .newClient(transport)
- .build()) {
-
+ try (TableClient tableClient = TableClient.newClient(transport).build()) {
SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build();
- retryCtx.supplyResult(session -> {
- ResultSetReader rsReader = session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
- .join().getValue().getResultSet(0);
+ DataQueryResult dataQueryResult = retryCtx.supplyResult(
+ session -> session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
+ ).join().getValue();
- rsReader.next();
+ ResultSetReader rsReader = dataQueryResult.getResultSet(0);
+ while (rsReader.next()) {
System.out.println(rsReader.getColumn(0).getInt32());
-
- return CompletableFuture.completedFuture(Result.success(Boolean.TRUE));
- }).join();
+ }
}
}
}
diff --git a/auth/metadata_credentials/src/main/java/tech/ydb/example/Main.java b/auth/metadata_credentials/src/main/java/tech/ydb/example/Main.java
index cdbc64b..67462de 100644
--- a/auth/metadata_credentials/src/main/java/tech/ydb/example/Main.java
+++ b/auth/metadata_credentials/src/main/java/tech/ydb/example/Main.java
@@ -1,13 +1,12 @@
package tech.ydb.example;
-import java.util.concurrent.CompletableFuture;
import tech.ydb.auth.AuthProvider;
import tech.ydb.auth.iam.CloudAuthHelper;
-import tech.ydb.core.Result;
import tech.ydb.core.grpc.GrpcTransport;
import tech.ydb.table.SessionRetryContext;
import tech.ydb.table.TableClient;
+import tech.ydb.table.query.DataQueryResult;
import tech.ydb.table.result.ResultSetReader;
import tech.ydb.table.transaction.TxControl;
@@ -23,24 +22,20 @@ public static void main(String[] args) {
// Use metadata credentials
AuthProvider authProvider = CloudAuthHelper.getMetadataAuthProvider();
- try ( GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
- .withAuthProvider(authProvider) // Or this method could not be called at all
+ try (GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
+ .withAuthProvider(authProvider)
.build()) {
- try ( TableClient tableClient = TableClient
- .newClient(transport)
- .build()) {
-
+ try (TableClient tableClient = TableClient.newClient(transport).build()) {
SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build();
- retryCtx.supplyResult(session -> {
- ResultSetReader rsReader = session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
- .join().getValue().getResultSet(0);
+ DataQueryResult dataQueryResult = retryCtx.supplyResult(
+ session -> session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
+ ).join().getValue();
- rsReader.next();
+ ResultSetReader rsReader = dataQueryResult.getResultSet(0);
+ while (rsReader.next()) {
System.out.println(rsReader.getColumn(0).getInt32());
-
- return CompletableFuture.completedFuture(Result.success(Boolean.TRUE));
- }).join();
+ }
}
}
}
diff --git a/auth/service_account_credentials/src/main/java/tech/ydb/example/Main.java b/auth/service_account_credentials/src/main/java/tech/ydb/example/Main.java
index 57d88a5..8edf12e 100644
--- a/auth/service_account_credentials/src/main/java/tech/ydb/example/Main.java
+++ b/auth/service_account_credentials/src/main/java/tech/ydb/example/Main.java
@@ -1,13 +1,12 @@
package tech.ydb.example;
-import java.util.concurrent.CompletableFuture;
import tech.ydb.auth.AuthProvider;
import tech.ydb.auth.iam.CloudAuthHelper;
-import tech.ydb.core.Result;
import tech.ydb.core.grpc.GrpcTransport;
import tech.ydb.table.SessionRetryContext;
import tech.ydb.table.TableClient;
+import tech.ydb.table.query.DataQueryResult;
import tech.ydb.table.result.ResultSetReader;
import tech.ydb.table.transaction.TxControl;
@@ -23,24 +22,20 @@ public static void main(String[] args) {
AuthProvider authProvider = CloudAuthHelper.getServiceAccountFileAuthProvider(saKeyFile);
- try ( GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
- .withAuthProvider(authProvider) // Or this method could not be called at all
+ try (GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
+ .withAuthProvider(authProvider)
.build()) {
- try ( TableClient tableClient = TableClient
- .newClient(transport)
- .build()) {
-
+ try (TableClient tableClient = TableClient.newClient(transport).build()) {
SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build();
- retryCtx.supplyResult(session -> {
- ResultSetReader rsReader = session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
- .join().getValue().getResultSet(0);
+ DataQueryResult dataQueryResult = retryCtx.supplyResult(
+ session -> session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
+ ).join().getValue();
- rsReader.next();
+ ResultSetReader rsReader = dataQueryResult.getResultSet(0);
+ while (rsReader.next()) {
System.out.println(rsReader.getColumn(0).getInt32());
-
- return CompletableFuture.completedFuture(Result.success(Boolean.TRUE));
- }).join();
+ }
}
}
}
diff --git a/auth/static_credentials/src/main/java/tech/ydb/example/Main.java b/auth/static_credentials/src/main/java/tech/ydb/example/Main.java
index 876292d..b5272fd 100644
--- a/auth/static_credentials/src/main/java/tech/ydb/example/Main.java
+++ b/auth/static_credentials/src/main/java/tech/ydb/example/Main.java
@@ -1,13 +1,11 @@
package tech.ydb.example;
-import java.util.concurrent.CompletableFuture;
-
-import tech.ydb.core.Result;
import tech.ydb.core.auth.StaticCredentials;
import tech.ydb.core.grpc.GrpcTransport;
import tech.ydb.table.SessionRetryContext;
import tech.ydb.table.TableClient;
+import tech.ydb.table.query.DataQueryResult;
import tech.ydb.table.result.ResultSetReader;
import tech.ydb.table.transaction.TxControl;
@@ -29,23 +27,20 @@ public static void main(String[] args) {
// Use credentials auth provider with username and password
StaticCredentials authProvider = new StaticCredentials(username, password);
- try ( GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
- .withAuthProvider(authProvider) // Or this method could not be called at all
+ try (GrpcTransport transport = GrpcTransport.forConnectionString(connectionString)
+ .withAuthProvider(authProvider)
.build()) {
- try ( TableClient tableClient = TableClient
- .newClient(transport)
- .build()) {
+ try (TableClient tableClient = TableClient.newClient(transport).build()) {
SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build();
- retryCtx.supplyResult(session -> {
- ResultSetReader rsReader = session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
- .join().getValue().getResultSet(0);
+ DataQueryResult dataQueryResult = retryCtx.supplyResult(
+ session -> session.executeDataQuery("SELECT 1;", TxControl.serializableRw())
+ ).join().getValue();
- rsReader.next();
+ ResultSetReader rsReader = dataQueryResult.getResultSet(0);
+ while (rsReader.next()) {
System.out.println(rsReader.getColumn(0).getInt32());
-
- return CompletableFuture.completedFuture(Result.success(Boolean.TRUE));
- }).join();
+ }
}
}
}
diff --git a/basic_example/pom.xml b/basic_example/pom.xml
index c47233a..d69fe3b 100644
--- a/basic_example/pom.xml
+++ b/basic_example/pom.xml
@@ -12,15 +12,15 @@
YDB Basic Example
Simple example of usage Java SDK for YDB
+
+ 5.10.1
+
+
tech.ydb
ydb-sdk-table
-
- tech.ydb
- ydb-sdk-topic
-
tech.ydb.auth
yc-auth-provider
@@ -30,6 +30,19 @@
org.apache.logging.log4j
log4j-slf4j-impl
+
+
+ tech.ydb.test
+ ydb-junit5-support
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit5.version}
+ test
+
@@ -52,7 +65,18 @@
tech.ydb.example.App
-
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ true
+ 1
+
+
diff --git a/basic_example/src/main/java/tech/ydb/example/App.java b/basic_example/src/main/java/tech/ydb/example/App.java
index 72cefcc..05d1c8e 100644
--- a/basic_example/src/main/java/tech/ydb/example/App.java
+++ b/basic_example/src/main/java/tech/ydb/example/App.java
@@ -12,6 +12,7 @@
import org.slf4j.LoggerFactory;
import tech.ydb.auth.iam.CloudAuthHelper;
+import tech.ydb.common.transaction.TxMode;
import tech.ydb.core.Status;
import tech.ydb.core.grpc.GrpcReadStream;
import tech.ydb.core.grpc.GrpcTransport;
@@ -24,7 +25,7 @@
import tech.ydb.table.result.ResultSetReader;
import tech.ydb.table.settings.BulkUpsertSettings;
import tech.ydb.table.settings.ExecuteScanQuerySettings;
-import tech.ydb.table.transaction.Transaction;
+import tech.ydb.table.transaction.TableTransaction;
import tech.ydb.table.transaction.TxControl;
import tech.ydb.table.values.ListType;
import tech.ydb.table.values.ListValue;
@@ -41,7 +42,7 @@ public final class App implements Runnable, AutoCloseable {
private final String database;
private final SessionRetryContext retryCtx;
- private App(String connectionString) {
+ App(String connectionString) {
this.transport = GrpcTransport.forConnectionString(connectionString)
.withAuthProvider(CloudAuthHelper.getAuthProviderFromEnviron())
.build();
@@ -303,6 +304,7 @@ private void scanQueryWithParams(long seriesID, long seasonID) {
private void multiStepTransaction(long seriesID, long seasonID) {
retryCtx.supplyStatus(session -> {
+ TableTransaction transaction = session.createNewTransaction(TxMode.SERIALIZABLE_RW);
String query1
= "DECLARE $seriesId AS Uint64; "
+ "DECLARE $seasonId AS Uint64; "
@@ -312,8 +314,7 @@ private void multiStepTransaction(long seriesID, long seasonID) {
// Execute first query to get the required values to the client.
// Transaction control settings don't set CommitTx flag to keep transaction active
// after query execution.
- TxControl> tx1 = TxControl.serializableRw().setCommitTx(false);
- DataQueryResult res1 = session.executeDataQuery(query1, tx1, Params.of(
+ DataQueryResult res1 = transaction.executeDataQuery(query1, Params.of(
"$seriesId", PrimitiveValue.newUint64(seriesID),
"$seasonId", PrimitiveValue.newUint64(seasonID)
)).join().getValue();
@@ -327,7 +328,7 @@ private void multiStepTransaction(long seriesID, long seasonID) {
LocalDate toDate = fromDate.plusDays(15);
// Get active transaction id
- String txId = res1.getTxId();
+ logger.info("got transaction id {}", transaction.getId());
// Construct next query based on the results of client logic
String query2
@@ -340,8 +341,7 @@ private void multiStepTransaction(long seriesID, long seasonID) {
// Execute second query.
// Transaction control settings continues active transaction (tx) and
// commits it at the end of second query execution.
- TxControl> tx2 = TxControl.id(txId).setCommitTx(true);
- DataQueryResult res2 = session.executeDataQuery(query2, tx2, Params.of(
+ DataQueryResult res2 = transaction.executeDataQueryAndCommit(query2, Params.of(
"$seriesId", PrimitiveValue.newUint64(seriesID),
"$fromDate", PrimitiveValue.newDate(fromDate),
"$toDate", PrimitiveValue.newDate(toDate)
@@ -362,7 +362,7 @@ private void multiStepTransaction(long seriesID, long seasonID) {
private void tclTransaction() {
retryCtx.supplyStatus(session -> {
- Transaction transaction = session.beginTransaction(Transaction.Mode.SERIALIZABLE_READ_WRITE)
+ TableTransaction transaction = session.beginTransaction(TxMode.SERIALIZABLE_RW)
.join().getValue();
String query
@@ -373,8 +373,7 @@ private void tclTransaction() {
// Execute data query.
// Transaction control settings continues active transaction (tx)
- TxControl> txControl = TxControl.id(transaction).setCommitTx(false);
- DataQueryResult result = session.executeDataQuery(query, txControl, params)
+ DataQueryResult result = transaction.executeDataQuery(query, params)
.join().getValue();
logger.info("get transaction {}", result.getTxId());
diff --git a/basic_example/src/main/resources/log4j2.xml b/basic_example/src/main/resources/log4j2.xml
index 7ca65b6..cdcbde9 100644
--- a/basic_example/src/main/resources/log4j2.xml
+++ b/basic_example/src/main/resources/log4j2.xml
@@ -2,30 +2,21 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
+
diff --git a/basic_example/src/test/java/tech/ydb/example/BasicExampleTest.java b/basic_example/src/test/java/tech/ydb/example/BasicExampleTest.java
new file mode 100644
index 0000000..8d162a1
--- /dev/null
+++ b/basic_example/src/test/java/tech/ydb/example/BasicExampleTest.java
@@ -0,0 +1,30 @@
+package tech.ydb.example;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import tech.ydb.test.junit5.YdbHelperExtension;
+
+/**
+ *
+ * @author Aleksandr Gorshenin
+ */
+public class BasicExampleTest {
+ @RegisterExtension
+ private static final YdbHelperExtension ydb = new YdbHelperExtension();
+
+ private static String connectionString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ydb.useTls() ? "grpcs://" : "grpc://" );
+ sb.append(ydb.endpoint());
+ sb.append(ydb.database());
+ return sb.toString();
+ }
+
+ @Test
+ public void testBasicApp() {
+ App app = new App(connectionString());
+ app.run();
+ app.close();
+ }
+}
diff --git a/jdbc/spring-data-jpa-v5/pom.xml b/jdbc/spring-data-jpa-v5/pom.xml
index bba7163..3299cc8 100644
--- a/jdbc/spring-data-jpa-v5/pom.xml
+++ b/jdbc/spring-data-jpa-v5/pom.xml
@@ -57,7 +57,7 @@
org.postgresql
postgresql
- 42.7.1
+ 42.7.3
org.testcontainers
@@ -65,23 +65,17 @@
1.19.1
test
-
- tech.ydb.test
- ydb-junit5-support
- test
-
-
- org.junit.jupiter
- junit-jupiter-api
-
-
-
org.springframework.boot
spring-boot-starter-test
${spring.boot.version}
test
+
+ tech.ydb.test
+ ydb-junit5-support
+ test
+
${project.basedir}/src/main/kotlin
diff --git a/jdbc/spring-data-jpa/pom.xml b/jdbc/spring-data-jpa/pom.xml
index d883b09..1be2214 100644
--- a/jdbc/spring-data-jpa/pom.xml
+++ b/jdbc/spring-data-jpa/pom.xml
@@ -58,7 +58,7 @@
org.postgresql
postgresql
- 42.7.1
+ 42.7.3
org.testcontainers
diff --git a/pom.xml b/pom.xml
index 1f1188a..1655ee9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,13 +18,14 @@
2.22.1
1.82
- 2.1.11
+ 2.2.0
auth
secondary_index
basic_example
+ query-example
ydb-cookbook
url-shortener-demo
jdbc
diff --git a/query-example/pom.xml b/query-example/pom.xml
new file mode 100644
index 0000000..42a68f9
--- /dev/null
+++ b/query-example/pom.xml
@@ -0,0 +1,84 @@
+
+
+ 4.0.0
+
+
+ tech.ydb.examples
+ ydb-sdk-examples
+ 1.1.0-SNAPSHOT
+
+
+ ydb-query-example
+ YDB QueryClient basic example
+ Simple example of usage QueryClient of Java SDK for YDB
+
+
+ 5.10.1
+
+
+
+
+ tech.ydb
+ ydb-sdk-query
+
+
+ tech.ydb.auth
+ yc-auth-provider
+
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+
+
+
+ tech.ydb.test
+ ydb-junit5-support
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit5.version}
+ test
+
+
+
+
+ ydb-basic-example
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ true
+ libs/
+ tech.ydb.example.App
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ cr.yandex/yc/yandex-docker-local-ydb:trunk
+ true
+ 1
+
+
+
+
+
+
diff --git a/query-example/src/main/java/tech/ydb/example/App.java b/query-example/src/main/java/tech/ydb/example/App.java
new file mode 100644
index 0000000..58ff312
--- /dev/null
+++ b/query-example/src/main/java/tech/ydb/example/App.java
@@ -0,0 +1,374 @@
+package tech.ydb.example;
+
+import java.io.IOException;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import tech.ydb.auth.iam.CloudAuthHelper;
+import tech.ydb.common.transaction.TxMode;
+import tech.ydb.core.Status;
+import tech.ydb.core.grpc.GrpcTransport;
+import tech.ydb.query.QueryClient;
+import tech.ydb.query.QueryStream;
+import tech.ydb.query.QueryTransaction;
+import tech.ydb.query.tools.QueryReader;
+import tech.ydb.query.tools.SessionRetryContext;
+import tech.ydb.table.query.Params;
+import tech.ydb.table.result.ResultSetReader;
+import tech.ydb.table.values.ListType;
+import tech.ydb.table.values.ListValue;
+import tech.ydb.table.values.PrimitiveType;
+import tech.ydb.table.values.PrimitiveValue;
+import tech.ydb.table.values.StructType;
+
+
+public final class App implements Runnable, AutoCloseable {
+ private static final Logger logger = LoggerFactory.getLogger(App.class);
+
+ private final GrpcTransport transport;
+ private final QueryClient queryClient;
+ private final SessionRetryContext retryCtx;
+
+ App(String connectionString) {
+ this.transport = GrpcTransport.forConnectionString(connectionString)
+ .withAuthProvider(CloudAuthHelper.getAuthProviderFromEnviron())
+ .build();
+ this.queryClient = QueryClient.newClient(transport).build();
+ this.retryCtx = SessionRetryContext.create(queryClient).build();
+ }
+
+ @Override
+ public void run() {
+ createTables();
+ upsertTablesData();
+
+ upsertSimple();
+
+ selectSimple();
+ selectWithParams(1, 2);
+ asyncSelectRead(2, 1);
+
+ multiStepTransaction(2, 5);
+ tclTransaction();
+
+ dropTables();
+ }
+
+ @Override
+ public void close() {
+ queryClient.close();
+ transport.close();
+ }
+
+ private void createTables() {
+ retryCtx.supplyResult(session -> session.createQuery(""
+ + "CREATE TABLE series ("
+ + " series_id UInt64,"
+ + " title Text,"
+ + " series_info Text,"
+ + " release_date Date,"
+ + " PRIMARY KEY(series_id)"
+ + ")", TxMode.NONE).execute()
+ ).join().getStatus().expectSuccess("Can't create table series");
+
+ retryCtx.supplyResult(session -> session.createQuery(""
+ + "CREATE TABLE seasons ("
+ + " series_id UInt64,"
+ + " season_id UInt64,"
+ + " title Text,"
+ + " first_aired Date,"
+ + " last_aired Date,"
+ + " PRIMARY KEY(series_id, season_id)"
+ + ")", TxMode.NONE).execute()
+ ).join().getStatus().expectSuccess("Can't create table seasons");
+
+ retryCtx.supplyResult(session -> session.createQuery(""
+ + "CREATE TABLE episodes ("
+ + " series_id UInt64,"
+ + " season_id UInt64,"
+ + " episode_id UInt64,"
+ + " title Text,"
+ + " air_date Date,"
+ + " PRIMARY KEY(series_id, season_id, episode_id)"
+ + ")", TxMode.NONE).execute()
+ ).join().getStatus().expectSuccess("Can't create table episodes");
+ }
+
+ private void upsertTablesData() {
+ // Create type for struct of series
+ StructType seriesType = StructType.of(
+ "series_id", PrimitiveType.Uint64,
+ "title", PrimitiveType.Text,
+ "release_date", PrimitiveType.Date,
+ "series_info", PrimitiveType.Text
+ );
+ // Create and fill list of series
+ ListValue seriesData = ListType.of(seriesType).newValue(
+ SeriesData.SERIES.stream().map(series -> seriesType.newValue(
+ "series_id", PrimitiveValue.newUint64(series.seriesID()),
+ "title", PrimitiveValue.newText(series.title()),
+ "release_date", PrimitiveValue.newDate(series.releaseDate()),
+ "series_info", PrimitiveValue.newText(series.seriesInfo())
+ )).collect(Collectors.toList())
+ );
+
+ // Upsert list of series to table
+ retryCtx.supplyResult(session -> session.createQuery(
+ "UPSERT INTO series SELECT * FROM AS_TABLE($values)",
+ TxMode.SERIALIZABLE_RW,
+ Params.of("$values", seriesData)
+ ).execute()).join().getStatus().expectSuccess("upsert problem");
+
+
+ // Create type for struct of season
+ StructType seasonType = StructType.of(
+ "series_id", PrimitiveType.Uint64,
+ "season_id", PrimitiveType.Uint64,
+ "title", PrimitiveType.Text,
+ "first_aired", PrimitiveType.Date,
+ "last_aired", PrimitiveType.Date
+ );
+ // Create and fill list of seasons
+ ListValue seasonsData = ListType.of(seasonType).newValue(
+ SeriesData.SEASONS.stream().map(season -> seasonType.newValue(
+ "series_id", PrimitiveValue.newUint64(season.seriesID()),
+ "season_id", PrimitiveValue.newUint64(season.seasonID()),
+ "title", PrimitiveValue.newText(season.title()),
+ "first_aired", PrimitiveValue.newDate(season.firstAired()),
+ "last_aired", PrimitiveValue.newDate(season.lastAired())
+ )).collect(Collectors.toList())
+ );
+
+ // Upsert list of seasons to table
+ retryCtx.supplyResult(session -> session.createQuery(
+ "UPSERT INTO seasons SELECT * FROM AS_TABLE($values)",
+ TxMode.SERIALIZABLE_RW,
+ Params.of("$values", seasonsData)
+ ).execute()).join().getStatus().expectSuccess("upsert problem");
+
+
+ // Create type for struct of episode
+ StructType episodeType = StructType.of(
+ "series_id", PrimitiveType.Uint64,
+ "season_id", PrimitiveType.Uint64,
+ "episode_id", PrimitiveType.Uint64,
+ "title", PrimitiveType.Text,
+ "air_date", PrimitiveType.Date
+ );
+ // Create and fill list of episodes
+ ListValue episodesData = ListType.of(episodeType).newValue(
+ SeriesData.EPISODES.stream().map(episode -> episodeType.newValue(
+ "series_id", PrimitiveValue.newUint64(episode.seriesID()),
+ "season_id", PrimitiveValue.newUint64(episode.seasonID()),
+ "episode_id", PrimitiveValue.newUint64(episode.episodeID()),
+ "title", PrimitiveValue.newText(episode.title()),
+ "air_date", PrimitiveValue.newDate(episode.airDate())
+ )).collect(Collectors.toList())
+ );
+
+ // Upsert list of series to episodes
+ retryCtx.supplyResult(session -> session.createQuery(
+ "UPSERT INTO episodes SELECT * FROM AS_TABLE($values)",
+ TxMode.SERIALIZABLE_RW,
+ Params.of("$values", episodesData)
+ ).execute()).join().getStatus().expectSuccess("upsert problem");
+ }
+
+ private void upsertSimple() {
+ String query
+ = "UPSERT INTO episodes (series_id, season_id, episode_id, title) "
+ + "VALUES (2, 6, 1, \"TBD\");";
+
+ // Executes data query with specified transaction control settings.
+ retryCtx.supplyResult(session -> session.createQuery(query, TxMode.SERIALIZABLE_RW).execute())
+ .join().getValue();
+ }
+
+ private void selectSimple() {
+ String query
+ = "SELECT series_id, title, release_date "
+ + "FROM series WHERE series_id = 1;";
+
+ // Executes data query with specified transaction control settings.
+ QueryReader result = retryCtx.supplyResult(
+ session -> QueryReader.readFrom(session.createQuery(query, TxMode.SERIALIZABLE_RW))
+ ).join().getValue();
+
+ logger.info("--[ SelectSimple ]--");
+
+ ResultSetReader rs = result.getResultSet(0);
+ while (rs.next()) {
+ logger.info("read series with id {}, title {} and release_date {}",
+ rs.getColumn("series_id").getUint64(),
+ rs.getColumn("title").getText(),
+ rs.getColumn("release_date").getDate()
+ );
+ }
+ }
+
+ private void selectWithParams(long seriesID, long seasonID) {
+ String query
+ = "DECLARE $seriesId AS Uint64; "
+ + "DECLARE $seasonId AS Uint64; "
+ + "SELECT sa.title AS season_title, sr.title AS series_title "
+ + "FROM seasons AS sa INNER JOIN series AS sr ON sa.series_id = sr.series_id "
+ + "WHERE sa.series_id = $seriesId AND sa.season_id = $seasonId";
+
+ // Type of parameter values should be exactly the same as in DECLARE statements.
+ Params params = Params.of(
+ "$seriesId", PrimitiveValue.newUint64(seriesID),
+ "$seasonId", PrimitiveValue.newUint64(seasonID)
+ );
+
+ QueryReader result = retryCtx.supplyResult(
+ session -> QueryReader.readFrom(session.createQuery(query, TxMode.SNAPSHOT_RO, params))
+ ).join().getValue();
+
+ logger.info("--[ SelectWithParams ] -- ");
+
+ ResultSetReader rs = result.getResultSet(0);
+ while (rs.next()) {
+ logger.info("read season with title {} for series {}",
+ rs.getColumn("season_title").getText(),
+ rs.getColumn("series_title").getText()
+ );
+ }
+ }
+
+ private void asyncSelectRead(long seriesID, long seasonID) {
+ String query
+ = "DECLARE $seriesId AS Uint64; "
+ + "DECLARE $seasonId AS Uint64; "
+ + "SELECT ep.title AS episode_title, sa.title AS season_title, sr.title AS series_title "
+ + "FROM episodes AS ep "
+ + "JOIN seasons AS sa ON sa.season_id = ep.season_id "
+ + "JOIN series AS sr ON sr.series_id = sa.series_id "
+ + "WHERE sa.series_id = $seriesId AND sa.season_id = $seasonId;";
+
+ // Type of parameter values should be exactly the same as in DECLARE statements.
+ Params params = Params.of(
+ "$seriesId", PrimitiveValue.newUint64(seriesID),
+ "$seasonId", PrimitiveValue.newUint64(seasonID)
+ );
+
+ logger.info("--[ ExecuteAsyncQueryWithParams ]--");
+ retryCtx.supplyResult(session -> {
+ QueryStream asyncQuery = session.createQuery(query, TxMode.SNAPSHOT_RO, params);
+ return asyncQuery.execute(part -> {
+ ResultSetReader rs = part.getResultSetReader();
+ logger.info("read {} rows of result set {}", rs.getRowCount(), part.getResultSetIndex());
+ while (rs.next()) {
+ logger.info("read episode {} of {} for {}",
+ rs.getColumn("episode_title").getText(),
+ rs.getColumn("season_title").getText(),
+ rs.getColumn("series_title").getText()
+ );
+ }
+ });
+ }).join().getStatus().expectSuccess("execute query problem");
+ }
+
+ private void multiStepTransaction(long seriesID, long seasonID) {
+ retryCtx.supplyStatus(session -> {
+ QueryTransaction transaction = session.createNewTransaction(TxMode.SNAPSHOT_RO);
+ String query1
+ = "DECLARE $seriesId AS Uint64; "
+ + "DECLARE $seasonId AS Uint64; "
+ + "SELECT MIN(first_aired) AS from_date FROM seasons "
+ + "WHERE series_id = $seriesId AND season_id = $seasonId;";
+
+ // Execute first query to start a new transaction
+ QueryReader res1 = QueryReader.readFrom(transaction.createQuery(query1, Params.of(
+ "$seriesId", PrimitiveValue.newUint64(seriesID),
+ "$seasonId", PrimitiveValue.newUint64(seasonID)
+ ))).join().getValue();
+
+ // Perform some client logic on returned values
+ ResultSetReader resultSet = res1.getResultSet(0);
+ if (!resultSet.next()) {
+ throw new RuntimeException("not found first_aired");
+ }
+ LocalDate fromDate = resultSet.getColumn("from_date").getDate();
+ LocalDate toDate = fromDate.plusDays(15);
+
+ // Get active transaction id
+ logger.info("started new transaction {}", transaction.getId());
+
+ // Construct next query based on the results of client logic
+ String query2
+ = "DECLARE $seriesId AS Uint64;"
+ + "DECLARE $fromDate AS Date;"
+ + "DECLARE $toDate AS Date;"
+ + "SELECT season_id, episode_id, title, air_date FROM episodes "
+ + "WHERE series_id = $seriesId AND air_date >= $fromDate AND air_date <= $toDate;";
+
+ // Execute second query with commit at end.
+ QueryReader res2 = QueryReader.readFrom(transaction.createQueryWithCommit(query2, Params.of(
+ "$seriesId", PrimitiveValue.newUint64(seriesID),
+ "$fromDate", PrimitiveValue.newDate(fromDate),
+ "$toDate", PrimitiveValue.newDate(toDate)
+ ))).join().getValue();
+
+ logger.info("--[ MultiStep ]--");
+ ResultSetReader rs = res2.getResultSet(0);
+ while (rs.next()) {
+ logger.info("read episode {} with air date {}",
+ rs.getColumn("title").getText(),
+ rs.getColumn("air_date").getDate()
+ );
+ }
+
+ return CompletableFuture.completedFuture(Status.SUCCESS);
+ }).join().expectSuccess("multistep transaction problem");
+ }
+
+ private void tclTransaction() {
+ retryCtx.supplyResult(session -> {
+ QueryTransaction transaction = session.beginTransaction(TxMode.SERIALIZABLE_RW)
+ .join().getValue();
+
+ String query
+ = "DECLARE $airDate AS Date; "
+ + "UPDATE episodes SET air_date = $airDate WHERE title = \"TBD\";";
+
+ Params params = Params.of("$airDate", PrimitiveValue.newDate(Instant.now()));
+
+ // Execute data query.
+ // Transaction control settings continues active transaction (tx)
+ QueryReader reader = QueryReader.readFrom(transaction.createQuery(query, params))
+ .join().getValue();
+
+ logger.info("get transaction {}", transaction.getId());
+
+ // Commit active transaction (tx)
+ return transaction.commit();
+ }).join().getStatus().expectSuccess("tcl transaction problem");
+ }
+
+ private void dropTables() {
+ retryCtx.supplyResult(session -> session.createQuery("DROP TABLE episodes;", TxMode.NONE).execute())
+ .join().getStatus().expectSuccess("drop table episodes problem");
+ retryCtx.supplyResult(session -> session.createQuery("DROP TABLE seasons;", TxMode.NONE).execute())
+ .join().getStatus().expectSuccess("drop table seasons problem");
+ retryCtx.supplyResult(session -> session.createQuery("DROP TABLE series;", TxMode.NONE).execute())
+ .join().getStatus().expectSuccess("drop table series problem");
+ }
+
+ public static void main(String[] args) throws IOException {
+ if (args.length != 1) {
+ System.err.println("Usage: java -jar ydb-basic-example.jar ");
+ return;
+ }
+
+ try (App app = new App(args[0])) {
+ app.run();
+ } catch (Exception e) {
+ logger.error("app problem", e);
+ }
+ }
+}
diff --git a/query-example/src/main/java/tech/ydb/example/SeriesData.java b/query-example/src/main/java/tech/ydb/example/SeriesData.java
new file mode 100644
index 0000000..f047a2d
--- /dev/null
+++ b/query-example/src/main/java/tech/ydb/example/SeriesData.java
@@ -0,0 +1,114 @@
+package tech.ydb.example;
+
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.List;
+
+import tech.ydb.example.model.Episode;
+import tech.ydb.example.model.Season;
+import tech.ydb.example.model.Series;
+
+
+final class SeriesData {
+ public static final List SERIES = Arrays.asList(
+ new Series(
+ 1, "IT Crowd", date("2006-02-03"),
+ "The IT Crowd is a British sitcom produced by Channel 4, written by Graham Linehan, produced by " +
+ "Ash Atalla and starring Chris O'Dowd, Richard Ayoade, Katherine Parkinson, and Matt Berry."),
+ new Series(
+ 2, "Silicon Valley", date("2014-04-06"),
+ "Silicon Valley is an American comedy television series created by Mike Judge, John Altschuler and " +
+ "Dave Krinsky. The series focuses on five young men who founded a startup company in Silicon Valley.")
+ );
+
+ public static final List SEASONS = Arrays.asList(
+ new Season(1, 1, "Season 1", date("2006-02-03"), date("2006-03-03")),
+ new Season(1, 2, "Season 2", date("2007-08-24"), date("2007-09-28")),
+ new Season(1, 3, "Season 3", date("2008-11-21"), date("2008-12-26")),
+ new Season(1, 4, "Season 4", date("2010-06-25"), date("2010-07-30")),
+ new Season(2, 1, "Season 1", date("2014-04-06"), date("2014-06-01")),
+ new Season(2, 2, "Season 2", date("2015-04-12"), date("2015-06-14")),
+ new Season(2, 3, "Season 3", date("2016-04-24"), date("2016-06-26")),
+ new Season(2, 4, "Season 4", date("2017-04-23"), date("2017-06-25")),
+ new Season(2, 5, "Season 5", date("2018-03-25"), date("2018-05-13"))
+ );
+
+ public static final List EPISODES = Arrays.asList(
+ new Episode(1, 1, 1, "Yesterday's Jam", date("2006-02-03")),
+ new Episode(1, 1, 2, "Calamity Jen", date("2006-02-03")),
+ new Episode(1, 1, 3, "Fifty-Fifty", date("2006-02-10")),
+ new Episode(1, 1, 4, "The Red Door", date("2006-02-17")),
+ new Episode(1, 1, 5, "The Haunting of Bill Crouse", date("2006-02-24")),
+ new Episode(1, 1, 6, "Aunt Irma Visits", date("2006-03-03")),
+ new Episode(1, 2, 1, "The Work Outing", date("2006-08-24")),
+ new Episode(1, 2, 2, "Return of the Golden Child", date("2007-08-31")),
+ new Episode(1, 2, 3, "Moss and the German", date("2007-09-07")),
+ new Episode(1, 2, 4, "The Dinner Party", date("2007-09-14")),
+ new Episode(1, 2, 5, "Smoke and Mirrors", date("2007-09-21")),
+ new Episode(1, 2, 6, "Men Without Women", date("2007-09-28")),
+ new Episode(1, 3, 1, "From Hell", date("2008-11-21")),
+ new Episode(1, 3, 2, "Are We Not Men?", date("2008-11-28")),
+ new Episode(1, 3, 3, "Tramps Like Us", date("2008-12-05")),
+ new Episode(1, 3, 4, "The Speech", date("2008-12-12")),
+ new Episode(1, 3, 5, "Friendface", date("2008-12-19")),
+ new Episode(1, 3, 6, "Calendar Geeks", date("2008-12-26")),
+ new Episode(1, 4, 1, "Jen The Fredo", date("2010-06-25")),
+ new Episode(1, 4, 2, "The Final Countdown", date("2010-07-02")),
+ new Episode(1, 4, 3, "Something Happened", date("2010-07-09")),
+ new Episode(1, 4, 4, "Italian For Beginners", date("2010-07-16")),
+ new Episode(1, 4, 5, "Bad Boys", date("2010-07-23")),
+ new Episode(1, 4, 6, "Reynholm vs Reynholm", date("2010-07-30")),
+ new Episode(2, 1, 1, "Minimum Viable Product", date("2014-04-06")),
+ new Episode(2, 1, 2, "The Cap Table", date("2014-04-13")),
+ new Episode(2, 1, 3, "Articles of Incorporation", date("2014-04-20")),
+ new Episode(2, 1, 4, "Fiduciary Duties", date("2014-04-27")),
+ new Episode(2, 1, 5, "Signaling Risk", date("2014-05-04")),
+ new Episode(2, 1, 6, "Third Party Insourcing", date("2014-05-11")),
+ new Episode(2, 1, 7, "Proof of Concept", date("2014-05-18")),
+ new Episode(2, 1, 8, "Optimal Tip-to-Tip Efficiency", date("2014-06-01")),
+ new Episode(2, 2, 1, "Sand Hill Shuffle", date("2015-04-12")),
+ new Episode(2, 2, 2, "Runaway Devaluation", date("2015-04-19")),
+ new Episode(2, 2, 3, "Bad Money", date("2015-04-26")),
+ new Episode(2, 2, 4, "The Lady", date("2015-05-03")),
+ new Episode(2, 2, 5, "Server Space", date("2015-05-10")),
+ new Episode(2, 2, 6, "Homicide", date("2015-05-17")),
+ new Episode(2, 2, 7, "Adult Content", date("2015-05-24")),
+ new Episode(2, 2, 8, "White Hat/Black Hat", date("2015-05-31")),
+ new Episode(2, 2, 9, "Binding Arbitration", date("2015-06-07")),
+ new Episode(2, 2, 10, "Two Days of the Condor", date("2015-06-14")),
+ new Episode(2, 3, 1, "Founder Friendly", date("2016-04-24")),
+ new Episode(2, 3, 2, "Two in the Box", date("2016-05-01")),
+ new Episode(2, 3, 3, "Meinertzhagen's Haversack", date("2016-05-08")),
+ new Episode(2, 3, 4, "Maleant Data Systems Solutions", date("2016-05-15")),
+ new Episode(2, 3, 5, "The Empty Chair", date("2016-05-22")),
+ new Episode(2, 3, 6, "Bachmanity Insanity", date("2016-05-29")),
+ new Episode(2, 3, 7, "To Build a Better Beta", date("2016-06-05")),
+ new Episode(2, 3, 8, "Bachman's Earnings Over-Ride", date("2016-06-12")),
+ new Episode(2, 3, 9, "Daily Active Users", date("2016-06-19")),
+ new Episode(2, 3, 10, "The Uptick", date("2016-06-26")),
+ new Episode(2, 4, 1, "Success Failure", date("2017-04-23")),
+ new Episode(2, 4, 2, "Terms of Service", date("2017-04-30")),
+ new Episode(2, 4, 3, "Intellectual Property", date("2017-05-07")),
+ new Episode(2, 4, 4, "Teambuilding Exercise", date("2017-05-14")),
+ new Episode(2, 4, 5, "The Blood Boy", date("2017-05-21")),
+ new Episode(2, 4, 6, "Customer Service", date("2017-05-28")),
+ new Episode(2, 4, 7, "The Patent Troll", date("2017-06-04")),
+ new Episode(2, 4, 8, "The Keenan Vortex", date("2017-06-11")),
+ new Episode(2, 4, 9, "Hooli-Con", date("2017-06-18")),
+ new Episode(2, 4, 10, "Server Error", date("2017-06-25")),
+ new Episode(2, 5, 1, "Grow Fast or Die Slow", date("2018-03-25")),
+ new Episode(2, 5, 2, "Reorientation", date("2018-04-01")),
+ new Episode(2, 5, 3, "Chief Operating Officer", date("2018-04-08")),
+ new Episode(2, 5, 4, "Tech Evangelist", date("2018-04-15")),
+ new Episode(2, 5, 5, "Facial Recognition", date("2018-04-22")),
+ new Episode(2, 5, 6, "Artificial Emotional Intelligence", date("2018-04-29")),
+ new Episode(2, 5, 7, "Initial Coin Offering", date("2018-05-06")),
+ new Episode(2, 5, 8, "Fifty-One Percent", date("2018-05-13"))
+ );
+
+ private SeriesData() { }
+
+ private static Instant date(String str) {
+ return Instant.parse(str + "T00:00:00Z");
+ }
+}
diff --git a/query-example/src/main/java/tech/ydb/example/model/Episode.java b/query-example/src/main/java/tech/ydb/example/model/Episode.java
new file mode 100644
index 0000000..0c68ef7
--- /dev/null
+++ b/query-example/src/main/java/tech/ydb/example/model/Episode.java
@@ -0,0 +1,40 @@
+package tech.ydb.example.model;
+
+import java.time.Instant;
+
+
+public class Episode {
+ private final long seriesID;
+ private final long seasonID;
+ private final long episodeID;
+ private final String title;
+ private final Instant airDate;
+
+ public Episode(long seriesID, long seasonID, long episodeID, String title, Instant airDate) {
+ this.seriesID = seriesID;
+ this.seasonID = seasonID;
+ this.episodeID = episodeID;
+ this.title = title;
+ this.airDate = airDate;
+ }
+
+ public long seriesID() {
+ return seriesID;
+ }
+
+ public long seasonID() {
+ return seasonID;
+ }
+
+ public long episodeID() {
+ return episodeID;
+ }
+
+ public String title() {
+ return title;
+ }
+
+ public Instant airDate() {
+ return airDate;
+ }
+}
diff --git a/query-example/src/main/java/tech/ydb/example/model/Season.java b/query-example/src/main/java/tech/ydb/example/model/Season.java
new file mode 100644
index 0000000..eeb512d
--- /dev/null
+++ b/query-example/src/main/java/tech/ydb/example/model/Season.java
@@ -0,0 +1,40 @@
+package tech.ydb.example.model;
+
+import java.time.Instant;
+
+
+public class Season {
+ private final long seriesID;
+ private final long seasonID;
+ private final String title;
+ private final Instant firstAired;
+ private final Instant lastAired;
+
+ public Season(long seriesID, long seasonID, String title, Instant firstAired, Instant lastAired) {
+ this.seriesID = seriesID;
+ this.seasonID = seasonID;
+ this.title = title;
+ this.firstAired = firstAired;
+ this.lastAired = lastAired;
+ }
+
+ public long seriesID() {
+ return this.seriesID;
+ }
+
+ public long seasonID() {
+ return this.seasonID;
+ }
+
+ public String title() {
+ return this.title;
+ }
+
+ public Instant firstAired() {
+ return this.firstAired;
+ }
+
+ public Instant lastAired() {
+ return this.lastAired;
+ }
+}
diff --git a/query-example/src/main/java/tech/ydb/example/model/Series.java b/query-example/src/main/java/tech/ydb/example/model/Series.java
new file mode 100644
index 0000000..d074c28
--- /dev/null
+++ b/query-example/src/main/java/tech/ydb/example/model/Series.java
@@ -0,0 +1,34 @@
+package tech.ydb.example.model;
+
+import java.time.Instant;
+
+
+public class Series {
+ private final long seriesID;
+ private final String title;
+ private final Instant releaseDate;
+ private final String seriesInfo;
+
+ public Series(long seriesID, String title, Instant releaseDate, String seriesInfo) {
+ this.seriesID = seriesID;
+ this.title = title;
+ this.releaseDate = releaseDate;
+ this.seriesInfo = seriesInfo;
+ }
+
+ public long seriesID() {
+ return seriesID;
+ }
+
+ public String title() {
+ return title;
+ }
+
+ public Instant releaseDate() {
+ return releaseDate;
+ }
+
+ public String seriesInfo() {
+ return seriesInfo;
+ }
+}
diff --git a/query-example/src/main/resources/log4j2.xml b/query-example/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..cdcbde9
--- /dev/null
+++ b/query-example/src/main/resources/log4j2.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/query-example/src/test/java/tech/ydb/example/BasicExampleTest.java b/query-example/src/test/java/tech/ydb/example/BasicExampleTest.java
new file mode 100644
index 0000000..8d162a1
--- /dev/null
+++ b/query-example/src/test/java/tech/ydb/example/BasicExampleTest.java
@@ -0,0 +1,30 @@
+package tech.ydb.example;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import tech.ydb.test.junit5.YdbHelperExtension;
+
+/**
+ *
+ * @author Aleksandr Gorshenin
+ */
+public class BasicExampleTest {
+ @RegisterExtension
+ private static final YdbHelperExtension ydb = new YdbHelperExtension();
+
+ private static String connectionString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ydb.useTls() ? "grpcs://" : "grpc://" );
+ sb.append(ydb.endpoint());
+ sb.append(ydb.database());
+ return sb.toString();
+ }
+
+ @Test
+ public void testBasicApp() {
+ App app = new App(connectionString());
+ app.run();
+ app.close();
+ }
+}
diff --git a/url-shortener-demo/pom.xml b/url-shortener-demo/pom.xml
index 4b51b88..9209912 100644
--- a/url-shortener-demo/pom.xml
+++ b/url-shortener-demo/pom.xml
@@ -16,6 +16,7 @@
10.0.14
2.9.0
+ 5.10.1
@@ -53,6 +54,13 @@
ydb-junit5-support
test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit5.version}
+ test
+
diff --git a/ydb-cookbook/pom.xml b/ydb-cookbook/pom.xml
index 799d38e..a0aa1c1 100644
--- a/ydb-cookbook/pom.xml
+++ b/ydb-cookbook/pom.xml
@@ -14,7 +14,7 @@
Receipts of usage Java SDK for YDB
- UTF-8
+ 5.10.1
@@ -50,5 +50,27 @@
ydb-junit5-support
test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit5.version}
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ true
+ 1
+
+
+
+
+
diff --git a/ydb-cookbook/src/main/java/tech/ydb/examples/simple/ComplexTransaction.java b/ydb-cookbook/src/main/java/tech/ydb/examples/simple/ComplexTransaction.java
index b269a70..47cd292 100644
--- a/ydb-cookbook/src/main/java/tech/ydb/examples/simple/ComplexTransaction.java
+++ b/ydb-cookbook/src/main/java/tech/ydb/examples/simple/ComplexTransaction.java
@@ -1,14 +1,15 @@
package tech.ydb.examples.simple;
import java.time.Duration;
-import tech.ydb.core.grpc.GrpcTransport;
+import tech.ydb.common.transaction.TxMode;
+import tech.ydb.core.grpc.GrpcTransport;
import tech.ydb.examples.SimpleExample;
import tech.ydb.table.Session;
import tech.ydb.table.TableClient;
import tech.ydb.table.description.TableDescription;
import tech.ydb.table.query.DataQueryResult;
-import tech.ydb.table.transaction.Transaction;
+import tech.ydb.table.transaction.TableTransaction;
import tech.ydb.table.transaction.TxControl;
import tech.ydb.table.values.PrimitiveType;
@@ -24,7 +25,7 @@ protected void run(GrpcTransport transport, String pathPrefix) {
try (
TableClient tableClient = TableClient.newClient(transport).build();
- Session session = tableClient.createSession(Duration.ofSeconds(5)).join().getValue();
+ Session session = tableClient.createSession(Duration.ofSeconds(5)).join().getValue()
) {
session.dropTable(tablePath)
@@ -40,27 +41,22 @@ protected void run(GrpcTransport transport, String pathPrefix) {
.join()
.expectSuccess("cannot create table");
- Transaction transaction = session.beginTransaction(Transaction.Mode.SERIALIZABLE_READ_WRITE)
- .join()
- .getValue();
+ TableTransaction transaction = session.beginTransaction(TxMode.SERIALIZABLE_RW)
+ .join().getValue();
- String query1 = "UPSERT INTO [" + tablePath + "] (key, value) VALUES (1, 'one');";
- DataQueryResult result1 = session.executeDataQuery(query1, TxControl.id(transaction))
- .join()
- .getValue();
+ String query1 = "UPSERT INTO `" + tablePath + "` (key, value) VALUES (1, 'one');";
+ DataQueryResult result1 = transaction.executeDataQuery(query1).join().getValue();
System.out.println("--[insert1]-------------------");
DataQueryResults.print(result1);
System.out.println("------------------------------");
- String query2 = "UPSERT INTO [" + tablePath + "] (key, value) VALUES (2, 'two');";
- DataQueryResult result2 = session.executeDataQuery(query2, TxControl.id(transaction))
- .join()
- .getValue();
+ String query2 = "UPSERT INTO `" + tablePath + "` (key, value) VALUES (2, 'two');";
+ DataQueryResult result2 = transaction.executeDataQuery(query2).join().getValue();
System.out.println("--[insert2]-------------------");
DataQueryResults.print(result2);
System.out.println("------------------------------");
- String query3 = "SELECT * FROM [" + tablePath + "];";
+ String query3 = "SELECT * FROM `" + tablePath + "`;";
DataQueryResult result3 = session.executeDataQuery(query3, TxControl.onlineRo().setCommitTx(true))
.join()
.getValue();
@@ -72,7 +68,7 @@ protected void run(GrpcTransport transport, String pathPrefix) {
.join()
.expectSuccess("cannot commit transaction");
- String query = "SELECT * FROM [" + tablePath + "];";
+ String query = "SELECT * FROM `" + tablePath + "`;";
DataQueryResult result = session.executeDataQuery(query, TxControl.onlineRo().setCommitTx(true))
.join()
.getValue();
@@ -85,4 +81,9 @@ protected void run(GrpcTransport transport, String pathPrefix) {
public static void main(String[] args) {
new ComplexTransaction().doMain(args);
}
+
+ public static int test(String[] args) {
+ new ComplexTransaction().doMain(args);
+ return 0;
+ }
}
diff --git a/ydb-cookbook/src/main/java/tech/ydb/examples/simple/ReadTableExample.java b/ydb-cookbook/src/main/java/tech/ydb/examples/simple/ReadTableExample.java
index f53a456..e6ab31b 100644
--- a/ydb-cookbook/src/main/java/tech/ydb/examples/simple/ReadTableExample.java
+++ b/ydb-cookbook/src/main/java/tech/ydb/examples/simple/ReadTableExample.java
@@ -1,11 +1,13 @@
package tech.ydb.examples.simple;
-import java.time.Duration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import tech.ydb.core.grpc.GrpcTransport;
import tech.ydb.examples.SimpleExample;
-import tech.ydb.table.Session;
+import tech.ydb.table.SessionRetryContext;
import tech.ydb.table.TableClient;
import tech.ydb.table.result.ResultSetReader;
import tech.ydb.table.settings.ReadTableSettings;
@@ -17,28 +19,31 @@
* @author Sergey Polovko
*/
public class ReadTableExample extends SimpleExample {
+ private static final String TABLE_NAME = "read_table_example";
+ private static final Logger logger = LoggerFactory.getLogger(ReadTableExample.class);
+
@Override
protected void run(GrpcTransport transport, String pathPrefix) {
- try (
- TableClient tableClient = TableClient.newClient(transport).build();
- Session session = tableClient.createSession(Duration.ofSeconds(5)).join().getValue()
- ) {
-
- String tablePath = pathPrefix + getClass().getSimpleName();
- createAndFillTable(session, tablePath);
- readTable(session, tablePath);
+ try (TableClient tableClient = TableClient.newClient(transport).build()) {
+ SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build();
+
+ createAndFillTable(retryCtx);
+ readTable(retryCtx, transport.getDatabase());
+ dropTable(retryCtx);
}
}
- private void readTable(Session session, String tablePath) {
+ private void readTable(SessionRetryContext retryCtx, String database) {
+
ReadTableSettings settings = ReadTableSettings.newBuilder()
.orderedRead(true)
.fromKeyInclusive(PrimitiveValue.newUint32(10))
.toKeyExclusive(PrimitiveValue.newUint32(25))
.build();
- session.executeReadTable(tablePath, settings).start(part -> {
+ String tablePath = database + "/" + TABLE_NAME;
+ retryCtx.supplyStatus(session -> session.executeReadTable(tablePath, settings).start(part -> {
ResultSetReader resultSet = part.getResultSetReader();
// we are going to read a lot of data, so map column names to indexes
@@ -49,31 +54,37 @@ private void readTable(Session session, String tablePath) {
while (resultSet.next()) {
long key = resultSet.getColumn(keyIdx).getUint32();
String value = resultSet.getColumn(valueIdx).getText();
- System.out.printf("key=%d, value=%s\n", key, value);
+ logger.info("key={}, value={}", key, value);
}
- }).join().expectSuccess("readTable failed");
+ })).join().expectSuccess("readTable failed");
}
- private void createAndFillTable(Session session, String tablePath) {
+ private void createAndFillTable(SessionRetryContext retryCtx) {
String createTable =
- "CREATE TABLE [" + tablePath + "] (" +
+ "CREATE TABLE " + TABLE_NAME + " (" +
" key Uint32," +
" value Utf8," +
" PRIMARY KEY(key)" +
");";
- session.executeSchemeQuery(createTable)
+ retryCtx.supplyStatus(session -> session.executeSchemeQuery(createTable))
.join()
.expectSuccess("cannot create table");
for (int i = 0; i < 100; i++) {
- String query = "REPLACE INTO [" + tablePath + "](key, value) VALUES (" + i + ", \"<" + i + ">\");";
- session.executeDataQuery(query, TxControl.serializableRw().setCommitTx(true))
- .join()
- .getStatus().expectSuccess("cannot execute insert");
+ String query = "UPSERT INTO " + TABLE_NAME + "(key, value) VALUES (" + i + ", \"<" + i + ">\");";
+ retryCtx.supplyResult(session -> session.executeDataQuery(query, TxControl.serializableRw()))
+ .join().getStatus().expectSuccess("cannot execute insert");
}
}
+ private void dropTable(SessionRetryContext retryCtx) {
+ String dropSQL = "DROP TABLE " + TABLE_NAME + ";";
+ retryCtx.supplyStatus(session -> session.executeSchemeQuery(dropSQL))
+ .join()
+ .expectSuccess("cannot create table");
+ }
+
public static void main(String[] args) {
new ReadTableExample().doMain(args);
}
diff --git a/ydb-cookbook/src/test/java/tech/ydb/examples/ExamplesTest.java b/ydb-cookbook/src/test/java/tech/ydb/examples/ExamplesTest.java
index 0d4884d..98c5d6b 100644
--- a/ydb-cookbook/src/test/java/tech/ydb/examples/ExamplesTest.java
+++ b/ydb-cookbook/src/test/java/tech/ydb/examples/ExamplesTest.java
@@ -7,6 +7,8 @@
import tech.ydb.examples.batch_upload.BatchUpload;
import tech.ydb.examples.bulk_upsert.BulkUpsert;
import tech.ydb.examples.pagination.PaginationApp;
+import tech.ydb.examples.simple.ComplexTransaction;
+import tech.ydb.examples.simple.ReadTableExample;
import tech.ydb.test.junit5.YdbHelperExtension;
/**
@@ -24,6 +26,14 @@ private String[] args() {
};
}
+ private String[] connectionString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ydb.useTls() ? "grpcs://" : "grpc://" );
+ sb.append(ydb.endpoint());
+ sb.append(ydb.database());
+ return new String [] { sb.toString() };
+ }
+
@Test
public void testBatchUpload() {
Assertions.assertEquals(0, BatchUpload.test(args()), "Batch upload test");
@@ -34,8 +44,18 @@ public void testBulkUpsert() {
Assertions.assertEquals(0, BulkUpsert.test(args()), "Bulk upsert test");
}
+ @Test
+ public void testReadTable() {
+ ReadTableExample.main(connectionString());
+ }
+
@Test
public void testPagination() {
Assertions.assertEquals(0, PaginationApp.test(args(), "Pagination test"));
}
+
+ @Test
+ public void testComplexTransaction() {
+ Assertions.assertEquals(0, ComplexTransaction.test(connectionString()));
+ }
}