@@ -137,7 +137,7 @@ public class CassandraStatement extends AbstractStatement
137
137
* The consistency level used for the statement.
138
138
*/
139
139
protected ConsistencyLevel consistencyLevel ;
140
-
140
+ private boolean isClosed ;
141
141
private DriverExecutionProfile customTimeoutProfile ;
142
142
143
143
/**
@@ -210,6 +210,7 @@ public class CassandraStatement extends AbstractStatement
210
210
this .cql = cql ;
211
211
this .batchQueries = new ArrayList <>();
212
212
this .consistencyLevel = connection .getDefaultConsistencyLevel ();
213
+ this .isClosed = false ;
213
214
214
215
if (!(resultSetType == ResultSet .TYPE_FORWARD_ONLY
215
216
|| resultSetType == ResultSet .TYPE_SCROLL_INSENSITIVE
@@ -264,7 +265,7 @@ public void clearWarnings() throws SQLException {
264
265
265
266
@ Override
266
267
public void close () {
267
- this .connection = null ;
268
+ this .isClosed = true ;
268
269
this .cql = null ;
269
270
}
270
271
@@ -284,67 +285,68 @@ private void doExecute(final String cql) throws SQLException {
284
285
285
286
try {
286
287
final String [] cqlQueries = cql .split (STATEMENTS_SEPARATOR_REGEX );
287
- if (cqlQueries .length > 1 && !(cql .trim ().toLowerCase ().startsWith ("begin" )
288
+ if (cqlQueries .length > 1
289
+ && !(cql .trim ().toLowerCase ().startsWith ("begin" )
288
290
&& cql .toLowerCase ().contains ("batch" ) && cql .toLowerCase ().contains ("apply" ))) {
289
- // Several statements in the query to execute asynchronously...
290
-
291
291
final ArrayList <com .datastax .oss .driver .api .core .cql .ResultSet > results = new ArrayList <>();
292
+
293
+ // Several statements in the query to execute asynchronously...
292
294
if (cqlQueries .length > MAX_ASYNC_QUERIES * 1.1 ) {
293
295
// Protect the cluster from receiving too many queries at once and force the dev to split the load
294
296
throw new SQLNonTransientException ("Too many queries at once (" + cqlQueries .length
295
297
+ "). You must split your queries into more batches !" );
296
298
}
297
299
298
- StringBuilder prevCqlQuery = new StringBuilder ();
299
- for (final String cqlQuery : cqlQueries ) {
300
- if ((cqlQuery .contains ("'" ) && ((StringUtils .countMatches (cqlQuery , "'" ) % 2 == 1
301
- && prevCqlQuery .length () == 0 )
302
- || (StringUtils .countMatches (cqlQuery , "'" ) % 2 == 0 && prevCqlQuery .length () > 0 )))
303
- || (prevCqlQuery .toString ().length () > 0 && !cqlQuery .contains ("'" ))) {
304
- prevCqlQuery .append (cqlQuery ).append (";" );
305
- } else {
306
- prevCqlQuery .append (cqlQuery );
307
- if (LOG .isTraceEnabled () || this .connection .isDebugMode ()) {
308
- LOG .debug ("CQL: {}" , prevCqlQuery );
309
- }
310
- SimpleStatement stmt = SimpleStatement .newInstance (prevCqlQuery .toString ())
311
- .setConsistencyLevel (this .connection .getDefaultConsistencyLevel ())
312
- .setPageSize (this .fetchSize );
313
- if (this .customTimeoutProfile != null ) {
314
- stmt = stmt .setExecutionProfile (this .customTimeoutProfile );
300
+ // If we should not execute the queries asynchronously, for example if they must be executed in the
301
+ // specified order (e.g. in Liquibase scripts with queries such as CREATE TABLE t, then
302
+ // INSERT INTO t ...).
303
+ if (!this .connection .getOptionSet ().executeMultipleQueriesByStatementAsync ()) {
304
+ for (final String cqlQuery : cqlQueries ) {
305
+ final com .datastax .oss .driver .api .core .cql .ResultSet rs = executeSingleStatement (cqlQuery );
306
+ results .add (rs );
307
+ }
308
+ } else {
309
+ StringBuilder prevCqlQuery = new StringBuilder ();
310
+ for (final String cqlQuery : cqlQueries ) {
311
+ if ((cqlQuery .contains ("'" ) && ((StringUtils .countMatches (cqlQuery , "'" ) % 2 == 1
312
+ && prevCqlQuery .length () == 0 )
313
+ || (StringUtils .countMatches (cqlQuery , "'" ) % 2 == 0 && prevCqlQuery .length () > 0 )))
314
+ || (!prevCqlQuery .toString ().isEmpty () && !cqlQuery .contains ("'" ))) {
315
+ prevCqlQuery .append (cqlQuery ).append (";" );
316
+ } else {
317
+ prevCqlQuery .append (cqlQuery );
318
+ if (LOG .isTraceEnabled () || this .connection .isDebugMode ()) {
319
+ LOG .debug ("CQL: {}" , prevCqlQuery );
320
+ }
321
+ SimpleStatement stmt = SimpleStatement .newInstance (prevCqlQuery .toString ())
322
+ .setConsistencyLevel (this .connection .getDefaultConsistencyLevel ())
323
+ .setPageSize (this .fetchSize );
324
+ if (this .customTimeoutProfile != null ) {
325
+ stmt = stmt .setExecutionProfile (this .customTimeoutProfile );
326
+ }
327
+ final CompletionStage <AsyncResultSet > resultSetFuture =
328
+ ((CqlSession ) this .connection .getSession ()).executeAsync (stmt );
329
+ futures .add (resultSetFuture );
330
+ prevCqlQuery = new StringBuilder ();
315
331
}
316
- final CompletionStage <AsyncResultSet > resultSetFuture =
317
- ((CqlSession ) this .connection .getSession ()).executeAsync (stmt );
318
- futures .add (resultSetFuture );
319
- prevCqlQuery = new StringBuilder ();
320
332
}
321
- }
322
333
323
- for (final CompletionStage <AsyncResultSet > future : futures ) {
324
- final AsyncResultSet asyncResultSet = CompletableFutures .getUninterruptibly (future );
325
- final com .datastax .oss .driver .api .core .cql .ResultSet rows ;
326
- if (asyncResultSet .hasMorePages ()) {
327
- rows = new MultiPageResultSet (asyncResultSet );
328
- } else {
329
- rows = new SinglePageResultSet (asyncResultSet );
334
+ for (final CompletionStage <AsyncResultSet > future : futures ) {
335
+ final AsyncResultSet asyncResultSet = CompletableFutures .getUninterruptibly (future );
336
+ final com .datastax .oss .driver .api .core .cql .ResultSet rows ;
337
+ if (asyncResultSet .hasMorePages ()) {
338
+ rows = new MultiPageResultSet (asyncResultSet );
339
+ } else {
340
+ rows = new SinglePageResultSet (asyncResultSet );
341
+ }
342
+ results .add (rows );
330
343
}
331
- results .add (rows );
332
344
}
333
345
334
346
this .currentResultSet = new CassandraResultSet (this , results );
335
347
} else {
336
348
// Only one statement to execute, so do it synchronously.
337
- if (LOG .isTraceEnabled () || this .connection .isDebugMode ()) {
338
- LOG .debug ("CQL: " + cql );
339
- }
340
- SimpleStatement stmt = SimpleStatement .newInstance (cql )
341
- .setConsistencyLevel (this .connection .getDefaultConsistencyLevel ())
342
- .setPageSize (this .fetchSize );
343
- if (this .customTimeoutProfile != null ) {
344
- stmt = stmt .setExecutionProfile (this .customTimeoutProfile );
345
- }
346
- this .currentResultSet = new CassandraResultSet (this ,
347
- ((CqlSession ) this .connection .getSession ()).execute (stmt ));
349
+ this .currentResultSet = new CassandraResultSet (this , executeSingleStatement (cql ));
348
350
}
349
351
} catch (final Exception e ) {
350
352
for (final CompletionStage <AsyncResultSet > future : futures ) {
@@ -354,6 +356,19 @@ private void doExecute(final String cql) throws SQLException {
354
356
}
355
357
}
356
358
359
+ private com .datastax .oss .driver .api .core .cql .ResultSet executeSingleStatement (final String cql ) {
360
+ if (LOG .isTraceEnabled () || this .connection .isDebugMode ()) {
361
+ LOG .debug ("CQL: " + cql );
362
+ }
363
+ SimpleStatement stmt = SimpleStatement .newInstance (cql )
364
+ .setConsistencyLevel (this .connection .getDefaultConsistencyLevel ())
365
+ .setPageSize (this .fetchSize );
366
+ if (this .customTimeoutProfile != null ) {
367
+ stmt = stmt .setExecutionProfile (this .customTimeoutProfile );
368
+ }
369
+ return ((CqlSession ) this .connection .getSession ()).execute (stmt );
370
+ }
371
+
357
372
@ Override
358
373
public boolean execute (final String query ) throws SQLException {
359
374
checkNotClosed ();
@@ -647,7 +662,7 @@ public SQLWarning getWarnings() throws SQLException {
647
662
648
663
@ Override
649
664
public boolean isClosed () {
650
- return this .connection == null ;
665
+ return this .isClosed ;
651
666
}
652
667
653
668
/**
0 commit comments