1 | [![NodeJs](https://github.com/Belphemur/node-json-db/actions/workflows/nodejs.yml/badge.svg)](https://github.com/Belphemur/node-json-db/actions/workflows/nodejs.yml)[![codecov](https://codecov.io/gh/Belphemur/node-json-db/branch/master/graph/badge.svg?token=J3Ppt4UCbY)](https://codecov.io/gh/Belphemur/node-json-db)[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FBelphemur%2Fnode-json-db.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FBelphemur%2Fnode-json-db?ref=badge_shield)
|
2 |
|
3 | [![NPM](https://nodei.co/npm/node-json-db.png?downloads=true&stars=true)](https://nodei.co/npm/node-json-db/)
|
4 |
|
5 | > A simple "database" that use JSON file for Node.JS.
|
6 |
|
7 | ## Installation
|
8 | Add `node-json-db` to your existing Node.js project.
|
9 | ```bash
|
10 | yarn add node-json-db
|
11 | ```
|
12 |
|
13 | ## Documentation
|
14 | [Auto Generated](https://belphemur.github.io/node-json-db)
|
15 |
|
16 | ## Inner Working
|
17 |
|
18 | ### Data
|
19 | The module stores the data using JavaScript Object directly into a JSON file. You can easily traverse the data to reach
|
20 | directly the interesting property using the DataPath. The principle of DataPath is the same as XMLPath.
|
21 |
|
22 | ### Example
|
23 | ```javascript
|
24 | {
|
25 | test: {
|
26 | data1 : {
|
27 | array : ['test','array']
|
28 | },
|
29 | data2 : 5
|
30 | }
|
31 | }
|
32 | ```
|
33 | If you want to fetch the value of array, the DataPath is **/test/data1/array**
|
34 | To reach the value of data2 : **/test/data2**
|
35 | You can of course get also the full object **test** : **/test**
|
36 | Or even the root : **/**
|
37 | ## Usage
|
38 | See [test](https://github.com/Belphemur/node-json-db/tree/master/test) for more usage details.
|
39 |
|
40 |
|
41 | ```javascript
|
42 | import { JsonDB } from 'node-json-db';
|
43 | import { Config } from 'node-json-db/dist/lib/JsonDBConfig'
|
44 |
|
45 | // The first argument is the database filename. If no extension, '.json' is assumed and automatically added.
|
46 | // The second argument is used to tell the DB to save after each push
|
47 | // If you put false, you'll have to call the save() method.
|
48 | // The third argument is to ask JsonDB to save the database in an human readable format. (default false)
|
49 | // The last argument is the separator. By default it's slash (/)
|
50 | var db = new JsonDB(new Config("myDataBase", true, false, '/'));
|
51 |
|
52 | // Pushing the data into the database
|
53 | // With the wanted DataPath
|
54 | // By default the push will override the old value
|
55 | db.push("/test1","super test");
|
56 |
|
57 | // It also create automatically the hierarchy when pushing new data for a DataPath that doesn't exists
|
58 | db.push("/test2/my/test",5);
|
59 |
|
60 | // You can also push directly objects
|
61 | db.push("/test3", {test:"test", json: {test:["test"]}});
|
62 |
|
63 | // If you don't want to override the data but to merge them
|
64 | // The merge is recursive and work with Object and Array.
|
65 | db.push("/test3", {
|
66 | new:"cool",
|
67 | json: {
|
68 | important : 5
|
69 | }
|
70 | }, false);
|
71 |
|
72 | /*
|
73 | This give you this results :
|
74 | {
|
75 | "test":"test",
|
76 | "json":{
|
77 | "test":[
|
78 | "test"
|
79 | ],
|
80 | "important":5
|
81 | },
|
82 | "new":"cool"
|
83 | }
|
84 | */
|
85 |
|
86 | // You can't merge primitive.
|
87 | // If you do this:
|
88 | db.push("/test2/my/test/",10,false);
|
89 |
|
90 | // The data will be overriden
|
91 |
|
92 | // Get the data from the root
|
93 | var data = db.getData("/");
|
94 |
|
95 | // From a particular DataPath
|
96 | var data = db.getData("/test1");
|
97 |
|
98 | // If you try to get some data from a DataPath that doesn't exists
|
99 | // You'll get an Error
|
100 | try {
|
101 | var data = db.getData("/test1/test/dont/work");
|
102 | } catch(error) {
|
103 | // The error will tell you where the DataPath stopped. In this case test1
|
104 | // Since /test1/test does't exist.
|
105 | console.error(error);
|
106 | };
|
107 |
|
108 | // Deleting data
|
109 | db.delete("/test1");
|
110 |
|
111 | // Save the data (useful if you disable the saveOnPush)
|
112 | db.save();
|
113 |
|
114 | // In case you have a exterior change to the databse file and want to reload it
|
115 | // use this method
|
116 | db.reload();
|
117 |
|
118 | ```
|
119 |
|
120 | ### TypeScript Support
|
121 |
|
122 | #### v0.8.0
|
123 | As of v0.8.0, [TypeScript](https://www.typescriptlang.org) types are
|
124 | included in this package, so using `@types/node-json-db` is no longer required.
|
125 |
|
126 |
|
127 | #### v1.0.0
|
128 |
|
129 | JsonDB isn't exported as default any more. You'll need to change how you load the library.
|
130 |
|
131 | This change is done to follow the right way to import module.
|
132 | ```javascript
|
133 | import { JsonDB } from 'node-json-db';
|
134 | import { Config } from 'node-json-db/dist/lib/JsonDBConfig'
|
135 |
|
136 | const db = new JsonDB(new Config("myDataBase", true, false, '/'));
|
137 | ```
|
138 |
|
139 | #### Typing
|
140 | With TypeScript, you have access to a new method: getObject<T> that will take care of typing your return object.
|
141 | ```typescript
|
142 | import { JsonDB } from 'node-json-db';
|
143 | import { Config } from 'node-json-db/dist/lib/JsonDBConfig'
|
144 |
|
145 | const db = new JsonDB(new Config("myDataBase", true, false, '/'));
|
146 |
|
147 | interface FooBar {
|
148 | Hello: string
|
149 | World: number
|
150 | }
|
151 | const object = {Hello: "World", World: 5} as FooBar;
|
152 |
|
153 | db.push("/test", object);
|
154 |
|
155 | //Will be typed as FooBar in your IDE
|
156 | const result = db.getObject<FooBar>("/test");
|
157 | ```
|
158 |
|
159 |
|
160 | ### Array Support
|
161 | You can also access the information stored into arrays and manipulate them.
|
162 | ```typescript
|
163 | import { JsonDB } from 'node-json-db';
|
164 | import { Config } from 'node-json-db/dist/lib/JsonDBConfig'
|
165 |
|
166 | // The first argument is the database filename. If no extension, '.json' is assumed and automatically added.
|
167 | // The second argument is used to tell the DB to save after each push
|
168 | // If you put false, you'll have to call the save() method.
|
169 | // The third argument is to ask JsonDB to save the database in an human readable format. (default false)
|
170 | const db = new JsonDB(new Config("myDataBase", true, false, '/'));
|
171 |
|
172 | // This will create an array 'myarray' with the object '{obj:'test'}' at index 0
|
173 | db.push("/arraytest/myarray[0]", {
|
174 | obj:'test'
|
175 | }, true);
|
176 |
|
177 | // You can retrieve a property of an object included in an array
|
178 | // testString = 'test';
|
179 | var testString = db.getData("/arraytest/myarray[0]/obj");
|
180 |
|
181 | // Doing this will delete the object stored at the index 0 of the array.
|
182 | // Keep in mind this won't delete the array even if it's empty.
|
183 | db.delete("/arraytest/myarray[0]");
|
184 | ```
|
185 |
|
186 | #### Appending in Array
|
187 | ```javascript
|
188 | // You can also easily append new item to an existing array
|
189 | // This set the next index with {obj: 'test'}
|
190 | db.push("/arraytest/myarray[]", {
|
191 | obj:'test'
|
192 | }, true);
|
193 |
|
194 |
|
195 | // The append feature can be used in conjuction with properties
|
196 | // This will set the next index as an object {myTest: 'test'}
|
197 | db.push("/arraytest/myarray[]/myTest", 'test', true);
|
198 |
|
199 | ```
|
200 |
|
201 | #### Last Item in Array
|
202 | ```javascript
|
203 | // Add basic array
|
204 | db.push("/arraytest/lastItemArray", [1, 2, 3], true);
|
205 |
|
206 | // You can easily get the last item of the array with the index -1
|
207 | // This will return 3
|
208 | db.getData("/arraytest/lastItemArray[-1]");
|
209 |
|
210 |
|
211 | // You can delete the last item of an array with -1
|
212 | // This will remove the integer "3" from the array
|
213 | db.delete("/arraytest/lastItemArray[-1]");
|
214 |
|
215 | // This will return 2 since 3 just got removed
|
216 | db.getData("/arraytest/lastItemArray[-1]");
|
217 | ```
|
218 | #### Count for Array
|
219 | ```javascript
|
220 | //
|
221 | db.push("/arraytest/list", [{id: 65464646155, name: "test"}], true);
|
222 |
|
223 | // You can have the number of element, in this case = 1
|
224 | let numberOfElement = db.count("/arraytest/list");
|
225 | ```
|
226 |
|
227 | #### Get Index in Array
|
228 | ```javascript
|
229 |
|
230 | // You can have the current index of an object
|
231 | db.push("/arraytest/myarray", {id: 65464646155, name: "test"}, true);
|
232 | db.getIndex("/arraytest/myarray", 65464646155);
|
233 | // By default, the property is 'id'
|
234 | // You can add another property instead
|
235 | db.getIndex("/arraytest/myarray", "test", "name");
|
236 |
|
237 | // It's useful if you want to delete some object
|
238 | db.delete("/arraytest/myarray[" + db.getIndex("/arraytest/myarray", 65464646155) + "]");
|
239 | ```
|
240 | ### Exception/Error
|
241 | #### Type
|
242 |
|
243 | | Type | Explanation |
|
244 | | ------------- |:----------------------------------------------------------------:|
|
245 | | DataError | When the error is linked to the Data Given |
|
246 | | DatabaseError | Linked to a problem with the loading or saving of the Database. |
|
247 |
|
248 | #### Errors
|
249 |
|
250 | | Error | Type | Explanation |
|
251 | | ------------------------------------------------------|:-------------:|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
252 | |The Data Path can't be empty |DataError |The Database expect to minimum receive the root **separator** as DataPath. |
|
253 | |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* |
|
254 | |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). |
|
255 | |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. |
|
256 | |DataPath: /XXX. YYY is not an array. |DataError |When trying to access an object as an array. |
|
257 | |DataPath: /XXX. Can't find index INDEX in array YYY |DataError |When trying to access a non-existent index in the array. |
|
258 | |Only numerical values accepted for array index |DataError |An array can only use number for its indexes. For this use the normal object. |
|
259 | |The entry at the path (/XXX) needs to be either an Object or an Array |DataError |When using the find method, the rootPath need to point to an object or an array to search into it for the wanted value. |
|
260 | |Can't Load Database: XXXX |DatabaseError |JsonDB can't load the database for "err" reason. You can find the nested error in **error.inner** |
|
261 | |Can't save the database: XXX |DatabaseError |JsonDB can't save the database for "err" reason. You can find the nested error in **error.inner** |
|
262 | |DataBase not loaded. Can't write |DatabaseError |Since the database hasn't been loaded correctly, the module won't let you save the data to avoid erasing your database. |
|
263 |
|
264 | # Limitations
|
265 |
|
266 | ## Object with `separator` in key
|
267 | Object pushed with key containing the `separator` character won't be reachable. See [#75](https://github.com/Belphemur/node-json-db/issues/75).
|
268 |
|
269 | Please consider the `separator` as a reserved character by node-json-db.
|
270 |
|
271 |
|
272 | # Thanks
|
273 |
|
274 | [James Davis](https://github.com/davisjam) for helping to fix a regular expression vulnerable to [catastrophic backtracking](https://docs.microsoft.com/en-us/dotnet/standard/base-types/backtracking-in-regular-expressions).
|
275 |
|
276 |
|
277 | ## License
|
278 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FBelphemur%2Fnode-json-db.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FBelphemur%2Fnode-json-db?ref=badge_large)
|