@@ -31,11 +31,12 @@ Generator.prototype.toQuery = function (q) {
31
31
if ( q . distinct )
32
32
query += 'DISTINCT ' ;
33
33
34
- if ( q . variables )
34
+ if ( q . variables ) {
35
35
query += mapJoin ( q . variables , undefined , function ( variable ) {
36
- return isString ( variable ) ? this . toEntity ( variable ) :
37
- '(' + this . toExpression ( variable . expression ) + ' AS ' + variable . variable + ')' ;
36
+ return isTerm ( variable ) ? this . toEntity ( variable ) :
37
+ '(' + this . toExpression ( variable . expression ) + ' AS ' + variableToString ( variable . variable ) + ')' ;
38
38
} , this ) + ' ' ;
39
+ }
39
40
else if ( q . template )
40
41
query += this . group ( q . template , true ) + this . _newline ;
41
42
@@ -51,7 +52,7 @@ Generator.prototype.toQuery = function (q) {
51
52
if ( q . group )
52
53
query += 'GROUP BY ' + mapJoin ( q . group , undefined , function ( it ) {
53
54
var result = isString ( it . expression ) ? it . expression : '(' + this . toExpression ( it . expression ) + ')' ;
54
- return it . variable ? '(' + result + ' AS ' + it . variable + ')' : result ;
55
+ return it . variable ? '(' + result + ' AS ' + variableToString ( it . variable ) + ')' : result ;
55
56
} , this ) + this . _newline ;
56
57
if ( q . having )
57
58
query += 'HAVING (' + mapJoin ( q . having , undefined , this . toExpression , this ) + ')' + this . _newline ;
@@ -156,7 +157,7 @@ Generator.prototype.filter = function (filter) {
156
157
} ;
157
158
158
159
Generator . prototype . bind = function ( bind ) {
159
- return 'BIND(' + this . toExpression ( bind . expression ) + ' AS ' + bind . variable + ')' ;
160
+ return 'BIND(' + this . toExpression ( bind . expression ) + ' AS ' + variableToString ( bind . variable ) + ')' ;
160
161
} ;
161
162
162
163
Generator . prototype . optional = function ( optional ) {
@@ -189,7 +190,7 @@ Generator.prototype.values = function (valuesList) {
189
190
return 'VALUES ' + lparen + keys . join ( ' ' ) + rparen + ' {' + this . _newline +
190
191
mapJoin ( valuesList . values , this . _newline , function ( values ) {
191
192
return ' ' + lparen + mapJoin ( keys , undefined , function ( key ) {
192
- return values [ key ] !== undefined ? this . toEntity ( values [ key ] ) : 'UNDEF' ;
193
+ return values [ key ] ? this . toEntity ( values [ key ] ) : 'UNDEF' ;
193
194
} , this ) + rparen ;
194
195
} , this ) + this . _newline + '}' ;
195
196
} ;
@@ -201,14 +202,14 @@ Generator.prototype.service = function (service) {
201
202
202
203
// Converts the parsed expression object into a SPARQL expression
203
204
Generator . prototype . toExpression = function ( expr ) {
204
- if ( isString ( expr ) )
205
+ if ( isTerm ( expr ) ) {
205
206
return this . toEntity ( expr ) ;
206
-
207
+ }
207
208
switch ( expr . type . toLowerCase ( ) ) {
208
209
case 'aggregate' :
209
210
return expr . aggregation . toUpperCase ( ) +
210
211
'(' + ( expr . distinct ? 'DISTINCT ' : '' ) + this . toExpression ( expr . expression ) +
211
- ( expr . separator ? '; SEPARATOR = ' + this . toEntity ( '"' + expr . separator + '"' ) : '' ) + ')' ;
212
+ ( expr . separator ? '; SEPARATOR = ' + '"' + expr . separator . replace ( escape , escapeReplacer ) + '"' : '' ) + ')' ;
212
213
case 'functioncall' :
213
214
return this . toEntity ( expr . function ) + '(' + mapJoin ( expr . args , ', ' , this . toExpression , this ) + ')' ;
214
215
case 'operation' :
@@ -227,9 +228,9 @@ Generator.prototype.toExpression = function (expr) {
227
228
case '-' :
228
229
case '*' :
229
230
case '/' :
230
- return ( isString ( args [ 0 ] ) ? this . toEntity ( args [ 0 ] ) : '(' + this . toExpression ( args [ 0 ] ) + ')' ) +
231
+ return ( isTerm ( args [ 0 ] ) ? this . toEntity ( args [ 0 ] ) : '(' + this . toExpression ( args [ 0 ] ) + ')' ) +
231
232
' ' + operator + ' ' +
232
- ( isString ( args [ 1 ] ) ? this . toEntity ( args [ 1 ] ) : '(' + this . toExpression ( args [ 1 ] ) + ')' ) ;
233
+ ( isTerm ( args [ 1 ] ) ? this . toEntity ( args [ 1 ] ) : '(' + this . toExpression ( args [ 1 ] ) + ')' ) ;
233
234
// Unary operators
234
235
case '!' :
235
236
return '!(' + this . toExpression ( args [ 0 ] ) + ')' ;
@@ -255,30 +256,31 @@ Generator.prototype.toExpression = function (expr) {
255
256
256
257
// Converts the parsed entity (or property path) into a SPARQL entity
257
258
Generator . prototype . toEntity = function ( value ) {
258
- // regular entity
259
- if ( isString ( value ) ) {
260
- switch ( value [ 0 ] ) {
259
+ if ( isTerm ( value ) ) {
260
+ switch ( value . termType ) {
261
261
// variable, * selector, or blank node
262
- case '?' :
263
- case '$' :
264
- case '*' :
265
- case '_' :
266
- return value ;
262
+ case 'Wildcard' :
263
+ return '*' ;
264
+ case 'Variable' :
265
+ return variableToString ( value ) ;
266
+ case 'BlankNode' :
267
+ return '_:' + value . value ;
267
268
// literal
268
- case '"' :
269
- var match = value . match ( / ^ " ( [ ^ ] * ) " (?: ( @ .+ ) | \^ \^ ( .+ ) ) ? $ / ) || { } ,
270
- lexical = match [ 1 ] || '' , language = match [ 2 ] || '' , datatype = match [ 3 ] ;
271
- value = '"' + lexical . replace ( escape , escapeReplacer ) + '"' + language ;
272
- if ( datatype ) {
273
- if ( datatype === XSD_INTEGER && / ^ \d + $ / . test ( lexical ) )
269
+ case 'Literal' :
270
+ var lexical = value . value || '' , language = value . language || '' , datatype = value . datatype ;
271
+ value = '"' + lexical . replace ( escape , escapeReplacer ) + '"' ;
272
+ if ( language ) {
273
+ value += '@' + language ;
274
+ } else if ( datatype ) {
275
+ if ( datatype . value === XSD_INTEGER && / ^ \d + $ / . test ( lexical ) )
274
276
// Add space to avoid confusion with decimals in broken parsers
275
277
return lexical + ' ' ;
276
- value += '^^' + this . encodeIRI ( datatype ) ;
278
+ value += '^^' + this . encodeIRI ( datatype . value ) ;
277
279
}
278
280
return value ;
279
281
// IRI
280
282
default :
281
- return this . encodeIRI ( value ) ;
283
+ return this . encodeIRI ( value . value ) ;
282
284
}
283
285
}
284
286
// property path
@@ -355,9 +357,16 @@ Generator.prototype.toUpdate = function (update) {
355
357
// Indents each line of the string
356
358
Generator . prototype . indent = function ( text ) { return text . replace ( / ^ / gm, this . _indent ) ; }
357
359
360
+ function variableToString ( variable ) {
361
+ return '?' + variable . value ;
362
+ }
363
+
358
364
// Checks whether the object is a string
359
365
function isString ( object ) { return typeof object === 'string' ; }
360
366
367
+ // Checks whether the object is a Term
368
+ function isTerm ( object ) { return ! ! object . termType ; }
369
+
361
370
// Maps the array with the given function, and joins the results using the separator
362
371
function mapJoin ( array , sep , func , self ) {
363
372
return array . map ( func , self ) . join ( isString ( sep ) ? sep : ' ' ) ;
0 commit comments