Skip to content

Commit 6c15ca6

Browse files
committed
BAEL-6767: Writing Stored Procedures for H2 in Java
1 parent 59fca51 commit 6c15ca6

File tree

3 files changed

+343
-0
lines changed

3 files changed

+343
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.baeldung.h2functions;
2+
3+
import org.junit.jupiter.api.AfterEach;
4+
import org.junit.jupiter.api.BeforeEach;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.sql.*;
8+
9+
import static org.junit.jupiter.api.Assertions.assertEquals;
10+
11+
public class BuiltInFunctionUnitTest {
12+
private static Connection connection;
13+
14+
@BeforeEach
15+
public void setUp() throws Exception {
16+
connection = DriverManager.getConnection("jdbc:h2:mem:generated", "sa", "");
17+
}
18+
19+
@AfterEach
20+
public void tearDown() throws SQLException {
21+
connection.close();
22+
}
23+
24+
@Test
25+
void whenUsingUpper_thenParametersAreUppercased() throws SQLException{
26+
try (Statement statement = connection.createStatement()) {
27+
ResultSet rs = statement.executeQuery("SELECT UPPER('Hello')");
28+
29+
rs.next();
30+
String hello = rs.getString(1);
31+
assertEquals("HELLO", hello);
32+
}
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.baeldung.h2functions;
2+
3+
import org.junit.jupiter.api.AfterEach;
4+
import org.junit.jupiter.api.BeforeEach;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.sql.*;
8+
9+
import static org.junit.jupiter.api.Assertions.assertEquals;
10+
import static org.junit.jupiter.api.Assertions.assertTrue;
11+
12+
public class CompiledFunctionUnitTest {
13+
private static Connection connection;
14+
15+
@BeforeEach
16+
public void setUp() throws Exception {
17+
connection = DriverManager.getConnection("jdbc:h2:mem:generated", "sa", "");
18+
}
19+
20+
@AfterEach
21+
public void tearDown() throws SQLException {
22+
connection.close();
23+
}
24+
25+
@Test
26+
void givenAUserDefinedFunctionAsClassReference_whenICallTheFunction_thenIGetTheResult() throws SQLException {
27+
try (Statement statement = connection.createStatement()) {
28+
statement.execute("""
29+
CREATE ALIAS JAVA_RANDOM FOR "java.lang.Math.random";
30+
""");
31+
}
32+
33+
try (PreparedStatement statement = connection.prepareStatement("SELECT JAVA_RANDOM()")) {
34+
ResultSet rs = statement.executeQuery();
35+
36+
rs.next();
37+
double rnd = rs.getDouble(1);
38+
assertTrue(rnd >= 0);
39+
assertTrue(rnd <= 1);
40+
}
41+
}
42+
43+
@Test
44+
void givenAUserDefinedFunctionAsMyOwnClassReference_whenICallTheFunction_thenIGetTheResult() throws SQLException {
45+
try (Statement statement = connection.createStatement()) {
46+
statement.execute("""
47+
CREATE ALIAS HELLO FOR "com.baeldung.h2functions.CompiledFunctionUnitTest.hello";
48+
""");
49+
}
50+
51+
try (PreparedStatement statement = connection.prepareStatement("SELECT HELLO()")) {
52+
ResultSet rs = statement.executeQuery();
53+
54+
rs.next();
55+
String hello = rs.getString(1);
56+
assertEquals("Hello", hello);
57+
}
58+
}
59+
60+
public static String hello() {
61+
return "Hello";
62+
}
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
package com.baeldung.h2functions;
2+
3+
import org.junit.jupiter.api.AfterEach;
4+
import org.junit.jupiter.api.BeforeEach;
5+
import org.junit.jupiter.api.Test;
6+
import org.junit.jupiter.params.ParameterizedTest;
7+
import org.junit.jupiter.params.provider.Arguments;
8+
import org.junit.jupiter.params.provider.MethodSource;
9+
10+
import java.io.IOException;
11+
import java.sql.*;
12+
import java.util.stream.Stream;
13+
14+
import static org.junit.jupiter.api.Assertions.*;
15+
16+
public class SourceCodeFunctionUnitTest {
17+
private static Connection connection;
18+
19+
@BeforeEach
20+
public void setUp() throws Exception {
21+
connection = DriverManager.getConnection("jdbc:h2:mem:generated", "sa", "");
22+
}
23+
24+
@AfterEach
25+
public void tearDown() throws SQLException {
26+
connection.close();
27+
}
28+
29+
@Test
30+
void givenAUserDefinedFunctionWithoutArguments_whenICallTheFunction_thenIGetTheResult() throws SQLException {
31+
try (Statement statement = connection.createStatement()) {
32+
statement.execute("""
33+
CREATE ALIAS SAY_HELLO AS '
34+
String sayHello() {
35+
return "Hello, World!";
36+
}
37+
'
38+
""");
39+
}
40+
41+
try (PreparedStatement statement = connection.prepareStatement("SELECT SAY_HELLO()")) {
42+
ResultSet rs = statement.executeQuery();
43+
44+
rs.next();
45+
String hello = rs.getString(1);
46+
assertEquals("Hello, World!", hello);
47+
}
48+
}
49+
50+
@Test
51+
void givenAUserDefinedFunctionReferencingOtherClasses_whenICallTheFunction_thenIGetTheResult() throws SQLException {
52+
try (Statement statement = connection.createStatement()) {
53+
statement.execute("""
54+
CREATE ALIAS JAVA_TIME_NOW AS '
55+
String javaTimeNow() {
56+
return java.time.Instant.now().toString();
57+
}
58+
'
59+
""");
60+
}
61+
62+
try (PreparedStatement statement = connection.prepareStatement("SELECT JAVA_TIME_NOW()")) {
63+
ResultSet rs = statement.executeQuery();
64+
65+
rs.next();
66+
String now = rs.getString(1);
67+
assertNotNull(now);
68+
}
69+
}
70+
71+
@Test
72+
void givenAUserDefinedFunctionReferencingImportedClasses_whenICallTheFunction_thenIGetTheResult() throws SQLException {
73+
try (Statement statement = connection.createStatement()) {
74+
statement.execute("""
75+
CREATE ALIAS JAVA_TIME_NOW AS '
76+
import java.time.Instant;
77+
@CODE
78+
String javaTimeNow() {
79+
return Instant.now().toString();
80+
}
81+
'
82+
""");
83+
}
84+
85+
try (PreparedStatement statement = connection.prepareStatement("SELECT JAVA_TIME_NOW()")) {
86+
ResultSet rs = statement.executeQuery();
87+
88+
rs.next();
89+
String now = rs.getString(1);
90+
assertNotNull(now);
91+
}
92+
}
93+
94+
@ParameterizedTest
95+
@MethodSource("arguments")
96+
void givenAUserDefinedFunctionWithBoxedArguments_whenICallTheFunction_thenIGetTheResult(Integer input, Boolean output) throws SQLException {
97+
try (Statement statement = connection.createStatement()) {
98+
statement.execute("""
99+
CREATE ALIAS IS_ODD AS '
100+
Boolean isOdd(Integer value) {
101+
if (value == null) {
102+
return null;
103+
}
104+
return (value % 2) != 0;
105+
}
106+
'
107+
""");
108+
}
109+
110+
try (PreparedStatement statement = connection.prepareStatement("SELECT IS_ODD(?)")) {
111+
statement.setObject(1, input);
112+
ResultSet rs = statement.executeQuery();
113+
114+
rs.next();
115+
Boolean isOdd = rs.getObject(1, Boolean.class);
116+
assertEquals(output, isOdd);
117+
}
118+
}
119+
120+
@ParameterizedTest
121+
@MethodSource("arguments")
122+
void givenAUserDefinedFunctionWithPrimitiveArguments_whenICallTheFunction_thenIGetTheResult(Integer input, Boolean output) throws SQLException {
123+
try (Statement statement = connection.createStatement()) {
124+
statement.execute("""
125+
CREATE ALIAS IS_ODD AS '
126+
boolean isOdd(int value) {
127+
return (value % 2) != 0;
128+
}
129+
'
130+
""");
131+
}
132+
133+
try (PreparedStatement statement = connection.prepareStatement("SELECT IS_ODD(?)")) {
134+
statement.setObject(1, input);
135+
ResultSet rs = statement.executeQuery();
136+
137+
rs.next();
138+
Boolean isOdd = rs.getObject(1, Boolean.class);
139+
assertEquals(output, isOdd);
140+
}
141+
}
142+
143+
private static Stream<Arguments> arguments() {
144+
return Stream.of(
145+
Arguments.of(1, true),
146+
Arguments.of(2, false),
147+
Arguments.of(null, null)
148+
);
149+
}
150+
151+
152+
@Test
153+
void givenAUserDefinedFunctionWithConnectionArgument_whenICallTheFunction_thenIGetTheResult() throws SQLException {
154+
try (Statement statement = connection.createStatement()) {
155+
statement.execute("CREATE TABLE numbers(number INTEGER NOT NULL);");
156+
statement.execute("INSERT INTO numbers (number) SELECT X FROM SYSTEM_RANGE(1, 20);");
157+
statement.execute("""
158+
CREATE ALIAS SUM_BETWEEN AS '
159+
int sumBetween(Connection con, int lower, int higher) throws SQLException {
160+
try (Statement statement = con.createStatement()) {
161+
ResultSet rs = statement.executeQuery("SELECT number FROM numbers");
162+
int result = 0;
163+
while (rs.next()) {
164+
int value = rs.getInt(1);
165+
if (value > lower && value < higher) {
166+
result += value;
167+
}
168+
}
169+
return result;
170+
}
171+
}
172+
'
173+
""");
174+
}
175+
176+
try (Statement statement = connection.createStatement()) {
177+
ResultSet rs = statement.executeQuery("SELECT SUM_BETWEEN(5, 10)");
178+
179+
rs.next();
180+
int value = rs.getInt(1);
181+
assertEquals(30, value);
182+
}
183+
}
184+
185+
@Test
186+
void givenAUserDefinedFunctionThrowingSQLException_whenICallTheFunction_thenIGetTheException() throws SQLException {
187+
try (Statement statement = connection.createStatement()) {
188+
statement.execute("""
189+
CREATE ALIAS EXCEPTIONAL AS '
190+
int exceptional() throws SQLException {
191+
throw new SQLException("Oops");
192+
}
193+
'
194+
""");
195+
}
196+
197+
try (Statement statement = connection.createStatement()) {
198+
SQLException exception = assertThrows(SQLException.class,
199+
() -> statement.executeQuery("SELECT EXCEPTIONAL()"));
200+
assertTrue(exception.getCause() instanceof SQLException);
201+
assertEquals("Oops", exception.getCause().getMessage());
202+
}
203+
}
204+
205+
@Test
206+
void givenAUserDefinedFunctionThrowingRuntimeException_whenICallTheFunction_thenIGetTheWrappedException() throws SQLException {
207+
try (Statement statement = connection.createStatement()) {
208+
statement.execute("""
209+
CREATE ALIAS EXCEPTIONAL AS '
210+
int exceptional() {
211+
throw new IllegalStateException("Oops");
212+
}
213+
'
214+
""");
215+
}
216+
217+
try (Statement statement = connection.createStatement()) {
218+
SQLException exception = assertThrows(SQLException.class,
219+
() -> statement.executeQuery("SELECT EXCEPTIONAL()"));
220+
assertTrue(exception.getCause() instanceof IllegalStateException);
221+
assertEquals("Oops", exception.getCause().getMessage());
222+
}
223+
}
224+
225+
@Test
226+
void givenAUserDefinedFunctionThrowingCheckedException_whenICallTheFunction_thenIGetTheWrappedException() throws SQLException {
227+
try (Statement statement = connection.createStatement()) {
228+
statement.execute("""
229+
CREATE ALIAS EXCEPTIONAL AS '
230+
import java.io.IOException;
231+
@CODE
232+
int exceptional() throws IOException {
233+
throw new IOException("Oops");
234+
}
235+
'
236+
""");
237+
}
238+
239+
try (Statement statement = connection.createStatement()) {
240+
SQLException exception = assertThrows(SQLException.class,
241+
() -> statement.executeQuery("SELECT EXCEPTIONAL()"));
242+
assertTrue(exception.getCause() instanceof IOException);
243+
assertEquals("Oops", exception.getCause().getMessage());
244+
}
245+
}
246+
}

0 commit comments

Comments
 (0)