|
29 | 29 | import com.vaticle.typedb.client.api.answer.NumericGroup; |
30 | 30 | import com.vaticle.typedb.client.api.connection.database.Database; |
31 | 31 | import com.vaticle.typedb.client.api.connection.user.User; |
| 32 | +import com.vaticle.typedb.client.api.query.QueryFuture; |
32 | 33 | import com.vaticle.typedb.client.common.exception.TypeDBClientException; |
33 | 34 | import com.vaticle.typedb.common.collection.Either; |
34 | 35 | import com.vaticle.typedb.common.util.Java; |
|
72 | 73 | import java.util.Iterator; |
73 | 74 | import java.util.List; |
74 | 75 | import java.util.Objects; |
| 76 | +import java.util.Optional; |
75 | 77 | import java.util.concurrent.CancellationException; |
| 78 | +import java.util.concurrent.CompletableFuture; |
76 | 79 | import java.util.concurrent.ExecutionException; |
77 | 80 | import java.util.concurrent.ExecutorService; |
78 | 81 | import java.util.concurrent.Executors; |
@@ -305,9 +308,9 @@ private boolean transactionREPL(TypeDBClient client, String database, TypeDBSess |
305 | 308 | runClose(tx); |
306 | 309 | break; |
307 | 310 | } else if (replCommand.isSource()) { |
308 | | - runSource(tx, replCommand.asSource().file()); |
| 311 | + runSource(tx, replCommand.asSource().file(), replCommand.asSource().printAnswers()); |
309 | 312 | } else if (replCommand.isQuery()) { |
310 | | - runQuery(tx, replCommand.asQuery().query()); |
| 313 | + runQueriesPrintAnswers(tx, replCommand.asQuery().query()); |
311 | 314 | } |
312 | 315 | } |
313 | 316 | } |
@@ -390,10 +393,11 @@ private boolean runInlineCommandMode(CLIOptions options, List<String> inlineComm |
390 | 393 | runClose(tx); |
391 | 394 | break; |
392 | 395 | } else if (txCommand.first().isSource()) { |
393 | | - boolean success = runSource(tx, txCommand.first().asSource().file()); |
| 396 | + TransactionREPLCommand.Source source = txCommand.first().asSource(); |
| 397 | + boolean success = runSource(tx, source.file(), source.printAnswers()); |
394 | 398 | if (!success) return false; |
395 | 399 | } else if (txCommand.first().isQuery()) { |
396 | | - boolean success = runQuery(tx, txCommand.first().asQuery().query()); |
| 400 | + boolean success = runQueriesPrintAnswers(tx, txCommand.first().asQuery().query()); |
397 | 401 | if (!success) return false; |
398 | 402 | } else { |
399 | 403 | printer.error("Command is not available while running console script."); |
@@ -579,59 +583,112 @@ private void runClose(TypeDBTransaction tx) { |
579 | 583 | else printer.info("Transaction closed"); |
580 | 584 | } |
581 | 585 |
|
582 | | - private boolean runSource(TypeDBTransaction tx, String file) { |
| 586 | + private boolean runSource(TypeDBTransaction tx, String file, boolean printAnswers) { |
583 | 587 | try { |
584 | 588 | String queryString = new String(Files.readAllBytes(Paths.get(file)), StandardCharsets.UTF_8); |
585 | | - return runQuery(tx, queryString); |
| 589 | + if (printAnswers) return runQueriesPrintAnswers(tx, queryString); |
| 590 | + else return runQueries(tx, queryString); |
586 | 591 | } catch (IOException e) { |
587 | 592 | printer.error("Failed to open file '" + file + "'"); |
588 | 593 | return false; |
589 | 594 | } |
590 | 595 | } |
591 | 596 |
|
592 | | - private boolean runQuery(TypeDBTransaction tx, String queryString) { |
593 | | - List<TypeQLQuery> queries; |
| 597 | + private boolean runQueries(TypeDBTransaction tx, String queryString) { |
| 598 | + Optional<List<TypeQLQuery>> queries = parseQueries(queryString); |
| 599 | + if (!queries.isPresent()) return false; |
| 600 | + CompletableFuture.allOf(queries.get().stream().map(query -> runQuery(tx, query)) |
| 601 | + .toArray(CompletableFuture[]::new)).join(); |
| 602 | + return true; |
| 603 | + } |
| 604 | + |
| 605 | + private boolean runQueriesPrintAnswers(TypeDBTransaction tx, String queryString) { |
| 606 | + Optional<List<TypeQLQuery>> queries = parseQueries(queryString); |
| 607 | + if (!queries.isPresent()) return false; |
| 608 | + queries.get().forEach(query -> runQueryPrintAnswers(tx, query)); |
| 609 | + return true; |
| 610 | + } |
| 611 | + |
| 612 | + @SuppressWarnings("CheckReturnValue") |
| 613 | + private CompletableFuture<Void> runQuery(TypeDBTransaction tx, TypeQLQuery query) { |
| 614 | + if (query instanceof TypeQLDefine) { |
| 615 | + tx.query().define(query.asDefine()).get(); |
| 616 | + printer.info("Concepts have been defined"); |
| 617 | + return CompletableFuture.completedFuture(null); |
| 618 | + } else if (query instanceof TypeQLUndefine) { |
| 619 | + tx.query().undefine(query.asUndefine()).get(); |
| 620 | + printer.info("Concepts have been undefined"); |
| 621 | + return CompletableFuture.completedFuture(null); |
| 622 | + } else if (query instanceof TypeQLInsert) { |
| 623 | + Stream<ConceptMap> result = tx.query().insert(query.asInsert()); |
| 624 | + return CompletableFuture.runAsync(result::findFirst); |
| 625 | + } else if (query instanceof TypeQLDelete) { |
| 626 | + QueryFuture<Void> deleteFuture = tx.query().delete(query.asDelete()); |
| 627 | + return CompletableFuture.runAsync(deleteFuture::get); |
| 628 | + } else if (query instanceof TypeQLUpdate) { |
| 629 | + Stream<ConceptMap> result = tx.query().update(query.asUpdate()); |
| 630 | + return CompletableFuture.runAsync(result::findFirst); |
| 631 | + } else if (query instanceof TypeQLMatch) { |
| 632 | + Stream<ConceptMap> result = tx.query().match(query.asMatch()); |
| 633 | + return CompletableFuture.runAsync(result::findFirst); |
| 634 | + } else if (query instanceof TypeQLMatch.Aggregate) { |
| 635 | + QueryFuture<Numeric> answerFuture = tx.query().match(query.asMatchAggregate()); |
| 636 | + return CompletableFuture.runAsync(answerFuture::get); |
| 637 | + } else if (query instanceof TypeQLMatch.Group) { |
| 638 | + Stream<ConceptMapGroup> result = tx.query().match(query.asMatchGroup()); |
| 639 | + return CompletableFuture.runAsync(result::findFirst); |
| 640 | + } else if (query instanceof TypeQLMatch.Group.Aggregate) { |
| 641 | + Stream<NumericGroup> result = tx.query().match(query.asMatchGroupAggregate()); |
| 642 | + return CompletableFuture.runAsync(result::findFirst); |
| 643 | + } else if (query instanceof TypeQLCompute) { |
| 644 | + throw new TypeDBConsoleException("Compute query is not yet supported"); |
| 645 | + } else { |
| 646 | + throw new TypeDBConsoleException("Query is of unrecognized type: " + query); |
| 647 | + } |
| 648 | + } |
| 649 | + |
| 650 | + private void runQueryPrintAnswers(TypeDBTransaction tx, TypeQLQuery query) { |
| 651 | + if (query instanceof TypeQLDefine) { |
| 652 | + tx.query().define(query.asDefine()).get(); |
| 653 | + printer.info("Concepts have been defined"); |
| 654 | + } else if (query instanceof TypeQLUndefine) { |
| 655 | + tx.query().undefine(query.asUndefine()).get(); |
| 656 | + printer.info("Concepts have been undefined"); |
| 657 | + } else if (query instanceof TypeQLInsert) { |
| 658 | + Stream<ConceptMap> result = tx.query().insert(query.asInsert()); |
| 659 | + printCancellableResult(result, x -> printer.conceptMap(x, tx)); |
| 660 | + } else if (query instanceof TypeQLDelete) { |
| 661 | + tx.query().delete(query.asDelete()).get(); |
| 662 | + printer.info("Concepts have been deleted"); |
| 663 | + } else if (query instanceof TypeQLUpdate) { |
| 664 | + Stream<ConceptMap> result = tx.query().update(query.asUpdate()); |
| 665 | + printCancellableResult(result, x -> printer.conceptMap(x, tx)); |
| 666 | + } else if (query instanceof TypeQLMatch) { |
| 667 | + Stream<ConceptMap> result = tx.query().match(query.asMatch()); |
| 668 | + printCancellableResult(result, x -> printer.conceptMap(x, tx)); |
| 669 | + } else if (query instanceof TypeQLMatch.Aggregate) { |
| 670 | + QueryFuture<Numeric> answerFuture = tx.query().match(query.asMatchAggregate()); |
| 671 | + printer.numeric(answerFuture.get()); |
| 672 | + } else if (query instanceof TypeQLMatch.Group) { |
| 673 | + Stream<ConceptMapGroup> result = tx.query().match(query.asMatchGroup()); |
| 674 | + printCancellableResult(result, x -> printer.conceptMapGroup(x, tx)); |
| 675 | + } else if (query instanceof TypeQLMatch.Group.Aggregate) { |
| 676 | + Stream<NumericGroup> result = tx.query().match(query.asMatchGroupAggregate()); |
| 677 | + printCancellableResult(result, x -> printer.numericGroup(x, tx)); |
| 678 | + } else if (query instanceof TypeQLCompute) { |
| 679 | + throw new TypeDBConsoleException("Compute query is not yet supported"); |
| 680 | + } else { |
| 681 | + throw new TypeDBConsoleException("Query is of unrecognized type: " + query); |
| 682 | + } |
| 683 | + } |
| 684 | + |
| 685 | + Optional<List<TypeQLQuery>> parseQueries(String queryString) { |
594 | 686 | try { |
595 | | - queries = TypeQL.parseQueries(queryString).collect(toList()); |
| 687 | + return Optional.of(TypeQL.parseQueries(queryString).collect(toList())); |
596 | 688 | } catch (TypeQLException e) { |
597 | 689 | printer.error(e.getMessage()); |
598 | | - return false; |
| 690 | + return Optional.empty(); |
599 | 691 | } |
600 | | - for (TypeQLQuery query : queries) { |
601 | | - if (query instanceof TypeQLDefine) { |
602 | | - tx.query().define(query.asDefine()).get(); |
603 | | - printer.info("Concepts have been defined"); |
604 | | - } else if (query instanceof TypeQLUndefine) { |
605 | | - tx.query().undefine(query.asUndefine()).get(); |
606 | | - printer.info("Concepts have been undefined"); |
607 | | - } else if (query instanceof TypeQLInsert) { |
608 | | - Stream<ConceptMap> result = tx.query().insert(query.asInsert()); |
609 | | - printCancellableResult(result, x -> printer.conceptMap(x, tx)); |
610 | | - } else if (query instanceof TypeQLDelete) { |
611 | | - tx.query().delete(query.asDelete()).get(); |
612 | | - printer.info("Concepts have been deleted"); |
613 | | - } else if (query instanceof TypeQLUpdate) { |
614 | | - Stream<ConceptMap> result = tx.query().update(query.asUpdate()); |
615 | | - printCancellableResult(result, x -> printer.conceptMap(x, tx)); |
616 | | - } else if (query instanceof TypeQLMatch) { |
617 | | - Stream<ConceptMap> result = tx.query().match(query.asMatch()); |
618 | | - printCancellableResult(result, x -> printer.conceptMap(x, tx)); |
619 | | - } else if (query instanceof TypeQLMatch.Aggregate) { |
620 | | - Numeric answer = tx.query().match(query.asMatchAggregate()).get(); |
621 | | - printer.numeric(answer); |
622 | | - } else if (query instanceof TypeQLMatch.Group) { |
623 | | - Stream<ConceptMapGroup> result = tx.query().match(query.asMatchGroup()); |
624 | | - printCancellableResult(result, x -> printer.conceptMapGroup(x, tx)); |
625 | | - } else if (query instanceof TypeQLMatch.Group.Aggregate) { |
626 | | - Stream<NumericGroup> result = tx.query().match(query.asMatchGroupAggregate()); |
627 | | - printCancellableResult(result, x -> printer.numericGroup(x, tx)); |
628 | | - } else if (query instanceof TypeQLCompute) { |
629 | | - throw new TypeDBConsoleException("Compute query is not yet supported"); |
630 | | - } else { |
631 | | - throw new TypeDBConsoleException("Query is of unrecognized type: " + query); |
632 | | - } |
633 | | - } |
634 | | - return true; |
635 | 692 | } |
636 | 693 |
|
637 | 694 | private <T> void printCancellableResult(Stream<T> results, Consumer<T> printFn) { |
|
0 commit comments