diff --git a/plugins/tiddlywiki/multiwikiserver/modules/route-get-bag-tiddler.js b/plugins/tiddlywiki/multiwikiserver/modules/route-get-bag-tiddler.js new file mode 100644 index 000000000..e1165062b --- /dev/null +++ b/plugins/tiddlywiki/multiwikiserver/modules/route-get-bag-tiddler.js @@ -0,0 +1,61 @@ +/*\ +title: $:/plugins/tiddlywiki/multiwikiserver/route-get-bag-tiddler.js +type: application/javascript +module-type: route + +GET /wikis/:bag_name/bags/:bag_name/tiddler/:title + +NOTE: Urls currently include the bag name twice. This is temporary to minimise the changes to the TiddlyWeb plugin + +\*/ +(function() { + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +exports.method = "GET"; + +exports.path = /^\/wiki\/([^\/]+)\/bags\/([^\/]+)\/tiddlers\/([^\/]+)$/; + +exports.handler = function(request,response,state) { + // Get the parameters + var bag_name = $tw.utils.decodeURIComponentSafe(state.params[0]), + bag_name_2 = $tw.utils.decodeURIComponentSafe(state.params[1]), + title = $tw.utils.decodeURIComponentSafe(state.params[2]), + tiddler = bag_name === bag_name_2 && $tw.sqlTiddlerStore.getBagTiddler(title,bag_name); + if(bag_name === bag_name_2 && tiddler) { + // If application/json is requested then this is an API request, and gets the response in JSON + if(request.headers.accept && request.headers.accept.indexOf("application/json") !== -1) { + var tiddlerFields = {}, + knownFields = [ + "bag", "created", "creator", "modified", "modifier", "permissions", "recipe", "revision", "tags", "text", "title", "type", "uri" + ]; + $tw.utils.each(tiddler,function(value,name) { + if(knownFields.indexOf(name) !== -1) { + tiddlerFields[name] = value; + } else { + tiddlerFields.fields = tiddlerFields.fields || {}; + tiddlerFields.fields[name] = value; + } + }); + tiddlerFields.revision = "0"; + tiddlerFields.bag = "bag-gamma"; + tiddlerFields.type = tiddlerFields.type || "text/vnd.tiddlywiki"; + state.sendResponse(200,{"Content-Type": "application/json"},JSON.stringify(tiddlerFields),"utf8"); + } else { + // This is not a JSON API request, we should return the raw tiddler content + var type = tiddler.type || "text/plain"; + response.writeHead(200, "OK",{ + "Content-Type": type + }); + response.write(tiddler.text || "",($tw.config.contentTypeInfo[type] ||{encoding: "utf8"}).encoding); + response.end();; + } + } else { + response.writeHead(404); + response.end(); + } +}; + +}()); diff --git a/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe-tiddler.js b/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe-tiddler.js index e2c539b9f..df04d5fb2 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe-tiddler.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe-tiddler.js @@ -23,7 +23,7 @@ exports.handler = function(request,response,state) { var recipe_name = $tw.utils.decodeURIComponentSafe(state.params[0]), recipe_name_2 = $tw.utils.decodeURIComponentSafe(state.params[1]), title = $tw.utils.decodeURIComponentSafe(state.params[2]), - tiddler = recipe_name === recipe_name_2 && $tw.sqlTiddlerStore.getTiddler(title,recipe_name); + tiddler = recipe_name === recipe_name_2 && $tw.sqlTiddlerStore.getRecipeTiddler(title,recipe_name); if(recipe_name === recipe_name_2 && tiddler) { // If application/json is requested then this is an API request, and gets the response in JSON if(request.headers.accept && request.headers.accept.indexOf("application/json") !== -1) { diff --git a/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe-tiddlers-json.js b/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe-tiddlers-json.js index 01cc42a2a..24c5eaf88 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe-tiddlers-json.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe-tiddlers-json.js @@ -28,7 +28,7 @@ exports.handler = function(request,response,state) { // Get a skinny version of each tiddler var tiddlers = []; $tw.utils.each(titles,function(title) { - var tiddler = $tw.sqlTiddlerStore.getTiddler(title,recipe_name); + var tiddler = $tw.sqlTiddlerStore.getRecipeTiddler(title,recipe_name); tiddlers.push(Object.assign({},tiddler,{text: undefined, revision: "0", bag: "bag-gamma"})); }); var text = JSON.stringify(tiddlers); diff --git a/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe.js b/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe.js index 60c235a11..fb011100e 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/route-get-recipe.js @@ -50,7 +50,7 @@ exports.handler = function(request,response,state) { } response.write(template.substring(0,markerPos + marker.length)); $tw.utils.each(titles,function(title) { - var tiddler = $tw.sqlTiddlerStore.getTiddler(title,recipe_name); + var tiddler = $tw.sqlTiddlerStore.getRecipeTiddler(title,recipe_name); if((tiddler.text || "").length > 10 * 1024 * 1024) { response.write(JSON.stringify(Object.assign({},tiddler,{ revision: "0", diff --git a/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-store.js b/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-store.js index d794fd543..3651e78e4 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-store.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/sql-tiddler-store.js @@ -299,7 +299,31 @@ SqlTiddlerStore.prototype.deleteTiddler = function(title,bagname) { }); }; -SqlTiddlerStore.prototype.getTiddler = function(title,recipename) { +SqlTiddlerStore.prototype.getBagTiddler = function(title,bagname) { + const rows = this.runStatementGetAll(` + SELECT field_name, field_value + FROM fields + WHERE tiddler_id = ( + SELECT t.tiddler_id + FROM bags AS b + INNER JOIN tiddlers AS t ON b.bag_id = t.bag_id + WHERE t.title = $title AND b.bag_name = $bag_name + ) + `,{ + title: title, + bag_name: bagname + }); + if(rows.length === 0) { + return null; + } else { + return rows.reduce((accumulator,value) => { + accumulator[value["field_name"]] = value.field_value; + return accumulator; + },{title: title}); + } +}; + +SqlTiddlerStore.prototype.getRecipeTiddler = function(title,recipename) { const rows = this.runStatementGetAll(` SELECT field_name, field_value FROM fields diff --git a/plugins/tiddlywiki/multiwikiserver/modules/tests-sql-tiddler-store.js b/plugins/tiddlywiki/multiwikiserver/modules/tests-sql-tiddler-store.js index f6724cf30..69cda1aab 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/tests-sql-tiddler-store.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/tests-sql-tiddler-store.js @@ -44,23 +44,23 @@ describe("SQL tiddler store", function() { // Verify what we've got expect(sqlTiddlerStore.getRecipeTiddlers("recipe-rho")).toEqual([ "Another Tiddler", "Hello There"]); expect(sqlTiddlerStore.getRecipeTiddlers("recipe-sigma")).toEqual([ "Another Tiddler", "Hello There"]); - expect(sqlTiddlerStore.getTiddler("Hello There","recipe-rho")).toEqual({ title: "Hello There", text: "I'm in beta", tags: "four five six" }); - expect(sqlTiddlerStore.getTiddler("Missing Tiddler","recipe-rho")).toEqual(null); - expect(sqlTiddlerStore.getTiddler("Another Tiddler","recipe-rho")).toEqual({ title: "Another Tiddler", text: "I'm in alpha", tags: "one two three" }); - expect(sqlTiddlerStore.getTiddler("Hello There","recipe-sigma")).toEqual({ title: "Hello There", text: "I'm in gamma", tags: "seven eight nine" }); - expect(sqlTiddlerStore.getTiddler("Another Tiddler","recipe-sigma")).toEqual({ title: "Another Tiddler", text: "I'm in alpha", tags: "one two three" }); - expect(sqlTiddlerStore.getTiddler("Hello There","recipe-upsilon")).toEqual({title: "Hello There",text: "I'm in beta",tags: "four five six"}); + expect(sqlTiddlerStore.getRecipeTiddler("Hello There","recipe-rho")).toEqual({ title: "Hello There", text: "I'm in beta", tags: "four five six" }); + expect(sqlTiddlerStore.getRecipeTiddler("Missing Tiddler","recipe-rho")).toEqual(null); + expect(sqlTiddlerStore.getRecipeTiddler("Another Tiddler","recipe-rho")).toEqual({ title: "Another Tiddler", text: "I'm in alpha", tags: "one two three" }); + expect(sqlTiddlerStore.getRecipeTiddler("Hello There","recipe-sigma")).toEqual({ title: "Hello There", text: "I'm in gamma", tags: "seven eight nine" }); + expect(sqlTiddlerStore.getRecipeTiddler("Another Tiddler","recipe-sigma")).toEqual({ title: "Another Tiddler", text: "I'm in alpha", tags: "one two three" }); + expect(sqlTiddlerStore.getRecipeTiddler("Hello There","recipe-upsilon")).toEqual({title: "Hello There",text: "I'm in beta",tags: "four five six"}); // Delete a tiddlers to ensure the underlying tiddler in the recipe shows through sqlTiddlerStore.deleteTiddler("Hello There","bag-beta"); expect(sqlTiddlerStore.getRecipeTiddlers("recipe-rho")).toEqual([ "Another Tiddler", "Hello There"]); expect(sqlTiddlerStore.getRecipeTiddlers("recipe-sigma")).toEqual([ "Another Tiddler", "Hello There"]); - expect(sqlTiddlerStore.getTiddler("Hello There","recipe-beta")).toEqual(null); + expect(sqlTiddlerStore.getRecipeTiddler("Hello There","recipe-beta")).toEqual(null); sqlTiddlerStore.deleteTiddler("Another Tiddler","bag-alpha"); expect(sqlTiddlerStore.getRecipeTiddlers("recipe-rho")).toEqual([ "Hello There"]); expect(sqlTiddlerStore.getRecipeTiddlers("recipe-sigma")).toEqual([ "Hello There"]); // Save a recipe tiddler sqlTiddlerStore.saveRecipeTiddler({title: "More", text: "None"},"recipe-rho"); - expect(sqlTiddlerStore.getTiddler("More","recipe-rho")).toEqual({title: "More", text: "None"}); + expect(sqlTiddlerStore.getRecipeTiddler("More","recipe-rho")).toEqual({title: "More", text: "None"}); }); });