|
|
|
@ -3,14 +3,27 @@ const viewTemplate = require("./viewBuilder") |
|
|
|
const { apiFileReturn } = require("../../../utilities/fileSystem") |
|
|
|
const exporters = require("./exporters") |
|
|
|
const { fetchView } = require("../row") |
|
|
|
const { ViewNames } = require("../../../db/utils") |
|
|
|
|
|
|
|
const controller = { |
|
|
|
fetch: async ctx => { |
|
|
|
const db = new CouchDB(ctx.appId) |
|
|
|
const { |
|
|
|
ViewNames, |
|
|
|
generateMemoryViewID, |
|
|
|
getMemoryViewParams, |
|
|
|
} = require("../../../db/utils") |
|
|
|
const env = require("../../../environment") |
|
|
|
|
|
|
|
async function getView(db, viewName) { |
|
|
|
if (env.SELF_HOSTED) { |
|
|
|
const designDoc = await db.get("_design/database") |
|
|
|
const response = [] |
|
|
|
return designDoc.views[viewName] |
|
|
|
} else { |
|
|
|
const viewDoc = await db.get(generateMemoryViewID(viewName)) |
|
|
|
return viewDoc.view |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
async function getViews(db) { |
|
|
|
const response = [] |
|
|
|
if (env.SELF_HOSTED) { |
|
|
|
const designDoc = await db.get("_design/database") |
|
|
|
for (let name of Object.keys(designDoc.views)) { |
|
|
|
// Only return custom views, not built ins
|
|
|
|
if (Object.values(ViewNames).indexOf(name) !== -1) { |
|
|
|
@ -21,30 +34,91 @@ const controller = { |
|
|
|
...designDoc.views[name], |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
ctx.body = response |
|
|
|
}, |
|
|
|
save: async ctx => { |
|
|
|
const db = new CouchDB(ctx.appId) |
|
|
|
const { originalName, ...viewToSave } = ctx.request.body |
|
|
|
const designDoc = await db.get("_design/database") |
|
|
|
const view = viewTemplate(viewToSave) |
|
|
|
|
|
|
|
if (!viewToSave.name) { |
|
|
|
ctx.throw(400, "Cannot create view without a name") |
|
|
|
} else { |
|
|
|
const views = ( |
|
|
|
await db.allDocs( |
|
|
|
getMemoryViewParams({ |
|
|
|
include_docs: true, |
|
|
|
}) |
|
|
|
) |
|
|
|
).rows.map(row => row.doc) |
|
|
|
for (let viewDoc of views) { |
|
|
|
response.push({ |
|
|
|
name: viewDoc.name, |
|
|
|
...viewDoc.view, |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
return response |
|
|
|
} |
|
|
|
|
|
|
|
async function saveView(db, originalName, viewToSave, viewTemplate) { |
|
|
|
if (env.SELF_HOSTED) { |
|
|
|
const designDoc = await db.get("_design/database") |
|
|
|
designDoc.views = { |
|
|
|
...designDoc.views, |
|
|
|
[viewToSave.name]: view, |
|
|
|
[viewToSave.name]: viewTemplate, |
|
|
|
} |
|
|
|
|
|
|
|
// view has been renamed
|
|
|
|
if (originalName) { |
|
|
|
delete designDoc.views[originalName] |
|
|
|
} |
|
|
|
await db.put(designDoc) |
|
|
|
} else { |
|
|
|
const id = generateMemoryViewID(viewToSave.name) |
|
|
|
const originalId = originalName ? generateMemoryViewID(originalName) : null |
|
|
|
const viewDoc = { |
|
|
|
_id: id, |
|
|
|
view: viewTemplate, |
|
|
|
name: viewToSave.name, |
|
|
|
tableId: viewTemplate.meta.tableId, |
|
|
|
} |
|
|
|
try { |
|
|
|
const old = await db.get(id) |
|
|
|
if (originalId) { |
|
|
|
const originalDoc = await db.get(originalId) |
|
|
|
await db.remove(originalDoc._id, originalDoc._rev) |
|
|
|
} |
|
|
|
if (old && old._rev) { |
|
|
|
viewDoc._rev = old._rev |
|
|
|
} |
|
|
|
} catch (err) { |
|
|
|
// didn't exist, just skip
|
|
|
|
} |
|
|
|
await db.put(viewDoc) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
async function deleteView(db, viewName) { |
|
|
|
if (env.SELF_HOSTED) { |
|
|
|
const designDoc = await db.get("_design/database") |
|
|
|
const view = designDoc.views[viewName] |
|
|
|
delete designDoc.views[viewName] |
|
|
|
await db.put(designDoc) |
|
|
|
return view |
|
|
|
} else { |
|
|
|
const id = generateMemoryViewID(viewName) |
|
|
|
const viewDoc = await db.get(id) |
|
|
|
await db.remove(viewDoc._id, viewDoc._rev) |
|
|
|
return viewDoc.view |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const controller = { |
|
|
|
fetch: async ctx => { |
|
|
|
const db = new CouchDB(ctx.appId) |
|
|
|
ctx.body = await getViews(db) |
|
|
|
}, |
|
|
|
save: async ctx => { |
|
|
|
const db = new CouchDB(ctx.appId) |
|
|
|
const { originalName, ...viewToSave } = ctx.request.body |
|
|
|
const view = viewTemplate(viewToSave) |
|
|
|
|
|
|
|
if (!viewToSave.name) { |
|
|
|
ctx.throw(400, "Cannot create view without a name") |
|
|
|
} |
|
|
|
|
|
|
|
await saveView(db, originalName, viewToSave, view) |
|
|
|
|
|
|
|
// add views to table document
|
|
|
|
const table = await db.get(ctx.request.body.tableId) |
|
|
|
@ -53,11 +127,9 @@ const controller = { |
|
|
|
view.meta.schema = table.schema |
|
|
|
} |
|
|
|
table.views[viewToSave.name] = view.meta |
|
|
|
|
|
|
|
if (originalName) { |
|
|
|
delete table.views[originalName] |
|
|
|
} |
|
|
|
|
|
|
|
await db.put(table) |
|
|
|
|
|
|
|
ctx.body = { |
|
|
|
@ -67,13 +139,8 @@ const controller = { |
|
|
|
}, |
|
|
|
destroy: async ctx => { |
|
|
|
const db = new CouchDB(ctx.appId) |
|
|
|
const designDoc = await db.get("_design/database") |
|
|
|
const viewName = decodeURI(ctx.params.viewName) |
|
|
|
const view = designDoc.views[viewName] |
|
|
|
delete designDoc.views[viewName] |
|
|
|
|
|
|
|
await db.put(designDoc) |
|
|
|
|
|
|
|
const view = await deleteView(db, viewName) |
|
|
|
const table = await db.get(view.meta.tableId) |
|
|
|
delete table.views[viewName] |
|
|
|
await db.put(table) |
|
|
|
@ -82,10 +149,9 @@ const controller = { |
|
|
|
}, |
|
|
|
exportView: async ctx => { |
|
|
|
const db = new CouchDB(ctx.appId) |
|
|
|
const designDoc = await db.get("_design/database") |
|
|
|
const viewName = decodeURI(ctx.query.view) |
|
|
|
const view = await getView(db, viewName) |
|
|
|
|
|
|
|
const view = designDoc.views[viewName] |
|
|
|
const format = ctx.query.format |
|
|
|
if (!format) { |
|
|
|
ctx.throw(400, "Format must be specified, either csv or json") |
|
|
|
|