Skip to content

Commit b05edbc

Browse files
Implement Fetch query (#216)
## What is the goal of this PR? We update to the newest version of TypeDB Driver which supports Fetch queries. For more details on fetch queries, see typedb/typeql#300
1 parent 90e0a92 commit b05edbc

File tree

6 files changed

+83
-56
lines changed

6 files changed

+83
-56
lines changed

TypeDBConsole.java

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525
import com.vaticle.typedb.driver.api.TypeDBTransaction;
2626
import com.vaticle.typedb.driver.api.answer.ConceptMap;
2727
import com.vaticle.typedb.driver.api.answer.ConceptMapGroup;
28-
import com.vaticle.typedb.driver.api.answer.Numeric;
29-
import com.vaticle.typedb.driver.api.answer.NumericGroup;
28+
import com.vaticle.typedb.driver.api.answer.JSON;
29+
import com.vaticle.typedb.driver.api.answer.ValueGroup;
30+
import com.vaticle.typedb.driver.api.concept.value.Value;
3031
import com.vaticle.typedb.driver.api.database.Database;
3132
import com.vaticle.typedb.driver.api.user.User;
3233
import com.vaticle.typedb.driver.common.exception.TypeDBDriverException;
@@ -41,8 +42,9 @@
4142
import com.vaticle.typeql.lang.common.exception.TypeQLException;
4243
import com.vaticle.typeql.lang.query.TypeQLDefine;
4344
import com.vaticle.typeql.lang.query.TypeQLDelete;
45+
import com.vaticle.typeql.lang.query.TypeQLFetch;
4446
import com.vaticle.typeql.lang.query.TypeQLInsert;
45-
import com.vaticle.typeql.lang.query.TypeQLMatch;
47+
import com.vaticle.typeql.lang.query.TypeQLGet;
4648
import com.vaticle.typeql.lang.query.TypeQLQuery;
4749
import com.vaticle.typeql.lang.query.TypeQLUndefine;
4850
import com.vaticle.typeql.lang.query.TypeQLUpdate;
@@ -148,11 +150,7 @@ private static CLIOptions parseCLIOptions(String[] args) {
148150
try {
149151
int exitCode = CLI.execute(args);
150152
if (exitCode == 0) {
151-
if (CLI.isUsageHelpRequested()) {
152-
CLI.usage(CLI.getOut());
153-
System.exit(0);
154-
} else if (CLI.isVersionHelpRequested()) {
155-
CLI.printVersionHelp(CLI.getOut());
153+
if (CLI.isUsageHelpRequested() || CLI.isVersionHelpRequested()) {
156154
System.exit(0);
157155
} else {
158156
return options;
@@ -321,7 +319,6 @@ private boolean transactionREPL(TypeDBDriver driver, boolean isEnterprise, Strin
321319
}
322320
if (command.isSecond()) {
323321
printer.error(command.second());
324-
continue;
325322
} else {
326323
TransactionREPLCommand replCommand = command.first();
327324
if (replCommand.isExit()) {
@@ -364,7 +361,7 @@ private boolean runScriptMode(CLIOptions options, String script) {
364361
}
365362

366363
private boolean runInlineCommandMode(CLIOptions options, List<String> inlineCommands) {
367-
inlineCommands = inlineCommands.stream().map(x -> x.trim()).filter(x -> !x.isEmpty()).collect(toList());
364+
inlineCommands = inlineCommands.stream().map(String::trim).filter(x -> !x.isEmpty()).collect(toList());
368365
boolean[] cancelled = new boolean[]{false};
369366
terminal.handle(Terminal.Signal.INT, s -> cancelled[0] = true);
370367
boolean isEnterprise = options.enterprise() != null;
@@ -674,15 +671,15 @@ private RunQueriesResult runSource(TypeDBTransaction tx, String file, boolean pr
674671

675672
private RunQueriesResult runQueries(TypeDBTransaction tx, String queryString) {
676673
Optional<List<TypeQLQuery>> queries = parseQueries(queryString);
677-
if (!queries.isPresent()) return RunQueriesResult.error();
678-
queries.get().stream().forEach(query -> runQuery(tx, query));
674+
if (queries.isEmpty()) return RunQueriesResult.error();
675+
queries.get().forEach(query -> runQuery(tx, query));
679676
boolean hasChanges = queries.get().stream().anyMatch(query -> query.type() == TypeQLArg.QueryType.WRITE);
680677
return new RunQueriesResult(true, hasChanges);
681678
}
682679

683680
private RunQueriesResult runQueriesPrintAnswers(TypeDBTransaction tx, String queryString) {
684681
Optional<List<TypeQLQuery>> queries = parseQueries(queryString);
685-
if (!queries.isPresent()) return RunQueriesResult.error();
682+
if (queries.isEmpty()) return RunQueriesResult.error();
686683
queries.get().forEach(query -> runQueryPrintAnswers(tx, query));
687684
boolean hasChanges = queries.get().stream().anyMatch(query -> query.type() == TypeQLArg.QueryType.WRITE);
688685
return new RunQueriesResult(true, hasChanges);
@@ -691,37 +688,39 @@ private RunQueriesResult runQueriesPrintAnswers(TypeDBTransaction tx, String que
691688
@SuppressWarnings("CheckReturnValue")
692689
private void runQuery(TypeDBTransaction tx, TypeQLQuery query) {
693690
if (query instanceof TypeQLDefine) {
694-
tx.query().define(query.asDefine());
691+
tx.query().define(query.asDefine()).resolve();
695692
printer.info("Concepts have been defined");
696693
} else if (query instanceof TypeQLUndefine) {
697-
tx.query().undefine(query.asUndefine());
694+
tx.query().undefine(query.asUndefine()).resolve();
698695
printer.info("Concepts have been undefined");
699696
} else if (query instanceof TypeQLInsert) {
700697
Optional<ConceptMap> ignore = tx.query().insert(query.asInsert()).findFirst();
701698
} else if (query instanceof TypeQLDelete) {
702-
tx.query().delete(query.asDelete());
699+
tx.query().delete(query.asDelete()).resolve();
703700
} else if (query instanceof TypeQLUpdate) {
704701
Optional<ConceptMap> ignore = tx.query().update(query.asUpdate()).findFirst();
705-
} else if (query instanceof TypeQLMatch) {
706-
Optional<ConceptMap> ignore = tx.query().match(query.asMatch()).findFirst();
707-
} else if (query instanceof TypeQLMatch.Aggregate) {
708-
Numeric ignore = tx.query().match(query.asMatchAggregate());
709-
} else if (query instanceof TypeQLMatch.Group) {
710-
Optional<ConceptMapGroup> ignore = tx.query().match(query.asMatchGroup()).findFirst();
711-
} else if (query instanceof TypeQLMatch.Group.Aggregate) {
712-
Optional<NumericGroup> ignore = tx.query().match(query.asMatchGroupAggregate()).findFirst();
702+
} else if (query instanceof TypeQLGet) {
703+
Optional<ConceptMap> ignore = tx.query().get(query.asGet()).findFirst();
704+
} else if (query instanceof TypeQLGet.Aggregate) {
705+
Optional<Value> ignore = tx.query().get(query.asGetAggregate()).resolve();
706+
} else if (query instanceof TypeQLGet.Group) {
707+
Optional<ConceptMapGroup> ignore = tx.query().get(query.asGetGroup()).findFirst();
708+
} else if (query instanceof TypeQLGet.Group.Aggregate) {
709+
Optional<ValueGroup> ignore = tx.query().get(query.asGetGroupAggregate()).findFirst();
710+
} else if (query instanceof TypeQLFetch) {
711+
Optional<JSON> ignore = tx.query().fetch(query.asFetch()).findFirst();
713712
} else {
714713
throw new TypeDBConsoleException("Query is of unrecognized type: " + query);
715714
}
716715
}
717716

718717
private void runQueryPrintAnswers(TypeDBTransaction tx, TypeQLQuery query) {
719718
if (query instanceof TypeQLDefine) {
720-
tx.query().define(query.asDefine());
719+
tx.query().define(query.asDefine()).resolve();
721720
printer.info("Concepts have been defined");
722721
hasUncommittedChanges = true;
723722
} else if (query instanceof TypeQLUndefine) {
724-
tx.query().undefine(query.asUndefine());
723+
tx.query().undefine(query.asUndefine()).resolve();
725724
printer.info("Concepts have been undefined");
726725
hasUncommittedChanges = true;
727726
} else if (query instanceof TypeQLInsert) {
@@ -733,9 +732,11 @@ private void runQueryPrintAnswers(TypeDBTransaction tx, TypeQLQuery query) {
733732
});
734733
if (changed.get()) hasUncommittedChanges = true;
735734
} else if (query instanceof TypeQLDelete) {
736-
long limitedCount = tx.query().match(query.asDelete().match()).limit(20).count();
735+
Optional<TypeQLQuery.MatchClause> match = query.asDelete().match();
736+
assert match.isPresent();
737+
long limitedCount = tx.query().get(match.get().get()).limit(20).count();
737738
if (limitedCount > 0) {
738-
tx.query().delete(query.asDelete());
739+
tx.query().delete(query.asDelete()).resolve();
739740
if (limitedCount == 20) printer.info("Deleted from 20+ matched answers");
740741
else printer.info("Deleted from " + limitedCount + " matched answer(s)");
741742
hasUncommittedChanges = true;
@@ -750,17 +751,20 @@ private void runQueryPrintAnswers(TypeDBTransaction tx, TypeQLQuery query) {
750751
printer.conceptMap(x, tx);
751752
});
752753
if (changed.get()) hasUncommittedChanges = true;
753-
} else if (query instanceof TypeQLMatch) {
754-
Stream<ConceptMap> result = tx.query().match(query.asMatch());
754+
} else if (query instanceof TypeQLGet) {
755+
Stream<ConceptMap> result = tx.query().get(query.asGet());
755756
printCancellableResult(result, x -> printer.conceptMap(x, tx));
756-
} else if (query instanceof TypeQLMatch.Aggregate) {
757-
printer.numeric(tx.query().match(query.asMatchAggregate()));
758-
} else if (query instanceof TypeQLMatch.Group) {
759-
Stream<ConceptMapGroup> result = tx.query().match(query.asMatchGroup());
757+
} else if (query instanceof TypeQLGet.Aggregate) {
758+
printer.value(tx.query().get(query.asGetAggregate()).resolve().orElse(null));
759+
} else if (query instanceof TypeQLGet.Group) {
760+
Stream<ConceptMapGroup> result = tx.query().get(query.asGetGroup());
760761
printCancellableResult(result, x -> printer.conceptMapGroup(x, tx));
761-
} else if (query instanceof TypeQLMatch.Group.Aggregate) {
762-
Stream<NumericGroup> result = tx.query().match(query.asMatchGroupAggregate());
763-
printCancellableResult(result, x -> printer.numericGroup(x, tx));
762+
} else if (query instanceof TypeQLGet.Group.Aggregate) {
763+
Stream<ValueGroup> result = tx.query().get(query.asGetGroupAggregate());
764+
printCancellableResult(result, x -> printer.valueGroup(x, tx));
765+
} else if (query instanceof TypeQLFetch) {
766+
Stream<JSON> result = tx.query().fetch(query.asFetch());
767+
printCancellableResult(result, printer::json);
764768
} else {
765769
throw new TypeDBConsoleException("Query is of unrecognized type: " + query);
766770
}
@@ -790,15 +794,19 @@ private <T> void printCancellableResult(Stream<T> results, Consumer<T> printFn)
790794
prevHandler = terminal.handle(Terminal.Signal.INT, s -> answerPrintingJob.cancel(true));
791795
answerPrintingJob.get();
792796
Instant end = Instant.now();
793-
printer.info("answers: " + counter[0] + ", total (with concept details) duration: " + Duration.between(start, end).toMillis() + " ms");
797+
printer.info("");
798+
printer.info("answers: " + counter[0] + ", total duration: " + Duration.between(start, end).toMillis() + " ms");
799+
printer.info("");
794800
} catch (InterruptedException e) {
795801
e.printStackTrace();
796802
} catch (ExecutionException e) {
797803
throw (TypeDBDriverException) e.getCause();
798804
} catch (CancellationException e) {
799805
Instant end = Instant.now();
800-
printer.info("answers: " + counter[0] + ", total (with concept details) duration: " + Duration.between(start, end).toMillis() + " ms");
806+
printer.info("");
807+
printer.info("answers: " + counter[0] + ", total duration: " + Duration.between(start, end).toMillis() + " ms");
801808
printer.info("The query has been cancelled. It may take some time for the cancellation to finish on the server side.");
809+
printer.info("");
802810
} finally {
803811
if (prevHandler != null) terminal.handle(Terminal.Signal.INT, prevHandler);
804812
}

WORKSPACE

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,17 @@ unuseddeps_deps()
119119
load("@vaticle_dependencies//tool/sonarcloud:deps.bzl", "sonarcloud_dependencies")
120120
sonarcloud_dependencies()
121121

122+
# Load //tool/docs
123+
load("@vaticle_dependencies//tool/docs:python_deps.bzl", docs_deps = "deps")
124+
docs_deps()
125+
load("@vaticle_dependencies_tool_docs//:requirements.bzl", install_doc_deps = "install_deps")
126+
install_doc_deps()
127+
128+
load("@vaticle_dependencies//tool/docs:java_deps.bzl", java_doc_deps = "deps")
129+
java_doc_deps()
130+
load("@google_bazel_common//:workspace_defs.bzl", "google_common_workspace_rules")
131+
google_common_workspace_rules()
132+
122133
######################################
123134
# Load @vaticle_bazel_distribution #
124135
######################################

common/Printer.java

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import com.vaticle.typedb.driver.api.TypeDBTransaction;
2121
import com.vaticle.typedb.driver.api.answer.ConceptMap;
2222
import com.vaticle.typedb.driver.api.answer.ConceptMapGroup;
23-
import com.vaticle.typedb.driver.api.answer.Numeric;
24-
import com.vaticle.typedb.driver.api.answer.NumericGroup;
23+
import com.vaticle.typedb.driver.api.answer.JSON;
24+
import com.vaticle.typedb.driver.api.answer.ValueGroup;
2525
import com.vaticle.typedb.driver.api.concept.Concept;
2626
import com.vaticle.typedb.driver.api.concept.thing.Attribute;
2727
import com.vaticle.typedb.driver.api.concept.thing.Relation;
@@ -38,11 +38,13 @@
3838
import java.io.PrintStream;
3939
import java.util.ArrayList;
4040
import java.util.Arrays;
41+
import java.util.Comparator;
4142
import java.util.List;
4243
import java.util.Map;
4344
import java.util.stream.Collectors;
4445

4546
import static com.vaticle.typedb.console.common.exception.ErrorMessage.Internal.ILLEGAL_CAST;
47+
import static com.vaticle.typedb.console.common.exception.ErrorMessage.Internal.ILLEGAL_STATE;
4648
import static com.vaticle.typeql.lang.common.TypeQLToken.Constraint.ISA;
4749
import static java.util.stream.Collectors.joining;
4850

@@ -75,12 +77,21 @@ public void conceptMapGroup(ConceptMapGroup answer, TypeDBTransaction tx) {
7577
out.println("}");
7678
}
7779

78-
public void numeric(Numeric answer) {
79-
out.println(answer.asNumber());
80+
public void json(JSON json) {
81+
out.println(json.toString());
8082
}
8183

82-
public void numericGroup(NumericGroup answer, TypeDBTransaction tx) {
83-
out.println(conceptDisplayString(answer.owner(), tx) + " => " + answer.numeric().asNumber());
84+
public void value(Value answer) {
85+
out.println(stringifyNumericValue(answer));
86+
}
87+
88+
public void valueGroup(ValueGroup answer, TypeDBTransaction tx) {
89+
out.println(conceptDisplayString(answer.owner(), tx) + " => " + stringifyNumericValue(answer.value().orElse(null)));
90+
}
91+
92+
private static String stringifyNumericValue(Value value) {
93+
if (value == null) return "NaN";
94+
else return value.toString();
8495
}
8596

8697
public void databaseReplica(Database.Replica replica) {
@@ -146,9 +157,7 @@ private String valueDisplayString(Value value) {
146157
}
147158

148159
private String isaDisplayString(Thing thing) {
149-
StringBuilder sb = new StringBuilder();
150-
sb.append(colorKeyword(ISA.toString())).append(" ").append(colorType(thing.getType().getLabel().scopedName()));
151-
return sb.toString();
160+
return colorKeyword(ISA.toString()) + " " + colorType(thing.getType().getLabel().scopedName());
152161
}
153162

154163
private String relationDisplayString(Relation relation, TypeDBTransaction tx) {
@@ -168,11 +177,7 @@ private String relationDisplayString(Relation relation, TypeDBTransaction tx) {
168177
}
169178

170179
private String iidDisplayString(Thing thing) {
171-
StringBuilder sb = new StringBuilder();
172-
sb.append(colorKeyword(TypeQLToken.Constraint.IID.toString()))
173-
.append(" ")
174-
.append(thing.getIID());
175-
return sb.toString();
180+
return colorKeyword(TypeQLToken.Constraint.IID.toString()) + " " + thing.getIID();
176181
}
177182

178183
private String typeDisplayString(Type type, TypeDBTransaction tx) {
@@ -183,7 +188,7 @@ private String typeDisplayString(Type type, TypeDBTransaction tx) {
183188
.append(colorType(type.getLabel().toString()));
184189

185190
if (!type.isRoot()) {
186-
Type superType = type.getSupertype(tx);
191+
Type superType = type.getSupertype(tx).resolve();
187192
sb.append(" ")
188193
.append(colorKeyword(TypeQLToken.Constraint.SUB.toString()))
189194
.append(" ")

common/exception/ErrorMessage.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public static class TransactionRepl extends ErrorMessage {
5353
}
5454

5555
public static class Internal extends ErrorMessage {
56+
public static final Internal ILLEGAL_STATE =
57+
new Internal(1, "Illegal internal state!");
5658
public static final Internal ILLEGAL_CAST =
5759
new Internal(2, "Illegal casting operation from '%s' to '%s'.");
5860

dependencies/maven/artifacts.snapshot

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
@maven//:org_jline_jline_3_17_1
115115
@maven//:org_jline_jline_terminal_3_17_1
116116
@maven//:org_jline_jline_terminal_jansi_3_17_1
117+
@maven//:org_jsoup_jsoup_1_16_1
117118
@maven//:org_mockito_mockito_core_2_6_4
118119
@maven//:org_objenesis_objenesis_2_5
119120
@maven//:org_slf4j_jcl_over_slf4j_2_0_0

dependencies/vaticle/repositories.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def vaticle_dependencies():
2121
git_repository(
2222
name = "vaticle_dependencies",
2323
remote = "https://github.com/vaticle/dependencies",
24-
commit = "23b42ae6bd857dea03cf123d45942995b5dfa0ca", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
24+
commit = "6843746768973d441be943b0f7c5c9b3ac7a88a9", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
2525
)
2626

2727
def vaticle_typedb_common():
@@ -35,5 +35,5 @@ def vaticle_typedb_driver():
3535
git_repository(
3636
name = "vaticle_typedb_driver",
3737
remote = "https://github.com/vaticle/typedb-driver",
38-
tag = "2.24.15", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_driver
38+
commit = "fa567227e5349d43e207155a377a14669a0163ce", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_driver
3939
)

0 commit comments

Comments
 (0)