Skip to content

Commit 6202160

Browse files
committed
Merge branch 'dev' of https://github.com/terminusdb/terminus-client into dev
2 parents 6427249 + 9343291 commit 6202160

File tree

4 files changed

+139
-29
lines changed

4 files changed

+139
-29
lines changed

lib/terminusRule.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ TerminusRule.prototype.type = function(...list){
3131
}
3232

3333
/**
34-
* Specifies the scope of a rule - row / cell / object / property / * .. what part of the result does the rule apply to
34+
* Specifies the scope of a rule - row / cell / object / property / * .. what part of the result does the rule apply to
3535
*/
3636
TerminusRule.prototype.scope = function(scope){
3737
if(typeof scope == "undefined"){
@@ -49,7 +49,6 @@ TerminusRule.prototype.value = function(...val){
4949
return this.pattern.value;
5050
}
5151
this.pattern.value = val;
52-
console.log(this.pattern.value);
5352
return this;
5453
}
5554

@@ -72,7 +71,7 @@ TerminusRule.prototype.json = function(mjson){
7271

7372
/**
7473
* Contained Pattern Object to encapsulate pattern matching
75-
* @param {Object} pattern
74+
* @param {Object} pattern
7675
*/
7776
function TerminusPattern(pattern){};
7877

@@ -99,7 +98,7 @@ TerminusPattern.prototype.testBasics = function(scope, value){
9998
if(this.scope && scope && this.scope != scope) return false;
10099
if(this.type){
101100
var dt = value["@type"];
102-
if(!dt || !this.testValue(dt, this.type)) return false;
101+
if(!dt || !this.testValue(dt, this.type)) return false;
103102
}
104103
if(typeof this.literal != "undefined"){
105104
if(!(this.literal == !(typeof value["@type"] == "undefined"))) return false;
@@ -141,7 +140,7 @@ TerminusPattern.prototype.unpack = function(arr, nonstring){
141140
str += arr[i];
142141
}
143142
if(i < (arr.length - 1)) str += ", ";
144-
}
143+
}
145144
}
146145
else {
147146
str = '"' + arr.join('","') + '"';
@@ -192,4 +191,4 @@ TerminusPattern.prototype.stringMatch = function (vala, valb) {
192191
};
193192

194193

195-
module.exports = {TerminusRule, TerminusPattern};
194+
module.exports = {TerminusRule, TerminusPattern};

lib/woql.js

Lines changed: 94 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
21
const UTILS = require('./utils');
3-
const WOQLRule = require('./woqlRule');
4-
const FrameRule = require('./frameRule');
52

63
/**
74
* The WOQL object is a wrapper around the WOQLQuery object
@@ -222,7 +219,7 @@ WOQL.with = function(graph, source, query){ return new WOQLQuery().with(graph, s
222219
* @param {string} vari - Target
223220
* @return {object} WOQLQuery
224221
*/
225-
WOQL.as = function(map, vari){ return new WOQLQuery().as(map, vari); }
222+
WOQL.as = function(map, vari, ty){ return new WOQLQuery().as(map, vari, ty); }
226223

227224
/**
228225
* Provides details of a remote data source in a JSON format that includes a URL property
@@ -321,12 +318,29 @@ WOQL.pad = function(input, pad, len, output){ return new WOQLQuery().pad(input,
321318
/**
322319
* Joins a list variable together (input) into a string variable (output) by glueing the strings together with glue
323320
* @param {array} input - a list of variables
324-
* @param {string} glue - jioining character(s)
325-
* @param {string} output - variable that sotres output
321+
* @param {string} glue - joining character(s)
322+
* @param {string} output - variable that stores output
326323
* @return {object} WOQLQuery
327324
*/
328325
WOQL.join = function(input, glue, output){ return new WOQLQuery().join(input, glue, output); }
329326

327+
/**
328+
* Splits a variable apart (input) into a list of variables (output) by separating the strings together with separator
329+
* @param {string} input - a string or variable
330+
* @param {string} separator - character string to separate string into list
331+
* @param {string} output - variable that stores output list
332+
* @return {object} WOQLQuery
333+
*/
334+
WOQL.split = function(input, separator, output){ return new WOQLQuery().split(input, separator, output); }
335+
336+
/**
337+
* Iterates through a list and returns a value for each member
338+
* @param {string} El - a variable representing an element of the list
339+
* @param {string} List - A list variable
340+
* @return {object} WOQLQuery
341+
*/
342+
WOQL.member = function(El, List){ return new WOQLQuery().member(El, List); }
343+
330344
/**
331345
* Generates an ID for a node as a function of the passed VariableList with a specific prefix (URL base). If the values of the passed variables are the same, the output will be the same
332346
* @param {string} prefix - prefix for the id
@@ -515,6 +529,7 @@ WOQL.boxClasses = function(prefix, classes, except, graph){ return new WOQLQuery
515529

516530
WOQL.libs = function(...libs){ return new WOQLQuery().libs(...libs)}
517531

532+
WOQL.generateChoiceList = function(cls, clslabel, clsdesc, choices, graph, parent){ return new WOQLQuery().generateChoiceList(cls, clslabel, clsdesc, choices, graph, parent)}
518533

519534
/**
520535
* Deletes the Class with the passed ID form the schema (and all references to it)
@@ -900,12 +915,25 @@ WOQLQuery.prototype.pad = function(input, pad, len, output){
900915
return this;
901916
}
902917

918+
WOQLQuery.prototype.member = function(El, List){
919+
this.cursor['member'] = [El, List];
920+
return this;
921+
}
922+
903923
WOQLQuery.prototype.join = function(input, glue, output){
904924
glue = this.packString(glue);
905925
this.cursor['join'] = [input, glue, output];
906926
return this;
907927
}
908928

929+
WOQLQuery.prototype.split = function(input, glue, output){
930+
glue = this.packString(glue);
931+
input = this.packString(input);
932+
this.cursor['split'] = [input, glue, output];
933+
return this;
934+
}
935+
936+
909937
WOQLQuery.prototype.less = function(v1, v2){
910938
v1 = (v1.json ? v1.json() : v1);
911939
v2 = (v2.json ? v2.json() : v2);
@@ -1289,20 +1317,18 @@ WOQLQuery.prototype.delete_property = function(p, graph){
12891317
WOQLQuery.prototype.boxClasses = function(prefix, classes, except, graph){
12901318
graph = (graph ? this.cleanGraph(graph) : "db:schema");
12911319
prefix = prefix || "scm:";
1292-
var subs = [
1293-
WOQL.quad("v:Cid", "rdf:type", "owl:Class", graph),
1294-
WOQL.not().abstract("v:Cid", graph),
1295-
];
1320+
var subs = [];
12961321
for(var i = 0; i<classes.length; i++){
12971322
subs.push(WOQL.sub("v:Cid", this.cleanClass(classes[i])));
12981323
}
1324+
var nsubs = [];
12991325
for(var i = 0; i<except.length; i++){
1300-
subs.push(WOQL.not().sub("v:Cid", this.cleanClass(except[i])));
1326+
nsubs.push(WOQL.not().sub("v:Cid", this.cleanClass(except[i])));
13011327
}
13021328
//property punning
13031329
//generate a property id that is the same as the classname but starting with a lowercase letter
13041330
let idgens = [
1305-
WOQL.re(".*#(.)(.*)", "v:Cid", ["v:AllB", "v:FirstB", "v:RestB"]),
1331+
WOQL.re("#(.)(.*)", "v:Cid", ["v:AllB", "v:FirstB", "v:RestB"]),
13061332
WOQL.lower("v:FirstB", "v:Lower"),
13071333
WOQL.concat(["v:Lower", "v:RestB"], "v:Propname"),
13081334
WOQL.concat(["Scoped", "v:FirstB", "v:RestB"], "v:Cname"),
@@ -1311,7 +1337,10 @@ WOQLQuery.prototype.boxClasses = function(prefix, classes, except, graph){
13111337
];
13121338

13131339
const filter = WOQL.and(
1340+
WOQL.quad("v:Cid", "rdf:type", "owl:Class", graph),
1341+
WOQL.not().abstract("v:Cid", graph),
13141342
WOQL.or(...subs),
1343+
WOQL.and(...nsubs),
13151344
WOQL.and(...idgens),
13161345
WOQL.quad("v:Cid", "rdfs:label", "v:Label", graph),
13171346
WOQL.quad("v:Cid", "rdfs:comment", "v:Desc", graph)
@@ -1327,12 +1356,50 @@ WOQLQuery.prototype.boxClasses = function(prefix, classes, except, graph){
13271356
));
13281357
}
13291358

1359+
WOQLQuery.prototype.generateChoiceList = function(cls, clslabel, clsdesc, choices, graph, parent){
1360+
parent = parent || "scm:Enumerated";
1361+
graph = graph || "db:schema";
1362+
var confs = [
1363+
WOQL.add_class(cls, graph)
1364+
.label(clslabel)
1365+
.description(clsdesc)
1366+
.parent(parent)
1367+
];
1368+
for(var i = 0; i<choices.length; i++){
1369+
if(!choices[i]) continue;
1370+
confs.push(WOQL.insert(choices[i][0], cls, graph)
1371+
.label(choices[i][1])
1372+
.description(choices[i][2])
1373+
)
1374+
}
1375+
//generate one of list
1376+
var clist = [];
1377+
var listid = "_:" + cls.split(":")[1];
1378+
var lastid = listid;
1379+
for(var i = 0; i <= choices.length; i++){
1380+
if(!choices[i]) continue;
1381+
var nextid = (i < (choices.length -1) ? listid + "_" + i : "rdf:nil");
1382+
clist.push( WOQL.add_quad(lastid, "rdf:first", choices[i][0], graph))
1383+
clist.push( WOQL.add_quad(lastid, "rdf:rest", nextid, graph));
1384+
lastid = nextid;
1385+
}
1386+
//do the owl oneof
1387+
let oneof = WOQL.and(
1388+
WOQL.add_quad(cls, "owl:oneOf", listid, graph),
1389+
...clist
1390+
)
1391+
return WOQL.and(...confs, oneof);
1392+
}
1393+
1394+
13301395
WOQLQuery.prototype.libs = function(...libs){
13311396
var bits = [];
13321397
if(libs.indexOf("xdd") != -1){
13331398
bits.push(this.loadXDD());
1334-
if(libs.indexOf("box") != -1) bits.push(this.loadXDDBoxes());
1335-
1399+
if(libs.indexOf("box") != -1) {
1400+
bits.push(this.loadXDDBoxes());
1401+
bits.push(this.loadXSDBoxes());
1402+
}
13361403
}
13371404
else if(libs.indexOf("box") != -1){
13381405
bits.push(this.loadXSDBoxes());
@@ -1417,9 +1484,9 @@ WOQLQuery.prototype.loadXSDBoxes = function(){
14171484
this.boxDatatype("xsd:ID", "ID", "An xsd:ID value."),
14181485
this.boxDatatype("xsd:IDREF", "IDREF", "An xsd:IDREF value."),
14191486
this.boxDatatype("xsd:ENTITY", "ENTITY", "An xsd:ENTITY value."),
1420-
this.boxDatatype("xsd:XMLLiteral", "XML Literal", "An rdf:XMLLiteral value."),
1421-
this.boxDatatype("xsd:PlainLiteral", "Plain Literal", "An rdf:PlainLiteral value."),
1422-
this.boxDatatype("rdfs:Literal", "Literal", "An rdfs:Literal value.")
1487+
//this.boxDatatype("rdf:XMLLiteral", "XML Literal", "An rdf:XMLLiteral value."),
1488+
//this.boxDatatype("rdf:PlainLiteral", "Plain Literal", "An rdf:PlainLiteral value."),
1489+
//this.boxDatatype("rdfs:Literal", "Literal", "An rdfs:Literal value.")
14231490
)
14241491
}
14251492

@@ -1454,15 +1521,15 @@ WOQLQuery.prototype.boxDatatype = function(datatype, label, descr, graph, prefix
14541521
let ext = datatype.split(":")[1];
14551522
let box_class_id = prefix + ext.charAt(0).toUpperCase() + ext.slice(1);
14561523
let box_prop_id = prefix + ext.charAt(0).toLowerCase() + ext.slice(1);
1457-
var box_class = WOQL.insert(box_class_id, "owl:Class", graph).label(label).parent("scm:Box");
1524+
var box_class = WOQL.add_class(box_class_id).label(label).parent("scm:Box");
14581525
if(descr) box_class.description(descr);
1459-
var box_prop = WOQL.insert(box_prop_id, datatype, graph).label(label);
1526+
var box_prop = WOQL.add_property(box_prop_id, datatype).label(label).domain(box_class_id)
14601527
if(descr) box_prop.description(descr);
14611528
return WOQL.and(box_class, box_prop);
14621529
}
14631530

14641531

1465-
WOQLQuery.prototype.as = function(a, b){
1532+
WOQLQuery.prototype.as = function(a, b, c){
14661533
if(!a) return;
14671534
if(!this.asArray){
14681535
this.asArray = true;
@@ -1471,7 +1538,12 @@ WOQLQuery.prototype.as = function(a, b){
14711538
if(b){
14721539
b = (b.indexOf(":") == -1 ? "v:" + b : b);
14731540
var val = (typeof a == "object" ? a : { "@value" : a});
1474-
this.query.push({as: [val, b]});
1541+
1542+
if(c){
1543+
this.query.push({as: [val, b, c]});
1544+
}else{
1545+
this.query.push({as: [val, b]});
1546+
}
14751547
}
14761548
else {
14771549
a = (a.indexOf(":") == -1 ? "v:" + a : a);
@@ -1891,12 +1963,12 @@ WOQLQuery.prototype.execute = function(client,fileList){
18911963
if(typeof this.query['@context'][pref] == "undefined")
18921964
this.query['@context'][pref] = UTILS.standard_urls[pref];
18931965
}
1966+
this.query["@context"]["_"] = "_:";
18941967
var json = this.json();
18951968
}
18961969
else {
18971970
var json = this.json();
18981971
}
1899-
this.query["@context"]["_"] = "_:";
19001972
const opts=fileList ? {fileList:fileList} : null;
19011973
if(this.contains_update){
19021974
//return client.select(false, json,opts);

lib/woqlClient.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ WOQLClient.prototype.update = function (qurl, woql, opts) {
327327
let q = {'terminus:query' : JSON.stringify(woql), ...fileList};
328328

329329
q = this.addOptionsToWOQL(q, opts);
330-
return this.dispatch(this.connectionConfig.queryURL(), CONST.WOQL_UPDATE, q);
330+
return this.dispatch(this.connectionConfig.queryURL(), CONST.WOQL_SELECT, q);
331331
};
332332

333333
/**

test/woql.spec.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,36 @@ describe('woql queries', function () {
347347

348348
})
349349

350+
it('check the join method',function(){
351+
352+
const woqlObject=WOQL.join(["v:A_obj", "v:B_obj"], ", ", "v:output");
353+
const jsonObj={
354+
'join': [
355+
[ 'v:A_obj', 'v:B_obj' ],
356+
{ '@value': ', ', '@type': 'xsd:string' },
357+
'v:output'
358+
]
359+
};
360+
361+
expect(woqlObject.json()).to.eql(jsonObj);
362+
363+
})
364+
365+
it('check the split method',function(){
366+
367+
const woqlObject=WOQL.split("A, B, C", ", ", "v:list_obj");
368+
369+
const jsonObj={
370+
'split': [
371+
{ '@value': 'A, B, C', '@type': 'xsd:string' },
372+
{"@type": "xsd:string", "@value": ", "},
373+
"v:list_obj"
374+
]
375+
};
376+
377+
expect(woqlObject.json()).to.eql(jsonObj);
378+
379+
})
350380

351381
it('check the list method',function(){
352382

@@ -358,6 +388,15 @@ describe('woql queries', function () {
358388

359389
})
360390

391+
it('check the member method',function(){
392+
393+
const woqlObject=WOQL.member("v:member", "v:list_obj");
394+
const jsonObj={ 'member': [ 'v:member', 'v:list_obj' ] };
395+
396+
expect(woqlObject.json()).to.eql(jsonObj);
397+
398+
})
399+
361400
it('check the group_by method',function(){
362401
const woqlObject=WOQL.group_by(["v:A", "v:B"],["v:C"],"v:New");
363402
const jsonObj={ group_by: [ {list: ['v:A', "v:B"]}, {list: ["v:C"]}, {}, "v:New"] };

0 commit comments

Comments
 (0)