Skip to content

Commit 76abae2

Browse files
feat: update lessons
1 parent 96e2ddc commit 76abae2

File tree

46 files changed

+1442
-1109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1442
-1109
lines changed

dev-1/lesson-2.1/java/src/main/java/tech/ydb/app/Application.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static void main(String[] args) {
3333
// Создаем клиент для выполнения SQL-запросов
3434
try (QueryClient queryClient = QueryClient.newClient(grpcTransport).build()) {
3535
// Создаем контекст для автоматических повторных попыток выполнения запросов
36-
SessionRetryContext retryCtx = SessionRetryContext.create(queryClient).build();
36+
var retryCtx = SessionRetryContext.create(queryClient).build();
3737

3838
LOGGER.info("Database is available! Result `SELECT 1;` command: {}", new YdbRepository(retryCtx).SelectOne());
3939
}

dev-1/lesson-3.1/java/src/main/java/tech/ydb/app/IssueYdbRepository.java

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import java.util.concurrent.ThreadLocalRandom;
77

88
import tech.ydb.common.transaction.TxMode;
9-
import tech.ydb.query.tools.QueryReader;
109
import tech.ydb.query.tools.SessionRetryContext;
1110
import tech.ydb.table.query.Params;
1211
import tech.ydb.table.values.PrimitiveValue;
@@ -25,10 +24,10 @@ public class IssueYdbRepository {
2524
// 2. Улучшения тестируемости - можно передать mock-объект для тестов
2625
// 3. Централизованного управления конфигурацией ретраев
2726
// 4. Возможности переиспользования одного контекста для разных репозиториев
28-
private final SessionRetryContext retryCtx;
27+
private final QueryServiceHelper queryServiceHelper;
2928

3029
public IssueYdbRepository(SessionRetryContext retryCtx) {
31-
this.retryCtx = retryCtx;
30+
this.queryServiceHelper = new QueryServiceHelper(retryCtx);
3231
}
3332

3433
/**
@@ -44,23 +43,20 @@ public Issue addIssue(String title) {
4443

4544
// Выполняем UPSERT запрос для добавления тикета
4645
// Изменять данные можно только в режиме транзакции SERIALIZABLE_RW, поэтому используем его
47-
retryCtx.supplyResult(
48-
session -> session.createQuery(
49-
"""
50-
DECLARE $id AS Int64;
51-
DECLARE $title AS Text;
52-
DECLARE $created_at AS Timestamp;
53-
UPSERT INTO issues (id, title, created_at)
54-
VALUES ($id, $title, $created_at);
55-
""",
56-
TxMode.SERIALIZABLE_RW,
57-
Params.of(
58-
"$id", PrimitiveValue.newInt64(id),
59-
"$title", PrimitiveValue.newText(title),
60-
"$created_at", PrimitiveValue.newTimestamp(now)
61-
)
62-
).execute()
63-
).join().getStatus().expectSuccess("Failed upsert title");
46+
queryServiceHelper.executeQuery("""
47+
DECLARE $id AS Int64;
48+
DECLARE $title AS Text;
49+
DECLARE $created_at AS Timestamp;
50+
UPSERT INTO issues (id, title, created_at)
51+
VALUES ($id, $title, $created_at);
52+
""",
53+
TxMode.SERIALIZABLE_RW,
54+
Params.of(
55+
"$id", PrimitiveValue.newInt64(id),
56+
"$title", PrimitiveValue.newText(title),
57+
"$created_at", PrimitiveValue.newTimestamp(now)
58+
)
59+
);
6460

6561
return new Issue(id, title, now);
6662
}
@@ -76,11 +72,8 @@ public List<Issue> findAll() {
7672
// Этот режим сообщает серверу, что это транзакция только для чтения.
7773
// Это позволяет снизить накладные расходы на подготовку к изменениям и просто читать данные из
7874
// одного снимка базы данных.
79-
var resultSet = retryCtx.supplyResult(
80-
session -> QueryReader.readFrom(
81-
session.createQuery("SELECT id, title, created_at FROM issues;", TxMode.SNAPSHOT_RO)
82-
)
83-
).join().getValue();
75+
var resultSet = queryServiceHelper.executeQuery("SELECT id, title, created_at FROM issues;",
76+
TxMode.SNAPSHOT_RO, Params.empty());
8477

8578
var resultSetReader = resultSet.getResultSet(0);
8679

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package tech.ydb.app;
2+
3+
import tech.ydb.common.transaction.TxMode;
4+
import tech.ydb.query.tools.QueryReader;
5+
import tech.ydb.query.tools.SessionRetryContext;
6+
import tech.ydb.table.query.Params;
7+
8+
/**
9+
* @author Kirill Kurdyukov
10+
*/
11+
public class QueryServiceHelper {
12+
13+
// Контекст для автоматических повторных попыток выполнения запросов
14+
// Принимается извне через конструктор для:
15+
// 1. Следования принципу Dependency Injection - зависимости класса передаются ему извне
16+
// 2. Улучшения тестируемости - можно передать mock-объект для тестов
17+
// 3. Централизованного управления конфигурацией ретраев
18+
// 4. Возможности переиспользования одного контекста для разных репозиториев
19+
private final SessionRetryContext retryCtx;
20+
21+
public QueryServiceHelper(SessionRetryContext retryCtx) {
22+
this.retryCtx = retryCtx;
23+
}
24+
25+
public void executeQuery(String yql) {
26+
retryCtx.supplyResult(
27+
session -> QueryReader.readFrom(session.createQuery(yql, TxMode.NONE))
28+
).join().getValue();
29+
}
30+
31+
public QueryReader executeQuery(String yql, TxMode txMode, Params params) {
32+
return retryCtx.supplyResult(
33+
session -> QueryReader.readFrom(session.createQuery(yql, txMode, params))
34+
).join().getValue();
35+
}
36+
}
Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package tech.ydb.app;
22

3-
import tech.ydb.common.transaction.TxMode;
43
import tech.ydb.query.tools.SessionRetryContext;
54

65
/**
@@ -11,11 +10,10 @@
1110
*/
1211
public class SchemaYdbRepository {
1312

14-
// Контекст для автоматических повторных попыток выполнения запросов
15-
private final SessionRetryContext retryCtx;
13+
private final QueryServiceHelper queryServiceHelper;
1614

1715
public SchemaYdbRepository(SessionRetryContext retryCtx) {
18-
this.retryCtx = retryCtx;
16+
this.queryServiceHelper = new QueryServiceHelper(retryCtx);
1917
}
2018

2119
/**
@@ -28,27 +26,22 @@ public SchemaYdbRepository(SessionRetryContext retryCtx) {
2826
* Все поля являются обязательными.
2927
*/
3028
public void createSchema() {
31-
retryCtx.supplyResult(
32-
session -> session.createQuery(
33-
"""
34-
CREATE TABLE IF NOT EXISTS issues (
35-
id Int64 NOT NULL,
36-
title Text NOT NULL,
37-
created_at Timestamp NOT NULL,
38-
PRIMARY KEY (id)
39-
);
40-
""", TxMode.NONE
41-
).execute()
42-
).join().getStatus().expectSuccess("Can't create table issues");
29+
queryServiceHelper.executeQuery("""
30+
CREATE TABLE IF NOT EXISTS issues (
31+
id Int64 NOT NULL,
32+
title Text NOT NULL,
33+
created_at Timestamp NOT NULL,
34+
PRIMARY KEY (id)
35+
);
36+
"""
37+
);
4338
}
4439

4540
/**
4641
* Удаляет таблицу issues из базы данных
4742
* Используется для очистки схемы перед созданием новой
4843
*/
4944
public void dropSchema() {
50-
retryCtx.supplyResult(
51-
session -> session.createQuery("DROP TABLE IF EXISTS issues;", TxMode.NONE).execute()
52-
).join().getStatus().expectSuccess("Can't drop table issues");
45+
queryServiceHelper.executeQuery("DROP TABLE IF EXISTS issues;");
5346
}
5447
}

dev-1/lesson-4.1/java/src/main/java/tech/ydb/app/IssueYdbRepository.java

Lines changed: 59 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
* @author Kirill Kurdyukov
2121
*/
2222
public class IssueYdbRepository {
23-
// Контекст для автоматических повторных попыток выполнения запросов
23+
2424
private final SessionRetryContext retryCtx;
25+
private final QueryServiceHelper queryServiceHelper;
2526

2627
public IssueYdbRepository(SessionRetryContext retryCtx) {
2728
this.retryCtx = retryCtx;
29+
this.queryServiceHelper = new QueryServiceHelper(retryCtx);
2830
}
2931

3032
/**
@@ -33,29 +35,27 @@ public IssueYdbRepository(SessionRetryContext retryCtx) {
3335
* выполняются за один запрос к YDB.
3436
*/
3537
public List<IssueLinkCount> linkTicketsNoInteractive(long idT1, long idT2) {
36-
var valueReader = retryCtx.supplyResult(
37-
session -> QueryReader.readFrom(session.createQuery(
38-
"""
39-
DECLARE $t1 AS Int64;
40-
DECLARE $t2 AS Int64;
41-
42-
-- Обновляем счетчики связей
43-
UPDATE issues
44-
SET link_count = COALESCE(link_count, 0) + 1
45-
WHERE id IN ($t1, $t2);
46-
47-
-- Добавляем записи о связях между тикетами
48-
INSERT INTO links (source, destination)
49-
VALUES ($t1, $t2), ($t2, $t1);
50-
51-
-- Читаем обновленные данные
52-
SELECT id, link_count FROM issues
53-
WHERE id IN ($t1, $t2)
54-
""",
55-
TxMode.SERIALIZABLE_RW,
56-
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
57-
))
58-
).join().getValue();
38+
var valueReader = queryServiceHelper.executeQuery(
39+
"""
40+
DECLARE $t1 AS Int64;
41+
DECLARE $t2 AS Int64;
42+
43+
-- Обновляем счетчики связей
44+
UPDATE issues
45+
SET link_count = COALESCE(link_count, 0) + 1
46+
WHERE id IN ($t1, $t2);
47+
48+
-- Добавляем записи о связях между тикетами
49+
INSERT INTO links (source, destination)
50+
VALUES ($t1, $t2), ($t2, $t1);
51+
52+
-- Читаем обновленные данные
53+
SELECT id, link_count FROM issues
54+
WHERE id IN ($t1, $t2)
55+
""",
56+
TxMode.SERIALIZABLE_RW,
57+
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
58+
);
5959

6060
return getLinkTicketPairs(valueReader);
6161
}
@@ -74,10 +74,10 @@ public List<IssueLinkCount> linkTicketsInteractive(long idT1, long idT2) {
7474
return retryCtx.supplyResult(
7575
session -> {
7676
// Транзакция будет изменять данные, поэтому используем режим SERIALIZABLE_RW
77-
var tx = session.createNewTransaction(TxMode.SERIALIZABLE_RW);
77+
var tx = new TransactionHelper(session.createNewTransaction(TxMode.SERIALIZABLE_RW));
7878

7979
// Обновляем счетчики связей
80-
tx.createQuery("""
80+
tx.executeQuery("""
8181
DECLARE $t1 AS Int64;
8282
DECLARE $t2 AS Int64;
8383
@@ -86,30 +86,29 @@ public List<IssueLinkCount> linkTicketsInteractive(long idT1, long idT2) {
8686
WHERE id IN ($t1, $t2);
8787
""",
8888
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
89-
).execute().join().getStatus().expectSuccess();
89+
);
9090

9191
// Добавляем записи о связях между тикетами
92-
tx.createQuery("""
92+
tx.executeQuery("""
9393
DECLARE $t1 AS Int64;
9494
DECLARE $t2 AS Int64;
9595
9696
INSERT INTO links (source, destination)
9797
VALUES ($t1, $t2), ($t2, $t1);
9898
""",
9999
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
100-
).execute().join().getStatus().expectSuccess();
100+
);
101101

102102
// Читаем обновленные данные и фиксируем транзакцию
103-
var valueReader = QueryReader.readFrom(
104-
tx.createQueryWithCommit("""
105-
DECLARE $t1 AS Int64;
106-
DECLARE $t2 AS Int64;
107-
108-
SELECT id, link_count FROM issues
109-
WHERE id IN ($t1, $t2)
110-
""",
111-
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2)))
112-
).join().getValue();
103+
var valueReader = tx.executeQueryWithCommit("""
104+
DECLARE $t1 AS Int64;
105+
DECLARE $t2 AS Int64;
106+
107+
SELECT id, link_count FROM issues
108+
WHERE id IN ($t1, $t2)
109+
""",
110+
Params.of("$t1", PrimitiveValue.newInt64(idT1), "$t2", PrimitiveValue.newInt64(idT2))
111+
);
113112

114113
var linkTicketPairs = getLinkTicketPairs(valueReader);
115114

@@ -128,25 +127,22 @@ public void addIssue(String title, String author) {
128127
var id = ThreadLocalRandom.current().nextLong();
129128
var now = Instant.now();
130129

131-
retryCtx.supplyResult(
132-
session -> session.createQuery(
133-
"""
134-
DECLARE $id AS Int64;
135-
DECLARE $title AS Text;
136-
DECLARE $created_at AS Timestamp;
137-
DECLARE $author AS Text;
138-
UPSERT INTO issues (id, title, created_at, author)
139-
VALUES ($id, $title, $created_at, $author);
140-
""",
141-
TxMode.SERIALIZABLE_RW,
142-
Params.of(
143-
"$id", PrimitiveValue.newInt64(id),
144-
"$title", PrimitiveValue.newText(title),
145-
"$created_at", PrimitiveValue.newTimestamp(now),
146-
"$author", PrimitiveValue.newText(author)
147-
)
148-
).execute()
149-
).join().getStatus().expectSuccess("Failed upsert title");
130+
queryServiceHelper.executeQuery("""
131+
DECLARE $id AS Int64;
132+
DECLARE $title AS Text;
133+
DECLARE $created_at AS Timestamp;
134+
DECLARE $author AS Text;
135+
UPSERT INTO issues (id, title, created_at, author)
136+
VALUES ($id, $title, $created_at, $author);
137+
""",
138+
TxMode.SERIALIZABLE_RW,
139+
Params.of(
140+
"$id", PrimitiveValue.newInt64(id),
141+
"$title", PrimitiveValue.newText(title),
142+
"$created_at", PrimitiveValue.newTimestamp(now),
143+
"$author", PrimitiveValue.newText(author)
144+
)
145+
);
150146
}
151147

152148
/**
@@ -156,11 +152,11 @@ UPSERT INTO issues (id, title, created_at, author)
156152
*/
157153
public List<Issue> findAll() {
158154
var titles = new ArrayList<Issue>();
159-
var resultSet = retryCtx.supplyResult(
160-
session -> QueryReader.readFrom(
161-
session.createQuery("SELECT id, title, created_at, author, COALESCE(link_count, 0) FROM issues;", TxMode.SNAPSHOT_RO)
162-
)
163-
).join().getValue();
155+
var resultSet = queryServiceHelper.executeQuery(
156+
"SELECT id, title, created_at, author, COALESCE(link_count, 0) FROM issues;",
157+
TxMode.SNAPSHOT_RO,
158+
Params.empty()
159+
);
164160

165161
var resultSetReader = resultSet.getResultSet(0);
166162

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package tech.ydb.app;
2+
3+
import tech.ydb.common.transaction.TxMode;
4+
import tech.ydb.query.tools.QueryReader;
5+
import tech.ydb.query.tools.SessionRetryContext;
6+
import tech.ydb.table.query.Params;
7+
8+
/**
9+
* @author Kirill Kurdyukov
10+
*/
11+
public class QueryServiceHelper {
12+
13+
// Контекст для автоматических повторных попыток выполнения запросов
14+
// Принимается извне через конструктор для:
15+
// 1. Следования принципу Dependency Injection - зависимости класса передаются ему извне
16+
// 2. Улучшения тестируемости - можно передать mock-объект для тестов
17+
// 3. Централизованного управления конфигурацией ретраев
18+
// 4. Возможности переиспользования одного контекста для разных репозиториев
19+
private final SessionRetryContext retryCtx;
20+
21+
public QueryServiceHelper(SessionRetryContext retryCtx) {
22+
this.retryCtx = retryCtx;
23+
}
24+
25+
public void executeQuery(String yql) {
26+
retryCtx.supplyResult(
27+
session -> QueryReader.readFrom(session.createQuery(yql, TxMode.NONE))
28+
).join().getValue();
29+
}
30+
31+
public QueryReader executeQuery(String yql, TxMode txMode, Params params) {
32+
return retryCtx.supplyResult(
33+
session -> QueryReader.readFrom(session.createQuery(yql, txMode, params))
34+
).join().getValue();
35+
}
36+
}

0 commit comments

Comments
 (0)