Skip to content

Commit

Permalink
feat(Config): Add Config file to setup the Database
Browse files Browse the repository at this point in the history
Also add possibility to set own separator instead of the default one.
  • Loading branch information
Belphemur committed Mar 15, 2019
1 parent 52df16b commit 3915aee
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 37 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ db.getData("/arraytest/lastItemArray[-1]");
| Error | Type | Explanation |
| ------------------------------------------------------|:-------------:|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|The Data Path can't be empty |DataError |The Database expect to minimum receive the root **/** as DataPath. |
|The Data Path can't be empty |DataError |The Database expect to minimum receive the root **separator** as DataPath. |
|Can't find dataPath: /XXX. Stopped at YYY |DataError |When the full hierarchy of the DataPath given is not present in the Database. It tells you until where it's valid. This error can happen when using *getData* and *delete* |
|Can't merge another type of data with an Array |DataError |If you chose to not override the data (merging) when pushing and the new data is an array but the current data isn't an array (an Object by example). |
|Can't merge an Array with an Object |DataError |Same idea as the previous message. You have an array as current data and ask to merge it with an Object. |
Expand All @@ -211,10 +211,10 @@ db.getData("/arraytest/lastItemArray[-1]");
# Limitations
## Object with '/' in key
Object pushed with key containing the slash (/) character won't be reachable. See [#75](https://github.com/Belphemur/node-json-db/issues/75).
## Object with `seperator` in key
Object pushed with key containing the `seperator` character won't be reachable. See [#75](https://github.com/Belphemur/node-json-db/issues/75).
Please consider the slash (/) as a reserved character by node-json-db.
Please consider the `seperator` as a reserved character by node-json-db.
# Thanks
Expand Down
66 changes: 33 additions & 33 deletions src/JsonDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,36 @@ import * as mkdirp from "mkdirp"
import {DatabaseError, DataError} from "./lib/Errors"
import {DBParentData} from "./lib/DBParentData"
import {ArrayInfo} from "./lib/ArrayInfo"
import { Config, JsonDBConfig } from "./lib/JsonDBConfig"

type DataPath = Array<string>


export type FindCallback = (entry: any, index: number | string) => boolean

export default class JsonDB {
readonly filename: string
private loaded: boolean = false
private data: KeyValue = {}
readonly saveOnPush: boolean = true
readonly humanReadable: boolean


/**
* JSONDB Constructor
* @param filename where to save the "DB"
* @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
*/
constructor(filename: string, saveOnPush: boolean = true, humanReadable: boolean = false) {
this.filename = filename

if (!filename.endsWith(".json")) {
this.filename += ".json"
private readonly config : JsonDBConfig


/**
* JSONDB Constructor
* @param filename where to save the "DB". Can also be used to give the whole configuration
* @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
*/
constructor(filename: string | Config, saveOnPush: boolean = true, humanReadable: boolean = false, separator: string = '/') {

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

this.saveOnPush = saveOnPush
this.humanReadable = humanReadable

if (!FS.existsSync(this.filename)) {
const dirname = path.dirname(this.filename)
if (!FS.existsSync(this.config.filename)) {
const dirname = path.dirname(this.config.filename)
mkdirp.sync(dirname)
this.save(true)
this.loaded = true
Expand All @@ -51,18 +49,20 @@ export default class JsonDB {
if (dataPath === undefined || !dataPath.trim()) {
throw new DataError("The Data Path can't be empty", 6)
}
if (dataPath == "/") {
if (dataPath == this.config.separator) {
return []
}
dataPath = removeTrailingSlash(dataPath)
const path = dataPath.split("/")
const path = dataPath.split(this.config.separator)
path.shift()
return path
}

private retrieveData(dataPath: DataPath, create: boolean = false) {
this.load()

const thisDb = this

const recursiveProcessDataPath = (data: any, index: number): any => {

let property = dataPath[index]
Expand All @@ -82,7 +82,7 @@ export default class JsonDB {
}
data = data[property]
} else {
throw new DataError("Can't find dataPath: /" + dataPath.join("/") + ". Stopped at " + property, 5)
throw new DataError(`Can't find dataPath: ${thisDb.config.separator}${dataPath.join(thisDb.config.separator)}. Stopped at ${property}`, 5)
}
}

Expand All @@ -91,7 +91,7 @@ export default class JsonDB {
property = arrayInfo.property
findData(true)
if (!Array.isArray(data)) {
throw new DataError("DataPath: /" + dataPath.join("/") + ". " + property + " is not an array.", 11)
throw new DataError(`DataPath: ${thisDb.config.separator}${dataPath.join(thisDb.config.separator)}. ${property} is not an array.`, 11)
}
const arrayIndex = arrayInfo.getIndex(data, true)
if (!arrayInfo.append && data.hasOwnProperty(arrayIndex)) {
Expand All @@ -106,7 +106,7 @@ export default class JsonDB {
data = data[arrayIndex]
}
} else {
throw new DataError("DataPath: /" + dataPath.join("/") + ". Can't find index " + arrayInfo.index + " in array " + property, 10)
throw new DataError(`DataPath: ${thisDb.config.separator}${dataPath.join(thisDb.config.separator)}. . Can't find index ${arrayInfo.index} in array ${property}`, 10)
}
} else {
findData()
Expand Down Expand Up @@ -237,7 +237,7 @@ export default class JsonDB {
}
dbData.setData(toSet)

if (this.saveOnPush) {
if (this.config.saveOnPush) {
this.save()
}
}
Expand All @@ -253,7 +253,7 @@ export default class JsonDB {
}
dbData.delete()

if (this.saveOnPush) {
if (this.config.saveOnPush) {
this.save()
}
}
Expand Down Expand Up @@ -284,7 +284,7 @@ export default class JsonDB {
return
}
try {
const data = FS.readFileSync(this.filename, 'utf8')
const data = FS.readFileSync(this.config.filename, 'utf8')
this.data = JSON.parse(data)
this.loaded = true
} catch (err) {
Expand All @@ -303,17 +303,17 @@ export default class JsonDB {
if (!force && !this.loaded) {
throw new DatabaseError("DataBase not loaded. Can't write", 7)
}
var data = ""
let data = ""
try {
if (this.humanReadable) {
if (this.config.humanReadable) {
data = JSON.stringify(this.data, null, 4)
}
else {
data = JSON.stringify(this.data)
}
FS.writeFileSync(this.filename, data, 'utf8')
FS.writeFileSync(this.config.filename, data, 'utf8')
} catch (err) {
var error = new DatabaseError("Can't save the database", 2, err)
const error = new DatabaseError("Can't save the database", 2, err)
throw error
}
}
Expand Down
26 changes: 26 additions & 0 deletions src/lib/JsonDBConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export interface JsonDBConfig {
filename: string,
saveOnPush: boolean,
humanReadable: boolean,
separator: string
}

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


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

if (!filename.endsWith(".json")) {
this.filename += ".json"
}

this.humanReadable = humanReadable
this.saveOnPush = saveOnPush
this.separator = separator
}
}

0 comments on commit 3915aee

Please sign in to comment.