forked from tsai/budibase
committed by
GitHub
20 changed files with 424 additions and 209 deletions
@ -0,0 +1,109 @@ |
|||
const { |
|||
ViewNames, |
|||
generateMemoryViewID, |
|||
getMemoryViewParams, |
|||
} = require("../../../db/utils") |
|||
const env = require("../../../environment") |
|||
|
|||
exports.getView = async (db, viewName) => { |
|||
if (env.SELF_HOSTED) { |
|||
const designDoc = await db.get("_design/database") |
|||
return designDoc.views[viewName] |
|||
} else { |
|||
const viewDoc = await db.get(generateMemoryViewID(viewName)) |
|||
return viewDoc.view |
|||
} |
|||
} |
|||
|
|||
exports.getViews = async 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) { |
|||
continue |
|||
} |
|||
response.push({ |
|||
name, |
|||
...designDoc.views[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 |
|||
} |
|||
|
|||
exports.saveView = async (db, originalName, viewName, viewTemplate) => { |
|||
if (env.SELF_HOSTED) { |
|||
const designDoc = await db.get("_design/database") |
|||
designDoc.views = { |
|||
...designDoc.views, |
|||
[viewName]: viewTemplate, |
|||
} |
|||
// view has been renamed
|
|||
if (originalName) { |
|||
delete designDoc.views[originalName] |
|||
} |
|||
await db.put(designDoc) |
|||
} else { |
|||
const id = generateMemoryViewID(viewName) |
|||
const originalId = originalName ? generateMemoryViewID(originalName) : null |
|||
const viewDoc = { |
|||
_id: id, |
|||
view: viewTemplate, |
|||
name: viewName, |
|||
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) |
|||
} |
|||
} |
|||
|
|||
exports.deleteView = async (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 |
|||
} |
|||
} |
|||
|
|||
exports.migrateToInMemoryView = async (db, viewName) => { |
|||
// delete the view initially
|
|||
const designDoc = await db.get("_design/database") |
|||
const view = designDoc.views[viewName] |
|||
delete designDoc.views[viewName] |
|||
await db.put(designDoc) |
|||
await exports.saveView(db, null, viewName, view) |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
const PouchDB = require("pouchdb") |
|||
const memory = require("pouchdb-adapter-memory") |
|||
const newid = require("./newid") |
|||
|
|||
PouchDB.plugin(memory) |
|||
const Pouch = PouchDB.defaults({ |
|||
prefix: undefined, |
|||
adapter: "memory", |
|||
}) |
|||
|
|||
exports.runView = async (view, calculation, group, data) => { |
|||
// use a different ID each time for the DB, make sure they
|
|||
// are always unique for each query, don't want overlap
|
|||
// which could cause 409s
|
|||
const db = new Pouch(newid()) |
|||
// write all the docs to the in memory Pouch (remove revs)
|
|||
await db.bulkDocs( |
|||
data.map(row => ({ |
|||
...row, |
|||
_rev: undefined, |
|||
})) |
|||
) |
|||
let fn = (doc, emit) => emit(doc._id) |
|||
eval("fn = " + view.map.replace("function (doc)", "function (doc, emit)")) |
|||
const queryFns = { |
|||
meta: view.meta, |
|||
map: fn, |
|||
} |
|||
if (view.reduce) { |
|||
queryFns.reduce = view.reduce |
|||
} |
|||
const response = await db.query(queryFns, { |
|||
include_docs: !calculation, |
|||
group: !!group, |
|||
}) |
|||
// need to fix the revs to be totally accurate
|
|||
for (let row of response.rows) { |
|||
if (!row._rev || !row._id) { |
|||
continue |
|||
} |
|||
const found = data.find(possible => possible._id === row._id) |
|||
if (found) { |
|||
row._rev = found._rev |
|||
} |
|||
} |
|||
await db.destroy() |
|||
return response |
|||
} |
|||
Loading…
Reference in new issue