Skip to content

Commit

Permalink
feat(FSYNC): Optional fsync when saving the database
Browse files Browse the repository at this point in the history
Merge pull request #372 from drproktor/optional-fsync

You can configure it in the settings.
  • Loading branch information
Belphemur committed Mar 11, 2022
2 parents c33211e + c8fa0f7 commit d1c67fd
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
24 changes: 21 additions & 3 deletions src/JsonDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ export class JsonDB {
* @param saveOnPush save the database at each push command into the json file
* @param humanReadable the JSON file will be readable easily by a human
* @param separator what to use as separator
* @param syncOnSave force sync of the database (call fsync())
*/
constructor(filename: string | Config, saveOnPush: boolean = true, humanReadable: boolean = false, separator: string = '/') {
constructor(filename: string | Config, saveOnPush: boolean = true, humanReadable: boolean = false, separator: string = '/', syncOnSave: boolean = false) {

if(filename instanceof Config) {
this.config = filename
} else {
this.config = new Config(filename, saveOnPush, humanReadable, separator)
this.config = new Config(filename, saveOnPush, humanReadable, separator, syncOnSave)
}

if (!FS.existsSync(this.config.filename)) {
Expand Down Expand Up @@ -363,7 +364,24 @@ export class JsonDB {
else {
data = JSON.stringify(this.data)
}
FS.writeFileSync(this.config.filename, data, 'utf8')
if(this.config.syncOnSave) {
const buffer = Buffer.from(String(data), 'utf8')
const fd_tmp = FS.openSync(this.config.filename, 'w')
let offset = 0
let length = buffer.byteLength
try {
while (length > 0) {
const written = FS.writeSync(fd_tmp, buffer, offset, length)
offset += written
length -= written
}
} finally {
FS.fsyncSync(fd_tmp)
FS.closeSync(fd_tmp)
}
} else {
FS.writeFileSync(this.config.filename, data, 'utf8')
}
} catch (err) {
const error = new DatabaseError("Can't save the database", 2, err)
throw error
Expand Down
8 changes: 5 additions & 3 deletions src/lib/JsonDBConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ export interface JsonDBConfig {
filename: string,
saveOnPush: boolean,
humanReadable: boolean,
separator: string
separator: string,
syncOnSave: boolean
}

export class Config implements JsonDBConfig {
filename: string
humanReadable: boolean
saveOnPush: boolean
separator: string
syncOnSave: boolean


constructor(filename: string, saveOnPush: boolean = true, humanReadable: boolean = false, separator: string = '/') {
constructor(filename: string, saveOnPush: boolean = true, humanReadable: boolean = false, separator: string = '/', syncOnSave: boolean = false) {
this.filename = filename

// Force json if no extension
Expand All @@ -25,5 +26,6 @@ export class Config implements JsonDBConfig {
this.humanReadable = humanReadable
this.saveOnPush = saveOnPush
this.separator = separator
this.syncOnSave = syncOnSave
}
}
10 changes: 10 additions & 0 deletions test/02-jsondb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const testFile3 = "test/test_file3"
const testFile4 = "test/array_file"
const testFile5 = "test/test_file_empty"
const testFile6 = "test/test_delete"
const testFile7 = "test/test_sync"


interface Test {
Expand Down Expand Up @@ -56,6 +57,14 @@ describe('JsonDB', () => {

})

test('should create JSON file with sync', done => {
const jsondb = new JsonDB(testFile7, true, false, '/', true)
fs.access(testFile7+ ".json", fs.constants.R_OK, function (err) {
expect(err).toBeNull()
done()
})
})

test('should set en empty root', () => {
expect(JSON.stringify(db.getData("/"))).toEqual("{}")
})
Expand Down Expand Up @@ -652,6 +661,7 @@ describe('JsonDB', () => {
fs.unlinkSync(testFile4 + ".json")
fs.unlinkSync(testFile5 + ".json")
fs.unlinkSync(testFile6 + ".json")
fs.unlinkSync(testFile7 + ".json")
fs.rmdirSync("test/dirCreation")
})
})
Expand Down

0 comments on commit d1c67fd

Please sign in to comment.