Added alt stricter file name collision checks

This commit is contained in:
Bobby Wibowo 2020-09-27 05:18:42 +07:00
parent b7399d2d8d
commit ea15b145b1
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
2 changed files with 40 additions and 1 deletions

View File

@ -415,6 +415,20 @@ module.exports = {
*/
cacheFileIdentifiers: true,
/*
An alternative to caching file identifiers.
Basically the service will instead query the database for stricter collision checks.
Right off the bat this has the disadvantage of adding one or more SQL queries on every
new uploads, but it has the advantage of not having to pre-cache anything.
Essentially this reduces the service's startup time and memory usage, but slows down new uploads.
As this is an alternative, you need to disable cacheFileIdentifiers to use this.
You'll have to figure out which method suits your use case best.
*/
queryDbForFileCollisions: true,
/*
The length of the randomly generated identifier for albums.
*/

View File

@ -13,7 +13,9 @@ const config = require('./../config')
const logger = require('./../logger')
const db = require('knex')(config.database)
const self = {}
const self = {
onHold: new Set()
}
const fileIdentifierLengthFallback = 32
const fileIdentifierLengthChangeable = !config.uploads.fileIdentifierLength.force &&
@ -191,6 +193,22 @@ self.getUniqueRandomName = async (length, extension) => {
}
utils.idSet.add(identifier)
// logger.log(`Added ${identifier} to identifiers cache`)
} else if (config.uploads.queryDbForFileCollisions) {
if (self.onHold.has(identifier))
continue
// Put token on-hold (wait for it to be inserted to DB)
self.onHold.add(identifier)
const file = await db.table('files')
.where('name', 'like', 'identifier.%')
.select('id')
.first()
if (file) {
self.onHold.delete(identifier)
logger.log(`Identifier ${identifier} is already in use (${i + 1}/${utils.idMaxTries}).`)
continue
}
} else {
try {
await paths.access(path.join(paths.uploads, name))
@ -721,6 +739,13 @@ self.storeFilesToDb = async (req, res, user, infoMap) => {
await db.table('files').insert(files)
utils.invalidateStatsCache('uploads')
if (config.uploads.queryDbForFileCollisions)
for (const file of files) {
const extname = utils.extname(file.name)
const identifier = file.name.slice(0, -(extname.length))
self.onHold.delete(identifier)
}
// Update albums' timestamp
if (authorizedIds.length) {
await db.table('albums')