dobo
Version:
DBMS for Bajo Framework
223 lines (194 loc) • 7.1 kB
JavaScript
import { sanitizeAll, sanitizeRef } from '../collect-models.js'
import clearRecord from './model/clear-record.js'
import countRecord from './model/count-record.js'
import createRecord from './model/create-record.js'
import drop from './model/drop.js'
import findAllRecord from './model/find-all-record.js'
import findOneRecord from './model/find-one-record.js'
import findRecord from './model/find-record.js'
import getRecord from './model/get-record.js'
import createHistogram from './model/create-histogram.js'
import createAggregate from './model/create-aggregate.js'
import exists from './model/exists.js'
import build from './model/build.js'
import loadFixtures from './model/load-fixtures.js'
import removeRecord from './model/remove-record.js'
import updateRecord from './model/update-record.js'
import createAttachment from './model/create-attachment.js'
import updateAttachment from './model/update-attachment.js'
import getAttachment from './model/get-attachment.js'
import removeAttachment from './model/remove-attachment.js'
import findAttachment from './model/find-attachment.js'
import sanitizeBody from './model/sanitize-body.js'
import sanitizeRecord from './model/sanitize-record.js'
import sanitizeId from './model/sanitize-id.js'
import sanitizeFixture from './model/sanitize-fixture.js'
import upsertRecord from './model/upsert-record.js'
import bulkCreateRecord from './model/bulk-create-record.js'
import listAttachment from './model/list-attachment.js'
import transaction from './model/transaction.js'
import validate from './model/validate.js'
/**
* @typedef {string} TRecordSortKey
*/
/**
* Key value pairs used as sort information:
* - Key represent model's field name
* - value represent its sort order: ```1``` for ascending order, and ```-1``` for descending order
*
* Example: to sort by firstName (ascending) and lastName (descending)
* ```javascript
* const sort = {
* firstName: 1,
* lastName: -1
* }
* ```
*
* @typedef {Object.<string, TRecordSortKey>} TRecordSort
*/
/**
* @typedef {Object} TRecordPagination
* @property {number} limit - Number of records per page
* @property {number} page - Page number
* @property {number} skip - Records to skip
* @property {TRecordSort} sort - Sort order
*/
async function modelFactory () {
const { Tools } = this.app.baseClass
const { defaults } = this.app.lib._
/**
* Feature class
*
* ```this.plugin``` should be the one who owned this driver
*
* @class
*/
class DoboModel extends Tools {
constructor (plugin, options) {
super(plugin)
defaults(this, options)
this.driver = this.connection.driver
}
action = (name, ...args) => {
const action = new this.app.baseClass.DoboAction(this, name, ...args)
return action
}
sanitizeObjectDef = async (obj) => {
await sanitizeAll.call(this.app.dobo, obj)
}
sanitizeRef = async (obj, fatal = true) => {
await sanitizeRef.call(this.app.dobo, obj, this.app.dobo.models, fatal)
}
getProperty = (name) => {
return this.properties.find(prop => prop.name === name)
}
getProperties = ({ noVirtual, namesOnly } = {}) => {
const items = noVirtual ? this.properties.filter(prop => !prop.virtual) : this.properties
return namesOnly ? items.map(item => item.name) : items
}
getVirtualProperties = (namesOnly) => {
const items = this.properties.filter(prop => prop.virtual)
return namesOnly ? items.map(item => item.name) : items
}
getNonVirtualProperties = (namesOnly) => {
const items = this.properties.filter(prop => !prop.virtual)
return namesOnly ? items.map(item => item.name) : items
}
getIndexes = () => {
return this.indexes
}
hasProperty = (name) => {
return !!this.getProperty(name)
}
syncIdField = (idField) => {
const { cloneDeep, findIndex } = this.app.lib._
if (!this.driver) return
if (!idField) idField = cloneDeep(this.driver.idField)
const idx = findIndex(this.properties, { name: 'id' })
if (idx === -1) return
this.properties.splice(idx, 1)
this.properties.unshift(idField)
}
_simpleLookup = async (value, lookupValue, options = {}) => {
const { get, isEmpty, isString, isPlainObject, isArray } = this.app.lib._
let model
let field
let query
if (isString(value)) {
[model, field, ...query] = value.split(':')
query = query.join(':')
} else if (isPlainObject(value)) ({ model, field, query } = value)
else if (isArray(value)) [model, field, query] = value
else return
for (const key in lookupValue) {
query = query.replaceAll(`{${key}}`, lookupValue[key])
}
if (isEmpty(field)) field = 'id'
const { getModel } = this.app.dobo
const ref = getModel(model)
const opts = { ...options, noCache: true, noMagic: true }
opts.dataOnly = true
const rec = await ref.findOneRecord({ query }, opts)
return get(rec, field, null)
}
buildPropValues = async (prop, opts) => {
const { isString, camelCase, isFunction } = this.app.lib._
const { callHandler } = this.app.bajo
const values = isString(prop.values) || isFunction(prop.values) ? await callHandler(this, prop.values, opts) : [...prop.values]
return values.map(v => {
if (isString(v)) v = { value: v, text: v }
if (opts.req) {
const key = camelCase(`${prop.name} ${v.text}`)
if (opts.req.te(key)) v.text = opts.req.t(key)
}
return v
})
}
build = build
exists = exists
drop = drop
createRecord = createRecord
getRecord = getRecord
updateRecord = updateRecord
upsertRecord = upsertRecord
removeRecord = removeRecord
clearRecord = clearRecord
findRecord = findRecord
findOneRecord = findOneRecord
findAllRecord = findAllRecord
transaction = transaction
bulkCreateRecord = bulkCreateRecord
createAggregate = createAggregate
createHistogram = createHistogram
countRecord = countRecord
createAttachment = createAttachment
getAttachment = getAttachment
updateAttachment = updateAttachment
removeAttachment = removeAttachment
findAttachment = findAttachment
listAttachment = listAttachment
loadFixtures = loadFixtures
sanitizeRecord = sanitizeRecord
sanitizeBody = sanitizeBody
sanitizeId = sanitizeId
sanitizeFixture = sanitizeFixture
validate = validate
// aliases
deleteRecord = removeRecord
clearRecords = clearRecord
countRecords = countRecord
findRecords = findRecord
findAllRecords = findAllRecord
listAttachments = listAttachment
bulkCreateRecords = bulkCreateRecord
getField = (name) => this.getProperty(name)
hasField = (name) => this.hasProperty(name)
dispose = async () => {
await super.dispose()
this.connection = null
this.driver = null
}
}
this.app.baseClass.DoboModel = DoboModel
}
export default modelFactory