Skip to content

Commit 43f6435

Browse files
committed
Add Integration Test for Complex Types
1 parent 4ed19c2 commit 43f6435

2 files changed

Lines changed: 142 additions & 22 deletions

File tree

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package de.bytefish.pgbulkinsert.test;
2+
3+
import de.bytefish.pgbulkinsert.PgBulkInsert;
4+
import org.junit.jupiter.api.AfterAll;
5+
import org.junit.jupiter.api.BeforeAll;
6+
import org.junit.jupiter.api.BeforeEach;
7+
import org.junit.jupiter.api.Test;
8+
9+
import java.io.IOException;
10+
import java.io.InputStream;
11+
import java.sql.Connection;
12+
import java.sql.DriverManager;
13+
import java.sql.ResultSet;
14+
import java.sql.Statement;
15+
import java.util.List;
16+
import java.util.Properties;
17+
import java.util.UUID;
18+
19+
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
import static org.junit.jupiter.api.Assertions.assertTrue;
21+
22+
import static de.bytefish.pgbulkinsert.PgBulkInsert.*;
23+
24+
public class FirewallRuleIntegrationTest {
25+
26+
private static Connection connection;
27+
28+
public record FirewallRule(UUID ruleId, String serverName, List<PgBulkInsert.PgRange<Integer>> openPorts) {}
29+
30+
@BeforeAll
31+
static void connect() throws Exception {
32+
33+
Properties properties = getProperties("db.properties");
34+
35+
connection = DriverManager.getConnection(
36+
properties.getProperty("db.url"),
37+
properties.getProperty("db.user"),
38+
properties.getProperty("db.password"));
39+
40+
try (Statement stmt = connection.createStatement()) {
41+
stmt.execute("""
42+
CREATE TABLE IF NOT EXISTS firewall_rules (
43+
rule_id uuid PRIMARY KEY,
44+
server_name text,
45+
open_ports int4range[]
46+
)
47+
""");
48+
}
49+
}
50+
51+
@BeforeEach
52+
void cleanTable() throws Exception {
53+
try (Statement stmt = connection.createStatement()) {
54+
stmt.execute("TRUNCATE TABLE firewall_rules;");
55+
}
56+
}
57+
58+
@AfterAll
59+
static void disconnect() throws Exception {
60+
if (connection != null && !connection.isClosed()) {
61+
connection.close();
62+
}
63+
}
64+
65+
@Test
66+
void testInsertInt4RangeArray() throws Exception {
67+
PgMapper<FirewallRule> mapper = PgMapper.forClass(FirewallRule.class)
68+
.map("rule_id", PostgresTypes.UUID.from(FirewallRule::ruleId))
69+
.map("server_name", PostgresTypes.TEXT.from(FirewallRule::serverName))
70+
.map("open_ports", PostgresTypes.array(PostgresTypes.INT4RANGE).from(FirewallRule::openPorts));
71+
72+
PgBulkWriter<FirewallRule> writer = new PgBulkWriter<>(mapper);
73+
74+
FirewallRule webServer = new FirewallRule(
75+
UUID.randomUUID(),
76+
"prod-web-01",
77+
List.of(
78+
PgRange.closed(80, 80), // [80, 80]
79+
PgRange.closedOpen(8000, 8081), // [8000, 8081)
80+
PgRange.atLeast(50000) // [50000, infinity)
81+
)
82+
);
83+
84+
// Act
85+
writer.saveAll(connection, "firewall_rules", List.of(webServer));
86+
87+
// Assert
88+
try (Statement stmt = connection.createStatement()) {
89+
ResultSet rs = stmt.executeQuery(
90+
"SELECT server_name, open_ports::text as ports_text FROM firewall_rules WHERE server_name = 'prod-web-01'"
91+
);
92+
93+
assertTrue(rs.next());
94+
assertEquals("prod-web-01", rs.getString("server_name"));
95+
96+
String savedPorts = rs.getString("ports_text");
97+
98+
System.out.println("Array stored in Postgres: " + savedPorts);
99+
100+
assertTrue(savedPorts.contains("[8000,8081)"));
101+
assertTrue(savedPorts.contains("[50000,)"));
102+
}
103+
}
104+
105+
private static Properties getProperties(String filename) {
106+
107+
Properties props = new Properties();
108+
109+
InputStream is = ClassLoader.getSystemResourceAsStream(filename);
110+
111+
try {
112+
props.load(is);
113+
}
114+
catch (IOException e) {
115+
throw new RuntimeException("Could not load unittest.properties", e);
116+
}
117+
118+
return props;
119+
}
120+
}

PgBulkInsert/src/test/java/de/bytefish/pgbulkinsert/test/IntegrationTest.java

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package de.bytefish.pgbulkinsert.test;
22

3-
import de.bytefish.pgbulkinsert.PgBulkInsert;
43
import org.junit.jupiter.api.AfterAll;
54
import org.junit.jupiter.api.BeforeAll;
65
import org.junit.jupiter.api.Test;
@@ -25,6 +24,7 @@
2524

2625
import static org.junit.jupiter.api.Assertions.assertEquals;
2726
import static org.junit.jupiter.api.Assertions.assertTrue;
27+
import static de.bytefish.pgbulkinsert.PgBulkInsert.*;
2828

2929
public class IntegrationTest {
3030

@@ -82,30 +82,30 @@ public record TestEntity(
8282
LocalDate dateVal,
8383
LocalTime timeVal,
8484
Instant timestampTzVal,
85-
PgBulkInsert.PgRange<Integer> intRange,
86-
PgBulkInsert.PgRange<LocalDateTime> tsRange,
85+
PgRange<Integer> intRange,
86+
PgRange<LocalDateTime> tsRange,
8787
List<String> tags
8888
) {}
8989

9090
@Test
9191
public void testBulkInsertSavesDataCorrectly() throws Exception {
9292

9393
// Build the Test Subject
94-
PgBulkInsert.PgMapper<TestEntity> mapper = PgBulkInsert.PgMapper.forClass(TestEntity.class)
95-
.map("id", PgBulkInsert.PostgresTypes.INT8.primitive(TestEntity::id))
96-
.map("text_val", PgBulkInsert.PostgresTypes.TEXT.removeNullCharacters().from(TestEntity::textVal))
97-
.map("numeric_val", PgBulkInsert.PostgresTypes.NUMERIC.from(TestEntity::numericVal))
98-
.map("numeric_int_val", PgBulkInsert.PostgresTypes.NUMERIC_INTEGER.from(TestEntity::numericIntVal))
99-
.map("is_active", PgBulkInsert.PostgresTypes.BOOLEAN.primitive(TestEntity::isActive))
100-
.map("created_at", PgBulkInsert.PostgresTypes.TIMESTAMP.localDateTime(TestEntity::createdAt))
101-
.map("date_val", PgBulkInsert.PostgresTypes.DATE.from(TestEntity::dateVal))
102-
.map("time_val", PgBulkInsert.PostgresTypes.TIME.from(TestEntity::timeVal))
103-
.map("timestamptz_val", PgBulkInsert.PostgresTypes.TIMESTAMPTZ.instant(TestEntity::timestampTzVal))
104-
.map("int_range", PgBulkInsert.PostgresTypes.range(PgBulkInsert.PostgresTypes.INT4).from(TestEntity::intRange))
105-
.map("ts_range", PgBulkInsert.PostgresTypes.range(PgBulkInsert.PostgresTypes.TIMESTAMP).from(TestEntity::tsRange))
106-
.map("tags", PgBulkInsert.PostgresTypes.array(PgBulkInsert.PostgresTypes.TEXT).from(TestEntity::tags));
107-
108-
PgBulkInsert.PgBulkWriter<TestEntity> writer = new PgBulkInsert.PgBulkWriter<>(mapper);
94+
PgMapper<TestEntity> mapper = PgMapper.forClass(TestEntity.class)
95+
.map("id", PostgresTypes.INT8.primitive(TestEntity::id))
96+
.map("text_val", PostgresTypes.TEXT.removeNullCharacters().from(TestEntity::textVal))
97+
.map("numeric_val", PostgresTypes.NUMERIC.from(TestEntity::numericVal))
98+
.map("numeric_int_val", PostgresTypes.NUMERIC_INTEGER.from(TestEntity::numericIntVal))
99+
.map("is_active", PostgresTypes.BOOLEAN.primitive(TestEntity::isActive))
100+
.map("created_at", PostgresTypes.TIMESTAMP.localDateTime(TestEntity::createdAt))
101+
.map("date_val", PostgresTypes.DATE.from(TestEntity::dateVal))
102+
.map("time_val", PostgresTypes.TIME.from(TestEntity::timeVal))
103+
.map("timestamptz_val", PostgresTypes.TIMESTAMPTZ.instant(TestEntity::timestampTzVal))
104+
.map("int_range", PostgresTypes.range(PostgresTypes.INT4).from(TestEntity::intRange))
105+
.map("ts_range", PostgresTypes.range(PostgresTypes.TIMESTAMP).from(TestEntity::tsRange))
106+
.map("tags", PostgresTypes.array(PostgresTypes.TEXT).from(TestEntity::tags));
107+
108+
PgBulkWriter<TestEntity> writer = new PgBulkWriter<>(mapper);
109109

110110
// Arrange
111111
LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MICROS); // Postgres speichert auf Mikrosekunden genau
@@ -117,16 +117,16 @@ public void testBulkInsertSavesDataCorrectly() throws Exception {
117117
new TestEntity(
118118
1L, "Normaler Text", new BigDecimal("42.1234"), new BigInteger("98765432101234567890987654321"), true, now,
119119
today, timeNow, instantNow,
120-
PgBulkInsert.PgRange.closedOpen(1, 100),
121-
PgBulkInsert.PgRange.closed(now.minusDays(1), now),
120+
PgRange.closedOpen(1, 100),
121+
PgRange.closed(now.minusDays(1), now),
122122
List.of("java", "postgres")
123123
),
124124
// Invalid Null to be removed
125125
new TestEntity(
126126
2L, "Fieser \u0000 Text", new BigDecimal("-99.99"), new BigInteger("-12345678909876543210123456789"), false, now.minusDays(1),
127127
today.minusDays(1), timeNow.minusHours(1), instantNow.minus(1, ChronoUnit.DAYS),
128-
PgBulkInsert.PgRange.emptyRange(),
129-
PgBulkInsert.PgRange.atLeast(now),
128+
PgRange.emptyRange(),
129+
PgRange.atLeast(now),
130130
Arrays.asList("test", null, "array")
131131
)
132132
);

0 commit comments

Comments
 (0)