all repos — litestore @ 4e017d58d9806db374f64f8125b9df71bd15bcf3

A minimalist nosql document store.

Cleans up trailing whitespaces.
Steve Kellock steve@kellock.ca
Tue, 29 Jan 2019 10:54:51 -0500
commit

4e017d58d9806db374f64f8125b9df71bd15bcf3

parent

c8f651f3b50e01c85da0b3379c564907bfd9c1a9

M LICENSELICENSE

@@ -1,6 +1,6 @@

The MIT License (MIT) -Copyright (c) 2015-2018 Fabio Cevasco +Copyright (c) 2015-2019 Fabio Cevasco Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal

@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -
M litestore.nimblelitestore.nimble

@@ -57,13 +57,13 @@ shell compile, windows_x64, ls_file

task linux_x64_build, "Build LiteStore for Linux (x64)": shell compile, linux_x64, ls_file - + task linux_x86_build, "Build LiteStore for Linux (x86)": shell compile, linux_x86, ls_file - + task linux_arm_build, "Build LiteStore for Linux (ARM)": shell compile, linux_arm, ls_file - + task macosx_x64_build, "Build LiteStore for Mac OS X (x64)": shell compile, macosx_x64, ls_file

@@ -86,17 +86,17 @@ shell "rm", ls & ".exe"

echo "\n\n\n LINUX - x64:\n\n" linux_x64_buildTask() shell zip, "$1 $2 $3 $4" % [filename_for("linux", "x64"), ls, doc, db] - shell "rm", ls + shell "rm", ls echo "\n\n\n LINUX - x86:\n\n" linux_x86_buildTask() shell zip, "$1 $2 $3 $4" % [filename_for("linux", "x86"), ls, doc, db] - shell "rm", ls + shell "rm", ls echo "\n\n\n LINUX - ARM:\n\n" linux_arm_buildTask() shell zip, "$1 $2 $3 $4" % [filename_for("linux", "arm"), ls, doc, db] - shell "rm", ls + shell "rm", ls echo "\n\n\n MAC OS X - x64:\n\n" macosx_x64_buildTask() shell zip, "$1 $2 $3 $4" % [filename_for("macosx", "x64"), ls, doc, db] - shell "rm", ls + shell "rm", ls echo "\n\n\n ALL DONE!"
M src/admin/js/app.jssrc/admin/js/app.js

@@ -1,11 +1,11 @@

(function(){ 'use strict'; var app = window.LS || (window.LS = {}); - + app.flash = m.prop(); app.system = {}; m.route.mode = "hash"; - + app.init = function(info){ app.system = info; app.system.v = app.system.version.match(/(v.+)$/)[1];

@@ -24,5 +24,5 @@ "/search/:q/:page/:limit": app.search

}); }; Info.get().then(app.init); - + }());
M src/admin/js/components/doclist.jssrc/admin/js/components/doclist.js

@@ -2,12 +2,12 @@ (function(){

'use strict'; var app = window.LS || (window.LS = {}); var u = app.utils; - + app.doclist = {}; - + // Subcomponent app.doclist.panel = { - + /** * @typedef {Object} DoclistPanelConfig * @prop {string} id

@@ -27,10 +27,10 @@ m("p", args.tags.map(function(tag){

return u.taglink({name: tag, key: u.guid()}); })) ]); - return m(".row.search-result", m(".col-md-12", [u.panel(obj)])); + return m(".row.search-result", m(".col-md-12", [u.panel(obj)])); } }; - + /** * @param {Function} ctrl * @param {Object} args

@@ -44,7 +44,7 @@ var results = m(".row", [m(".col-md-12", args.items.map(function(item){

item.key = u.guid(); return m.component(app.doclist.panel, item); }))]); - + return m("section", [ m(".row", [args.title]), m(".row", [args.subtitle]),

@@ -53,5 +53,5 @@ results,

m(".row.text-center", [u.paginator(args.querydata)]) ]); }; - + }());
M src/admin/js/components/document.jssrc/admin/js/components/document.js

@@ -9,7 +9,7 @@ app.document.vm.init = function() {

var vm = this; vm.id = m.prop(m.route.param("id")); vm.action = m.route.param("action"); - vm.readOnly = true; + vm.readOnly = true; vm.contentType = m.prop(""); vm.updatedTags = m.prop(""); vm.content = "";

@@ -21,7 +21,7 @@ vm.ext = vm.id().match(/\.([a-z0-9]+)$/i)[1];

} catch(e) { vm.ext = ""; } - + // Retrieve single document & update relevant variables vm.getDoc = function(cb){ vm.doc = Doc.get(vm.id());

@@ -37,7 +37,7 @@ }

} }, vm.flashError); }; - + // Reset some properties based on action switch (vm.action) { case 'create':

@@ -52,7 +52,7 @@ case 'view':

vm.getDoc(); break; } - + // View document in editor vm.viewDocument = function(){ if (vm.ext === "md" && vm.id().match(new RegExp("^admin\/md\/"))) {

@@ -62,14 +62,14 @@ } else {

m.route("/document/view/"+vm.id()); } }; - + // Set current document editable vm.edit = function(){ vm.editor.setReadOnly(false); vm.action = "edit"; vm.flash(""); }; - + // Save document vm.save = function(){ var doc = {};

@@ -95,7 +95,7 @@ } else {

put(); } }; - + // Delete Document vm.delete = function(){ Doc.delete(vm.id()).then(function(){

@@ -107,7 +107,7 @@ m.route("/info");

}); }, vm.flashError); }; - + // Cancel editing vm.cancel = function(){ if (vm.action === "create"){

@@ -116,7 +116,7 @@ } else {

vm.viewDocument(); } }; - + // Patch document (update tags) vm.patch = function(){ var sysTags = vm.tags.filter(function(t){return /^\$/.test(t)});

@@ -129,7 +129,7 @@ vm.viewDocument();

}); }, vm.flashError); }; - + // File uploader callbacks. var onSuccess = function(data){ vm.id(data.id);

@@ -139,13 +139,13 @@ app.system = info;

vm.viewDocument(); }); }; - + var onFailure = function(data) { vm.flashError(data); }; var modalId = u.guid(); vm.uploader = u.uploader({docid: vm.id() || "", onSuccess: onSuccess, onFailure: onFailure, id: modalId}); - + // Populate tools based on current action vm.tools = function(){ if (app.system.read_only) {

@@ -174,7 +174,7 @@ }

return tools; }; }; - + // Module main view app.document.main = function(){ var vm = app.document.vm;

@@ -196,8 +196,8 @@ action: vm.patch,

actionText: "Update", content: m("div", [ m("input", { - type: "text", - class:"form-control", + type: "text", + class:"form-control", onchange: m.withAttr("value", vm.updatedTags), value: vm.updatedTags(), placeholder: "Enter comma-separated tags..."

@@ -235,7 +235,7 @@ } else {

panelContent = m.component(app.editor, vm); } var title = m("span",[titleLeft, titleRight]); - + return m("div", [ vm.uploader, u.modal(deleteDialogCfg),

@@ -244,6 +244,6 @@ m(".row", [u.toolbar({links: vm.tools()})]),

m(".row", [u.panel({title: title, content:panelContent})]) ]); }; - + u.layout(app.document); -}());+}());
M src/admin/js/components/editor.jssrc/admin/js/components/editor.js

@@ -1,5 +1,5 @@

(function(){ - 'use strict'; + 'use strict'; var app = window.LS || (window.LS = {}); app.editor = {};

@@ -61,5 +61,5 @@ args.content = JSON.stringify(args.content);

} return m(".editor.panel.panal-default", {config: app.editor.config(args)}, args.content); }; - -}());+ +}());
M src/admin/js/components/guide.jssrc/admin/js/components/guide.js

@@ -16,11 +16,11 @@ vm.links = app.system.read_only ? m.prop([]) : m.prop([{action: vm.edit, title: "Edit", icon: "edit"}]);

}; app.guide.main = function(){ return m("article.row", [ - u.toolbar({links: app.guide.vm.links()}), + u.toolbar({links: app.guide.vm.links()}), m.trust(app.guide.vm.content()) ]); }; u.layout(app.guide); -}());+}());
M src/admin/js/components/htmldoc.jssrc/admin/js/components/htmldoc.js

@@ -18,7 +18,7 @@ vm.links = m.prop([{action: vm.view, title: "View Source", icon: "code"}]);

}; app.htmldoc.main = function(){ return m("article.row", [ - u.toolbar({links: app.htmldoc.vm.links()}), + u.toolbar({links: app.htmldoc.vm.links()}), m.trust(app.htmldoc.vm.content()) ]); };
M src/admin/js/components/info.jssrc/admin/js/components/info.js

@@ -15,8 +15,8 @@ } else {

return m("li", [m("span", title+": "), m("strong", content)]); } }; - var readonly = info.read_only ? m("span.label.label-success", "Yes") : m("span.label.label-danger", "No"); - var mirror = info.mount ? m("span.label.label-success", "Yes") : m("span.label.label-danger", "No"); + var readonly = info.read_only ? m("span.label.label-success", "Yes") : m("span.label.label-danger", "No"); + var mirror = info.mount ? m("span.label.label-success", "Yes") : m("span.label.label-danger", "No"); var infolist = m(".col-sm-6", [m("ul.list-unstyled", [ li("Version", info.version), li("Datastore Version", info.datastore_version),
M src/admin/js/components/navbar.jssrc/admin/js/components/navbar.js

@@ -25,7 +25,7 @@ {path: "/guide/api_docs", title: caret+"docs (LiteStore Documents)"},

{path: "/guide/api_tags", title: caret+"tags (LiteStore Tags)"}, {path: "/guide/credits", title: "Credits"} ]; - vm.taglinks = function(info){ + vm.taglinks = function(info){ return info.tags.map(function(tag){ var key = Object.keys(tag)[0]; return {path: "/tags/"+key, title: key+" ("+tag[key]+")"};

@@ -35,19 +35,19 @@ return vm;

}, view: function(ctrl){ var links = [ - m("li", {class: ctrl.activelink("info")}, [m("a", {href: "/info", config: m.route}, + m("li", {class: ctrl.activelink("info")}, [m("a", {href: "/info", config: m.route}, [m("i.fa.fa-info-circle"), " Info"])]), u.dropdown({title: "Guide", icon:"fa-book", links: ctrl.guidelinks, active: ctrl.activelink("guide")}), u.dropdown({title: "Tags", icon:"fa-tags", links: ctrl.taglinks(app.system), active: ctrl.activelink("tags")})]; if (!app.system.read_only) { - links.push(m("li", - {class: ctrl.activelink("new")}, [m("a", {href: "/document/create/", config: m.route}, + links.push(m("li", + {class: ctrl.activelink("new")}, [m("a", {href: "/document/create/", config: m.route}, [m("i.fa.fa-plus-circle"), " New"])])); } return m("ul.nav.navbar-nav", links); } }; - + app.navheader = { view: function(ctrl, args) { return m(".navbar-header", [

@@ -61,7 +61,7 @@ m("a.navbar-brand", {href: "/", config:m.route}, "LiteStore Admin")

]); } }; - + app.searchbox = { controller: function() { var vm = {};

@@ -86,25 +86,25 @@ view: function(ctrl, args) {

return m("form.navbar-form.navbar-right[role='search']", [ m(".input-group", [ m("input.form-control", { - type:"text", + type:"text", placeholder:"Search...", onchange: m.withAttr("value", ctrl.query), config: ctrl.keySearch, value: ctrl.query() }), - m("span.input-group-btn", + m("span.input-group-btn", m("button.btn.btn-default", { type: "button", onclick: ctrl.search - }, + }, [m("i.fa.fa-search")])) ]) ] ); } }; - + app.navbar = { view: function(ctrl, args) { return m("nav.navbar.navbar-inverse.navbar-fixed-top", [

@@ -114,8 +114,8 @@ m("#nav-collapse.collapse.navbar-collapse", [

m.component(app.navlinks), m.component(app.searchbox) ]) - ]) + ]) ]); } }; -}());+}());
M src/admin/js/components/search.jssrc/admin/js/components/search.js

@@ -20,7 +20,7 @@ Doc.search(vm.query, vm.offset, vm.limit).then(function(result){

vm.result(result); vm.total = result.total; vm.execTime = (result.execution_time*1000).toFixed(0); - }, vm.flashError); + }, vm.flashError); }; app.search.main = function(){ var vm = app.search.vm;
M src/admin/js/components/tags.jssrc/admin/js/components/tags.js

@@ -19,7 +19,7 @@ vm.docs = Doc.getByTag(vm.id, vm.offset, vm.limit).then(function(docs){

vm.total = docs.total; vm.execTime = (docs["execution_time"]*1000).toFixed(0); return docs; - }, vm.flashError); + }, vm.flashError); }; app.tags.main = function(){ var vm = app.tags.vm;

@@ -29,7 +29,7 @@ obj.querydata = vm;

obj.title = m("h2", ["Tag: ", m("em", docs.tags)]); obj.subtitle = m("p", [m("strong",docs.total), " results, ("+vm.execTime+" ms)"]); obj.items = docs.results; - obj.items.forEach(function(item){ + obj.items.forEach(function(item){ item.content = m("ul", [ m("li", [m("strong", "Created: "), u.date(item.created)]), m("li", [m("strong", "Modified: "), u.date(item.modified)]),
M src/admin/js/components/uploader.jssrc/admin/js/components/uploader.js

@@ -1,5 +1,5 @@

(function(){ - 'use strict'; + 'use strict'; var app = window.LS || (window.LS = {}); var u = app.utils;

@@ -10,7 +10,7 @@ return function(element, isInitialized, context){

$(element).change(function(event){ obj.file(element.files[0]); if (obj.reader.readyState != 1) { - obj.reader.readAsDataURL(obj.file()); + obj.reader.readAsDataURL(obj.file()); } }); };

@@ -21,7 +21,7 @@ var vm = this;

vm.docid = m.prop(args.docid); vm.file = m.prop(); - vm.id = args.id; + vm.id = args.id; vm.btnId = "#upload-"+vm.id+"-btn"; vm.modalId = "#upload-"+vm.id+"-modal"; vm.reader = new FileReader();

@@ -46,14 +46,14 @@ doc.data = window.atob(doc.data);

} return Doc.put(doc, vm.file().type).then(args.onSuccess, args.onFailure); }; - + vm.cancel = function(){ $("input:file").val(''); }; - + return vm; }; - + app.uploader.view = function(ctrl, args){ var config = { title: "Upload Document",

@@ -78,7 +78,7 @@ m("p.help-block", "Select a file to upload as document.")

]), m(".checkbox", [ m("label", [ - m("input", {type: "checkbox", value: ctrl.isText(), onchange: m.withAttr("value", ctrl.isText)}), + m("input", {type: "checkbox", value: ctrl.isText(), onchange: m.withAttr("value", ctrl.isText)}), "Text File" ]), m("p.help-block", "Select if the file to upload contains textual content.")

@@ -87,5 +87,5 @@ ])

}; return u.modal(config); }; - -}());+ +}());
M src/admin/js/components/widgets.jssrc/admin/js/components/widgets.js

@@ -1,7 +1,7 @@

(function(){ 'use strict'; var app = window.LS || (window.LS = {}); - + app.widgets = {}; /* PANEL */

@@ -11,7 +11,7 @@ var title = "";

var footer = ""; if (args.title){ title = m(".panel-heading", [ - m("h2.panel-title", [args.title]) + m("h2.panel-title", [args.title]) ]); } if (args.footer){

@@ -26,7 +26,7 @@ footer

]); } }; - + /* PAGINATOR */ app.widgets.paginator = { view: function(ctrl, args){

@@ -42,7 +42,7 @@ }

var first = (n === 0); var last = (n == max_page); var offset = args.limit * n; - sign = sign || n+1; + sign = sign || n+1; return m("li", {class: klass}, [m("a", { href: args.baseurl +(n+1), // assuming 10 elements per page //+"/"+obj.limit,

@@ -51,7 +51,7 @@ }, [m.trust(sign)]

)] ); }; - + var pages = []; var prev; var next;

@@ -78,7 +78,7 @@ pages.push(next);

return m("nav", [m("ul.pagination", pages)]); } }; - + /* DROPDOWN */ app.widgets.dropdown = { view: function(ctrl, args){

@@ -90,9 +90,9 @@ }

return m(el, [ m("a.dropdown-toggle[href='#'][data-toggle='dropdown'][role='button'][aria-expanded='false']", [icon, m("span", " "+args.title+" "), m("span.caret")]), - m("ul.dropdown-menu[role='menu']", + m("ul.dropdown-menu[role='menu']", args.links.map(function(e){ - return m("li", + return m("li", [m("a", {href: e.path, config: m.route}, m.trust(e.title))]);})) ]); }

@@ -102,18 +102,18 @@ /* DROPDOWN */

app.widgets.taglink = { view: function(ctrl, args) { var color = /^\$/.test(args.name) ? "warning" : "primary"; - return m("span.tag-label.label.label-"+color, + return m("span.tag-label.label.label-"+color, [m("i.fa.fa-tag"), " ", m("a", {href: "/tags/"+args.name, config:m.route}, args.name)]); } }; - + /* DOCLINK */ app.widgets.doclink = { view: function(ctrl, args) { return m("a", {href: "/document/view/"+args.id, config: m.route}, id); } }; - + /* TAGBUTTON */ app.widgets.tagbutton = { view: function(ctrl, args) {

@@ -121,20 +121,20 @@ return m("a", {href: "/tags/"+args.name, config:m.route},

[m("i.fa.fa-tag"), " "+args.name+" ", m("span.badge", args.n)]); } }; - + /* TOOLBAR */ app.widgets.toolbar = { view: function(ctrl, args){ - return m("nav.toolbar.btn-group[role='group'][aria-label='...'].pull-right", + return m("nav.toolbar.btn-group[role='group'][aria-label='...'].pull-right", args.links.map(function(l){ - return m("a.btn.btn-default", - {onclick:l.action, config: l.config}, + return m("a.btn.btn-default", + {onclick:l.action, config: l.config}, [m("i.fa.fa-"+l.icon), " "+l.title]); - }) + }) ); } }; - + /* MODAL */ app.widgets.modal = { view: function(ctrl, args){

@@ -144,13 +144,13 @@ }

if (!args.dismissText) { args.dismissText = "Close"; } - return m(".modal.fade", + return m(".modal.fade", {id: args.id, tabindex: "-1", role: "dialog"}, [ m(".modal-dialog", [ m(".modal-content", [ m(".modal-header", [ - m("button", {type: "button", class: "close", "data-dismiss": "modal"}, + m("button", {type: "button", class: "close", "data-dismiss": "modal"}, [m.trust("×")]), m("h4.modal-title", args.title) ]),

@@ -166,4 +166,4 @@ );

} }; -}());+}());
M src/admin/js/models.jssrc/admin/js/models.js

@@ -7,44 +7,44 @@ var u = app.utils;

app.host = ""; //'http://localhost:9500'; var host = location.origin === app.host ? "" : app.host; - + Page.get = function(id) { var content = m.prop(""); return m.request({ - method: "GET", + method: "GET", url: host+"/docs/admin/md/"+id+".md", deserialize: function(value) { return value; } - }).then(function(content){ + }).then(function(content){ return u.markdown(content); }); }; - + Info.get = function(){ var content = m.prop(""); return m.request({ - method: "GET", + method: "GET", url: host+"/info" }).then(content); }; - + Doc.getByTag = function(tag, offset, limit) { offset = offset || 0; limit = limit || 10; var docs = m.prop(""); return m.request({ - method: "GET", + method: "GET", url: host+"/docs?contents=false&tags="+tag+"&limit="+limit+"&offset="+offset }).then(docs); }; - + Doc.search = function(search, offset, limit){ offset = offset || 0; limit = limit || 10; var docs = m.prop(""); return m.request({ - method: "GET", + method: "GET", url: host+"/docs?contents=false&search="+search+"&limit="+limit+"&offset="+offset, }).then(docs); };

@@ -52,23 +52,23 @@

Doc.get = function(id) { var doc = m.prop(""); return m.request({ - method: "GET", + method: "GET", url: host+"/docs/"+id+"?raw=true" }).then(doc); }; - + Doc.delete = function(id){ return m.request({ - method: "DELETE", + method: "DELETE", url: host+"/docs/"+id }); }; - + Doc.put = function(doc, contentType){ xhrcfg = u.setContentType(doc, contentType); console.log("Doc.put - Saving Document:", doc); return m.request({ - method: "PUT", + method: "PUT", url: host+"/docs/"+doc.id, data: doc.data, serialize: function(data){

@@ -77,7 +77,7 @@ },

config: xhrcfg }); }; - + Doc.upload = function(doc) { console.log("Doc.put - Uploading Document:", doc); return m.request({

@@ -89,7 +89,7 @@ return data;

} }); }; - + Doc.patch = function(id, updatedTags){ return Doc.get(id).then(function(doc){ var tags = doc.tags;

@@ -121,4 +121,4 @@ data: ops

}); }); }; -}());+}());
M src/admin/js/utils.jssrc/admin/js/utils.js

@@ -2,7 +2,7 @@ (function(){

'use strict'; var app = window.LS || (window.LS = {}); var u = app.utils = {}; - + // http://byronsalau.com/blog/how-to-create-a-guid-uuid-in-javascript/ u.guid = function(){ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {

@@ -10,7 +10,7 @@ var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8);

return v.toString(16); }); }; - + u.fixHeadings = function(html, maxheading){ var $content = $(html); var n = maxheading;

@@ -26,7 +26,7 @@ }

return u.fixHeadings($content, maxheading); } }; - + u.setContentType = function(doc, contentType){ var type = ""; var subtype = "";

@@ -80,7 +80,7 @@ var html = marked(s, {renderer: hs}).replace(/\{\{\$version\}\}/g, app.system.v);

var $html = $('<div>').append($(html).clone()); return u.fixHeadings($html, 2); }; - + /** * mod object: * @param {Object} mod

@@ -129,7 +129,7 @@ u.date = function(date) {

return (date) ? new Date(Date.parse(date)).toUTCString() : "n/a"; }; - + u.showModal = function(sel){ return function(){ $(sel).modal();

@@ -165,7 +165,7 @@ */

u.panel = function(obj){ return m.component(app.widgets.panel, obj); }; - + /** * @typedef {Object} PaginatorConfig * @prop {string} baseurl

@@ -204,7 +204,7 @@ */

u.taglink = function(obj){ return m.component(app.widgets.taglink, obj); }; - + /** * Creates a DocLink component. * @param {Object} obj
M src/admin/md/admin_app.mdsrc/admin/md/admin_app.md

@@ -64,4 +64,4 @@ * It is possible to upload local files instead of creating them by hand.

* Preview is available for images and HTML documents * Source code highlighting is available for Javascript, CSS, HTML, JSON and Markdown files. -![Document](images/app_document.png)+![Document](images/app_document.png)
M src/admin/md/api_docs.mdsrc/admin/md/api_docs.md

@@ -551,4 +551,4 @@ Content-Length: 0

Access-Control-Allow-Headers: Content-Type Access-Control-Allow-Origin: * Server: LiteStore/1.0.3 -```+```
M src/admin/md/api_tags.mdsrc/admin/md/api_tags.md

@@ -104,4 +104,4 @@ access-control-allow-headers: Content-Type

Content-Length: 34 {"id":"$type:text","documents":32} -```+```
M src/admin/md/architecture.mdsrc/admin/md/architecture.md

@@ -48,4 +48,4 @@ The [tags](class:kwd) table is used to store the associations between tags and documents. Tags can be added by users or add automatically by the system when a document is imported into the data store.

##### searchdata Table -This table is used as full-text index for searchable documents.+This table is used as full-text index for searchable documents.
M src/admin/md/credits.mdsrc/admin/md/credits.md

@@ -7,4 +7,4 @@ * Andreas Rumpf and all the contributors to the [Nim Programming Language](http://nim-lang.org/), used to develop LiteStore.

* Leo Horie, for creating the [Mithril Javascript Framework](https://lhorie.github.io/mithril/), used to develop the LiteStore Administration App. * The creators and contributors to the [Bootstrap](http://getbootstrap.com/) CSS and Javascript framework, used by the LiteStore Administration App. * The creators and contributors to the [Ace Editor](http://ace.c9.io/), used by the LiteStore Administration App. -* Cristopher Jeffrey and all the contributors to the [Marked Javascript Library](https://github.com/chjj/marked) used by the LiteStore Administration App.+* Cristopher Jeffrey and all the contributors to the [Marked Javascript Library](https://github.com/chjj/marked) used by the LiteStore Administration App.
M src/admin/md/data_model.mdsrc/admin/md/data_model.md

@@ -20,4 +20,4 @@ All system tags are prefixed by a [$](class:kwd) characters, and are used to identify the following document metadata. More specifically:

* **$dir:*directory*** &ndash; System tags starting with [$dir:](class:kwd) identify the name of a directory whose contents were imported into a data store. All files within the specified directory will be tagged with a [$dir:](class:kwd) system tag. Example: If a directory called **admin** is imported, imported files will be tagged with [$dir:admin](class:kwd). * **$type:*type*** &ndash; System tags starting with [$type:](class:kwd) identify the type of a document (i.e. the first portion of its content type). Example: Documents whose content type is **text/plain** will be tagged with [$type:text](class:kwd). -* **$subtype:*subtype*** &ndash; System tags starting with [$subtype:](class:kwd) identify the subtype of a document (i.e. the second portion of its content type). Example: Documents whose content type is **text/plain** will be tagged with [$subtype:plain](class:kwd).+* **$subtype:*subtype*** &ndash; System tags starting with [$subtype:](class:kwd) identify the subtype of a document (i.e. the second portion of its content type). Example: Documents whose content type is **text/plain** will be tagged with [$subtype:plain](class:kwd).
M src/admin/md/nim-api.mdsrc/admin/md/nim-api.md

@@ -113,6 +113,3 @@

runForever() ``` - - -
M src/admin/md/use-cases.mdsrc/admin/md/use-cases.md

@@ -42,4 +42,4 @@ Your app could then be served on any desktop system able to run LiteStore (e.g. OSX, Windows, Linux, ...even on a [Raspberry Pi](https://www.raspberrypi.org)).

#### Static Site Backend -LiteStore can be configured to run in read-only mode, so that only GET, HEAD, or OPTIONS request are accepted by the server. This makes it ideal as a backend for static web site generated with something like [nanoc](http://nanoc.ws) or [Jekyll](http://jekyllrb.com).+LiteStore can be configured to run in read-only mode, so that only GET, HEAD, or OPTIONS request are accepted by the server. This makes it ideal as a backend for static web site generated with something like [nanoc](http://nanoc.ws) or [Jekyll](http://jekyllrb.com).
M src/admin/styles/elements.lesssrc/admin/styles/elements.less

@@ -148,4 +148,4 @@

.search-result { margin: 5px 0; word-break: break-word; -}+}
M src/admin/styles/fa-core.lesssrc/admin/styles/fa-core.less

@@ -8,5 +8,4 @@ font-size: inherit; // can't have font-size inherit on line above, so need to override

text-rendering: auto; // optimizelegibility throws things off #1094 -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - }
M src/admin/styles/fa-variables.lesssrc/admin/styles/fa-variables.less

@@ -705,4 +705,3 @@ @fa-var-yen: "\f157";

@fa-var-youtube: "\f167"; @fa-var-youtube-play: "\f16a"; @fa-var-youtube-square: "\f166"; -
M src/litestore.nimsrc/litestore.nim

@@ -1,12 +1,12 @@

-import - litestorepkg/lib/x_sqlite3, - litestorepkg/lib/x_db_sqlite as db, - strutils, +import + litestorepkg/lib/x_sqlite3, + litestorepkg/lib/x_db_sqlite as db, + strutils, os, oids, times, json, - pegs, + pegs, uri, strtabs, httpcore,

@@ -15,7 +15,7 @@ base64

import litestorepkg/lib/types, litestorepkg/lib/logger, - litestorepkg/lib/utils, + litestorepkg/lib/utils, litestorepkg/lib/core, litestorepkg/lib/cli, litestorepkg/lib/server

@@ -37,7 +37,7 @@ let body = LS.execution.body

let ctype = LS.execution.ctype let uri = LS.execution.uri let operation = LS.execution.operation - var req:LSRequest + var req:LSRequest case operation.toUpperAscii: of "GET": req.reqMethod = HttpGet

@@ -98,7 +98,7 @@ if LS.operation == opVacuum:

setup(false) vacuum LS.file else: - # Open Datastore + # Open Datastore setup(true) case LS.operation:

@@ -127,13 +127,13 @@ for pair in pairs:

let data = pair.split("=") result[data[0]] = data[1] - proc query*(table: StringTableRef): string = + proc query*(table: StringTableRef): string = var params = newSeq[string](0) for key, value in pairs(table): params.add("$1=$2" % @[key, value]) return params.join("&") - proc newLSRequest(meth: HttpMethod, resource, id, body = "", params = newStringTable(), headers = newHttpHeaders()): LSRequest = + proc newLSRequest(meth: HttpMethod, resource, id, body = "", params = newStringTable(), headers = newHttpHeaders()): LSRequest = result.reqMethod = meth result.body = body result.headers = headers
M src/litestore.nim.cfgsrc/litestore.nim.cfg

@@ -23,5 +23,5 @@ amd64.linux.gcc.linkerexe = "x86_64-pc-linux-gcc"

# http://www.jaredwolff.com/toolchains/ arm.linux.gcc.path = "/usr/local/arm-none-linux-gnueabi/bin" -arm.linux.gcc.exe = "arm-none-linux-gnueabi-gcc" -arm.linux.gcc.linkerexe = "arm-none-linux-gnueabi-gcc" +arm.linux.gcc.exe = "arm-none-linux-gnueabi-gcc" +arm.linux.gcc.linkerexe = "arm-none-linux-gnueabi-gcc"
M src/litestorepkg/examples/jester_integration.nimsrc/litestorepkg/examples/jester_integration.nim

@@ -5,29 +5,29 @@

routes: # Just a simple, unrelated Jester route - get "/": + get "/": resp "Hello, World!" - + # Remapping LiteStore routes on Jester get re"^\/litestore\/(docs|info)\/?(.*)": let r = get(request.matches[0], request.matches[1], newStringTable(toSeq(request.params.pairs)), request.headers) - resp(r.code, r.content, r.headers["Content-Type"]) + resp(r.code, r.content, r.headers["Content-Type"]) post re"^\/litestore\/docs\/?(.*)": let r = post("docs", request.matches[0], request.body, request.headers) - resp(r.code, r.content, r.headers["Content-Type"]) + resp(r.code, r.content, r.headers["Content-Type"]) put re"^\/litestore\/docs\/?(.*)": let r = put("docs", request.matches[0], request.body, request.headers) - resp(r.code, r.content, r.headers["Content-Type"]) + resp(r.code, r.content, r.headers["Content-Type"]) patch re"^\/litestore\/docs\/?(.*)": let r = patch("docs", request.matches[0], request.body, request.headers) - resp(r.code, r.content, r.headers["Content-Type"]) + resp(r.code, r.content, r.headers["Content-Type"]) delete re"^\/litestore\/docs\/?(.*)": let r = delete("docs", request.matches[0], request.headers) - resp(r.code, r.content) + resp(r.code, r.content) head re"^\/litestore\/docs\/?(.*)": let r = head("docs", request.matches[0], request.headers)
M src/litestorepkg/lib/api_v1.nimsrc/litestorepkg/lib/api_v1.nim

@@ -1,4 +1,4 @@

-import +import asynchttpserver, asyncdispatch, strutils,

@@ -8,7 +8,7 @@ pegs,

json, os, times -import +import types, contenttypes, core,

@@ -188,10 +188,10 @@ content["datastore_version"] = %version

content["size"] = %($((LS.file.getFileSize().float/(1024*1024)).formatFloat(ffDecimal, 2)) & " MB") content["read_only"] = %LS.readonly content["log_level"] = %LS.loglevel - if LS.directory.len == 0: + if LS.directory.len == 0: content["directory"] = newJNull() - else: - content["directory"] = %LS.directory + else: + content["directory"] = %LS.directory content["mount"] = %LS.mount content["total_documents"] = %total_documents content["total_tags"] = %total_tags

@@ -361,7 +361,7 @@ else:

discard # never happens really. -proc post(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc post(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id == "": var ct = "text/plain" if req.headers.hasKey("Content-Type"):

@@ -370,7 +370,7 @@ return LS.postDocument(req.body.strip, ct)

else: return resError(Http400, "Bad request: document ID cannot be specified in POST requests.") -proc put(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc put(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": var ct = "text/plain" if req.headers.hasKey("Content-Type"):

@@ -379,13 +379,13 @@ return LS.putDocument(id, req.body.strip, ct)

else: return resError(Http400, "Bad request: document ID must be specified in PUT requests.") -proc delete(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc delete(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": return LS.deleteDocument(id) else: return resError(Http400, "Bad request: document ID must be specified in DELETE requests.") -proc patch(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc patch(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": return LS.patchDocument(id, req.body) else:

@@ -415,24 +415,24 @@ return resError(Http500, "Unable to read file '$1'." % path)

else: return resError(Http404, "File '$1' not found." % path) else: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) -proc route*(req: LSRequest, LS: LiteStore, resource = "docs", id = ""): LSResponse = +proc route*(req: LSRequest, LS: LiteStore, resource = "docs", id = ""): LSResponse = var reqMethod = $req.reqMethod if req.headers.hasKey("X-HTTP-Method-Override"): reqMethod = req.headers["X-HTTP-Method-Override"] case reqMethod.toUpperAscii: of "POST": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, post) of "PUT": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, put) of "DELETE": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, delete) of "HEAD": return validate(req, LS, resource, id, head)

@@ -442,7 +442,7 @@ of "GET":

return validate(req, LS, resource, id, get) of "PATCH": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, patch) else: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod)
M src/litestorepkg/lib/api_v2.nimsrc/litestorepkg/lib/api_v2.nim

@@ -1,4 +1,4 @@

-import +import asynchttpserver, asyncdispatch, strutils,

@@ -8,7 +8,7 @@ pegs,

json, os, times -import +import types, contenttypes, core,

@@ -66,7 +66,7 @@ var fragments = querystring.split('&')

for f in fragments: f.parseQueryOption(options) -proc validate*(req: LSRequest, LS: LiteStore, resource: string, id: string, cb: proc(req: LSRequest, LS: LiteStore, resource: string, id: string):LSResponse): LSResponse = +proc validate*(req: LSRequest, LS: LiteStore, resource: string, id: string, cb: proc(req: LSRequest, LS: LiteStore, resource: string, id: string):LSResponse): LSResponse = if req.reqMethod == HttpPost or req.reqMethod == HttpPut or req.reqMethod == HttpPatch: var ct = "" let body = req.body.strip

@@ -207,10 +207,10 @@ content["datastore_version"] = %version

content["size"] = %($((LS.file.getFileSize().float/(1024*1024)).formatFloat(ffDecimal, 2)) & " MB") content["read_only"] = %LS.readonly content["log_level"] = %LS.loglevel - if LS.directory.len == 0: + if LS.directory.len == 0: content["directory"] = newJNull() - else: - content["directory"] = %LS.directory + else: + content["directory"] = %LS.directory content["mount"] = %LS.mount content["total_documents"] = %total_documents content["total_tags"] = %total_tags

@@ -221,7 +221,7 @@ result.code = Http200

proc postDocument*(LS: LiteStore, body: string, ct: string, folder=""): LSResponse = if not folder.isFolder: - return resError(Http400, "Invalid folder specified when creating document: $1" % folder) + return resError(Http400, "Invalid folder specified when creating document: $1" % folder) try: var doc = LS.store.createDocument(folder, body, ct) if doc != "":

@@ -402,13 +402,13 @@ else:

discard # never happens really. -proc post*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc post*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = var ct = "text/plain" if req.headers.hasKey("Content-Type"): ct = req.headers["Content-Type"] return LS.postDocument(req.body.strip, ct, id) -proc put*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc put*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": var ct = "text/plain" if req.headers.hasKey("Content-Type"):

@@ -417,13 +417,13 @@ return LS.putDocument(id, req.body.strip, ct)

else: return resError(Http400, "Bad request: document ID must be specified in PUT requests.") -proc delete*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc delete*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": return LS.deleteDocument(id) else: return resError(Http400, "Bad request: document ID must be specified in DELETE requests.") -proc patch*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc patch*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": return LS.patchDocument(id, req.body) else:

@@ -453,24 +453,24 @@ return resError(Http500, "Unable to read file '$1'." % path)

else: return resError(Http404, "File '$1' not found." % path) else: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) -proc route*(req: LSRequest, LS: LiteStore, resource = "docs", id = ""): LSResponse = +proc route*(req: LSRequest, LS: LiteStore, resource = "docs", id = ""): LSResponse = var reqMethod = $req.reqMethod if req.headers.hasKey("X-HTTP-Method-Override"): reqMethod = req.headers["X-HTTP-Method-Override"] case reqMethod.toUpperAscii: of "POST": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, post) of "PUT": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, put) of "DELETE": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, delete) of "HEAD": return validate(req, LS, resource, id, head)

@@ -480,7 +480,7 @@ of "GET":

return validate(req, LS, resource, id, get) of "PATCH": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, patch) else: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod)
M src/litestorepkg/lib/api_v3.nimsrc/litestorepkg/lib/api_v3.nim

@@ -1,4 +1,4 @@

-import +import asynchttpserver, asyncdispatch, strutils,

@@ -9,7 +9,7 @@ pegs,

json, os, times -import +import types, contenttypes, core,

@@ -51,7 +51,7 @@ else:

clauses.add("$1 ASC" % field) return clauses.join(", ") -proc selectClause*(str: string, options: var QueryOptions) = +proc selectClause*(str: string, options: var QueryOptions) = let tokens = """ path <- '$' (objItem / objField)+ ident <- [a-zA-Z0-9_]+

@@ -61,10 +61,10 @@ objItem <- objField objIndex

""" let fields = peg(""" fields <- ^{field} (\s* ',' \s* {field})*$ - field <- path \s+ ('as' / 'AS') \s+ ident + field <- path \s+ ('as' / 'AS') \s+ ident """ & tokens) let field = peg(""" - field <- ^{path} \s+ ('as' / 'AS') \s+ {ident}$ + field <- ^{path} \s+ ('as' / 'AS') \s+ {ident}$ """ & tokens) var fieldMatches = newSeq[string](10) if str.strip.match(fields, fieldMatches):

@@ -74,7 +74,7 @@ var rawTuple = newSeq[string](2)

if m.match(field, rawTuple): options.jsonSelect.add((path: rawTuple[0], alias: rawTuple[1])) -proc filterClauses*(str: string, options: var QueryOptions) = +proc filterClauses*(str: string, options: var QueryOptions) = let tokens = """ operator <- 'not eq' / 'eq' / 'gte' / 'gt' / 'lte' / 'lt' / 'contains' value <- string / number / 'null' / 'true' / 'false'

@@ -181,7 +181,7 @@ var fragments = querystring.split('&')

for f in fragments: f.parseQueryOption(options) -proc validate*(req: LSRequest, LS: LiteStore, resource: string, id: string, cb: proc(req: LSRequest, LS: LiteStore, resource: string, id: string):LSResponse): LSResponse = +proc validate*(req: LSRequest, LS: LiteStore, resource: string, id: string, cb: proc(req: LSRequest, LS: LiteStore, resource: string, id: string):LSResponse): LSResponse = if req.reqMethod == HttpPost or req.reqMethod == HttpPut or req.reqMethod == HttpPatch: var ct = "" let body = req.body.strip

@@ -252,11 +252,11 @@ d.elems[index] = value

case op: of "remove": d.elems.del(index) - of "add": + of "add": d.elems.insert(value, index) - of "replace": + of "replace": d.elems[index] = value - of "test": + of "test": if d.elems[index] != value: return false else:

@@ -274,14 +274,14 @@ if d.hasKey(key):

d.delete(key) else: raise newException(EInvalidRequest, "key '$1' not found in path '$2'" % [key, path]) - of "add": + of "add": d[key] = value - of "replace": + of "replace": if d.hasKey(key): d[key] = value else: raise newException(EInvalidRequest, "key '$1' not found in path '$2'" % [key, path]) - of "test": + of "test": if dorig.hasKey(key): if dorig[key] != value: return false

@@ -398,10 +398,10 @@ content["datastore_version"] = %version

content["size"] = %($((LS.file.getFileSize().float/(1024*1024)).formatFloat(ffDecimal, 2)) & " MB") content["read_only"] = %LS.readonly content["log_level"] = %LS.loglevel - if LS.directory.len == 0: + if LS.directory.len == 0: content["directory"] = newJNull() - else: - content["directory"] = %LS.directory + else: + content["directory"] = %LS.directory content["mount"] = %LS.mount content["total_documents"] = %total_documents content["total_tags"] = %total_tags

@@ -412,7 +412,7 @@ result.code = Http200

proc postDocument*(LS: LiteStore, body: string, ct: string, folder=""): LSResponse = if not folder.isFolder: - return resError(Http400, "Invalid folder specified when creating document: $1" % folder) + return resError(Http400, "Invalid folder specified when creating document: $1" % folder) try: var doc = LS.store.createDocument(folder, body, ct) if doc != "":

@@ -611,13 +611,13 @@ else:

discard # never happens really. -proc post*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc post*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = var ct = "text/plain" if req.headers.hasKey("Content-Type"): ct = req.headers["Content-Type"] return LS.postDocument(req.body.strip, ct, id) -proc put*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc put*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": var ct = "text/plain" if req.headers.hasKey("Content-Type"):

@@ -626,13 +626,13 @@ return LS.putDocument(id, req.body.strip, ct)

else: return resError(Http400, "Bad request: document ID must be specified in PUT requests.") -proc delete*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc delete*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": return LS.deleteDocument(id) else: return resError(Http400, "Bad request: document ID must be specified in DELETE requests.") -proc patch*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc patch*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": return LS.patchDocument(id, req.body) else:

@@ -662,24 +662,24 @@ return resError(Http500, "Unable to read file '$1'." % path)

else: return resError(Http404, "File '$1' not found." % path) else: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) -proc route*(req: LSRequest, LS: LiteStore, resource = "docs", id = ""): LSResponse = +proc route*(req: LSRequest, LS: LiteStore, resource = "docs", id = ""): LSResponse = var reqMethod = $req.reqMethod if req.headers.hasKey("X-HTTP-Method-Override"): reqMethod = req.headers["X-HTTP-Method-Override"] case reqMethod.toUpperAscii: of "POST": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, post) of "PUT": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, put) of "DELETE": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, delete) of "HEAD": return validate(req, LS, resource, id, head)

@@ -689,7 +689,7 @@ of "GET":

return validate(req, LS, resource, id, get) of "PATCH": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, patch) else: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod)
M src/litestorepkg/lib/api_v4.nimsrc/litestorepkg/lib/api_v4.nim

@@ -1,4 +1,4 @@

-import +import asynchttpserver, asyncdispatch, strutils,

@@ -9,7 +9,7 @@ pegs,

json, os, times -import +import types, contenttypes, core,

@@ -51,7 +51,7 @@ else:

clauses.add("$1 ASC" % field) return clauses.join(", ") -proc selectClause*(str: string, options: var QueryOptions) = +proc selectClause*(str: string, options: var QueryOptions) = let tokens = """ path <- '$' (objItem / objField)+ ident <- [a-zA-Z0-9_]+

@@ -61,10 +61,10 @@ objItem <- objField objIndex

""" let fields = peg(""" fields <- ^{field} (\s* ',' \s* {field})*$ - field <- path \s+ ('as' / 'AS') \s+ ident + field <- path \s+ ('as' / 'AS') \s+ ident """ & tokens) let field = peg(""" - field <- ^{path} \s+ ('as' / 'AS') \s+ {ident}$ + field <- ^{path} \s+ ('as' / 'AS') \s+ {ident}$ """ & tokens) var fieldMatches = newSeq[string](10) if str.strip.match(fields, fieldMatches):

@@ -74,7 +74,7 @@ var rawTuple = newSeq[string](2)

if m.match(field, rawTuple): options.jsonSelect.add((path: rawTuple[0], alias: rawTuple[1])) -proc filterClauses*(str: string, options: var QueryOptions) = +proc filterClauses*(str: string, options: var QueryOptions) = let tokens = """ operator <- 'not eq' / 'eq' / 'gte' / 'gt' / 'lte' / 'lt' / 'contains' value <- string / number / 'null' / 'true' / 'false'

@@ -205,7 +205,7 @@ var fragments = querystring.split('&')

for f in fragments: f.parseQueryOption(options) -proc validate*(req: LSRequest, LS: LiteStore, resource: string, id: string, cb: proc(req: LSRequest, LS: LiteStore, resource: string, id: string):LSResponse): LSResponse = +proc validate*(req: LSRequest, LS: LiteStore, resource: string, id: string, cb: proc(req: LSRequest, LS: LiteStore, resource: string, id: string):LSResponse): LSResponse = if req.reqMethod == HttpPost or req.reqMethod == HttpPut or req.reqMethod == HttpPatch: var ct = "" let body = req.body.strip

@@ -275,11 +275,11 @@ d.elems[index] = value

case op: of "remove": d.elems.del(index) - of "add": + of "add": d.elems.insert(value, index) - of "replace": + of "replace": d.elems[index] = value - of "test": + of "test": if d.elems[index] != value: return false else:

@@ -297,14 +297,14 @@ if d.hasKey(key):

d.delete(key) else: raise newException(EInvalidRequest, "key '$1' not found in path '$2'" % [key, path]) - of "add": + of "add": d[key] = value - of "replace": + of "replace": if d.hasKey(key): d[key] = value else: raise newException(EInvalidRequest, "key '$1' not found in path '$2'" % [key, path]) - of "test": + of "test": if dorig.hasKey(key): if dorig[key] != value: return false

@@ -460,10 +460,10 @@ content["datastore_version"] = %version

content["size"] = %($((LS.file.getFileSize().float/(1024*1024)).formatFloat(ffDecimal, 2)) & " MB") content["read_only"] = %LS.readonly content["log_level"] = %LS.loglevel - if LS.directory.len == 0: + if LS.directory.len == 0: content["directory"] = newJNull() - else: - content["directory"] = %LS.directory + else: + content["directory"] = %LS.directory content["mount"] = %LS.mount content["total_documents"] = %total_documents content["total_tags"] = %total_tags

@@ -475,7 +475,7 @@ result.code = Http200

proc postDocument*(LS: LiteStore, body: string, ct: string, folder="", req: LSRequest): LSResponse = if not folder.isFolder: - return resError(Http400, "Invalid folder specified when creating document: $1" % folder) + return resError(Http400, "Invalid folder specified when creating document: $1" % folder) try: var doc = LS.store.createDocument(folder, body, ct) if doc != "":

@@ -687,7 +687,7 @@ of "tags":

var options = newQueryOptions() try: parseQueryOptions(req.url.query, options); - if id != "": + if id != "": return LS.getTag(id, options, req) else: return LS.getTags(options, req)

@@ -700,13 +700,13 @@ return LS.getInfo(req)

else: discard # never happens really. -proc post*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc post*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = var ct = "text/plain" if req.headers.hasKey("Content-Type"): ct = req.headers["Content-Type"] return LS.postDocument(req.body.strip, ct, id, req) -proc put*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc put*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": var ct = "text/plain" if req.headers.hasKey("Content-Type"):

@@ -715,13 +715,13 @@ return LS.putDocument(id, req.body.strip, ct, req)

else: return resError(Http400, "Bad request: document ID must be specified in PUT requests.") -proc delete*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc delete*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": return LS.deleteDocument(id, req) else: return resError(Http400, "Bad request: document ID must be specified in DELETE requests.") -proc patch*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = +proc patch*(req: LSRequest, LS: LiteStore, resource: string, id = ""): LSResponse = if id != "": return LS.patchDocument(id, req.body, req) else:

@@ -752,24 +752,24 @@ return resError(Http500, "Unable to read file '$1'." % path)

else: return resError(Http404, "File '$1' not found." % path) else: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) -proc route*(req: LSRequest, LS: LiteStore, resource = "docs", id = ""): LSResponse = +proc route*(req: LSRequest, LS: LiteStore, resource = "docs", id = ""): LSResponse = var reqMethod = $req.reqMethod if req.headers.hasKey("X-HTTP-Method-Override"): reqMethod = req.headers["X-HTTP-Method-Override"] case reqMethod.toUpperAscii: of "POST": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, post) of "PUT": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, put) of "DELETE": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, delete) of "HEAD": return validate(req, LS, resource, id, head)

@@ -779,7 +779,7 @@ of "GET":

return validate(req, LS, resource, id, get) of "PATCH": if LS.readonly: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod) return validate(req, LS, resource, id, patch) else: - return resError(Http405, "Method not allowed: $1" % $req.reqMethod) + return resError(Http405, "Method not allowed: $1" % $req.reqMethod)
M src/litestorepkg/lib/cli.nimsrc/litestorepkg/lib/cli.nim

@@ -10,7 +10,7 @@ utils

const favicon = "../../admin/favicon.ico".slurp -var +var operation = opRun directory:string = "" readonly = false

@@ -21,10 +21,10 @@ exFile:string = ""

exBody:string = "" exType:string = "" exUri:string = "" - + let usage* = appname & " v" & pkgVersion & " - Lightweight REST Document Store" & """ - + (c) 2015-2018 Fabio Cevasco Usage:
M src/litestorepkg/lib/config.nimsrc/litestorepkg/lib/config.nim

@@ -1,6 +1,6 @@

const pkgName* = "litestore" - pkgVersion* = "1.5.0" + pkgVersion* = "1.5.0" pkgAuthor* = "Fabio Cevasco" pkgDescription* = "Self-contained, lightweight, RESTful document store." pkgLicense* = "MIT"

@@ -10,4 +10,3 @@ var

file* = "data.db" address* = "127.0.0.1" port* = 9500 -
M src/litestorepkg/lib/contenttypes.jsonsrc/litestorepkg/lib/contenttypes.json

@@ -1,2468 +1,2468 @@

-[ - { +[ + { ".123":"application\/vnd.lotus-1-2-3" }, - { + { ".3dml":"text\/vnd.in3d.3dml" }, - { + { ".3g2":"video\/3gpp2" }, - { + { ".3gp":"video\/3gpp" }, - { + { ".a":"application\/octet-stream" }, - { + { ".aab":"application\/x-authorware-bin" }, - { + { ".aac":"audio\/x-aac" }, - { + { ".aam":"application\/x-authorware-map" }, - { + { ".aas":"application\/x-authorware-seg" }, - { + { ".abw":"application\/x-abiword" }, - { + { ".acc":"application\/vnd.americandynamics.acc" }, - { + { ".ace":"application\/x-ace-compressed" }, - { + { ".acu":"application\/vnd.acucobol" }, - { + { ".acutc":"application\/vnd.acucorp" }, - { + { ".adp":"audio\/adpcm" }, - { + { ".aep":"application\/vnd.audiograph" }, - { + { ".afm":"application\/x-font-type1" }, - { + { ".afp":"application\/vnd.ibm.modcap" }, - { + { ".ai":"application\/postscript" }, - { + { ".aif":"audio\/x-aiff" }, - { + { ".aifc":"audio\/x-aiff" }, - { + { ".aiff":"audio\/x-aiff" }, - { + { ".air":"application\/vnd.adobe.air-application-installer-package+zip" }, - { + { ".ami":"application\/vnd.amiga.ami" }, - { + { ".apk":"application\/vnd.android.package-archive" }, - { + { ".application":"application\/x-ms-application" }, - { + { ".apr":"application\/vnd.lotus-approach" }, - { + { ".asc":"application\/pgp-signature" }, - { + { ".asf":"video\/x-ms-asf" }, - { + { ".asm":"text\/x-asm" }, - { + { ".aso":"application\/vnd.accpac.simply.aso" }, - { + { ".asx":"video\/x-ms-asf" }, - { + { ".atc":"application\/vnd.acucorp" }, - { + { ".atom":"application\/atom+xml" }, - { + { ".atomcat":"application\/atomcat+xml" }, - { + { ".atomsvc":"application\/atomsvc+xml" }, - { + { ".atx":"application\/vnd.antix.game-component" }, - { + { ".au":"audio\/basic" }, - { + { ".avi":"video\/x-msvideo" }, - { + { ".aw":"application\/applixware" }, - { + { ".azf":"application\/vnd.airzip.filesecure.azf" }, - { + { ".azs":"application\/vnd.airzip.filesecure.azs" }, - { + { ".azw":"application\/vnd.amazon.ebook" }, - { + { ".bat":"application\/x-msdownload" }, - { + { ".bcpio":"application\/x-bcpio" }, - { + { ".bdf":"application\/x-font-bdf" }, - { + { ".bdm":"application\/vnd.syncml.dm+wbxml" }, - { + { ".bh2":"application\/vnd.fujitsu.oasysprs" }, - { + { ".bin":"application\/octet-stream" }, - { + { ".bmi":"application\/vnd.bmi" }, - { + { ".bmp":"image\/bmp" }, - { + { ".book":"application\/vnd.framemaker" }, - { + { ".box":"application\/vnd.previewsystems.box" }, - { + { ".boz":"application\/x-bzip2" }, - { + { ".bpk":"application\/octet-stream" }, - { + { ".btif":"image\/prs.btif" }, - { + { ".bz":"application\/x-bzip" }, - { + { ".bz2":"application\/x-bzip2" }, - { + { ".c":"text\/x-c" }, - { + { ".c4d":"application\/vnd.clonk.c4group" }, - { + { ".c4f":"application\/vnd.clonk.c4group" }, - { + { ".c4g":"application\/vnd.clonk.c4group" }, - { + { ".c4p":"application\/vnd.clonk.c4group" }, - { + { ".c4u":"application\/vnd.clonk.c4group" }, - { + { ".cab":"application\/vnd.ms-cab-compressed" }, - { + { ".car":"application\/vnd.curl.car" }, - { + { ".cat":"application\/vnd.ms-pki.seccat" }, - { + { ".cc":"text\/x-c" }, - { + { ".cct":"application\/x-director" }, - { + { ".ccxml":"application\/ccxml+xml" }, - { + { ".cdbcmsg":"application\/vnd.contact.cmsg" }, - { + { ".cdf":"application\/x-netcdf" }, - { + { ".cdkey":"application\/vnd.mediastation.cdkey" }, - { + { ".cdx":"chemical\/x-cdx" }, - { + { ".cdxml":"application\/vnd.chemdraw+xml" }, - { + { ".cdy":"application\/vnd.cinderella" }, - { + { ".cer":"application\/pkix-cert" }, - { + { ".cgm":"image\/cgm" }, - { + { ".chat":"application\/x-chat" }, - { + { ".chm":"application\/vnd.ms-htmlhelp" }, - { + { ".chrt":"application\/vnd.kde.kchart" }, - { + { ".cif":"chemical\/x-cif" }, - { + { ".cii":"application\/vnd.anser-web-certificate-issue-initiation" }, - { + { ".cil":"application\/vnd.ms-artgalry" }, - { + { ".cla":"application\/vnd.claymore" }, - { + { ".class":"application\/java-vm" }, - { + { ".clkk":"application\/vnd.crick.clicker.keyboard" }, - { + { ".clkp":"application\/vnd.crick.clicker.palette" }, - { + { ".clkt":"application\/vnd.crick.clicker.template" }, - { + { ".clkw":"application\/vnd.crick.clicker.wordbank" }, - { + { ".clkx":"application\/vnd.crick.clicker" }, - { + { ".clp":"application\/x-msclip" }, - { + { ".cmc":"application\/vnd.cosmocaller" }, - { + { ".cmdf":"chemical\/x-cmdf" }, - { + { ".cml":"chemical\/x-cml" }, - { + { ".cmp":"application\/vnd.yellowriver-custom-menu" }, - { + { ".cmx":"image\/x-cmx" }, - { + { ".cod":"application\/vnd.rim.cod" }, - { + { ".com":"application\/x-msdownload" }, - { + { ".conf":"text\/plain" }, - { + { ".cpio":"application\/x-cpio" }, - { + { ".cpp":"text\/x-c" }, - { + { ".cpt":"application\/mac-compactpro" }, - { + { ".crd":"application\/x-mscardfile" }, - { + { ".crl":"application\/pkix-crl" }, - { + { ".crt":"application\/x-x509-ca-cert" }, - { + { ".csh":"application\/x-csh" }, - { + { ".csml":"chemical\/x-csml" }, - { + { ".csp":"application\/vnd.commonspace" }, - { + { ".css":"text\/css" }, - { + { ".cst":"application\/x-director" }, - { + { ".csv":"text\/csv" }, - { + { ".cu":"application\/cu-seeme" }, - { + { ".curl":"text\/vnd.curl" }, - { + { ".cww":"application\/prs.cww" }, - { + { ".cxt":"application\/x-director" }, - { + { ".cxx":"text\/x-c" }, - { + { ".daf":"application\/vnd.mobius.daf" }, - { + { ".dataless":"application\/vnd.fdsn.seed" }, - { + { ".davmount":"application\/davmount+xml" }, - { + { ".dcr":"application\/x-director" }, - { + { ".dcurl":"text\/vnd.curl.dcurl" }, - { + { ".dd2":"application\/vnd.oma.dd2+xml" }, - { + { ".ddd":"application\/vnd.fujixerox.ddd" }, - { + { ".deb":"application\/x-debian-package" }, - { + { ".def":"text\/plain" }, - { + { ".deploy":"application\/octet-stream" }, - { + { ".der":"application\/x-x509-ca-cert" }, - { + { ".dfac":"application\/vnd.dreamfactory" }, - { + { ".dic":"text\/x-c" }, - { + { ".diff":"text\/plain" }, - { + { ".dir":"application\/x-director" }, - { + { ".dis":"application\/vnd.mobius.dis" }, - { + { ".dist":"application\/octet-stream" }, - { + { ".distz":"application\/octet-stream" }, - { + { ".djv":"image\/vnd.djvu" }, - { + { ".djvu":"image\/vnd.djvu" }, - { + { ".dll":"application\/x-msdownload" }, - { + { ".dmg":"application\/octet-stream" }, - { + { ".dms":"application\/octet-stream" }, - { + { ".dna":"application\/vnd.dna" }, - { + { ".doc":"application\/msword" }, - { + { ".docm":"application\/vnd.ms-word.document.macroenabled.12" }, - { + { ".docx":"application\/vnd.openxmlformats-officedocument.wordprocessingml.document" }, - { + { ".dot":"application\/msword" }, - { + { ".dotm":"application\/vnd.ms-word.template.macroenabled.12" }, - { + { ".dotx":"application\/vnd.openxmlformats-officedocument.wordprocessingml.template" }, - { + { ".dp":"application\/vnd.osgi.dp" }, - { + { ".dpg":"application\/vnd.dpgraph" }, - { + { ".dsc":"text\/prs.lines.tag" }, - { + { ".dtb":"application\/x-dtbook+xml" }, - { + { ".dtd":"application\/xml-dtd" }, - { + { ".dts":"audio\/vnd.dts" }, - { + { ".dtshd":"audio\/vnd.dts.hd" }, - { + { ".dump":"application\/octet-stream" }, - { + { ".dvi":"application\/x-dvi" }, - { + { ".dwf":"model\/vnd.dwf" }, - { + { ".dwg":"image\/vnd.dwg" }, - { + { ".dxf":"image\/vnd.dxf" }, - { + { ".dxp":"application\/vnd.spotfire.dxp" }, - { + { ".dxr":"application\/x-director" }, - { + { ".ecelp4800":"audio\/vnd.nuera.ecelp4800" }, - { + { ".ecelp7470":"audio\/vnd.nuera.ecelp7470" }, - { + { ".ecelp9600":"audio\/vnd.nuera.ecelp9600" }, - { + { ".ecma":"application\/ecmascript" }, - { + { ".edm":"application\/vnd.novadigm.edm" }, - { + { ".edx":"application\/vnd.novadigm.edx" }, - { + { ".efif":"application\/vnd.picsel" }, - { + { ".ei6":"application\/vnd.pg.osasli" }, - { + { ".elc":"application\/octet-stream" }, - { + { ".eml":"message\/rfc822" }, - { + { ".emma":"application\/emma+xml" }, - { + { ".eol":"audio\/vnd.digital-winds" }, - { + { ".eot":"application\/vnd.ms-fontobject" }, - { + { ".eps":"application\/postscript" }, - { + { ".epub":"application\/epub+zip" }, - { + { ".es3":"application\/vnd.eszigno3+xml" }, - { + { ".esf":"application\/vnd.epson.esf" }, - { + { ".et3":"application\/vnd.eszigno3+xml" }, - { + { ".etx":"text\/x-setext" }, - { + { ".exe":"application\/x-msdownload" }, - { + { ".ext":"application\/vnd.novadigm.ext" }, - { + { ".ez":"application\/andrew-inset" }, - { + { ".ez2":"application\/vnd.ezpix-album" }, - { + { ".ez3":"application\/vnd.ezpix-package" }, - { + { ".f":"text\/x-fortran" }, - { + { ".f4v":"video\/x-f4v" }, - { + { ".f77":"text\/x-fortran" }, - { + { ".f90":"text\/x-fortran" }, - { + { ".fbs":"image\/vnd.fastbidsheet" }, - { + { ".fdf":"application\/vnd.fdf" }, - { + { ".fe_launch":"application\/vnd.denovo.fcselayout-link" }, - { + { ".fg5":"application\/vnd.fujitsu.oasysgp" }, - { + { ".fgd":"application\/x-director" }, - { + { ".fh":"image\/x-freehand" }, - { + { ".fh4":"image\/x-freehand" }, - { + { ".fh5":"image\/x-freehand" }, - { + { ".fh7":"image\/x-freehand" }, - { + { ".fhc":"image\/x-freehand" }, - { + { ".fig":"application\/x-xfig" }, - { + { ".fli":"video\/x-fli" }, - { + { ".flo":"application\/vnd.micrografx.flo" }, - { + { ".flv":"video\/x-flv" }, - { + { ".flw":"application\/vnd.kde.kivio" }, - { + { ".flx":"text\/vnd.fmi.flexstor" }, - { + { ".fly":"text\/vnd.fly" }, - { + { ".fm":"application\/vnd.framemaker" }, - { + { ".fnc":"application\/vnd.frogans.fnc" }, - { + { ".for":"text\/x-fortran" }, - { + { ".fpx":"image\/vnd.fpx" }, - { + { ".frame":"application\/vnd.framemaker" }, - { + { ".fsc":"application\/vnd.fsc.weblaunch" }, - { + { ".fst":"image\/vnd.fst" }, - { + { ".ftc":"application\/vnd.fluxtime.clip" }, - { + { ".fti":"application\/vnd.anser-web-funds-transfer-initiation" }, - { + { ".fvt":"video\/vnd.fvt" }, - { + { ".fzs":"application\/vnd.fuzzysheet" }, - { + { ".g3":"image\/g3fax" }, - { + { ".gac":"application\/vnd.groove-account" }, - { + { ".gdl":"model\/vnd.gdl" }, - { + { ".geo":"application\/vnd.dynageo" }, - { + { ".gex":"application\/vnd.geometry-explorer" }, - { + { ".ggb":"application\/vnd.geogebra.file" }, - { + { ".ggt":"application\/vnd.geogebra.tool" }, - { + { ".ghf":"application\/vnd.groove-help" }, - { + { ".gif":"image\/gif" }, - { + { ".gim":"application\/vnd.groove-identity-message" }, - { + { ".gmx":"application\/vnd.gmx" }, - { + { ".gnumeric":"application\/x-gnumeric" }, - { + { ".gph":"application\/vnd.flographit" }, - { + { ".gqf":"application\/vnd.grafeq" }, - { + { ".gqs":"application\/vnd.grafeq" }, - { + { ".gram":"application\/srgs" }, - { + { ".gre":"application\/vnd.geometry-explorer" }, - { + { ".grv":"application\/vnd.groove-injector" }, - { + { ".grxml":"application\/srgs+xml" }, - { + { ".gsf":"application\/x-font-ghostscript" }, - { + { ".gtar":"application\/x-gtar" }, - { + { ".gtm":"application\/vnd.groove-tool-message" }, - { + { ".gtw":"model\/vnd.gtw" }, - { + { ".gv":"text\/vnd.graphviz" }, - { + { ".gz":"application\/x-gzip" }, - { + { ".h":"text\/x-c" }, - { + { ".h261":"video\/h261" }, - { + { ".h263":"video\/h263" }, - { + { ".h264":"video\/h264" }, - { + { ".hbci":"application\/vnd.hbci" }, - { + { ".hdf":"application\/x-hdf" }, - { + { ".hh":"text\/x-c" }, - { + { ".hlp":"application\/winhlp" }, - { + { ".hpgl":"application\/vnd.hp-hpgl" }, - { + { ".hpid":"application\/vnd.hp-hpid" }, - { + { ".hps":"application\/vnd.hp-hps" }, - { + { ".hqx":"application\/mac-binhex40" }, - { + { ".htke":"application\/vnd.kenameaapp" }, - { + { ".htm":"text\/html" }, - { + { ".html":"text\/html" }, - { + { ".hvd":"application\/vnd.yamaha.hv-dic" }, - { + { ".hvp":"application\/vnd.yamaha.hv-voice" }, - { + { ".hvs":"application\/vnd.yamaha.hv-script" }, - { + { ".icc":"application\/vnd.iccprofile" }, - { + { ".ice":"x-conference\/x-cooltalk" }, - { + { ".icm":"application\/vnd.iccprofile" }, - { + { ".ico":"image\/x-icon" }, - { + { ".ics":"text\/calendar" }, - { + { ".ief":"image\/ief" }, - { + { ".ifb":"text\/calendar" }, - { + { ".ifm":"application\/vnd.shana.informed.formdata" }, - { + { ".iges":"model\/iges" }, - { + { ".igl":"application\/vnd.igloader" }, - { + { ".igs":"model\/iges" }, - { + { ".igx":"application\/vnd.micrografx.igx" }, - { + { ".iif":"application\/vnd.shana.informed.interchange" }, - { + { ".imp":"application\/vnd.accpac.simply.imp" }, - { + { ".ims":"application\/vnd.ms-ims" }, - { + { ".in":"text\/plain" }, - { + { ".ipk":"application\/vnd.shana.informed.package" }, - { + { ".irm":"application\/vnd.ibm.rights-management" }, - { + { ".irp":"application\/vnd.irepository.package+xml" }, - { + { ".iso":"application\/octet-stream" }, - { + { ".itp":"application\/vnd.shana.informed.formtemplate" }, - { + { ".ivp":"application\/vnd.immervision-ivp" }, - { + { ".ivu":"application\/vnd.immervision-ivu" }, - { + { ".jad":"text\/vnd.sun.j2me.app-descriptor" }, - { + { ".jam":"application\/vnd.jam" }, - { + { ".jar":"application\/java-archive" }, - { + { ".java":"text\/x-java-source" }, - { + { ".jisp":"application\/vnd.jisp" }, - { + { ".jlt":"application\/vnd.hp-jlyt" }, - { + { ".jnlp":"application\/x-java-jnlp-file" }, - { + { ".joda":"application\/vnd.joost.joda-archive" }, - { + { ".jpe":"image\/jpeg" }, - { + { ".jpeg":"image\/jpeg" }, - { + { ".jpg":"image\/jpeg" }, - { + { ".jpgm":"video\/jpm" }, - { + { ".jpgv":"video\/jpeg" }, - { + { ".jpm":"video\/jpm" }, - { + { ".js":"application\/javascript" }, - { + { ".json":"application\/json" }, - { + { ".kar":"audio\/midi" }, - { + { ".karbon":"application\/vnd.kde.karbon" }, - { + { ".kfo":"application\/vnd.kde.kformula" }, - { + { ".kia":"application\/vnd.kidspiration" }, - { + { ".kil":"application\/x-killustrator" }, - { + { ".kml":"application\/vnd.google-earth.kml+xml" }, - { + { ".kmz":"application\/vnd.google-earth.kmz" }, - { + { ".kne":"application\/vnd.kinar" }, - { + { ".knp":"application\/vnd.kinar" }, - { + { ".kon":"application\/vnd.kde.kontour" }, - { + { ".kpr":"application\/vnd.kde.kpresenter" }, - { + { ".kpt":"application\/vnd.kde.kpresenter" }, - { + { ".ksh":"text\/plain" }, - { + { ".ksp":"application\/vnd.kde.kspread" }, - { + { ".ktr":"application\/vnd.kahootz" }, - { + { ".ktz":"application\/vnd.kahootz" }, - { + { ".kwd":"application\/vnd.kde.kword" }, - { + { ".kwt":"application\/vnd.kde.kword" }, - { + { ".latex":"application\/x-latex" }, - { + { ".lbd":"application\/vnd.llamagraphics.life-balance.desktop" }, - { + { ".lbe":"application\/vnd.llamagraphics.life-balance.exchange+xml" }, - { + { ".les":"application\/vnd.hhe.lesson-player" }, { ".less":"text/x-less" }, - { + { ".lha":"application\/octet-stream" }, - { + { ".link66":"application\/vnd.route66.link66+xml" }, - { + { ".list":"text\/plain" }, - { + { ".list3820":"application\/vnd.ibm.modcap" }, - { + { ".listafp":"application\/vnd.ibm.modcap" }, - { + { ".log":"text\/plain" }, - { + { ".lostxml":"application\/lost+xml" }, - { + { ".lrf":"application\/octet-stream" }, - { + { ".lrm":"application\/vnd.ms-lrm" }, - { + { ".ltf":"application\/vnd.frogans.ltf" }, - { + { ".lvp":"audio\/vnd.lucent.voice" }, - { + { ".lwp":"application\/vnd.lotus-wordpro" }, - { + { ".lzh":"application\/octet-stream" }, - { + { ".m13":"application\/x-msmediaview" }, - { + { ".m14":"application\/x-msmediaview" }, - { + { ".m1v":"video\/mpeg" }, - { + { ".m2a":"audio\/mpeg" }, - { + { ".m2v":"video\/mpeg" }, - { + { ".m3a":"audio\/mpeg" }, - { + { ".m3u":"audio\/x-mpegurl" }, - { + { ".m4u":"video\/vnd.mpegurl" }, - { + { ".m4v":"video\/x-m4v" }, - { + { ".ma":"application\/mathematica" }, - { + { ".mag":"application\/vnd.ecowin.chart" }, - { + { ".maker":"application\/vnd.framemaker" }, - { + { ".man":"text\/troff" }, - { + { ".markdown":"text\/x-markdown" }, - { + { ".mathml":"application\/mathml+xml" }, - { + { ".mb":"application\/mathematica" }, - { + { ".mbk":"application\/vnd.mobius.mbk" }, - { + { ".mbox":"application\/mbox" }, - { + { ".mc1":"application\/vnd.medcalcdata" }, - { + { ".mcd":"application\/vnd.mcd" }, - { + { ".mcurl":"text\/vnd.curl.mcurl" }, - { + { ".md":"text\/x-markdown" }, - { + { ".mdb":"application\/x-msaccess" }, - { + { ".mdi":"image\/vnd.ms-modi" }, - { + { ".me":"text\/troff" }, - { + { ".mesh":"model\/mesh" }, - { + { ".mfm":"application\/vnd.mfmp" }, - { + { ".mgz":"application\/vnd.proteus.magazine" }, - { + { ".mht":"message\/rfc822" }, - { + { ".mhtml":"message\/rfc822" }, - { + { ".mid":"audio\/midi" }, - { + { ".midi":"audio\/midi" }, - { + { ".mif":"application\/vnd.mif" }, - { + { ".mime":"message\/rfc822" }, - { + { ".mj2":"video\/mj2" }, - { + { ".mjp2":"video\/mj2" }, - { + { ".mlp":"application\/vnd.dolby.mlp" }, - { + { ".mmd":"application\/vnd.chipnuts.karaoke-mmd" }, - { + { ".mmf":"application\/vnd.smaf" }, - { + { ".mmr":"image\/vnd.fujixerox.edmics-mmr" }, - { + { ".mny":"application\/x-msmoney" }, - { + { ".mobi":"application\/x-mobipocket-ebook" }, - { + { ".mov":"video\/quicktime" }, - { + { ".movie":"video\/x-sgi-movie" }, - { + { ".mp2":"audio\/mpeg" }, - { + { ".mp2a":"audio\/mpeg" }, - { + { ".mp3":"audio\/mpeg" }, - { + { ".mp4":"video\/mp4" }, - { + { ".mp4a":"audio\/mp4" }, - { + { ".mp4s":"application\/mp4" }, - { + { ".mp4v":"video\/mp4" }, - { + { ".mpa":"video\/mpeg" }, - { + { ".mpc":"application\/vnd.mophun.certificate" }, - { + { ".mpe":"video\/mpeg" }, - { + { ".mpeg":"video\/mpeg" }, - { + { ".mpg":"video\/mpeg" }, - { + { ".mpg4":"video\/mp4" }, - { + { ".mpga":"audio\/mpeg" }, - { + { ".mpkg":"application\/vnd.apple.installer+xml" }, - { + { ".mpm":"application\/vnd.blueice.multipass" }, - { + { ".mpn":"application\/vnd.mophun.application" }, - { + { ".mpp":"application\/vnd.ms-project" }, - { + { ".mpt":"application\/vnd.ms-project" }, - { + { ".mpy":"application\/vnd.ibm.minipay" }, - { + { ".mqy":"application\/vnd.mobius.mqy" }, - { + { ".mrc":"application\/marc" }, - { + { ".ms":"text\/troff" }, - { + { ".mscml":"application\/mediaservercontrol+xml" }, - { + { ".mseed":"application\/vnd.fdsn.mseed" }, - { + { ".mseq":"application\/vnd.mseq" }, - { + { ".msf":"application\/vnd.epson.msf" }, - { + { ".msh":"model\/mesh" }, - { + { ".msi":"application\/x-msdownload" }, - { + { ".msl":"application\/vnd.mobius.msl" }, - { + { ".msty":"application\/vnd.muvee.style" }, - { + { ".mts":"model\/vnd.mts" }, - { + { ".mus":"application\/vnd.musician" }, - { + { ".musicxml":"application\/vnd.recordare.musicxml+xml" }, - { + { ".mvb":"application\/x-msmediaview" }, - { + { ".mwf":"application\/vnd.mfer" }, - { + { ".mxf":"application\/mxf" }, - { + { ".mxl":"application\/vnd.recordare.musicxml" }, - { + { ".mxml":"application\/xv+xml" }, - { + { ".mxs":"application\/vnd.triscape.mxs" }, - { + { ".mxu":"video\/vnd.mpegurl" }, - { + { ".n-gage":"application\/vnd.nokia.n-gage.symbian.install" }, - { + { ".nb":"application\/mathematica" }, - { + { ".nc":"application\/x-netcdf" }, - { + { ".ncx":"application\/x-dtbncx+xml" }, - { + { ".ngdat":"application\/vnd.nokia.n-gage.data" }, - { + { ".nlu":"application\/vnd.neurolanguage.nlu" }, - { + { ".nml":"application\/vnd.enliven" }, - { + { ".nnd":"application\/vnd.noblenet-directory" }, - { + { ".nns":"application\/vnd.noblenet-sealer" }, - { + { ".nnw":"application\/vnd.noblenet-web" }, - { + { ".npx":"image\/vnd.net-fpx" }, - { + { ".nsf":"application\/vnd.lotus-notes" }, - { + { ".nws":"message\/rfc822" }, - { + { ".o":"application\/octet-stream" }, - { + { ".oa2":"application\/vnd.fujitsu.oasys2" }, - { + { ".oa3":"application\/vnd.fujitsu.oasys3" }, - { + { ".oas":"application\/vnd.fujitsu.oasys" }, - { + { ".obd":"application\/x-msbinder" }, - { + { ".obj":"application\/octet-stream" }, - { + { ".oda":"application\/oda" }, - { + { ".odb":"application\/vnd.oasis.opendocument.database" }, - { + { ".odc":"application\/vnd.oasis.opendocument.chart" }, - { + { ".odf":"application\/vnd.oasis.opendocument.formula" }, - { + { ".odft":"application\/vnd.oasis.opendocument.formula-template" }, - { + { ".odg":"application\/vnd.oasis.opendocument.graphics" }, - { + { ".odi":"application\/vnd.oasis.opendocument.image" }, - { + { ".odp":"application\/vnd.oasis.opendocument.presentation" }, - { + { ".ods":"application\/vnd.oasis.opendocument.spreadsheet" }, - { + { ".odt":"application\/vnd.oasis.opendocument.text" }, - { + { ".oga":"audio\/ogg" }, - { + { ".ogg":"audio\/ogg" }, - { + { ".ogv":"video\/ogg" }, - { + { ".ogx":"application\/ogg" }, - { + { ".onepkg":"application\/onenote" }, - { + { ".onetmp":"application\/onenote" }, - { + { ".onetoc":"application\/onenote" }, - { + { ".onetoc2":"application\/onenote" }, - { + { ".opf":"application\/oebps-package+xml" }, - { + { ".oprc":"application\/vnd.palm" }, - { + { ".org":"application\/vnd.lotus-organizer" }, - { + { ".osf":"application\/vnd.yamaha.openscoreformat" }, - { + { ".osfpvg":"application\/vnd.yamaha.openscoreformat.osfpvg+xml" }, - { + { ".otc":"application\/vnd.oasis.opendocument.chart-template" }, - { + { ".otf":"application\/x-font-otf" }, - { + { ".otg":"application\/vnd.oasis.opendocument.graphics-template" }, - { + { ".oth":"application\/vnd.oasis.opendocument.text-web" }, - { + { ".oti":"application\/vnd.oasis.opendocument.image-template" }, - { + { ".otm":"application\/vnd.oasis.opendocument.text-master" }, - { + { ".otp":"application\/vnd.oasis.opendocument.presentation-template" }, - { + { ".ots":"application\/vnd.oasis.opendocument.spreadsheet-template" }, - { + { ".ott":"application\/vnd.oasis.opendocument.text-template" }, - { + { ".oxt":"application\/vnd.openofficeorg.extension" }, - { + { ".p":"text\/x-pascal" }, - { + { ".p10":"application\/pkcs10" }, - { + { ".p12":"application\/x-pkcs12" }, - { + { ".p7b":"application\/x-pkcs7-certificates" }, - { + { ".p7c":"application\/pkcs7-mime" }, - { + { ".p7m":"application\/pkcs7-mime" }, - { + { ".p7r":"application\/x-pkcs7-certreqresp" }, - { + { ".p7s":"application\/pkcs7-signature" }, - { + { ".pas":"text\/x-pascal" }, - { + { ".pbd":"application\/vnd.powerbuilder6" }, - { + { ".pbm":"image\/x-portable-bitmap" }, - { + { ".pcf":"application\/x-font-pcf" }, - { + { ".pcl":"application\/vnd.hp-pcl" }, - { + { ".pclxl":"application\/vnd.hp-pclxl" }, - { + { ".pct":"image\/x-pict" }, - { + { ".pcurl":"application\/vnd.curl.pcurl" }, - { + { ".pcx":"image\/x-pcx" }, - { + { ".pdb":"application\/vnd.palm" }, - { + { ".pdf":"application\/pdf" }, - { + { ".pfa":"application\/x-font-type1" }, - { + { ".pfb":"application\/x-font-type1" }, - { + { ".pfm":"application\/x-font-type1" }, - { + { ".pfr":"application\/font-tdpfr" }, - { + { ".pfx":"application\/x-pkcs12" }, - { + { ".pgm":"image\/x-portable-graymap" }, - { + { ".pgn":"application\/x-chess-pgn" }, - { + { ".pgp":"application\/pgp-encrypted" }, - { + { ".pic":"image\/x-pict" }, - { + { ".pkg":"application\/octet-stream" }, - { + { ".pki":"application\/pkixcmp" }, - { + { ".pkipath":"application\/pkix-pkipath" }, - { + { ".pl":"text\/plain" }, - { + { ".plb":"application\/vnd.3gpp.pic-bw-large" }, - { + { ".plc":"application\/vnd.mobius.plc" }, - { + { ".plf":"application\/vnd.pocketlearn" }, - { + { ".pls":"application\/pls+xml" }, - { + { ".pml":"application\/vnd.ctc-posml" }, - { + { ".png":"image\/png" }, - { + { ".pnm":"image\/x-portable-anymap" }, - { + { ".portpkg":"application\/vnd.macports.portpkg" }, - { + { ".pot":"application\/vnd.ms-powerpoint" }, - { + { ".potm":"application\/vnd.ms-powerpoint.template.macroenabled.12" }, - { + { ".potx":"application\/vnd.openxmlformats-officedocument.presentationml.template" }, - { + { ".ppa":"application\/vnd.ms-powerpoint" }, - { + { ".ppam":"application\/vnd.ms-powerpoint.addin.macroenabled.12" }, - { + { ".ppd":"application\/vnd.cups-ppd" }, - { + { ".ppm":"image\/x-portable-pixmap" }, - { + { ".pps":"application\/vnd.ms-powerpoint" }, - { + { ".ppsm":"application\/vnd.ms-powerpoint.slideshow.macroenabled.12" }, - { + { ".ppsx":"application\/vnd.openxmlformats-officedocument.presentationml.slideshow" }, - { + { ".ppt":"application\/vnd.ms-powerpoint" }, - { + { ".pptm":"application\/vnd.ms-powerpoint.presentation.macroenabled.12" }, - { + { ".pptx":"application\/vnd.openxmlformats-officedocument.presentationml.presentation" }, - { + { ".pqa":"application\/vnd.palm" }, - { + { ".prc":"application\/x-mobipocket-ebook" }, - { + { ".pre":"application\/vnd.lotus-freelance" }, - { + { ".prf":"application\/pics-rules" }, - { + { ".ps":"application\/postscript" }, - { + { ".psb":"application\/vnd.3gpp.pic-bw-small" }, - { + { ".psd":"image\/vnd.adobe.photoshop" }, - { + { ".psf":"application\/x-font-linux-psf" }, - { + { ".ptid":"application\/vnd.pvi.ptid1" }, - { + { ".pub":"application\/x-mspublisher" }, - { + { ".pvb":"application\/vnd.3gpp.pic-bw-var" }, - { + { ".pwn":"application\/vnd.3m.post-it-notes" }, - { + { ".pwz":"application\/vnd.ms-powerpoint" }, - { + { ".py":"text\/x-python" }, - { + { ".pya":"audio\/vnd.ms-playready.media.pya" }, - { + { ".pyc":"application\/x-python-code" }, - { + { ".pyo":"application\/x-python-code" }, - { + { ".pyv":"video\/vnd.ms-playready.media.pyv" }, - { + { ".qam":"application\/vnd.epson.quickanime" }, - { + { ".qbo":"application\/vnd.intu.qbo" }, - { + { ".qfx":"application\/vnd.intu.qfx" }, - { + { ".qps":"application\/vnd.publishare-delta-tree" }, - { + { ".qt":"video\/quicktime" }, - { + { ".qwd":"application\/vnd.quark.quarkxpress" }, - { + { ".qwt":"application\/vnd.quark.quarkxpress" }, - { + { ".qxb":"application\/vnd.quark.quarkxpress" }, - { + { ".qxd":"application\/vnd.quark.quarkxpress" }, - { + { ".qxl":"application\/vnd.quark.quarkxpress" }, - { + { ".qxt":"application\/vnd.quark.quarkxpress" }, - { + { ".ra":"audio\/x-pn-realaudio" }, - { + { ".ram":"audio\/x-pn-realaudio" }, - { + { ".rar":"application\/x-rar-compressed" }, - { + { ".ras":"image\/x-cmu-raster" }, - { + { ".rcprofile":"application\/vnd.ipunplugged.rcprofile" }, - { + { ".rdf":"application\/rdf+xml" }, - { + { ".rdz":"application\/vnd.data-vision.rdz" }, - { + { ".rep":"application\/vnd.businessobjects" }, - { + { ".res":"application\/x-dtbresource+xml" }, - { + { ".rgb":"image\/x-rgb" }, - { + { ".rif":"application\/reginfo+xml" }, - { + { ".rl":"application\/resource-lists+xml" }, - { + { ".rlc":"image\/vnd.fujixerox.edmics-rlc" }, - { + { ".rld":"application\/resource-lists-diff+xml" }, - { + { ".rm":"application\/vnd.rn-realmedia" }, - { + { ".rmi":"audio\/midi" }, - { + { ".rmp":"audio\/x-pn-realaudio-plugin" }, - { + { ".rms":"application\/vnd.jcp.javame.midlet-rms" }, - { + { ".rnc":"application\/relax-ng-compact-syntax" }, - { + { ".roff":"text\/troff" }, - { + { ".rpm":"application\/x-rpm" }, - { + { ".rpss":"application\/vnd.nokia.radio-presets" }, - { + { ".rpst":"application\/vnd.nokia.radio-preset" }, - { + { ".rq":"application\/sparql-query" }, - { + { ".rs":"application\/rls-services+xml" }, - { + { ".rsd":"application\/rsd+xml" }, - { + { ".rss":"application\/rss+xml" }, - { + { ".rtf":"application\/rtf" }, - { + { ".rtx":"text\/richtext" }, - { + { ".s":"text\/x-asm" }, - { + { ".saf":"application\/vnd.yamaha.smaf-audio" }, { ".sass":"text/x-sass" }, - { + { ".sbml":"application\/sbml+xml" }, - { + { ".sc":"application\/vnd.ibm.secure-container" }, - { + { ".scd":"application\/x-msschedule" }, - { + { ".scm":"application\/vnd.lotus-screencam" }, - { + { ".scq":"application\/scvp-cv-request" }, - { + { ".scs":"application\/scvp-cv-response" }, { ".scss":"text/x-scss" }, - { + { ".scurl":"text\/vnd.curl.scurl" }, - { + { ".sda":"application\/vnd.stardivision.draw" }, - { + { ".sdc":"application\/vnd.stardivision.calc" }, - { + { ".sdd":"application\/vnd.stardivision.impress" }, - { + { ".sdkd":"application\/vnd.solent.sdkm+xml" }, - { + { ".sdkm":"application\/vnd.solent.sdkm+xml" }, - { + { ".sdp":"application\/sdp" }, - { + { ".sdw":"application\/vnd.stardivision.writer" }, - { + { ".see":"application\/vnd.seemail" }, - { + { ".seed":"application\/vnd.fdsn.seed" }, - { + { ".sema":"application\/vnd.sema" }, - { + { ".semd":"application\/vnd.semd" }, - { + { ".semf":"application\/vnd.semf" }, - { + { ".ser":"application\/java-serialized-object" }, - { + { ".setpay":"application\/set-payment-initiation" }, - { + { ".setreg":"application\/set-registration-initiation" }, - { + { ".sfd-hdstx":"application\/vnd.hydrostatix.sof-data" }, - { + { ".sfs":"application\/vnd.spotfire.sfs" }, - { + { ".sgl":"application\/vnd.stardivision.writer-global" }, - { + { ".sgm":"text\/sgml" }, - { + { ".sgml":"text\/sgml" }, - { + { ".sh":"application\/x-sh" }, - { + { ".shar":"application\/x-shar" }, - { + { ".shf":"application\/shf+xml" }, - { + { ".si":"text\/vnd.wap.si" }, - { + { ".sic":"application\/vnd.wap.sic" }, - { + { ".sig":"application\/pgp-signature" }, - { + { ".silo":"model\/mesh" }, - { + { ".sis":"application\/vnd.symbian.install" }, - { + { ".sisx":"application\/vnd.symbian.install" }, - { + { ".sit":"application\/x-stuffit" }, - { + { ".sitx":"application\/x-stuffitx" }, - { + { ".skd":"application\/vnd.koan" }, - { + { ".skm":"application\/vnd.koan" }, - { + { ".skp":"application\/vnd.koan" }, - { + { ".skt":"application\/vnd.koan" }, - { + { ".sl":"text\/vnd.wap.sl" }, - { + { ".slc":"application\/vnd.wap.slc" }, - { + { ".sldm":"application\/vnd.ms-powerpoint.slide.macroenabled.12" }, - { + { ".sldx":"application\/vnd.openxmlformats-officedocument.presentationml.slide" }, - { + { ".slt":"application\/vnd.epson.salt" }, - { + { ".smf":"application\/vnd.stardivision.math" }, - { + { ".smi":"application\/smil+xml" }, - { + { ".smil":"application\/smil+xml" }, - { + { ".snd":"audio\/basic" }, - { + { ".snf":"application\/x-font-snf" }, - { + { ".so":"application\/octet-stream" }, - { + { ".spc":"application\/x-pkcs7-certificates" }, - { + { ".spf":"application\/vnd.yamaha.smaf-phrase" }, - { + { ".spl":"application\/x-futuresplash" }, - { + { ".spot":"text\/vnd.in3d.spot" }, - { + { ".spp":"application\/scvp-vp-response" }, - { + { ".spq":"application\/scvp-vp-request" }, - { + { ".spx":"audio\/ogg" }, - { + { ".src":"application\/x-wais-source" }, - { + { ".srx":"application\/sparql-results+xml" }, - { + { ".sse":"application\/vnd.kodak-descriptor" }, - { + { ".ssf":"application\/vnd.epson.ssf" }, - { + { ".ssml":"application\/ssml+xml" }, - { + { ".stc":"application\/vnd.sun.xml.calc.template" }, - { + { ".std":"application\/vnd.sun.xml.draw.template" }, - { + { ".stf":"application\/vnd.wt.stf" }, - { + { ".sti":"application\/vnd.sun.xml.impress.template" }, - { + { ".stk":"application\/hyperstudio" }, - { + { ".stl":"application\/vnd.ms-pki.stl" }, - { + { ".str":"application\/vnd.pg.format" }, - { + { ".stw":"application\/vnd.sun.xml.writer.template" }, - { + { ".sus":"application\/vnd.sus-calendar" }, - { + { ".susp":"application\/vnd.sus-calendar" }, - { + { ".sv4cpio":"application\/x-sv4cpio" }, - { + { ".sv4crc":"application\/x-sv4crc" }, - { + { ".svd":"application\/vnd.svd" }, - { + { ".svg":"image\/svg+xml" }, - { + { ".svgz":"image\/svg+xml" }, - { + { ".swa":"application\/x-director" }, - { + { ".swf":"application\/x-shockwave-flash" }, - { + { ".swi":"application\/vnd.arastra.swi" }, - { + { ".sxc":"application\/vnd.sun.xml.calc" }, - { + { ".sxd":"application\/vnd.sun.xml.draw" }, - { + { ".sxg":"application\/vnd.sun.xml.writer.global" }, - { + { ".sxi":"application\/vnd.sun.xml.impress" }, - { + { ".sxm":"application\/vnd.sun.xml.math" }, - { + { ".sxw":"application\/vnd.sun.xml.writer" }, - { + { ".t":"text\/troff" }, - { + { ".tao":"application\/vnd.tao.intent-module-archive" }, - { + { ".tar":"application\/x-tar" }, - { + { ".tcap":"application\/vnd.3gpp2.tcap" }, - { + { ".tcl":"application\/x-tcl" }, - { + { ".teacher":"application\/vnd.smart.teacher" }, - { + { ".tex":"application\/x-tex" }, - { + { ".texi":"application\/x-texinfo" }, - { + { ".texinfo":"application\/x-texinfo" }, - { + { ".text":"text\/plain" }, - { + { ".tfm":"application\/x-tex-tfm" }, - { + { ".tgz":"application\/x-gzip" }, - { + { ".tif":"image\/tiff" }, - { + { ".tiff":"image\/tiff" }, - { + { ".tmo":"application\/vnd.tmobile-livetv" }, - { + { ".torrent":"application\/x-bittorrent" }, - { + { ".tpl":"application\/vnd.groove-tool-template" }, - { + { ".tpt":"application\/vnd.trid.tpt" }, - { + { ".tr":"text\/troff" }, - { + { ".tra":"application\/vnd.trueapp" }, - { + { ".trm":"application\/x-msterminal" }, - { + { ".tsv":"text\/tab-separated-values" }, - { + { ".ttc":"application\/x-font-ttf" }, - { + { ".ttf":"application\/x-font-ttf" }, - { + { ".twd":"application\/vnd.simtech-mindmapper" }, - { + { ".twds":"application\/vnd.simtech-mindmapper" }, - { + { ".txd":"application\/vnd.genomatix.tuxedo" }, - { + { ".txf":"application\/vnd.mobius.txf" }, - { + { ".txt":"text\/plain" }, - { + { ".u32":"application\/x-authorware-bin" }, - { + { ".udeb":"application\/x-debian-package" }, - { + { ".ufd":"application\/vnd.ufdl" }, - { + { ".ufdl":"application\/vnd.ufdl" }, - { + { ".umj":"application\/vnd.umajin" }, - { + { ".unityweb":"application\/vnd.unity" }, - { + { ".uoml":"application\/vnd.uoml+xml" }, - { + { ".uri":"text\/uri-list" }, - { + { ".uris":"text\/uri-list" }, - { + { ".urls":"text\/uri-list" }, - { + { ".ustar":"application\/x-ustar" }, - { + { ".utz":"application\/vnd.uiq.theme" }, - { + { ".uu":"text\/x-uuencode" }, - { + { ".vcd":"application\/x-cdlink" }, - { + { ".vcf":"text\/x-vcard" }, - { + { ".vcg":"application\/vnd.groove-vcard" }, - { + { ".vcs":"text\/x-vcalendar" }, - { + { ".vcx":"application\/vnd.vcx" }, - { + { ".vis":"application\/vnd.visionary" }, - { + { ".viv":"video\/vnd.vivo" }, - { + { ".vor":"application\/vnd.stardivision.writer" }, - { + { ".vox":"application\/x-authorware-bin" }, - { + { ".vrml":"model\/vrml" }, - { + { ".vsd":"application\/vnd.visio" }, - { + { ".vsf":"application\/vnd.vsf" }, - { + { ".vss":"application\/vnd.visio" }, - { + { ".vst":"application\/vnd.visio" }, - { + { ".vsw":"application\/vnd.visio" }, - { + { ".vtu":"model\/vnd.vtu" }, - { + { ".vxml":"application\/voicexml+xml" }, - { + { ".w3d":"application\/x-director" }, - { + { ".wad":"application\/x-doom" }, - { + { ".wav":"audio\/x-wav" }, - { + { ".wax":"audio\/x-ms-wax" }, - { + { ".wbmp":"image\/vnd.wap.wbmp" }, - { + { ".wbs":"application\/vnd.criticaltools.wbs+xml" }, - { + { ".wbxml":"application\/vnd.wap.wbxml" }, - { + { ".wcm":"application\/vnd.ms-works" }, - { + { ".wdb":"application\/vnd.ms-works" }, - { + { ".wiz":"application\/msword" }, - { + { ".wks":"application\/vnd.ms-works" }, - { + { ".wm":"video\/x-ms-wm" }, - { + { ".wma":"audio\/x-ms-wma" }, - { + { ".wmd":"application\/x-ms-wmd" }, - { + { ".wmf":"application\/x-msmetafile" }, - { + { ".wml":"text\/vnd.wap.wml" }, - { + { ".wmlc":"application\/vnd.wap.wmlc" }, - { + { ".wmls":"text\/vnd.wap.wmlscript" }, - { + { ".wmlsc":"application\/vnd.wap.wmlscriptc" }, - { + { ".wmv":"video\/x-ms-wmv" }, - { + { ".wmx":"video\/x-ms-wmx" }, - { + { ".wmz":"application\/x-ms-wmz" }, - { + { ".wpd":"application\/vnd.wordperfect" }, - { + { ".wpl":"application\/vnd.ms-wpl" }, - { + { ".wps":"application\/vnd.ms-works" }, - { + { ".wqd":"application\/vnd.wqd" }, - { + { ".wri":"application\/x-mswrite" }, - { + { ".wrl":"model\/vrml" }, - { + { ".wsdl":"application\/wsdl+xml" }, - { + { ".wspolicy":"application\/wspolicy+xml" }, - { + { ".wtb":"application\/vnd.webturbo" }, - { + { ".wvx":"video\/x-ms-wvx" }, - { + { ".x32":"application\/x-authorware-bin" }, - { + { ".x3d":"application\/vnd.hzn-3d-crossword" }, - { + { ".xap":"application\/x-silverlight-app" }, - { + { ".xar":"application\/vnd.xara" }, - { + { ".xbap":"application\/x-ms-xbap" }, - { + { ".xbd":"application\/vnd.fujixerox.docuworks.binder" }, - { + { ".xbm":"image\/x-xbitmap" }, - { + { ".xdm":"application\/vnd.syncml.dm+xml" }, - { + { ".xdp":"application\/vnd.adobe.xdp+xml" }, - { + { ".xdw":"application\/vnd.fujixerox.docuworks" }, - { + { ".xenc":"application\/xenc+xml" }, - { + { ".xer":"application\/patch-ops-error+xml" }, - { + { ".xfdf":"application\/vnd.adobe.xfdf" }, - { + { ".xfdl":"application\/vnd.xfdl" }, - { + { ".xht":"application\/xhtml+xml" }, - { + { ".xhtml":"application\/xhtml+xml" }, - { + { ".xhvml":"application\/xv+xml" }, - { + { ".xif":"image\/vnd.xiff" }, - { + { ".xla":"application\/vnd.ms-excel" }, - { + { ".xlam":"application\/vnd.ms-excel.addin.macroenabled.12" }, - { + { ".xlb":"application\/vnd.ms-excel" }, - { + { ".xlc":"application\/vnd.ms-excel" }, - { + { ".xlm":"application\/vnd.ms-excel" }, - { + { ".xls":"application\/vnd.ms-excel" }, - { + { ".xlsb":"application\/vnd.ms-excel.sheet.binary.macroenabled.12" }, - { + { ".xlsm":"application\/vnd.ms-excel.sheet.macroenabled.12" }, - { + { ".xlsx":"application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, - { + { ".xlt":"application\/vnd.ms-excel" }, - { + { ".xltm":"application\/vnd.ms-excel.template.macroenabled.12" }, - { + { ".xltx":"application\/vnd.openxmlformats-officedocument.spreadsheetml.template" }, - { + { ".xlw":"application\/vnd.ms-excel" }, - { + { ".xml":"application\/xml" }, - { + { ".xo":"application\/vnd.olpc-sugar" }, - { + { ".xop":"application\/xop+xml" }, - { + { ".xpdl":"application\/xml" }, - { + { ".xpi":"application\/x-xpinstall" }, - { + { ".xpm":"image\/x-xpixmap" }, - { + { ".xpr":"application\/vnd.is-xpr" }, - { + { ".xps":"application\/vnd.ms-xpsdocument" }, - { + { ".xpw":"application\/vnd.intercon.formnet" }, - { + { ".xpx":"application\/vnd.intercon.formnet" }, - { + { ".xsl":"application\/xml" }, - { + { ".xslt":"application\/xslt+xml" }, - { + { ".xsm":"application\/vnd.syncml+xml" }, - { + { ".xspf":"application\/xspf+xml" }, - { + { ".xul":"application\/vnd.mozilla.xul+xml" }, - { + { ".xvm":"application\/xv+xml" }, - { + { ".xvml":"application\/xv+xml" }, - { + { ".xwd":"image\/x-xwindowdump" }, - { + { ".xyz":"chemical\/x-xyz" }, - { + { ".zaz":"application\/vnd.zzazz.deck+xml" }, - { + { ".zip":"application\/zip" }, - { + { ".zir":"application\/vnd.zul" }, - { + { ".zirz":"application\/vnd.zul" }, - { + { ".zmm":"application\/vnd.handheld-entertainment+xml" } ]
M src/litestorepkg/lib/contenttypes.nimsrc/litestorepkg/lib/contenttypes.nim

@@ -9,7 +9,7 @@ for item in json.items:

for pair in item.pairs: result[$pair.key] = $pair.val.getStr -var CONTENT_TYPES* {.threadvar.}: StringTableRef +var CONTENT_TYPES* {.threadvar.}: StringTableRef CONTENT_TYPES = loadContentTypes()
M src/litestorepkg/lib/core.nimsrc/litestorepkg/lib/core.nim

@@ -1,11 +1,11 @@

-import - x_sqlite3, +import + x_sqlite3, x_db_sqlite as db, - strutils, + strutils, os, oids, json, - pegs, + pegs, strtabs, strutils, base64,

@@ -27,13 +27,13 @@ db.exec SQL_CREATE_INDEX_DOCUMENTS_ID

db.exec SQL_CREATE_INDEX_TAGS_TAG_ID db.exec SQL_CREATE_INDEX_TAGS_DOCUMENT_ID -proc dropIndexes(db: DbConn) = +proc dropIndexes(db: DbConn) = db.exec SQL_DROP_INDEX_DOCUMENTS_DOCID db.exec SQL_DROP_INDEX_DOCUMENTS_ID db.exec SQL_DROP_INDEX_TAGS_TAG_ID db.exec SQL_DROP_INDEX_TAGS_DOCUMENT_ID -proc createDatastore*(file:string) = +proc createDatastore*(file:string) = if file.fileExists(): raise newException(EDatastoreExists, "Datastore '$1' already exists." % file) LOG.debug("Creating datastore '$1'", file)

@@ -48,7 +48,7 @@ LOG.debug("Creating indexes")

data.createIndexes() LOG.debug("Database created") -proc closeDatastore*(store: Datastore) = +proc closeDatastore*(store: Datastore) = try: db.close(store.db) except:

@@ -194,7 +194,7 @@ var data = rawdata

if contenttype == "application/json": # Validate JSON data try: - discard data.parseJson + discard data.parseJson except: raise newException(JsonParsingError, "Invalid JSON content - " & getCurrentExceptionMsg()) if id == "":

@@ -226,7 +226,7 @@ store.commit()

return $store.retrieveRawDocument(id) except: store.rollback() - eWarn() + eWarn() raise proc updateDocument*(store: Datastore, id: string, rawdata: string, contenttype = "text/plain", binary = -1, searchable = 1): string =

@@ -237,7 +237,7 @@ var data = rawdata

if contenttype == "application/json": # Validate JSON data try: - discard data.parseJson + discard data.parseJson except: raise newException(JsonParsingError, "Invalid JSON content - " & getCurrentExceptionMsg()) var searchable = searchable

@@ -382,7 +382,7 @@ raise newException(EDirectoryNotFound, "Directory '$1' not found." % dir)

for f in dir.walkDirRec(): if f.existsDir: continue - if f.splitFile.name.startsWith("."): + if f.splitFile.name.startsWith("."): # Ignore hidden files continue files.add(f)

@@ -395,7 +395,7 @@ store.begin()

LOG.info("Importing $1 files in $2 batches", files.len, nBatches) LOG.debug("Dropping column indexes...") store.db.dropIndexes() - for f in files: + for f in files: try: store.importFile(f, dir) cFiles.inc
M src/litestorepkg/lib/logger.nimsrc/litestorepkg/lib/logger.nim

@@ -1,4 +1,4 @@

-import +import strutils, times

@@ -18,19 +18,19 @@ stderr.writeLine(currentTime(true) & " " & kind & ": " & s)

else: echo currentTime(true), " ", kind, ": ", s -proc error*(logger: Logger, message: string, params: varargs[string, `$`]) = +proc error*(logger: Logger, message: string, params: varargs[string, `$`]) = if logger.level <= lvError: logger.msg(" ERROR", message, params) -proc warn*(logger: Logger, message: string, params: varargs[string, `$`]) = +proc warn*(logger: Logger, message: string, params: varargs[string, `$`]) = if logger.level <= lvWarn: logger.msg("WARNING", message, params) -proc info*(logger: Logger, message: string, params: varargs[string, `$`]) = +proc info*(logger: Logger, message: string, params: varargs[string, `$`]) = if logger.level <= lvInfo: logger.msg(" INFO", message, params) -proc debug*(logger: Logger, message: string, params: varargs[string, `$`]) = +proc debug*(logger: Logger, message: string, params: varargs[string, `$`]) = if logger.level <= lvDebug: logger.msg(" DEBUG", message, params)
M src/litestorepkg/lib/queries.nimsrc/litestorepkg/lib/queries.nim

@@ -20,21 +20,21 @@ SQL_CREATE_INDEX_DOCUMENTS_ID* = sql"CREATE INDEX IF NOT EXISTS documents_id ON documents(id)"

SQL_CREATE_INDEX_TAGS_DOCUMENT_ID* = sql"CREATE INDEX IF NOT EXISTS tags_document_id ON tags(document_id)" SQL_CREATE_INDEX_TAGS_TAG_ID* = sql"CREATE INDEX IF NOT EXISTS tags_tag_id ON tags(tag_id)" - SQL_DROP_INDEX_DOCUMENTS_DOCID* = sql"DROP INDEX IF EXISTS documents_docid" + SQL_DROP_INDEX_DOCUMENTS_DOCID* = sql"DROP INDEX IF EXISTS documents_docid" SQL_DROP_INDEX_DOCUMENTS_ID* = sql"DROP INDEX IF EXISTS documents_id" SQL_DROP_INDEX_TAGS_DOCUMENT_ID* = sql"DROP INDEX IF EXISTS tags_document_id" SQL_DROP_INDEX_TAGS_TAG_ID* = sql"DROP INDEX IF EXISTS tags_tag_id" - + SQL_REINDEX* = sql"REINDEX" SQL_OPTIMIZE* = sql"INSERT INTO searchdata(searchdata) VALUES('optimize')" SQL_REBUILD* = sql"INSERT INTO searchdata(searchdata) VALUES('rebuild')" - + SQL_VACUUM* = sql"VACUUM" const SQL_CREATE_SEARCHDATA_TABLE* = sql""" CREATE VIRTUAL TABLE searchdata USING fts4( id TEXT UNIQUE NOT NULL, -data TEXT, +data TEXT, tokenize=porter) """

@@ -102,7 +102,7 @@ """

const SQL_DELETE_DOCUMENT* = sql""" DELETE FROM documents -WHERE id = ? +WHERE id = ? """ const SQL_INSERT_TAG* = sql"""

@@ -161,32 +161,32 @@ tag_id = ?

""" const SQL_SELECT_TAGS_WITH_TOTALS* = sql""" -SELECT DISTINCT tag_id, COUNT(document_id) +SELECT DISTINCT tag_id, COUNT(document_id) FROM tags GROUP BY tag_id ORDER BY tag_id ASC """ const SQL_COUNT_TAGS* = sql""" -SELECT COUNT(DISTINCT tag_id) FROM tags +SELECT COUNT(DISTINCT tag_id) FROM tags """ const SQL_COUNT_DOCUMENTS* = sql""" -SELECT COUNT(docid) FROM documents +SELECT COUNT(docid) FROM documents """ const SQL_DELETE_DOCUMENTS_BY_TAG* = sql""" DELETE FROM documents -WHERE documents.id IN +WHERE documents.id IN (SELECT document_id FROM tags WHERE tag_id = ?) """ const SQL_DELETE_SEARCHDATA_BY_TAG* = sql""" DELETE FROM searchdata -WHERE id IN +WHERE id IN (SELECT document_id FROM tags WHERE tag_id = ?) """ const SQL_DELETE_TAGS_BY_TAG* = sql""" DELETE FROM tags -WHERE document_id IN +WHERE document_id IN (SELECT document_id FROM tags WHERE tag_id = ?) """
M src/litestorepkg/lib/server.nimsrc/litestorepkg/lib/server.nim

@@ -1,22 +1,22 @@

-import +import asynchttpserver, - asyncdispatch, - times, - strutils, - pegs, - strtabs, + asyncdispatch, + times, + strutils, + pegs, + strtabs, logger, cgi, os -import - types, - utils, +import + types, + utils, api_v1, api_v2, api_v3, api_v4 -export +export api_v4 proc getReqInfo(req: LSRequest): string =

@@ -32,7 +32,7 @@ echo ""

LOG.info("Exiting...") quit() -proc processApiUrl(req: LSRequest, LS: LiteStore, info: ResourceInfo): LSResponse = +proc processApiUrl(req: LSRequest, LS: LiteStore, info: ResourceInfo): LSResponse = if info.version == "v4": if info.resource.match(peg"^docs / info / tags$"): return api_v4.route(req, LS, info.resource, info.id)

@@ -63,7 +63,7 @@ else:

return resError(Http400, "Bad Request - Not serving any directory." % info.version) else: return resError(Http404, "Resource Not Found: $1" % info.resource) - elif info.version == "v1": + elif info.version == "v1": if info.resource.match(peg"^docs / info$"): return api_v1.route(req, LS, info.resource, info.id) elif info.resource.match(peg"^dir$"):

@@ -87,7 +87,7 @@ var matches = @["", "", ""]

template route(req: LSRequest, peg: Peg, op: untyped): untyped = if req.url.path.find(peg, matches) != -1: op - try: + try: var info: ResourceInfo req.route peg"^\/?$": info.version = "v4"

@@ -131,4 +131,3 @@ echo(LS.appname & " v" & LS.appversion & " started on " & LS.address & ":" & $LS.port & ".")

if LS.mount: echo("Mirroring datastore changes to: " & LS.directory) asyncCheck server.serve(LS.port.Port, handleHttpRequest, LS.address) -
M src/litestorepkg/lib/utils.nimsrc/litestorepkg/lib/utils.nim

@@ -1,22 +1,22 @@

-import +import x_sqlite3, - x_db_sqlite, - asynchttpserver, + x_db_sqlite, + asynchttpserver, json, - strutils, - pegs, - asyncdispatch, - math, + strutils, + pegs, + asyncdispatch, + math, sequtils, strtabs -import - types, - queries, - contenttypes, +import + types, + queries, + contenttypes, logger -proc setOrigin*(LS: LiteStore, req: LSRequest, headers: var HttpHeaders) = +proc setOrigin*(LS: LiteStore, req: LSRequest, headers: var HttpHeaders) = var host = "" var port = "" var protocol = "http"

@@ -56,7 +56,7 @@ for tag in tags.split(','):

if not tag.match(PEG_TAG): raise newException(EInvalidTag, "Invalid Tag '$1'" % tag) result = result & "AND " & doc_id_col & " IN (" & select_tagged & tag & "') " - + proc prepareSelectDocumentsQuery*(options: var QueryOptions): string = var tables = options.tables result = "SELECT "

@@ -68,11 +68,11 @@ options.tags = options.tags.split(",").concat(@["$subtype:json"]).join(",")

if options.search.len > 0: if options.select[0] != "COUNT(docid)": let rank = "rank(matchinfo(searchdata, 'pcxnal'), 1.20, 0.75, 5.0, 0.5) AS rank" - let snippet = "snippet(searchdata, \"<strong>\", \"</strong>\", \"<strong>&hellip;</strong>\", -1, 30) as highlight" + let snippet = "snippet(searchdata, \"<strong>\", \"</strong>\", \"<strong>&hellip;</strong>\", -1, 30) as highlight" options.select.add(snippet) options.select.add("ranktable.rank AS rank") options.orderby = "rank DESC" - # Create inner select + # Create inner select var innerSelect = "SELECT docid, " & rank & " FROM searchdata WHERE searchdata MATCH '" & options.search.replace("'", "''") & "' " if options.tags.len > 0: innerSelect = innerSelect & options.tags.selectDocumentsByTags()

@@ -120,14 +120,14 @@ result = result & "AND " & options.jsonFilter

if options.search.len > 0: result = result & "AND searchdata MATCH '" & options.search.replace("'", "''") & "' " if options.orderby.len > 0 and options.select[0] != "COUNT(docid)": - result = result & "ORDER BY " & options.orderby & " " - if options.limit > 0 and options.search.len == 0: + result = result & "ORDER BY " & options.orderby & " " + if options.limit > 0 and options.search.len == 0: # If searching, do not add limit to the outer select, it's already in the nested select (ranktable) result = result & "LIMIT " & $options.limit & " " if options.offset > 0: result = result & "OFFSET " & $options.offset & " " LOG.debug(result.replace("$", "$$")) - + proc prepareSelectTagsQuery*(options: QueryOptions): string = var group = true if options.select.len > 0 and options.select[0] == "COUNT(tag_id)":

@@ -141,9 +141,9 @@ if options.single:

result = result & "WHERE tag_id = ?" elif options.like.len > 0: if options.like[options.like.len-1] == '*': - result = result & "WHERE tag_id BETWEEN ? AND ? " + result = result & "WHERE tag_id BETWEEN ? AND ? " else: - result = result & "WHERE tag_id LIKE ? " + result = result & "WHERE tag_id LIKE ? " if group: result = result & "GROUP BY tag_id " if options.limit > 0:

@@ -241,7 +241,7 @@ tags.add "$format:text"

for tag in tags: store.db.exec(SQL_INSERT_TAG, tag, docid) -proc destroyDocumentSystemTags*(store: Datastore, docid: string) = +proc destroyDocumentSystemTags*(store: Datastore, docid: string) = discard store.db.execAffectedRows(SQL_DELETE_DOCUMENT_SYSTEM_TAGS, docid) proc fail*(code: int, msg: string) =

@@ -253,7 +253,7 @@ var h = newHttpHeaders(TAB_HEADERS)

h["Content-Type"] = ct return h -proc ctJsonHeader*(): HttpHeaders = +proc ctJsonHeader*(): HttpHeaders = return ctHeader("application/json") proc resError*(code: HttpCode, message: string, trace = ""): LSResponse =

@@ -275,7 +275,7 @@ var e = getCurrentException()

LOG.warn(e.msg) LOG.debug(getStackTrace(e)) -proc validate*(req: Request, LS: LiteStore, resource: string, id: string, cb: proc(req: Request, LS: LiteStore, resource: string, id: string):LSResponse): LSResponse = +proc validate*(req: Request, LS: LiteStore, resource: string, id: string, cb: proc(req: Request, LS: LiteStore, resource: string, id: string):LSResponse): LSResponse = if req.reqMethod == HttpPost or req.reqMethod == HttpPut or req.reqMethod == HttpPatch: var ct = "" let body = req.body.strip

@@ -308,7 +308,7 @@ # Setting the default values and ignoring argument based inputs so the extra

# arguments can be the column weights instead. if nVal < 2: pCtx.result_error("wrong number of arguments to function okapi_bm25_kb(), expected k1 parameter", -1) - if nVal < 3: + if nVal < 3: pCtx.result_error("wrong number of arguments to function okapi_bm25_kb(), expected b parameter", -1); let K1 = value_double(apVal[1]) # 1.2 let B = value_double(apVal[2]) # 0.75

@@ -325,8 +325,8 @@ let N_OFFSET = X_OFFSET + 3*termCount*colCount

let A_OFFSET = N_OFFSET + 1 let L_OFFSET = A_OFFSET + colCount let totalDocs = matchinfo[N_OFFSET].float - var avgLength:float = 0.0 - var docLength:float = 0.0 + var avgLength:float = 0.0 + var docLength:float = 0.0 for col in 0..colCount-1: avgLength = avgLength + matchinfo[A_OFFSET + col].float docLength = docLength + matchinfo[L_OFFSET + col].float
M src/litestorepkg/lib/x_sqlite3.nimsrc/litestorepkg/lib/x_sqlite3.nim

@@ -137,32 +137,32 @@ SQLITE_TRANSIENT* = cast[Tbind_destructor_func](-1)

proc close*(para1: PSqlite3): int32{.cdecl, importc: "sqlite3_close".} proc exec*(para1: PSqlite3, sql: cstring, para3: Callback, para4: pointer, - errmsg: var cstring): int32{.cdecl, + errmsg: var cstring): int32{.cdecl, importc: "sqlite3_exec".} -proc last_insert_rowid*(para1: PSqlite3): int64{.cdecl, +proc last_insert_rowid*(para1: PSqlite3): int64{.cdecl, importc: "sqlite3_last_insert_rowid".} proc changes*(para1: PSqlite3): int32{.cdecl, importc: "sqlite3_changes".} -proc total_changes*(para1: PSqlite3): int32{.cdecl, +proc total_changes*(para1: PSqlite3): int32{.cdecl, importc: "sqlite3_total_changes".} proc interrupt*(para1: PSqlite3){.cdecl, importc: "sqlite3_interrupt".} -proc complete*(sql: cstring): int32{.cdecl, +proc complete*(sql: cstring): int32{.cdecl, importc: "sqlite3_complete".} -proc complete16*(sql: pointer): int32{.cdecl, +proc complete16*(sql: pointer): int32{.cdecl, importc: "sqlite3_complete16".} proc busy_handler*(para1: PSqlite3, para2: proc (para1: pointer, para2: int32): int32{.cdecl.}, - para3: pointer): int32{.cdecl, + para3: pointer): int32{.cdecl, importc: "sqlite3_busy_handler".} -proc busy_timeout*(para1: PSqlite3, ms: int32): int32{.cdecl, +proc busy_timeout*(para1: PSqlite3, ms: int32): int32{.cdecl, importc: "sqlite3_busy_timeout".} proc get_table*(para1: PSqlite3, sql: cstring, resultp: var cstringArray, nrow, ncolumn: var cint, errmsg: ptr cstring): int32{.cdecl, importc: "sqlite3_get_table".} -proc free_table*(result: cstringArray){.cdecl, +proc free_table*(result: cstringArray){.cdecl, importc: "sqlite3_free_table".} # Todo: see how translate sqlite3_mprintf, sqlite3_vmprintf, sqlite3_snprintf # function sqlite3_mprintf(_para1:Pchar; args:array of const):Pchar;cdecl; external Sqlite3Lib name 'sqlite3_mprintf'; -proc mprintf*(para1: cstring): cstring{.cdecl, varargs, +proc mprintf*(para1: cstring): cstring{.cdecl, varargs, importc: "sqlite3_mprintf".} #function sqlite3_vmprintf(_para1:Pchar; _para2:va_list):Pchar;cdecl; external Sqlite3Lib name 'sqlite3_vmprintf'; proc free*(z: cstring){.cdecl, importc: "sqlite3_free".}

@@ -171,28 +171,28 @@ proc snprintf*(para1: int32, para2: cstring, para3: cstring): cstring{.cdecl,

varargs, importc: "sqlite3_snprintf".} proc set_authorizer*(para1: PSqlite3, xAuth: proc (para1: pointer, para2: int32, para3: cstring, para4: cstring, para5: cstring, para6: cstring): int32{. - cdecl.}, pUserData: pointer): int32{.cdecl, + cdecl.}, pUserData: pointer): int32{.cdecl, importc: "sqlite3_set_authorizer".} proc trace*(para1: PSqlite3, xTrace: proc (para1: pointer, para2: cstring){.cdecl.}, - para3: pointer): pointer{.cdecl, + para3: pointer): pointer{.cdecl, importc: "sqlite3_trace".} proc progress_handler*(para1: PSqlite3, para2: int32, para3: proc (para1: pointer): int32{.cdecl.}, - para4: pointer){.cdecl, + para4: pointer){.cdecl, importc: "sqlite3_progress_handler".} proc commit_hook*(para1: PSqlite3, para2: proc (para1: pointer): int32{.cdecl.}, - para3: pointer): pointer{.cdecl, + para3: pointer): pointer{.cdecl, importc: "sqlite3_commit_hook".} -proc open*(filename: cstring, ppDb: var PSqlite3): int32{.cdecl, +proc open*(filename: cstring, ppDb: var PSqlite3): int32{.cdecl, importc: "sqlite3_open".} -proc open16*(filename: pointer, ppDb: var PSqlite3): int32{.cdecl, +proc open16*(filename: pointer, ppDb: var PSqlite3): int32{.cdecl, importc: "sqlite3_open16".} proc errcode*(db: PSqlite3): int32{.cdecl, importc: "sqlite3_errcode".} proc errmsg*(para1: PSqlite3): cstring{.cdecl, importc: "sqlite3_errmsg".} -proc errmsg16*(para1: PSqlite3): pointer{.cdecl, +proc errmsg16*(para1: PSqlite3): pointer{.cdecl, importc: "sqlite3_errmsg16".} proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: var Pstmt, - pzTail: ptr cstring): int32{.cdecl, + pzTail: ptr cstring): int32{.cdecl, importc: "sqlite3_prepare".} proc prepare_v2*(db: PSqlite3, zSql: cstring, nByte: cint, ppStmt: var Pstmt,

@@ -200,10 +200,10 @@ pzTail: ptr cstring): cint {.

importc: "sqlite3_prepare_v2", cdecl, .} proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: var Pstmt, - pzTail: var pointer): int32{.cdecl, + pzTail: var pointer): int32{.cdecl, importc: "sqlite3_prepare16".} proc bind_blob*(para1: Pstmt, para2: int32, para3: pointer, n: int32, - para5: Tbind_destructor_func): int32{.cdecl, + para5: Tbind_destructor_func): int32{.cdecl, importc: "sqlite3_bind_blob".} proc bind_double*(para1: Pstmt, para2: int32, para3: float64): int32{.cdecl, importc: "sqlite3_bind_double".}

@@ -211,27 +211,27 @@ proc bind_int*(para1: Pstmt, para2: int32, para3: int32): int32{.cdecl,

importc: "sqlite3_bind_int".} proc bind_int64*(para1: Pstmt, para2: int32, para3: int64): int32{.cdecl, importc: "sqlite3_bind_int64".} -proc bind_null*(para1: Pstmt, para2: int32): int32{.cdecl, +proc bind_null*(para1: Pstmt, para2: int32): int32{.cdecl, importc: "sqlite3_bind_null".} proc bind_text*(para1: Pstmt, para2: int32, para3: cstring, n: int32, - para5: Tbind_destructor_func): int32{.cdecl, + para5: Tbind_destructor_func): int32{.cdecl, importc: "sqlite3_bind_text".} proc bind_text16*(para1: Pstmt, para2: int32, para3: pointer, para4: int32, - para5: Tbind_destructor_func): int32{.cdecl, + para5: Tbind_destructor_func): int32{.cdecl, importc: "sqlite3_bind_text16".} #function sqlite3_bind_value(_para1:Psqlite3_stmt; _para2:longint; _para3:Psqlite3_value):longint;cdecl; external Sqlite3Lib name 'sqlite3_bind_value'; #These overloaded functions were introduced to allow the use of SQLITE_STATIC and SQLITE_TRANSIENT #It's the c world man ;-) proc bind_blob*(para1: Pstmt, para2: int32, para3: pointer, n: int32, - para5: int32): int32{.cdecl, + para5: int32): int32{.cdecl, importc: "sqlite3_bind_blob".} proc bind_text*(para1: Pstmt, para2: int32, para3: cstring, n: int32, - para5: int32): int32{.cdecl, + para5: int32): int32{.cdecl, importc: "sqlite3_bind_text".} proc bind_text16*(para1: Pstmt, para2: int32, para3: pointer, para4: int32, - para5: int32): int32{.cdecl, + para5: int32): int32{.cdecl, importc: "sqlite3_bind_text16".} -proc bind_parameter_count*(para1: Pstmt): int32{.cdecl, +proc bind_parameter_count*(para1: Pstmt): int32{.cdecl, importc: "sqlite3_bind_parameter_count".} proc bind_parameter_name*(para1: Pstmt, para2: int32): cstring{.cdecl, importc: "sqlite3_bind_parameter_name".}

@@ -239,40 +239,40 @@ proc bind_parameter_index*(para1: Pstmt, zName: cstring): int32{.cdecl,

importc: "sqlite3_bind_parameter_index".} proc clear_bindings*(para1: Pstmt): int32 {.cdecl, importc: "sqlite3_clear_bindings".} -proc column_count*(pStmt: Pstmt): int32{.cdecl, +proc column_count*(pStmt: Pstmt): int32{.cdecl, importc: "sqlite3_column_count".} -proc column_name*(para1: Pstmt, para2: int32): cstring{.cdecl, +proc column_name*(para1: Pstmt, para2: int32): cstring{.cdecl, importc: "sqlite3_column_name".} -proc column_table_name*(para1: Pstmt; para2: int32): cstring{.cdecl, +proc column_table_name*(para1: Pstmt; para2: int32): cstring{.cdecl, importc: "sqlite3_column_table_name".} -proc column_name16*(para1: Pstmt, para2: int32): pointer{.cdecl, +proc column_name16*(para1: Pstmt, para2: int32): pointer{.cdecl, importc: "sqlite3_column_name16".} -proc column_decltype*(para1: Pstmt, i: int32): cstring{.cdecl, +proc column_decltype*(para1: Pstmt, i: int32): cstring{.cdecl, importc: "sqlite3_column_decltype".} proc column_decltype16*(para1: Pstmt, para2: int32): pointer{.cdecl, importc: "sqlite3_column_decltype16".} proc step*(para1: Pstmt): int32{.cdecl, importc: "sqlite3_step".} -proc data_count*(pStmt: Pstmt): int32{.cdecl, +proc data_count*(pStmt: Pstmt): int32{.cdecl, importc: "sqlite3_data_count".} -proc column_blob*(para1: Pstmt, iCol: int32): pointer{.cdecl, +proc column_blob*(para1: Pstmt, iCol: int32): pointer{.cdecl, importc: "sqlite3_column_blob".} -proc column_bytes*(para1: Pstmt, iCol: int32): int32{.cdecl, +proc column_bytes*(para1: Pstmt, iCol: int32): int32{.cdecl, importc: "sqlite3_column_bytes".} -proc column_bytes16*(para1: Pstmt, iCol: int32): int32{.cdecl, +proc column_bytes16*(para1: Pstmt, iCol: int32): int32{.cdecl, importc: "sqlite3_column_bytes16".} -proc column_double*(para1: Pstmt, iCol: int32): float64{.cdecl, +proc column_double*(para1: Pstmt, iCol: int32): float64{.cdecl, importc: "sqlite3_column_double".} -proc column_int*(para1: Pstmt, iCol: int32): int32{.cdecl, +proc column_int*(para1: Pstmt, iCol: int32): int32{.cdecl, importc: "sqlite3_column_int".} -proc column_int64*(para1: Pstmt, iCol: int32): int64{.cdecl, +proc column_int64*(para1: Pstmt, iCol: int32): int64{.cdecl, importc: "sqlite3_column_int64".} -proc column_text*(para1: Pstmt, iCol: int32): cstring{.cdecl, +proc column_text*(para1: Pstmt, iCol: int32): cstring{.cdecl, importc: "sqlite3_column_text".} -proc column_text16*(para1: Pstmt, iCol: int32): pointer{.cdecl, +proc column_text16*(para1: Pstmt, iCol: int32): pointer{.cdecl, importc: "sqlite3_column_text16".} -proc column_type*(para1: Pstmt, iCol: int32): int32{.cdecl, +proc column_type*(para1: Pstmt, iCol: int32): int32{.cdecl, importc: "sqlite3_column_type".} -proc finalize*(pStmt: Pstmt): int32{.cdecl, +proc finalize*(pStmt: Pstmt): int32{.cdecl, importc: "sqlite3_finalize".} proc reset*(pStmt: Pstmt): int32{.cdecl, importc: "sqlite3_reset".} proc create_function*(para1: PSqlite3, zFunctionName: cstring, nArg: int32,

@@ -287,67 +287,67 @@ xFunc: Create_function_func_func,

xStep: Create_function_step_func, xFinal: Create_function_final_func): int32{.cdecl, importc: "sqlite3_create_function16".} -proc aggregate_count*(para1: Pcontext): int32{.cdecl, +proc aggregate_count*(para1: Pcontext): int32{.cdecl, importc: "sqlite3_aggregate_count".} -proc value_blob*(para1: Pvalue): pointer{.cdecl, +proc value_blob*(para1: Pvalue): pointer{.cdecl, importc: "sqlite3_value_blob".} -proc value_bytes*(para1: Pvalue): int32{.cdecl, +proc value_bytes*(para1: Pvalue): int32{.cdecl, importc: "sqlite3_value_bytes".} -proc value_bytes16*(para1: Pvalue): int32{.cdecl, +proc value_bytes16*(para1: Pvalue): int32{.cdecl, importc: "sqlite3_value_bytes16".} -proc value_double*(para1: Pvalue): float64{.cdecl, +proc value_double*(para1: Pvalue): float64{.cdecl, importc: "sqlite3_value_double".} -proc value_int*(para1: Pvalue): int32{.cdecl, +proc value_int*(para1: Pvalue): int32{.cdecl, importc: "sqlite3_value_int".} -proc value_int64*(para1: Pvalue): int64{.cdecl, +proc value_int64*(para1: Pvalue): int64{.cdecl, importc: "sqlite3_value_int64".} -proc value_text*(para1: Pvalue): cstring{.cdecl, +proc value_text*(para1: Pvalue): cstring{.cdecl, importc: "sqlite3_value_text".} -proc value_text16*(para1: Pvalue): pointer{.cdecl, +proc value_text16*(para1: Pvalue): pointer{.cdecl, importc: "sqlite3_value_text16".} -proc value_text16le*(para1: Pvalue): pointer{.cdecl, +proc value_text16le*(para1: Pvalue): pointer{.cdecl, importc: "sqlite3_value_text16le".} -proc value_text16be*(para1: Pvalue): pointer{.cdecl, +proc value_text16be*(para1: Pvalue): pointer{.cdecl, importc: "sqlite3_value_text16be".} -proc value_type*(para1: Pvalue): int32{.cdecl, +proc value_type*(para1: Pvalue): int32{.cdecl, importc: "sqlite3_value_type".} proc aggregate_context*(para1: Pcontext, nBytes: int32): pointer{.cdecl, importc: "sqlite3_aggregate_context".} -proc user_data*(para1: Pcontext): pointer{.cdecl, +proc user_data*(para1: Pcontext): pointer{.cdecl, importc: "sqlite3_user_data".} -proc get_auxdata*(para1: Pcontext, para2: int32): pointer{.cdecl, +proc get_auxdata*(para1: Pcontext, para2: int32): pointer{.cdecl, importc: "sqlite3_get_auxdata".} proc set_auxdata*(para1: Pcontext, para2: int32, para3: pointer, - para4: proc (para1: pointer){.cdecl.}){.cdecl, + para4: proc (para1: pointer){.cdecl.}){.cdecl, importc: "sqlite3_set_auxdata".} proc result_blob*(para1: Pcontext, para2: pointer, para3: int32, - para4: Result_func){.cdecl, + para4: Result_func){.cdecl, importc: "sqlite3_result_blob".} -proc result_double*(para1: Pcontext, para2: float64){.cdecl, +proc result_double*(para1: Pcontext, para2: float64){.cdecl, importc: "sqlite3_result_double".} proc result_error*(para1: Pcontext, para2: cstring, para3: int32){.cdecl, importc: "sqlite3_result_error".} proc result_error16*(para1: Pcontext, para2: pointer, para3: int32){.cdecl, importc: "sqlite3_result_error16".} -proc result_int*(para1: Pcontext, para2: int32){.cdecl, +proc result_int*(para1: Pcontext, para2: int32){.cdecl, importc: "sqlite3_result_int".} -proc result_int64*(para1: Pcontext, para2: int64){.cdecl, +proc result_int64*(para1: Pcontext, para2: int64){.cdecl, importc: "sqlite3_result_int64".} -proc result_null*(para1: Pcontext){.cdecl, +proc result_null*(para1: Pcontext){.cdecl, importc: "sqlite3_result_null".} proc result_text*(para1: Pcontext, para2: cstring, para3: int32, - para4: Result_func){.cdecl, + para4: Result_func){.cdecl, importc: "sqlite3_result_text".} proc result_text16*(para1: Pcontext, para2: pointer, para3: int32, - para4: Result_func){.cdecl, + para4: Result_func){.cdecl, importc: "sqlite3_result_text16".} proc result_text16le*(para1: Pcontext, para2: pointer, para3: int32, - para4: Result_func){.cdecl, + para4: Result_func){.cdecl, importc: "sqlite3_result_text16le".} proc result_text16be*(para1: Pcontext, para2: pointer, para3: int32, - para4: Result_func){.cdecl, + para4: Result_func){.cdecl, importc: "sqlite3_result_text16be".} -proc result_value*(para1: Pcontext, para2: Pvalue){.cdecl, +proc result_value*(para1: Pcontext, para2: Pvalue){.cdecl, importc: "sqlite3_result_value".} proc create_collation*(para1: PSqlite3, zName: cstring, eTextRep: int32, para4: pointer, xCompare: Create_collation_func): int32{.

@@ -363,7 +363,7 @@ proc libversion*(): cstring{.cdecl, importc: "sqlite3_libversion".}

#Alias for allowing better code portability (win32 is not working with external variables) proc version*(): cstring{.cdecl, importc: "sqlite3_libversion".} # Not published functions -proc libversion_number*(): int32{.cdecl, +proc libversion_number*(): int32{.cdecl, importc: "sqlite3_libversion_number".} #function sqlite3_key(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external Sqlite3Lib name 'sqlite3_key'; #function sqlite3_rekey(db:Psqlite3; pKey:pointer; nKey:longint):longint;cdecl; external Sqlite3Lib name 'sqlite3_rekey';
M test/http_api.nimtest/http_api.nim

@@ -133,7 +133,7 @@ var ops = %*[

{"op": "remove", "path": "/data/name/first"}, {"op": "add", "path": "/data/test", "value": 111}, {"op": "replace", "path": "/data/friends/0", "value": {"id": 11, "name": "Tom Paris"}} - ] + ] var rpatch = jpatch("docs/" & ids[0], ops) var data = rpatch.body.parseJson["data"] check(data["name"] == %*{"last": "Walters"})

@@ -143,7 +143,7 @@ ops = %*[

{"op": "add", "path": "/data/not_added", "value": "!!!"}, {"op": "test", "path": "/data/test", "value": 222}, {"op": "replace", "path": "/data/test", "value": "!!!"} - ] + ] rpatch = jpatch("docs/" & ids[0], ops) data = rpatch.body.parseJson["data"] check(data["test"] == %111)

@@ -152,7 +152,7 @@ ops = %*[

{"op": "replace", "path": "/data/test", "value": 222}, {"op": "test", "path": "/data/test", "value": 222}, {"op": "add", "path": "/data/not_added", "value": "!!!"} - ] + ] rpatch = jpatch("docs/" & ids[0], ops) data = rpatch.body.parseJson["data"] check(data["test"] == %111)