Skip to content

Commit 0b03de7

Browse files
RubenVerborghdmitrizagidulin
authored andcommitted
Move patch handlers to separate files.
The patch handler contains logic for multiple request body types. Moving them to separate files facilitates adding support for more types.
1 parent 3659b65 commit 0b03de7

File tree

3 files changed

+158
-140
lines changed

3 files changed

+158
-140
lines changed

lib/handlers/patch.js

Lines changed: 4 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
module.exports = handler
22

33
var mime = require('mime-types')
4-
var fs = require('fs')
5-
var $rdf = require('rdflib')
64
var debug = require('../debug').handlers
75
var utils = require('../utils.js')
86
var error = require('../http-error')
9-
const waterfall = require('run-waterfall')
7+
const sparqlPatch = require('./patch/sparql-patcher.js')
8+
const sparqlUpdatePatch = require('./patch/sparql-update-patcher.js')
109

1110
const DEFAULT_CONTENT_TYPE = 'text/turtle'
1211

@@ -39,15 +38,15 @@ function patchHandler (req, res, next) {
3938
debug('PATCH -- Content-type ' + patchContentType + ' patching target ' + targetContentType + ' <' + targetURI + '>')
4039

4140
if (patchContentType === 'application/sparql') {
42-
sparql(filename, targetURI, req.text, function (err, result) {
41+
sparqlPatch(filename, targetURI, req.text, function (err, result) {
4342
if (err) {
4443
return next(err)
4544
}
4645
res.json(result)
4746
return next()
4847
})
4948
} else if (patchContentType === 'application/sparql-update') {
50-
return sparqlUpdate(filename, targetURI, req.text, function (err, patchKB) {
49+
return sparqlUpdatePatch(filename, targetURI, req.text, function (err, patchKB) {
5150
if (err) {
5251
return next(err)
5352
}
@@ -61,138 +60,3 @@ function patchHandler (req, res, next) {
6160
return next(error(400, 'Unknown patch content type: ' + patchContentType))
6261
}
6362
} // postOrPatch
64-
65-
function sparql (filename, targetURI, text, callback) {
66-
debug('PATCH -- parsing query ...')
67-
var patchURI = targetURI // @@@ beware the triples from the patch ending up in the same place
68-
var patchKB = $rdf.graph()
69-
var targetKB = $rdf.graph()
70-
var targetContentType = mime.lookup(filename) || DEFAULT_CONTENT_TYPE
71-
var query = $rdf.SPARQLToQuery(text, false, patchKB, patchURI) // last param not used ATM
72-
73-
fs.readFile(filename, {encoding: 'utf8'}, function (err, dataIn) {
74-
if (err) {
75-
return callback(error(404, 'Patch: Original file read error:' + err))
76-
}
77-
78-
debug('PATCH -- File read OK ' + dataIn.length)
79-
debug('PATCH -- parsing target file ...')
80-
81-
try {
82-
$rdf.parse(dataIn, targetKB, targetURI, targetContentType)
83-
} catch (e) {
84-
debug('Patch: Target ' + targetContentType + ' file syntax error:' + e)
85-
return callback(error(500, 'Patch: Target ' + targetContentType + ' file syntax error:' + e))
86-
}
87-
debug('PATCH -- Target parsed OK ')
88-
89-
var bindingsArray = []
90-
91-
var onBindings = function (bindings) {
92-
var b = {}
93-
var v
94-
var x
95-
for (v in bindings) {
96-
if (bindings.hasOwnProperty(v)) {
97-
x = bindings[v]
98-
b[v] = x.uri ? {'type': 'uri', 'value': x.uri} : { 'type': 'literal', 'value': x.value }
99-
if (x.lang) {
100-
b[v]['xml:lang'] = x.lang
101-
}
102-
if (x.dt) {
103-
b[v].dt = x.dt.uri // @@@ Correct? @@ check
104-
}
105-
}
106-
}
107-
debug('PATCH -- bindings: ' + JSON.stringify(b))
108-
bindingsArray.push(b)
109-
}
110-
111-
var onDone = function () {
112-
debug('PATCH -- Query done, no. bindings: ' + bindingsArray.length)
113-
return callback(null, {
114-
'head': {
115-
'vars': query.vars.map(function (v) {
116-
return v.toNT()
117-
})
118-
},
119-
'results': {
120-
'bindings': bindingsArray
121-
}
122-
})
123-
}
124-
125-
var fetcher = new $rdf.Fetcher(targetKB, 10000, true)
126-
targetKB.query(query, onBindings, fetcher, onDone)
127-
})
128-
}
129-
130-
function sparqlUpdate (filename, targetURI, text, callback) {
131-
var patchURI = targetURI // @@@ beware the triples from the patch ending up in the same place
132-
var patchKB = $rdf.graph()
133-
var targetKB = $rdf.graph()
134-
var targetContentType = mime.lookup(filename) || DEFAULT_CONTENT_TYPE
135-
136-
debug('PATCH -- parsing patch ...')
137-
var patchObject
138-
try {
139-
// Must parse relative to document's base address but patch doc should get diff URI
140-
patchObject = $rdf.sparqlUpdateParser(text, patchKB, patchURI)
141-
} catch (e) {
142-
return callback(error(400, 'Patch format syntax error:\n' + e + '\n'))
143-
}
144-
debug('PATCH -- reading target file ...')
145-
146-
waterfall([
147-
(cb) => {
148-
fs.stat(filename, (err) => {
149-
if (!err) return cb()
150-
151-
fs.writeFile(filename, '', (err) => {
152-
if (err) {
153-
return cb(error(err, 'Error creating the patch target'))
154-
}
155-
cb()
156-
})
157-
})
158-
},
159-
(cb) => {
160-
fs.readFile(filename, {encoding: 'utf8'}, function (err, dataIn) {
161-
if (err) {
162-
return cb(error(500, 'Error reading the patch target'))
163-
}
164-
165-
debug('PATCH -- target read OK ' + dataIn.length + ' bytes. Parsing...')
166-
167-
try {
168-
$rdf.parse(dataIn, targetKB, targetURI, targetContentType)
169-
} catch (e) {
170-
debug('Patch: Target ' + targetContentType + ' file syntax error:' + e)
171-
return cb(error(500, 'Patch: Target ' + targetContentType + ' file syntax error:' + e))
172-
}
173-
174-
var target = patchKB.sym(targetURI)
175-
debug('PATCH -- Target parsed OK, patching... ')
176-
177-
targetKB.applyPatch(patchObject, target, function (err) {
178-
if (err) {
179-
var message = err.message || err // returns string at the moment
180-
debug('PATCH FAILED. Returning 409. Message: \'' + message + '\'')
181-
return cb(error(409, 'Error when applying the patch'))
182-
}
183-
debug('PATCH -- Patched. Writeback URI base ' + targetURI)
184-
var data = $rdf.serialize(target, targetKB, targetURI, targetContentType)
185-
// debug('Writeback data: ' + data)
186-
187-
fs.writeFile(filename, data, {encoding: 'utf8'}, function (err, data) {
188-
if (err) {
189-
return cb(error(500, 'Failed to write file back after patch: ' + err))
190-
}
191-
debug('PATCH -- applied OK (sync)')
192-
return cb(null, patchKB)
193-
})
194-
})
195-
})
196-
}
197-
], callback)
198-
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
module.exports = patch
2+
3+
var mime = require('mime-types')
4+
var fs = require('fs')
5+
var $rdf = require('rdflib')
6+
var debug = require('../../debug').handlers
7+
var error = require('../../http-error')
8+
9+
const DEFAULT_CONTENT_TYPE = 'text/turtle'
10+
11+
function patch (filename, targetURI, text, callback) {
12+
debug('PATCH -- parsing query ...')
13+
var patchURI = targetURI // @@@ beware the triples from the patch ending up in the same place
14+
var patchKB = $rdf.graph()
15+
var targetKB = $rdf.graph()
16+
var targetContentType = mime.lookup(filename) || DEFAULT_CONTENT_TYPE
17+
var query = $rdf.SPARQLToQuery(text, false, patchKB, patchURI) // last param not used ATM
18+
19+
fs.readFile(filename, {encoding: 'utf8'}, function (err, dataIn) {
20+
if (err) {
21+
return callback(error(404, 'Patch: Original file read error:' + err))
22+
}
23+
24+
debug('PATCH -- File read OK ' + dataIn.length)
25+
debug('PATCH -- parsing target file ...')
26+
27+
try {
28+
$rdf.parse(dataIn, targetKB, targetURI, targetContentType)
29+
} catch (e) {
30+
debug('Patch: Target ' + targetContentType + ' file syntax error:' + e)
31+
return callback(error(500, 'Patch: Target ' + targetContentType + ' file syntax error:' + e))
32+
}
33+
debug('PATCH -- Target parsed OK ')
34+
35+
var bindingsArray = []
36+
37+
var onBindings = function (bindings) {
38+
var b = {}
39+
var v
40+
var x
41+
for (v in bindings) {
42+
if (bindings.hasOwnProperty(v)) {
43+
x = bindings[v]
44+
b[v] = x.uri ? {'type': 'uri', 'value': x.uri} : { 'type': 'literal', 'value': x.value }
45+
if (x.lang) {
46+
b[v]['xml:lang'] = x.lang
47+
}
48+
if (x.dt) {
49+
b[v].dt = x.dt.uri // @@@ Correct? @@ check
50+
}
51+
}
52+
}
53+
debug('PATCH -- bindings: ' + JSON.stringify(b))
54+
bindingsArray.push(b)
55+
}
56+
57+
var onDone = function () {
58+
debug('PATCH -- Query done, no. bindings: ' + bindingsArray.length)
59+
return callback(null, {
60+
'head': {
61+
'vars': query.vars.map(function (v) {
62+
return v.toNT()
63+
})
64+
},
65+
'results': {
66+
'bindings': bindingsArray
67+
}
68+
})
69+
}
70+
71+
var fetcher = new $rdf.Fetcher(targetKB, 10000, true)
72+
targetKB.query(query, onBindings, fetcher, onDone)
73+
})
74+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
module.exports = patch
2+
3+
var mime = require('mime-types')
4+
var fs = require('fs')
5+
var $rdf = require('rdflib')
6+
var debug = require('../../debug').handlers
7+
var error = require('../../http-error')
8+
const waterfall = require('run-waterfall')
9+
10+
const DEFAULT_CONTENT_TYPE = 'text/turtle'
11+
12+
function patch (filename, targetURI, text, callback) {
13+
var patchURI = targetURI // @@@ beware the triples from the patch ending up in the same place
14+
var patchKB = $rdf.graph()
15+
var targetKB = $rdf.graph()
16+
var targetContentType = mime.lookup(filename) || DEFAULT_CONTENT_TYPE
17+
18+
debug('PATCH -- parsing patch ...')
19+
var patchObject
20+
try {
21+
// Must parse relative to document's base address but patch doc should get diff URI
22+
patchObject = $rdf.sparqlUpdateParser(text, patchKB, patchURI)
23+
} catch (e) {
24+
return callback(error(400, 'Patch format syntax error:\n' + e + '\n'))
25+
}
26+
debug('PATCH -- reading target file ...')
27+
28+
waterfall([
29+
(cb) => {
30+
fs.stat(filename, (err) => {
31+
if (!err) return cb()
32+
33+
fs.writeFile(filename, '', (err) => {
34+
if (err) {
35+
return cb(error(err, 'Error creating the patch target'))
36+
}
37+
cb()
38+
})
39+
})
40+
},
41+
(cb) => {
42+
fs.readFile(filename, {encoding: 'utf8'}, function (err, dataIn) {
43+
if (err) {
44+
return cb(error(500, 'Error reading the patch target'))
45+
}
46+
47+
debug('PATCH -- target read OK ' + dataIn.length + ' bytes. Parsing...')
48+
49+
try {
50+
$rdf.parse(dataIn, targetKB, targetURI, targetContentType)
51+
} catch (e) {
52+
debug('Patch: Target ' + targetContentType + ' file syntax error:' + e)
53+
return cb(error(500, 'Patch: Target ' + targetContentType + ' file syntax error:' + e))
54+
}
55+
56+
var target = patchKB.sym(targetURI)
57+
debug('PATCH -- Target parsed OK, patching... ')
58+
59+
targetKB.applyPatch(patchObject, target, function (err) {
60+
if (err) {
61+
var message = err.message || err // returns string at the moment
62+
debug('PATCH FAILED. Returning 409. Message: \'' + message + '\'')
63+
return cb(error(409, 'Error when applying the patch'))
64+
}
65+
debug('PATCH -- Patched. Writeback URI base ' + targetURI)
66+
var data = $rdf.serialize(target, targetKB, targetURI, targetContentType)
67+
// debug('Writeback data: ' + data)
68+
69+
fs.writeFile(filename, data, {encoding: 'utf8'}, function (err, data) {
70+
if (err) {
71+
return cb(error(500, 'Failed to write file back after patch: ' + err))
72+
}
73+
debug('PATCH -- applied OK (sync)')
74+
return cb(null, patchKB)
75+
})
76+
})
77+
})
78+
}
79+
], callback)
80+
}

0 commit comments

Comments
 (0)