Skip to content

Commit bea5902

Browse files
db: table insert list of maps
1 parent 0240d67 commit bea5902

4 files changed

Lines changed: 93 additions & 17 deletions

File tree

webtau-db/src/main/java/org/testingisdocumenting/webtau/db/DatabaseTable.java

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@
2020
import org.testingisdocumenting.webtau.data.table.TableData;
2121
import org.testingisdocumenting.webtau.db.gen.SqlQueriesGenerator;
2222
import org.testingisdocumenting.webtau.reporter.MessageToken;
23+
import org.testingisdocumenting.webtau.reporter.TokenizedMessage;
2324

2425
import java.sql.SQLException;
26+
import java.util.List;
2527
import java.util.Map;
28+
import java.util.function.Function;
29+
import java.util.function.Supplier;
30+
import java.util.stream.Stream;
2631

2732
import static org.testingisdocumenting.webtau.reporter.IntegrationTestsMessageBuilder.*;
2833
import static org.testingisdocumenting.webtau.reporter.TokenizedMessage.tokenizedMessage;
@@ -39,19 +44,22 @@ public DatabaseTable(LabeledDataSource dataSource, String name) {
3944

4045
public void insert(TableData tableData) {
4146
createAndExecuteStep(
42-
tokenizedMessage(action("inserting"), numberValue(tableData.numberOfRows()), action("row(s)"),
43-
INTO, createMessageId()),
44-
() -> tokenizedMessage(action("inserted"), numberValue(tableData.numberOfRows()), action("row(s)"),
45-
INTO, createMessageId()),
47+
insertingMessage(tableData.numberOfRows()),
48+
() -> insertedMessage(tableData.numberOfRows()),
4649
() -> insertTableStep(tableData));
4750
}
4851

52+
public void insert(List<Map<String, Object>> rows) {
53+
createAndExecuteStep(
54+
insertingMessage(rows.size()),
55+
() -> insertedMessage(rows.size()),
56+
() -> insertTableStep(rows));
57+
}
58+
4959
public void insert(Map<String, Object> row) {
5060
createAndExecuteStep(
51-
tokenizedMessage(action("inserting"), numberValue(1), action("row"),
52-
INTO, createMessageId()),
53-
() -> tokenizedMessage(action("inserted"), numberValue(1), action("row"),
54-
INTO, createMessageId()),
61+
insertingMessage(1),
62+
() -> insertedMessage(1),
5563
() -> insertRowStep(row));
5664
}
5765

@@ -63,19 +71,52 @@ public DbQuery query() {
6371
return QueryRunnerUtils.createQuery(dataSource, SqlQueriesGenerator.fullTable(name));
6472
}
6573

74+
75+
private TokenizedMessage insertingMessage(int numberOfRows) {
76+
return insertMessageWithLabel("inserting", numberOfRows);
77+
}
78+
79+
private TokenizedMessage insertedMessage(int numberOfRows) {
80+
return insertMessageWithLabel("inserted", numberOfRows);
81+
}
82+
83+
private TokenizedMessage insertMessageWithLabel(String actionLabel, int numberOfRows) {
84+
return tokenizedMessage(action(actionLabel), numberValue(numberOfRows),
85+
numberOfRows > 1 ? action("rows") : action("row"),
86+
INTO, createMessageId());
87+
}
88+
6689
private void insertTableStep(TableData tableData) {
67-
if (tableData.isEmpty()) {
90+
insertMultipleRowsStep(tableData::isEmpty,
91+
tableData::numberOfRows,
92+
() -> tableData.getHeader().getNamesStream(),
93+
(idx) -> tableData.row(idx).valuesStream());
94+
}
95+
96+
private void insertTableStep(List<Map<String, Object>> rows) {
97+
insertMultipleRowsStep(rows::isEmpty,
98+
rows::size,
99+
() -> rows.get(0).keySet().stream(),
100+
(idx) -> rows.get(idx).values().stream());
101+
}
102+
103+
private void insertMultipleRowsStep(Supplier<Boolean> isEmpty,
104+
Supplier<Integer> size,
105+
Supplier<Stream<String>> header,
106+
Function<Integer, Stream<Object>> valuesByRowIdx) {
107+
if (isEmpty.get()) {
68108
return;
69109
}
70110

71111
QueryRunner run = new QueryRunner(dataSource.getDataSource());
72112
try {
73-
Object[][] values = new Object[tableData.numberOfRows()][];
74-
for (int idx = 0; idx < tableData.numberOfRows(); idx++) {
75-
values[idx] = tableData.row(idx).valuesStream().toArray();
113+
int numberOfRows = size.get();
114+
Object[][] values = new Object[numberOfRows][];
115+
for (int idx = 0; idx < numberOfRows; idx++) {
116+
values[idx] = valuesByRowIdx.apply(idx).toArray();
76117
}
77118

78-
run.batch(SqlQueriesGenerator.insert(name, tableData.row(0)), values);
119+
run.batch(SqlQueriesGenerator.insert(name, header.get(), valuesByRowIdx.apply(0)), values);
79120
} catch (SQLException e) {
80121
throw new RuntimeException(e);
81122
}
@@ -102,4 +143,8 @@ public void leftShift(TableData tableData) {
102143
public void leftShift(Map<String, Object> row) {
103144
insert(row);
104145
}
146+
147+
public void leftShift(List<Map<String, Object>> rows) {
148+
insert(rows);
149+
}
105150
}

webtau-db/src/main/java/org/testingisdocumenting/webtau/db/gen/SqlQueriesGenerator.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818

1919
import org.testingisdocumenting.webtau.data.table.Record;
2020

21-
import java.util.Collection;
22-
import java.util.List;
21+
import java.util.Map;
2322
import java.util.stream.Collectors;
2423
import java.util.stream.Stream;
2524

@@ -31,6 +30,10 @@ public static String insert(String tableName, Record record) {
3130
return insert(tableName, record.getHeader().getNamesStream(), record.valuesStream());
3231
}
3332

33+
public static String insert(String tableName, Map<String, Object> row) {
34+
return insert(tableName, row.keySet().stream(), row.values().stream());
35+
}
36+
3437
public static String insert(String tableName, Stream<String> columnNamesStream, Stream<Object> valuesStream) {
3538
String enumeratedColumnNames = columnNamesStream.collect(Collectors.joining(", "));
3639
String questionMarks = valuesStream.map(v -> "?").collect(Collectors.joining(", "));

webtau-db/src/test/groovy/org/testingisdocumenting/webtau/db/DatabaseFacadeTest.groovy

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,21 @@ class DatabaseFacadeTest extends DatabaseBaseTest {
7171
"id1" | "nice set" | 1000 }
7272
}
7373

74+
@Test
75+
void "should insert list of maps into table"() {
76+
db.update("delete from PRICES")
77+
78+
def PRICES = db.table("PRICES")
79+
PRICES << [
80+
[id: "id1", description: "nice set", price: 1000],
81+
[id: "id2", description: "warm set", price: 2000]]
82+
83+
PRICES.should == ["*ID" | "DESCRIPTION" | "PRICE"] {
84+
___________________________________
85+
"id1" | "nice set" | 1000
86+
"id2" | "warm set" | 2000 }
87+
}
88+
7489
@Test
7590
void "use table data permute, above and guid to generate rows"() {
7691
db.update("delete from PRICES")

webtau-docs/znai/database/data-setup.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Handcrafted TableData
1+
# Handcrafted Data
22

3-
The simplest way to set up a DB state is to use handcrafted [TableData](reference/table-data).
3+
One way to set up a DB state is to use handcrafted [TableData](reference/table-data).
44

55
:include-groovy: org/testingisdocumenting/webtau/db/DatabaseFacadeTest.groovy {
66
entry: "should use data source provider for primary database",
@@ -10,6 +10,19 @@ The simplest way to set up a DB state is to use handcrafted [TableData](referenc
1010
endLine: "2000 }",
1111
commentsType: "inline"
1212
}
13+
14+
Alternatively use list of maps as the parameter to perform multiple rows insertion
15+
16+
:include-groovy: org/testingisdocumenting/webtau/db/DatabaseFacadeTest.groovy {
17+
entry: "should insert list of maps into table",
18+
title: "inserting multiple rows using list",
19+
bodyOnly: true,
20+
startLine: "def PRICES",
21+
endLine: "2000]",
22+
commentsType: "inline"
23+
}
24+
25+
Use map as the parameter to perform a single row insertion
1326

1427
:include-groovy: org/testingisdocumenting/webtau/db/DatabaseFacadeTest.groovy {
1528
entry: "should insert single row into table",

0 commit comments

Comments
 (0)