You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
10 KiB

const Controller = require('libflitter/controller/Controller')
const Page = require('../../../models/api/Page.model')
const Node = require('../../../models/api/Node.model')
const Database = require('../../../models/api/db/Database.model')
const ColumnDef = require('../../../models/api/db/ColumnDef.model')
const DBEntry = require('../../../models/api/db/DBEntry.model')
/*
* Database Controller
* -------------------------------------------------------------
* Put some description here!
*/
class FormDatabase extends Controller {
async create_new(req, res) {
const PageId = req.params.PageId
let page = await Page.findOne({UUID: PageId})
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
if ( !(await page.is_accessible_by(req.user, 'update')) ) return req.security.deny()
const NodeId = req.params.NodeId
let node = await Node.findOne({UUID: NodeId})
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
const db = new Database({
Name: req.body.name ? req.body.name : 'New Database',
NodeId: node.UUID,
PageId: page.UUID,
})
await db.save()
req.user.allow(`database:${db.UUID}`);
await req.user.save()
return res.api(db)
}
async get_config(req, res) {
const PageId = req.params.PageId
let page = await Page.findOne({UUID: PageId})
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
if ( !(await page.is_accessible_by(req.user)) ) return req.security.deny()
const NodeId = req.params.NodeId
let node = await Node.findOne({UUID: NodeId})
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
const DatabaseId = req.params.DatabaseId
const db = await Database.findOne({UUID: DatabaseId})
if ( !db ) return res.status(404).message('Database not found with that ID.').api({})
// if ( !db.accessible_by(req.user) ) return req.security.deny()
return res.api(db)
}
async get_columns(req, res) {
const PageId = req.params.PageId
let page = await Page.findOne({UUID: PageId})
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
if ( !(await page.is_accessible_by(req.user)) ) return req.security.deny()
const NodeId = req.params.NodeId
let node = await Node.findOne({UUID: NodeId})
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
const DatabaseId = req.params.DatabaseId
const db = await Database.findOne({UUID: DatabaseId})
if ( !db ) return res.status(404).message('Database not found with that ID.').api({})
const columns = []
for ( const col_id of db.ColumnIds ) {
const rec = await ColumnDef.findOne({UUID: col_id})
if ( rec ) {
rec.additionalData = rec.data()
columns.push(rec)
}
}
// Fallback for backwards compat
if ( columns.length < 1 ) {
return res.api((await ColumnDef.find({DatabaseId: db.UUID})).map(x => {
x.additionalData = x.data()
return x
}))
}
return res.api(columns)
}
async set_name(req, res) {
if ( !req.body.Name ) {
return res.status(400)
.message('Missing required field: Name')
.api()
}
const PageId = req.params.PageId
let page = await Page.findOne({UUID: PageId})
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
if ( !(await page.is_accessible_by(req.user, 'update')) ) return req.security.deny()
const NodeId = req.params.NodeId
let node = await Node.findOne({UUID: NodeId})
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
const DatabaseId = req.params.DatabaseId
const db = await Database.findOne({UUID: DatabaseId})
if ( !db ) return res.status(404).message('Database not found with that ID.').api({})
// if ( !db.accessible_by(req.user, 'update') ) return req.security.deny()
db.Name = req.body.Name
await db.save()
return res.api(db)
}
async set_columns(req, res) {
const PageId = req.params.PageId
let page = await Page.findOne({UUID: PageId})
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
if ( !(await page.is_accessible_by(req.user, 'update')) ) return req.security.deny()
const NodeId = req.params.NodeId
let node = await Node.findOne({UUID: NodeId})
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
const DatabaseId = req.params.DatabaseId
const db = await Database.findOne({UUID: DatabaseId})
if ( !db ) return res.status(404).message('Database not found with that ID.').api({})
// if ( !db.accessible_by(req.user, 'update') ) return req.security.deny()
const existing_columns = await ColumnDef.find({ DatabaseId: db.UUID })
const assoc_columns = []
existing_columns.forEach(col => assoc_columns[col.UUID] = col)
const update_columns = []
for ( const col of req.body.columns ) {
if ( col.UUID && assoc_columns[col.UUID] ) {
assoc_columns[col.UUID].headerName = col.headerName
assoc_columns[col.UUID].field = col.field
assoc_columns[col.UUID].DatabaseId = db.UUID
assoc_columns[col.UUID].Type = col.Type
assoc_columns[col.UUID].additionalData = JSON.stringify(col.additionalData)
await assoc_columns[col.UUID].save()
update_columns.push(assoc_columns[col.UUID])
} else {
const new_col = new ColumnDef({
headerName: col.headerName,
field: col.field,
DatabaseId: db.UUID,
Type: col.Type,
additionalData: JSON.stringify(col.additionalData),
})
await new_col.save()
update_columns.push(new_col)
}
}
for ( const col of existing_columns ) {
if ( !update_columns.includes(col) ) {
await col.delete()
}
}
db.ColumnIds = update_columns.map(x => x.UUID)
await db.save()
return res.api(update_columns)
}
async get_data(req, res) {
const PageId = req.params.PageId
let page = await Page.findOne({UUID: PageId})
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
if ( !(await page.is_accessible_by(req.user)) ) return req.security.deny()
const NodeId = req.params.NodeId
let node = await Node.findOne({UUID: NodeId})
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
const DatabaseId = req.params.DatabaseId
const db = await Database.findOne({UUID: DatabaseId})
if ( !db ) return res.status(404).message('Database not found with that ID.').api({})
// if ( !db.accessible_by(req.user) ) return req.security.deny()
const entries = await DBEntry.find({DatabaseId: db.UUID})
entries.forEach(entry => entry.RowData.UUID = entry.UUID)
return res.api(entries)
}
async set_data(req, res) {
const PageId = req.params.PageId
let page = await Page.findOne({UUID: PageId})
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
if ( !(await page.is_accessible_by(req.user, 'update')) ) return req.security.deny()
const NodeId = req.params.NodeId
let node = await Node.findOne({UUID: NodeId})
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
const DatabaseId = req.params.DatabaseId
const db = await Database.findOne({UUID: DatabaseId})
if ( !db ) return res.status(404).message('Database not found with that ID.').api({})
// if ( !db.accessible_by(req.user) ) return req.security.deny()
await DBEntry.deleteMany({DatabaseId: db.UUID})
const new_recs = []
for ( const rec of req.body ) {
const data = {DatabaseId: db.UUID}
if ( rec.UUID ) data.UUID = rec.UUID
delete rec.UUID
data.RowData = rec
const dbe = new DBEntry(data)
await dbe.save()
dbe.RowData.UUID = dbe.UUID
new_recs.push(dbe)
}
return res.api(await this._set_indices(db, new_recs))
}
async drop_database(req, res) {
const PageId = req.params.PageId
let page = await Page.findOne({UUID: PageId})
if ( !page ) return res.status(404).message('Page not found with that ID.').api({})
if ( !(await page.is_accessible_by(req.user, 'update')) ) return req.security.deny()
const NodeId = req.params.NodeId
let node = await Node.findOne({UUID: NodeId})
if ( !node ) return res.status(404).message('Node not found with that ID.').api({})
const DatabaseId = req.params.DatabaseId
const db = await Database.findOne({UUID: DatabaseId})
if ( !db ) return res.status(404).message('Database not found with that ID.').api({})
// if ( !db.accessible_by(req.user) ) return req.security.deny()
await DBEntry.deleteMany({DatabaseId: db.UUID})
await db.delete()
return res.api({})
}
async _set_indices(db, data) {
const index_columns = await ColumnDef.find({DatabaseId: db.UUID, Type: 'index'})
for ( const col of index_columns ) {
let max_val = 0
data.forEach(row => {
const val = row.RowData[col.field]
if ( val && val > max_val ) max_val = val
});
let next_val = max_val + 1
for ( const row of data ) {
if ( !row.RowData[col.field] ) {
row.RowData[col.field] = next_val
next_val += 1
await row.save()
}
}
}
return data
}
}
module.exports = exports = FormDatabase