budibase/packages/server/middleware/controllers/record.js

102 lines
2.5 KiB
JavaScript
Raw Normal View History

2020-04-09 11:13:19 +02:00
const couchdb = require("../../db")
2020-04-09 17:53:48 +02:00
const { mapValues, keyBy } = require("lodash/fp")
2020-04-09 11:13:19 +02:00
const {
validateRecord,
} = require("../../../common/src/records/validateRecord.mjs")
const { events } = require("../../../common/src/common/events.mjs")
2020-04-09 17:42:55 +02:00
const { $ } = require("../../../common/src/common")
2020-04-09 17:53:48 +02:00
const { safeParseField } = require("../../../common/src/schema/types");
2020-04-07 16:12:08 +02:00
2020-04-09 17:53:48 +02:00
exports.save = async function(ctx) {
2020-04-09 11:13:19 +02:00
const db = couchdb.use(ctx.databaseId)
2020-04-09 17:53:48 +02:00
const record = ctx.body
2020-04-08 17:57:27 +02:00
2020-04-09 11:13:19 +02:00
if (!ctx.schema.findModel(record._modelId)) {
ctx.status = 400
ctx.message = `do not recognise modelId : ${record._modelId}`
return
}
const validationResult = await validateRecord(ctx.schema, record)
if (!validationResult.isValid) {
2020-04-09 17:42:55 +02:00
await ctx.publish(events.recordApi.save.onInvalid, {
2020-04-09 11:13:19 +02:00
record,
validationResult,
})
ctx.status = 400
ctx.message = "record failed validation rules"
ctx.body = validationResult
}
if (!record._rev) {
await db.insert(record)
2020-04-09 17:42:55 +02:00
await ctx.publish(events.recordApi.save.onRecordCreated, {
2020-04-09 11:13:19 +02:00
record: record,
2020-04-08 17:57:27 +02:00
})
2020-04-09 11:13:19 +02:00
} else {
const oldRecord = await _findRecord(db, ctx.schema, record._id)
await db.insert(record)
2020-04-09 17:42:55 +02:00
await ctx.publish(events.recordApi.save.onRecordUpdated, {
2020-04-09 11:13:19 +02:00
old: oldRecord,
new: record,
})
}
const savedHead = await db.head(record._id)
record._rev = savedHead._rev
return record
}
2020-04-09 17:53:48 +02:00
exports.fetch = function(ctx) {
2020-04-09 11:13:19 +02:00
const db = couchdb.db.use(ctx.params.databaseId)
2020-04-09 17:42:55 +02:00
const model = ctx.schema.findModel(ctx.modelName)
ctx.body = db.viewAsStream(
2020-04-09 17:53:48 +02:00
`all_${model.id}`,
`all_${model.id}`,
2020-04-09 17:42:55 +02:00
{
include_docs: true,
}
)
2020-04-09 11:13:19 +02:00
}
2020-04-09 17:53:48 +02:00
exports.find = async function(ctx) {
2020-04-09 11:13:19 +02:00
const db = couchdb.db.use(ctx.params.databaseId)
2020-04-09 17:53:48 +02:00
const { body, status } = await _findRecord({
2020-04-09 17:42:55 +02:00
db,
2020-04-09 17:53:48 +02:00
schema: ctx.schema,
id: ctx.params.recordId
})
2020-04-09 11:13:19 +02:00
ctx.status = status
ctx.body = body
}
2020-04-09 17:53:48 +02:00
async function _findRecord({ db, schema, id }) {
2020-04-09 11:13:19 +02:00
let storedData
try {
storedData = await db.get(id)
} catch (err) {
return err
}
const model = schema.findModel(storedData._modelId)
2020-04-09 17:53:48 +02:00
// TODO refactor
2020-04-09 11:13:19 +02:00
const loadedRecord = $(model.fields, [
keyBy("name"),
mapValues(f => safeParseField(f, storedData)),
])
2020-04-09 17:53:48 +02:00
2020-04-09 11:13:19 +02:00
2020-04-09 17:53:48 +02:00
return {
...loadedRecord,
_rev: storedData._rev,
_id: storedData._id,
_modelId: storedData._modelId
}
2020-04-09 11:13:19 +02:00
}
2020-04-09 17:53:48 +02:00
exports.destroy = async function(ctx) {
2020-04-09 11:13:19 +02:00
const databaseId = ctx.params.databaseId;
const database = couchdb.db.use(databaseId)
ctx.body = await database.destroy(ctx.params.recordId);
2020-04-09 17:53:48 +02:00
};