-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPreparedStatementTest.java
More file actions
212 lines (193 loc) Β· 8.82 KB
/
Copy pathPreparedStatementTest.java
File metadata and controls
212 lines (193 loc) Β· 8.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
package com.ladybugdb;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.util.*;
import java.util.stream.Collectors;
public class PreparedStatementTest extends TestBase {
@Test
void PrepStmtIsSuccess() {
String query = "MATCH (a:person) WHERE a.isStudent = $1 RETURN COUNT(*)";
try (PreparedStatement preparedStatement1 = conn.prepare(query)) {
assertNotNull(preparedStatement1);
assertTrue(preparedStatement1.isSuccess());
}
query = "MATCH (a:personnnn) WHERE a.isStudent = $1 RETURN COUNT(*)";
try (PreparedStatement preparedStatement2 = conn.prepare(query)) {
assertNotNull(preparedStatement2);
assertFalse(preparedStatement2.isSuccess());
}
}
@Test
void PrepStmtGetErrorMessage() {
String query = "MATCH (a:person) WHERE a.isStudent = $1 RETURN COUNT(*)";
try (PreparedStatement preparedStatement1 = conn.prepare(query)) {
assertNotNull(preparedStatement1);
String message = preparedStatement1.getErrorMessage();
assertTrue(message.equals(""));
}
query = "MATCH (a:personnnn) WHERE a.isStudent = $1 RETURN COUNT(*)";
try (PreparedStatement preparedStatement2 = conn.prepare(query)) {
assertNotNull(preparedStatement2);
String message = preparedStatement2.getErrorMessage();
assertTrue(message.equals("Binder exception: Table personnnn does not exist."));
}
}
@Test
void PrepStmtSpecialString() {
String query1 = "MATCH (n:movies) WHERE n.name = 'The πππ§π»ββοΈππ¦οΈππ movie' RETURN n.name";
try (PreparedStatement preparedStatement1 = conn.prepare(query1)) {
QueryResult result = conn.execute(preparedStatement1, Map.of());
while (result.hasNext()) {
String got = result.getNext().getValue(0).getValue();
assertTrue(got.equals("The πππ§π»ββοΈππ¦οΈππ movie"));
}
}
String query2 = "MATCH (n:movies) WHERE n.name = $1 RETURN n.name";
Map<String, Value> params = Map.of("1", new Value("The πππ§π»ββοΈππ¦οΈππ movie"));
try (PreparedStatement preparedStatement2 = conn.prepare(query2)) {
QueryResult result = conn.execute(preparedStatement2, params);
while (result.hasNext()) {
String got = result.getNext().getValue(0).getValue();
assertTrue(got.equals("The πππ§π»ββοΈππ¦οΈππ movie"));
}
}
}
@Test
void executeWithRawBoxedString() {
// Option A: raw String value auto-converted by C++ layer
String query = "MATCH (n:person) WHERE n.fName = $1 RETURN n.fName";
try (PreparedStatement ps = conn.prepare(query)) {
Map<String, Object> raw = new HashMap<>();
raw.put("1", "Alice");
@SuppressWarnings("unchecked")
Map<String, ?> params = (Map<String, ?>) (Map<?, ?>) raw;
QueryResult result = conn.execute(ps, params);
assertTrue(result.isSuccess());
assertTrue(result.hasNext());
String got = result.getNext().getValue(0).getValue();
assertEquals("Alice", got);
}
}
@Test
void executeWithRawBoxedLong() {
// Option A: raw Long value auto-converted by C++ layer
String query = "MATCH (n:person) WHERE n.ID = $1 RETURN n.fName";
try (PreparedStatement ps = conn.prepare(query)) {
Map<String, Object> raw = new HashMap<>();
raw.put("1", 0L);
@SuppressWarnings("unchecked")
Map<String, ?> params = (Map<String, ?>) (Map<?, ?>) raw;
QueryResult result = conn.execute(ps, params);
assertTrue(result.isSuccess());
assertTrue(result.hasNext());
String got = result.getNext().getValue(0).getValue();
assertEquals("Alice", got);
}
}
@Test
void executeWithRawBoxedDouble() {
// Option A: raw Double value auto-converted
String query = "MATCH (n:person) WHERE n.eyeSight = $1 RETURN n.fName";
try (PreparedStatement ps = conn.prepare(query)) {
Map<String, Object> raw = new HashMap<>();
raw.put("1", 5.0);
@SuppressWarnings("unchecked")
Map<String, ?> params = (Map<String, ?>) (Map<?, ?>) raw;
QueryResult result = conn.execute(ps, params);
assertTrue(result.isSuccess());
assertTrue(result.hasNext());
String got = result.getNext().getValue(0).getValue();
assertEquals("Alice", got);
}
}
@Test
void executeWithRawBoxedBoolean() {
// Option A: raw Boolean value auto-converted
String query = "MATCH (n:person) WHERE n.isStudent = $1 RETURN n.fName";
try (PreparedStatement ps = conn.prepare(query)) {
Map<String, Object> raw = new HashMap<>();
raw.put("1", true);
@SuppressWarnings("unchecked")
Map<String, ?> params = (Map<String, ?>) (Map<?, ?>) raw;
QueryResult result = conn.execute(ps, params);
assertTrue(result.isSuccess());
assertTrue(result.hasNext());
}
}
@Test
void executeWithUnsupportedTypeThrows() {
// Option B: unsupported type throws IllegalArgumentException instead of crashing
String query = "MATCH (n:person) WHERE n.fName = $1 RETURN n.fName";
try (PreparedStatement ps = conn.prepare(query)) {
Map<String, Object> raw = new HashMap<>();
raw.put("1", new ArrayList<>(List.of("not", "supported")));
@SuppressWarnings("unchecked")
Map<String, ?> params = (Map<String, ?>) (Map<?, ?>) raw;
assertThrows(IllegalArgumentException.class, () -> {
conn.execute(ps, params);
});
}
}
@Test
void executeWithValueWrappedParamsRegression() {
// Regression: Value-wrapped path is unchanged
String query = "MATCH (n:person) WHERE n.fName = $1 RETURN n.fName";
try (PreparedStatement ps = conn.prepare(query)) {
Map<String, Value> params = Map.of("1", new Value("Alice"));
QueryResult result = conn.execute(ps, params);
assertTrue(result.isSuccess());
assertTrue(result.hasNext());
String got = result.getNext().getValue(0).getValue();
assertEquals("Alice", got);
}
}
@Test
void executeWithMixedRawAndValueParams() {
// Option A: mixed raw and Value-wrapped params
String query = "MATCH (n:person) WHERE n.fName = $1 AND n.age = $2 RETURN n.fName";
try (PreparedStatement ps = conn.prepare(query)) {
Map<String, Object> raw = new HashMap<>();
raw.put("1", new Value("Alice"));
raw.put("2", 35L);
@SuppressWarnings("unchecked")
Map<String, ?> params = (Map<String, ?>) (Map<?, ?>) raw;
QueryResult result = conn.execute(ps, params);
assertTrue(result.isSuccess());
assertTrue(result.hasNext());
}
}
@Test
void executeWithNullParamThrows() {
// After the refactor, nulls are caught on the Java side with a clear
// error message naming the offending key, instead of crashing inside
// the JNI conversion ladder.
String query = "MATCH (n:person) WHERE n.fName = $1 RETURN n.fName";
try (PreparedStatement ps = conn.prepare(query)) {
Map<String, Object> raw = new HashMap<>();
raw.put("1", null);
@SuppressWarnings("unchecked")
Map<String, ?> params = (Map<String, ?>) (Map<?, ?>) raw;
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> {
conn.execute(ps, params);
});
assertTrue(ex.getMessage().contains("'1'"),
"exception should name the offending key, got: " + ex.getMessage());
}
}
@Test
void executeWithValueCreateNullParam() {
// Value.createNull() is the explicit way to bind a SQL NULL; it should
// round-trip cleanly through the new coercion path.
String query = "MATCH (n:person) WHERE n.fName = $1 RETURN n.fName";
try (PreparedStatement ps = conn.prepare(query)) {
Map<String, Object> raw = new HashMap<>();
raw.put("1", Value.createNull());
@SuppressWarnings("unchecked")
Map<String, ?> params = (Map<String, ?>) (Map<?, ?>) raw;
QueryResult result = conn.execute(ps, params);
assertTrue(result.isSuccess());
// SQL NULL never matches n.fName, so no rows.
assertFalse(result.hasNext());
}
}
}