gancio-upstream/server/api/models/index.js
2024-12-23 22:52:19 +01:00

180 lines
5.6 KiB
JavaScript

const Sequelize = require('sequelize')
const Umzug = require('umzug')
const path = require('path')
const config = require('../../config')
const log = require('../../log')
const SequelizeSlugify = require('sequelize-slugify')
const DB = require('./models')
const semver = require('semver')
const models = {
Announcement: require('./announcement'),
APUser: require('./ap_user'),
Collection: require('./collection'),
Event: require('./event'),
EventNotification: require('./eventnotification'),
Filter: require('./filter'),
Instance: require('./instance'),
Notification: require('./notification'),
OAuthClient: require('./oauth_client'),
OAuthCode: require('./oauth_code'),
OAuthToken: require('./oauth_token'),
Place: require('./place'),
Resource: require('./resource'),
Setting: require('./setting'),
Tag: require('./tag'),
User: require('./user'),
Message: require('./message')
}
const db = {
sequelize: null,
loadModels () {
for (const modelName in models) {
const m = models[modelName](db.sequelize, Sequelize.DataTypes)
DB[modelName] = m
}
},
associates () {
const { Filter, Collection, APUser, Instance, User, Event, EventNotification, Tag,
OAuthCode, OAuthClient, OAuthToken, Resource, Place, Notification, Message } = DB
Filter.belongsTo(Collection)
Collection.hasMany(Filter)
Instance.hasMany(APUser)
APUser.belongsTo(Instance)
OAuthCode.belongsTo(User)
OAuthCode.belongsTo(OAuthClient, { as: 'client' })
OAuthToken.belongsTo(User)
OAuthToken.belongsTo(OAuthClient, { as: 'client' })
APUser.hasMany(Resource)
Resource.belongsTo(APUser)
Event.belongsTo(Place)
Place.hasMany(Event)
Message.belongsTo(Event)
Event.hasMany(Message)
Event.belongsTo(User)
User.hasMany(Event)
Event.belongsToMany(Tag, { through: 'event_tags' })
Tag.belongsToMany(Event, { through: 'event_tags' })
// Event.belongsToMany(Notification, { through: EventNotification })
// Notification.belongsToMany(Event, { through: EventNotification })
Event.hasMany(EventNotification)
Notification.hasMany(EventNotification)
Event.hasMany(Resource)
Resource.belongsTo(Event)
APUser.hasMany(Event)
Event.belongsTo(APUser)
Event.hasMany(Event, { as: 'child', foreignKey: 'parentId' })
Event.belongsTo(Event, { as: 'parent' })
SequelizeSlugify.slugifyModel(Event, { source: ['title'], overwrite: false })
},
close() {
if (db.sequelize) {
return db.sequelize.close()
}
},
connect(dbConf = config.db) {
dbConf.dialectOptions = { autoJsonMap: true }
log.debug(`Connecting to DB: ${JSON.stringify(dbConf)}`)
if (dbConf.dialect === 'sqlite') {
dbConf.retry = {
match: [
Sequelize.ConnectionError,
Sequelize.ConnectionTimedOutError,
Sequelize.TimeoutError,
/Deadlock/i,
/SQLITE_BUSY/],
max: 15
}
}
db.sequelize = new Sequelize(dbConf)
},
async isEmpty() {
try {
const users = await db.sequelize.query('SELECT * from users')
return !(users && users.length)
} catch (e) {
return true
}
},
async fixMariaDBJSON () {
// manually fix mariadb JSON wrong parse
if (db.sequelize.options.dialect === 'mariadb' && semver.lt('10.5.2', db.sequelize.options.databaseVersion)) {
try {
const ret = await db.sequelize.query('SHOW CREATE TABLE `settings`')
if (!ret[0][0]['Create Table'].toLowerCase().includes('json_valid')){
await db.sequelize.query('alter table settings modify `value` JSON')
await db.sequelize.query('alter table ap_users modify `object` JSON')
await db.sequelize.query('alter table events modify `recurrent` JSON')
await db.sequelize.query('alter table events modify `likes` JSON')
await db.sequelize.query('alter table events modify `boost` JSON')
await db.sequelize.query('alter table events modify `media` JSON')
await db.sequelize.query('alter table events modify `online_locations` JSON')
await db.sequelize.query('alter table filters modify `tags` JSON')
await db.sequelize.query('alter table filters modify `places` JSON')
await db.sequelize.query('alter table instances modify `data` JSON')
await db.sequelize.query('alter table notifications modify `filters` JSON')
await db.sequelize.query('alter table resources modify `data` JSON')
await db.sequelize.query('alter table users modify `settings` JSON')
await db.sequelize.query('alter table users modify `rsa` JSON')
log.info(`MariaDB JSON migrations done`)
} else {
log.debug('MariaDB JSON issue already fixed')
}
} catch (e) {
console.error(e)
}
}
},
async runMigrations() {
const logging = log.debug.bind(log) // config.status !== 'READY' ? false : log.debug.bind(log)
const umzug = new Umzug({
storage: 'sequelize',
storageOptions: { sequelize: db.sequelize },
logging,
migrations: {
wrap: fun => {
return () =>
fun(db.sequelize.queryInterface, Sequelize).catch(e => {
log.warn(e)
return false
})
},
path: path.resolve(__dirname, '..', '..', 'migrations')
}
})
return umzug.up()
},
initialize() {
if (config.status === 'CONFIGURED') {
try {
db.connect()
db.loadModels()
db.associates()
} catch (e) {
log.warn(` ⚠️ Cannot connect to db, check your configuration => ${e}`)
process.exit(1)
}
}
}
}
module.exports = db