Skip to content

Commit 71a2db0

Browse files
adding new type of as query to woql
1 parent 8d7b7df commit 71a2db0

File tree

3 files changed

+110
-67
lines changed

3 files changed

+110
-67
lines changed

dist/terminus-client.min.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/terminus-client.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/woql.js

Lines changed: 106 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,15 @@ function WOQLQuery(query){
109109
* Takes an array of variables, an optional array of column names
110110
*/
111111
WOQLQuery.prototype.get = function(arr1, arr2, target){
112-
var map = this.buildAsClauses(arr1, arr2);
112+
if(arr1.json){
113+
var map = arr1.json();
114+
target = arr2;
115+
}
116+
else {
117+
var map = this.buildAsClauses(arr1, arr2);
118+
}
113119
if(target){
120+
if(target.json) target = target.json();
114121
this.cursor['get'] = [map, target];
115122
}
116123
else {
@@ -122,18 +129,18 @@ WOQLQuery.prototype.get = function(arr1, arr2, target){
122129

123130
WOQLQuery.prototype.buildAsClauses = function(vars, cols){
124131
var clauses = [];
125-
if(vars){
132+
if(vars && typeof vars == "object" && vars.length){
126133
for(var i = 0; i<vars.length; i++){
127134
var v = vars[i];
128-
if(cols){
135+
if(cols && typeof cols == "object" && cols.length){
129136
var c = cols[i];
130137
if(typeof c == "string"){
131138
c = {"@value": c};
132139
}
133140
clauses.push({as: [c, v]});
134141
}
135142
else {
136-
clauses.push({as: [v]});
143+
v.as ? clauses.push(v) : clauses.push({as: [v]});
137144
}
138145
}
139146
}
@@ -549,9 +556,15 @@ WOQLQuery.prototype.deleteProperty = function(p, graph){
549556
* Language elements that cannot be invoked from the top level and therefore are not exposed in the WOQL api
550557
*/
551558
WOQLQuery.prototype.as = function(a, b){
559+
if(!a || !b) return;
560+
if(!this.asArray){
561+
this.asArray = true;
562+
this.query = [];
563+
}
552564
b = (b.indexOf(":") == -1 ? "v:" + b : b);
553-
this.cursor['as'] = [{ "@value" : a}, b];
554-
return this.lastUpdate();
565+
var val = (typeof a == "object" ? a : { "@value" : a});
566+
this.query.push({as: [val, b]});
567+
return this;
555568
}
556569

557570
/**
@@ -1086,52 +1099,67 @@ WOQLQuery.prototype.prettyPrint = function(indent, show_context, q, fluent){
10861099
q = (q ? q : this.query);
10871100
var str = "";
10881101
const newlining_operators = ["get", "from", "into"];
1089-
const non_chaining_operators = ["and", "or"];
10901102
for(var operator in q){
10911103
//ignore context in pretty print
10921104
if(operator == "@context") {
10931105
if( show_context){
10941106
var c = this.getContext();
1095-
if(c) str += "@context: " + JSON.stringify(c);
1107+
if(c) str += "@context: " + JSON.stringify(c) + "\n";
10961108
}
10971109
continue;
10981110
}
1099-
if(operator == "true"){
1100-
str += "true";
1101-
continue;
1102-
}
1103-
if(operator == "false"){
1104-
str += "false";
1105-
continue;
1106-
}
1107-
if(fluent){
1108-
str += "." + operator;
1109-
}
1110-
else {
1111-
var inline = indent - this.indent;
1112-
if(inline){
1113-
str += "\n" + nspaces(inline);
1114-
}
1115-
str += "WOQL." + operator;
1116-
}
1111+
//statement starts differently depending on indent and whether it is fluent style or regular function style
1112+
str += this.getWOQLPrelude(operator, fluent, indent - this.indent);
11171113
var val = q[operator];
1118-
if(typeof val[val.length-1] == "object" && typeof val[val.length-1]['@value'] == "undefined" && typeof val[val.length-1]['@type'] == "undefined" && typeof val[val.length-1]['value'] == "undefined" && non_chaining_operators.indexOf(operator) == -1){
1114+
if(this.chainable(operator, val[val.length-1])){
1115+
//all arguments up until the last are regular function arguments
11191116
str += this.uncleanArguments(operator, val.slice(0, val.length-1), indent, show_context);
11201117
if(newlining_operators.indexOf(operator) !== -1){
1118+
//some fluent function calls demand a linebreak..
11211119
str += "\n" + nspaces(indent-this.indent);
11221120
}
1121+
//recursive call to query included in tail
11231122
str += this.prettyPrint(indent, show_context, val[val.length-1], true);
11241123
}
11251124
else {
1125+
//non chainable operators all live inside the function call parameters
11261126
str += this.uncleanArguments(operator, val, indent, show_context);
11271127
}
11281128
}
1129+
//remove any trailing dots in the chain (only exist in incompletely specified queries)
11291130
if(str.substring(str.length-1) == "."){
11301131
str = str.substring(0, str.length-1);
11311132
}
11321133
return str;
11331134
}
11341135

1136+
/**
1137+
* Gets the starting characters for a WOQL query - varies depending on how the query is invoked and how indented it is
1138+
*/
1139+
WOQLQuery.prototype.getWOQLPrelude = function(operator, fluent, inline){
1140+
if(operator === "true" || operator === "false"){
1141+
return operator;
1142+
}
1143+
if(fluent){
1144+
return "." + operator;
1145+
}
1146+
return (inline ? "\n" + nspaces(inline) : "") + "WOQL." + operator;
1147+
}
1148+
1149+
/**
1150+
* Determines whether a given operator can have a chained query as its last argument
1151+
*/
1152+
WOQLQuery.prototype.chainable = function(operator, lastArg){
1153+
const non_chaining_operators = ["and", "or"];
1154+
if(typeof lastArg == "object" && typeof lastArg['@value'] == "undefined" && typeof lastArg['@type'] == "undefined" && typeof lastArg['value'] == "undefined" && non_chaining_operators.indexOf(operator) == -1){
1155+
return true;
1156+
}
1157+
return false;
1158+
}
1159+
1160+
/**
1161+
* Transforms arguments to WOQL functions from the internal (clean) version, to the WOQL.js human-friendly version
1162+
*/
11351163
WOQLQuery.prototype.uncleanArguments = function(operator, args, indent, show_context){
11361164
str = '(';
11371165
const args_take_newlines = ["and", "or"];
@@ -1143,8 +1171,29 @@ WOQLQuery.prototype.uncleanArguments = function(operator, args, indent, show_con
11431171
if(this.argIsSubQuery(operator, args[i], i)){
11441172
str += this.prettyPrint(indent + this.indent, show_context, args[i], false);
11451173
}
1174+
else if(operator == "get" && i == 0){ // weird one, needs special casing
1175+
str += "\n" + nspaces(indent-this.indent) + "WOQL";
1176+
for(var j = 0; j < args[0].length; j++){
1177+
var myas = (args[0][j].as ? args[0][j].as : args[0][j]);
1178+
var lhs = myas[0];
1179+
var rhs = myas[1];
1180+
if(typeof lhs == "object" && lhs['@value']){
1181+
lhs = lhs['@value'];
1182+
}
1183+
if(typeof lhs == "object") {
1184+
lhs = JSON.stringify(lhs);
1185+
}
1186+
else {
1187+
lhs = '"' + lhs + '"'
1188+
}
1189+
str += '.as(' + lhs;
1190+
if(rhs) str += ', "' + rhs + '"';
1191+
str += ")";
1192+
str += "\n" + nspaces(indent);
1193+
}
1194+
}
11461195
else {
1147-
str += this.uncleanArgument(operator, args[i], i);
1196+
str += this.uncleanArgument(operator, args[i], i, args);
11481197
}
11491198
if(i < args.length -1) str += ',';
11501199
}
@@ -1156,7 +1205,13 @@ WOQLQuery.prototype.uncleanArguments = function(operator, args, indent, show_con
11561205
return str;
11571206
}
11581207

1159-
WOQLQuery.prototype.uncleanArgument = function(operator, val, index){
1208+
1209+
/**
1210+
* Passed as arguments: 1) the operator (and, triple, not, opt, etc)
1211+
* 2) the value of the argument
1212+
* 3) the index (position) of the argument.
1213+
*/
1214+
WOQLQuery.prototype.uncleanArgument = function(operator, val, index, allArgs){
11601215
//numeric values go out untouched...
11611216
const numeric_operators = ["limit", "start", "eval", "plus", "minus", "times", "divide", "exp"];
11621217
if(operator == "isa"){
@@ -1165,35 +1220,9 @@ WOQLQuery.prototype.uncleanArgument = function(operator, val, index){
11651220
else if(operator == "sub"){
11661221
val = this.unclean(val, 'class');
11671222
}
1168-
else if(operator == "get" && index == 0){
1169-
var lhs = [];
1170-
var rhs = [];
1171-
for(var i = 0; i< val.length; i++){
1172-
var entry = val[i].as;
1173-
if(entry.length == 2){
1174-
var colname = entry[0]['@value'];
1175-
if(colname) lhs.push(colname);
1176-
var varname = entry[1];
1177-
if(varname.indexOf(":") == -1) varname = "v:" + varname;
1178-
rhs.push(varname);
1179-
}
1180-
else {
1181-
var varname = entry[0];
1182-
if(varname.indexOf(":") == -1) varname = "v:" + varname;
1183-
rhs.push(varname);
1184-
}
1185-
}
1186-
if(lhs.length){
1187-
val = nspaces(this.index) + JSON.stringify(rhs) + ",\n" + nspaces(this.index) + JSON.stringify(lhs);
1188-
}
1189-
else {
1190-
val = JSON.stringify(rhs);
1191-
}
1192-
return val;
1193-
}
11941223
else if(["select"].indexOf(operator) != -1){
11951224
if(val.substring(0, 2) == "v:") val = val.substring(2);
1196-
}
1225+
}
11971226
else if(["quad", "add_quad", "delete_quad", "add_triple", "delete_triple", "triple"].indexOf(operator) != -1){
11981227
switch(index){
11991228
case 0: val = this.unclean(val, "subject"); break;
@@ -1224,6 +1253,8 @@ WOQLQuery.prototype.uncleanArgument = function(operator, val, index){
12241253
return '"' + val + '"';
12251254
}
12261255

1256+
1257+
12271258
WOQLQuery.prototype.uncleanObjectArgument = function(operator, val, index){
12281259
if(val['@value'] && (val['@language'] || (val['@type'] && val['@type'] == "xsd:string"))) return '"' + val['@value'] + '"';
12291260
if(val['@value'] && (val['@type'] && val['@type'] == "xsd:integer")) return val['@value'];
@@ -1259,12 +1290,13 @@ WOQLQuery.prototype.unclean = function(s, part){
12591290
if(s.indexOf(":") == -1) return s;
12601291
if(s.substring(0,4) == "http") return s;
12611292
var suff = s.split(":")[1];
1262-
if(this.vocab && this.vocab[suff]){
1293+
if(this.vocab && this.vocab[suff] && this.vocab[suff] == s){
12631294
return suff;
12641295
}
12651296
if(!part) return s;
12661297
if(part == "subject" && (s.split(":")[0] == "doc")) return suff;
12671298
if(part == "class" && (s.split(":")[0] == "scm")) return suff;
1299+
if(part == "predicate" && (s.split(":")[0] == "scm")) return suff;
12681300
if(part == "type" && (s.split(":")[0] == "scm")) return suff;
12691301
if(part == "graph" && (s.split(":")[0] == "db")) return suff;
12701302
return s;
@@ -1281,7 +1313,6 @@ WOQLQuery.prototype.getShortcut = function(operator, args, indent, show_context)
12811313

12821314

12831315

1284-
12851316
function nspaces(n){
12861317
let spaces = "";
12871318
for(var i = 0; i<n; i++){
@@ -1351,23 +1382,35 @@ function TripleBuilder(type, cursor, s){
13511382

13521383
TripleBuilder.prototype.label = function(l, lang){
13531384
lang = (lang ? lang : "en");
1354-
var x = this.addPO('rdfs:label', {"@value": l, "@language": lang });
1385+
if(l.substring(0, 2) == "v:"){
1386+
var d = {"value": l, "@language": lang }
1387+
}
1388+
else {
1389+
var d = {"@value": l, "@language": lang }
1390+
}
1391+
var x = this.addPO('rdfs:label', d);
13551392
return x;
13561393
}
13571394

13581395
TripleBuilder.prototype.comment = function(c, lang){
13591396
lang = (lang ? lang : "en");
1360-
return this.addPO('rdfs:comment', {"@value": c, "@language": lang});
1397+
if(c.substring(0, 2) == "v:"){
1398+
var d = {"value": l, "@language": lang }
1399+
}
1400+
else {
1401+
var d = {"@value": l, "@language": lang }
1402+
}
1403+
return this.addPO('rdfs:comment', d);
13611404
}
13621405

13631406
TripleBuilder.prototype.addPO = function(p, o, g){
13641407
if(this.type){
13651408
var ttype = (this.type == "isa" || this.type == "sub" ? "triple" : this.type);
13661409
}
13671410
else var ttype = "triple";
1368-
var evstr = ttype + "('" + this.subject + "', '" + p + "', ";
1411+
var evstr = ttype + '("' + this.subject + '", "' + p + '", ';
13691412
if(typeof o == "string"){
1370-
evstr += "'" + o + "'";
1413+
evstr += "'" + o + "'";
13711414
}
13721415
else if(typeof o == "object"){
13731416
evstr += JSON.stringify(o);
@@ -1377,7 +1420,7 @@ TripleBuilder.prototype.addPO = function(p, o, g){
13771420
}
13781421
if(ttype.substring(ttype.length-4) == "quad" || this.g){
13791422
var g = (g ? g : (this.g ? this.g : "db:schema"));
1380-
evstr += ", '" + g + "'";
1423+
evstr += ', "' + g + '"';
13811424
}
13821425
evstr += ")";
13831426
try {

0 commit comments

Comments
 (0)