2020-04-09 11:13:19 +02:00
|
|
|
const couchdb = require("../../db")
|
2020-04-13 12:47:53 +02:00
|
|
|
const { mapValues, keyBy, compose } = require("lodash/fp")
|
2020-04-09 11:13:19 +02:00
|
|
|
const {
|
|
|
|
validateRecord,
|
2020-04-14 16:14:57 +02:00
|
|
|
events,
|
|
|
|
safeParseField
|
|
|
|
} = require("@budibase/common")
|
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
|
2020-04-10 12:18:15 +02:00
|
|
|
ctx.message = `Model ${record._modelId} does not exist in schema.`
|
2020-04-09 11:13:19 +02:00
|
|
|
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-13 12:47:53 +02:00
|
|
|
const loadRecord = compose(
|
2020-04-09 11:13:19 +02:00
|
|
|
mapValues(f => safeParseField(f, storedData)),
|
2020-04-13 12:47:53 +02:00
|
|
|
keyBy("name")
|
|
|
|
);
|
|
|
|
|
|
|
|
const loadedRecord = loadRecord(model.fields);
|
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
|
|
|
};
|