json-v2
Version:
Used to store data in JSON files without corruption.
315 lines (243 loc) • 8.36 kB
JavaScript
let fs = require('fs')
let QueueSystem = require('pop-queue-system')
let CachedFiles = {}
function isEquivalent(a, b) {
// Create arrays of property names
var aProps = Object.getOwnPropertyNames(a);
var bProps = Object.getOwnPropertyNames(b);
// If number of properties is different,
// objects are not equivalent
if (aProps.length != bProps.length) {
return false;
}
for (var i = 0; i < aProps.length; i++) {
var propName = aProps[i];
// If values of same property are not equal,
// objects are not equivalent
if (a[propName] !== b[propName]) {
return false;
}
}
// If we made it this far, objects
// are considered equivalent
return true;
}
class FileSystem {
constructor(filePath) {
let file = null
let error = false
try {
file = fs.readFileSync(filePath)
} catch (err) {
error = err
}
if (error) throw new Error("Please provide a valid path.")
try {
file = JSON.parse(file)
} catch (err) {
error = err
}
if (error) throw new Error("Please provide a path to a valid JSON file.")
this._Queue = new QueueSystem.Queue()
this._FilePath = filePath
CachedFiles[filePath] = this
}
getObject(file, find) {
let Class = this
return new Promise(async function (resolve, reject) {
if (find != Object(find)) return reject("Please provide a valid object in the first argument.");
let FoundObject = null
let SortQueue = new QueueSystem.Queue()
let Sorted = 0
let Task = await SortQueue.wait()
file.forEach(object => {
Sorted = Sorted + 1
if (isEquivalent(object, find)) {
FoundObject = object
}
if (Sorted == file.length) {
SortQueue.finishWait(Task)
}
})
let Task2 = await SortQueue.wait()
SortQueue.finishWait(Task2)
resolve(FoundObject)
})
}
overwriteFile(newData) {
let Class = this
let NewPromise = new Promise(function (resolve, reject) {
Class._Queue.wait().then(function(TaskNumber) {
fs.writeFile(Class._FilePath, JSON.stringify(newData, null, " "), function(err) {
if (err) {
reject(err)
Class._Queue.finishWait(TaskNumber)
} else {
resolve(newData)
Class._Queue.finishWait(TaskNumber)
}
})
})
})
return NewPromise
}
getFile(finishWait) {
let Class = this
let NewPromise = new Promise(function (resolve, reject) {
Class._Queue.wait().then(function(TaskNumber) {
let file = null
let error = false
try {
file = fs.readFileSync(Class._FilePath)
} catch (err) {
error = err
}
if (error) {
reject("Please provide a valid path.")
}
try {
file = JSON.parse(file)
} catch (err) {
error = err
}
if (!finishWait) {
Class._Queue.finishWait(TaskNumber)
} else {
Class._TaskNumber = TaskNumber
}
if (error) {
reject("Please provide a path to a valid JSON file.")
} else {
resolve(file)
}
})
})
return NewPromise
}
removeObject(find) {
let Class = this
let NewPromise = new Promise(function (resolve, reject) {
if (find != Object(find)) return reject("Please provide a valid object in the first argument.");
Class.getFile(true).then(async file => {
let FoundObject2 = null
let SortQueue = new QueueSystem.Queue()
let Sorted = 0
let FoundObject2Index = -1
let Task = await SortQueue.wait()
file.forEach(object => {
Sorted = Sorted + 1
if (find == Object(find) && object[Object.keys(find)[0]] == Object.values(find)[0]) {
FoundObject2 = object
FoundObject2Index = Sorted - 1
}
if (Sorted == file.length) {
SortQueue.finishWait(Task)
}
})
let Task2 = await SortQueue.wait()
SortQueue.finishWait(Task2)
if (!FoundObject2) {
reject("There is no object found in the JSON with the first key and value in the 'find' table.")
Class._Queue.finishWait(Class._TaskNumber)
return
}
//let FoundObject = await Class.getObject(file, FoundObject2)
let FoundObject = FoundObject2Index
if (FoundObject) {
file.splice(FoundObject, 1)
fs.writeFile(Class._FilePath, JSON.stringify(file, null, " "), function(err) {
if (err) {
reject(err)
Class._Queue.finishWait(Class._TaskNumber)
} else {
resolve()
Class._Queue.finishWait(Class._TaskNumber)
}
})
} else {
reject("There is no object found in the JSON matching.")
Class._Queue.finishWait(Class._TaskNumber)
}
}).catch(error => {
reject(error)
Class._Queue.finishWait(Class._TaskNumber)
})
})
return NewPromise
}
changeProperty(find, replace) {
let Class = this
let NewPromise = new Promise(function (resolve, reject) {
if (find != Object(find) || replace != Object(replace)) return reject("Please provide a valid object in the first and second arguments.");
Class.getFile(true).then(async file => {
let FoundObject = null
let SortQueue = new QueueSystem.Queue()
let Sorted = 0
let Task = await SortQueue.wait()
file.forEach(object => {
Sorted = Sorted + 1
if (find == Object(find) && object[Object.keys(find)[0]] == Object.values(find)[0]) {
FoundObject = object
let index = -1
Object.keys(replace).forEach(value => {
index = index + 1
object[value] = Object.values(replace)[index]
})
}
if (Sorted == file.length) {
SortQueue.finishWait(Task)
}
})
let Task2 = await SortQueue.wait()
SortQueue.finishWait(Task2)
if (FoundObject) {
fs.writeFile(Class._FilePath, JSON.stringify(file, null, " "), function(err) {
if (err) {
reject(err)
Class._Queue.finishWait(Class._TaskNumber)
} else {
resolve(FoundObject)
Class._Queue.finishWait(Class._TaskNumber)
}
})
} else {
reject("There is no object found in the JSON with the first key and value in the 'find' table.")
Class._Queue.finishWait(Class._TaskNumber)
}
}).catch(error => {
reject(error)
Class._Queue.finishWait(Class._TaskNumber)
})
})
return NewPromise
}
push(value) {
let Class = this
let NewPromise = new Promise(function (resolve, reject) {
Class.getFile(true).then(async file => {
file.push(value)
fs.writeFile(Class._FilePath, JSON.stringify(file, null, " "), function(err) {
if (err) {
reject(err)
Class._Queue.finishWait(Class._TaskNumber)
} else {
resolve(file)
Class._Queue.finishWait(Class._TaskNumber)
}
})
}).catch(function (e) {
reject(e)
Class._Queue.finishWait(Class._TaskNumber)
})
})
return NewPromise;
}
}
module.exports = function (a) {
if (CachedFiles[a]) {
return CachedFiles[a]
} else {
CachedFiles[a] = new FileSystem(a)
return CachedFiles[a]
}
}