1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.jdbc;
25
26 import java.sql.Connection;
27 import java.sql.ResultSet;
28 import java.sql.SQLException;
29 import java.sql.SQLWarning;
30 import java.sql.Statement;
31
32 import javax.jcr.RepositoryException;
33 import javax.jcr.query.QueryResult;
34
35 import org.modeshape.jdbc.delegate.RepositoryDelegate;
36
37
38
39 class JcrStatement implements Statement {
40
41
42 private final JcrConnection connection;
43 private QueryResult jcrResults;
44 private ResultSet results;
45 private boolean closed;
46 private SQLWarning warning;
47 private int rowLimit = -1;
48 private int fetchDirection = ResultSet.FETCH_FORWARD;
49 private boolean poolable;
50 private int moreResults = 0;
51
52 private String sqlLanguage = JcrConnection.JCR_SQL2;
53
54 JcrStatement( JcrConnection connection) {
55 this.connection = connection;
56 assert this.connection != null;
57 }
58
59 JcrConnection connection() {
60 return this.connection;
61 }
62
63 public void setJcrSqlLanguage(String jcrSQL) {
64 this.sqlLanguage = (jcrSQL != null ? jcrSQL : JcrConnection.JCR_SQL2);
65 }
66
67
68
69
70
71
72
73
74
75 @Override
76 public int getFetchSize() throws SQLException {
77 notClosed();
78 return 0;
79 }
80
81
82
83
84
85
86
87
88
89 @Override
90 public void setFetchSize( int rows ) throws SQLException {
91 notClosed();
92 }
93
94
95
96
97
98
99 @Override
100 public int getFetchDirection() throws SQLException {
101 notClosed();
102 return fetchDirection;
103 }
104
105
106
107
108
109
110 @Override
111 public void setFetchDirection( int direction ) throws SQLException {
112 notClosed();
113 if (direction != ResultSet.FETCH_FORWARD && direction != ResultSet.FETCH_REVERSE && direction != ResultSet.FETCH_UNKNOWN) {
114 throw new SQLException(JdbcI18n.invalidArgument.text(direction, "" + ResultSet.FETCH_FORWARD + ", "
115 + ResultSet.FETCH_REVERSE + ", "
116 + ResultSet.FETCH_UNKNOWN));
117 }
118 fetchDirection = direction;
119 }
120
121
122
123
124
125
126
127
128
129 @Override
130 public int getMaxFieldSize() throws SQLException {
131 notClosed();
132 return 0;
133 }
134
135
136
137
138
139
140 @Override
141 public void setMaxFieldSize( int max ) throws SQLException {
142 notClosed();
143 if (max < 0) {
144 throw new SQLException(JdbcI18n.argumentMayNotBeNegative.text("max", max));
145 }
146
147 }
148
149
150
151
152
153
154 @Override
155 public int getMaxRows() throws SQLException {
156 notClosed();
157
158
159
160 return (rowLimit == -1 ? 0 : rowLimit);
161 }
162
163
164
165
166
167
168 @Override
169 public void setMaxRows( int max ) throws SQLException {
170 notClosed();
171 if (max < 0) {
172 throw new SQLException(JdbcI18n.argumentMayNotBeNegative.text("max", max));
173 }
174 rowLimit = max;
175 }
176
177
178
179
180
181
182
183
184
185 @Override
186 public int getQueryTimeout() throws SQLException {
187 notClosed();
188 return 0;
189 }
190
191
192
193
194
195
196 @Override
197 public void setQueryTimeout( int seconds ) throws SQLException {
198 notClosed();
199 if (seconds < 0) {
200 throw new SQLException(JdbcI18n.argumentMayNotBeNegative.text("seconds", seconds));
201 }
202
203 }
204
205
206
207
208
209
210 @Override
211 public boolean isPoolable() throws SQLException {
212 notClosed();
213 return poolable;
214 }
215
216
217
218
219
220
221 @Override
222 public void setPoolable( boolean poolable ) throws SQLException {
223 notClosed();
224 this.poolable = poolable;
225 }
226
227
228
229
230
231
232 @Override
233 public Connection getConnection() throws SQLException {
234 notClosed();
235 return connection;
236 }
237
238
239
240
241
242
243 @Override
244 public void cancel() throws SQLException {
245 notClosed();
246
247 }
248
249
250
251
252
253
254 @Override
255 public void clearWarnings() throws SQLException {
256 notClosed();
257 warning = null;
258 }
259
260
261
262
263
264
265 @Override
266 public SQLWarning getWarnings() throws SQLException {
267 notClosed();
268 return warning;
269 }
270
271
272
273
274
275
276 @Override
277 public boolean isClosed() {
278 return closed || connection.isClosed();
279 }
280
281
282
283
284
285
286 @Override
287 public void close() {
288 if (!closed) {
289 closed = true;
290 }
291 }
292
293 protected final void notClosed() throws SQLException {
294 if (isClosed()) throw new SQLException(JdbcI18n.statementIsClosed.text());
295 }
296
297 protected final void noUpdates() throws SQLException {
298 throw new SQLException(JdbcI18n.updatesNotSupported.text());
299 }
300
301
302
303
304
305
306
307
308
309 @Override
310 public int executeUpdate( String sql ) throws SQLException {
311 notClosed();
312 noUpdates();
313 return 0;
314 }
315
316
317
318
319
320
321 @Override
322 public int executeUpdate( String sql,
323 int autoGeneratedKeys ) throws SQLException {
324 notClosed();
325 noUpdates();
326 return 0;
327 }
328
329
330
331
332
333
334 @Override
335 public int executeUpdate( String sql,
336 int[] columnIndexes ) throws SQLException {
337 notClosed();
338 noUpdates();
339 return 0;
340 }
341
342
343
344
345
346
347 @Override
348 public int executeUpdate( String sql,
349 String[] columnNames ) throws SQLException {
350 notClosed();
351 noUpdates();
352 return 0;
353 }
354
355
356
357
358
359
360 @Override
361 public void setCursorName( String name ) throws SQLException {
362 notClosed();
363 noUpdates();
364 }
365
366
367
368
369
370
371 @Override
372 public int getUpdateCount() throws SQLException {
373 notClosed();
374 return -1;
375 }
376
377
378
379
380
381
382 @Override
383 public void addBatch( String sql ) throws SQLException {
384 notClosed();
385 noUpdates();
386 }
387
388
389
390
391
392
393 @Override
394 public void clearBatch() throws SQLException {
395 notClosed();
396 noUpdates();
397 }
398
399
400
401
402
403
404 @Override
405 public int[] executeBatch() throws SQLException {
406 notClosed();
407 noUpdates();
408 return null;
409 }
410
411
412
413
414
415
416
417
418
419
420 @Override
421 public boolean execute( String sql ) throws SQLException {
422 notClosed();
423 warning = null;
424 moreResults = 0;
425 try {
426
427 String jcrSql2 = connection.nativeSQL(sql);
428
429 jcrResults = getJcrRepositoryDelegate().execute(jcrSql2, this.sqlLanguage);
430 results = new JcrResultSet(this, jcrResults, null);
431 moreResults = 1;
432 } catch (RepositoryException e) {
433 throw new SQLException(e.getLocalizedMessage(), e);
434 }
435 return true;
436 }
437
438 protected RepositoryDelegate getJcrRepositoryDelegate() {
439 return this.connection.getRepositoryDelegate();
440 }
441
442
443
444
445
446
447
448
449 @Override
450 public boolean execute( String sql,
451 int autoGeneratedKeys ) throws SQLException {
452 return execute(sql);
453 }
454
455
456
457
458
459
460 @Override
461 public boolean execute( String sql,
462 int[] columnIndexes ) throws SQLException {
463 return execute(sql);
464 }
465
466
467
468
469
470
471 @Override
472 public boolean execute( String sql,
473 String[] columnNames ) throws SQLException {
474 return execute(sql);
475 }
476
477
478
479
480
481
482 @Override
483 public ResultSet executeQuery( String sql ) throws SQLException {
484 execute(sql);
485 return getResultSet();
486 }
487
488
489
490
491
492
493 @Override
494 public ResultSet getGeneratedKeys() throws SQLException {
495
496
497 return new JcrResultSet();
498 }
499
500
501
502
503
504
505 @Override
506 public boolean getMoreResults() throws SQLException {
507 notClosed();
508 return moreResults > 0;
509 }
510
511
512
513
514
515
516 @Override
517 public boolean getMoreResults( int current ) throws SQLException {
518 notClosed();
519 if (current != CLOSE_ALL_RESULTS && current != CLOSE_CURRENT_RESULT && current != KEEP_CURRENT_RESULT) {
520 throw new SQLException(JdbcI18n.invalidArgument.text(current, "" + CLOSE_ALL_RESULTS + ", " + CLOSE_CURRENT_RESULT
521 + ", " + KEEP_CURRENT_RESULT));
522 }
523 if (KEEP_CURRENT_RESULT != current) {
524
525 jcrResults = null;
526 results = null;
527 }
528 if (moreResults > 0) --moreResults;
529 return moreResults > 0;
530 }
531
532
533
534
535
536
537 @Override
538 public ResultSet getResultSet() throws SQLException {
539 notClosed();
540 return results;
541 }
542
543
544
545
546
547
548 @Override
549 public int getResultSetConcurrency() throws SQLException {
550 notClosed();
551 return ResultSet.CONCUR_READ_ONLY;
552 }
553
554
555
556
557
558
559 @Override
560 public int getResultSetHoldability() throws SQLException {
561 notClosed();
562 return ResultSet.CLOSE_CURSORS_AT_COMMIT;
563 }
564
565
566
567
568
569
570 @Override
571 public int getResultSetType() throws SQLException {
572 notClosed();
573 return ResultSet.TYPE_SCROLL_INSENSITIVE;
574 }
575
576
577
578
579
580
581 @Override
582 public void setEscapeProcessing( boolean enable ) throws SQLException {
583 notClosed();
584
585 }
586
587
588
589
590
591
592 @Override
593 public boolean isWrapperFor( Class<?> iface )
594 return iface.isInstance(this) ;
595 }
596
597
598
599
600
601
602 @Override
603 public <T> T unwrap( Class<T> iface ) throws SQLException {
604 if (!isWrapperFor(iface)) {
605 throw new SQLException(JdbcI18n.classDoesNotImplementInterface.text(Statement.class.getSimpleName(),
606 iface.getName()));
607 }
608
609 return iface.cast(this);
610 }
611
612 }