UNPKG

7.62 kBMarkdownView Raw
1# Overview
2
3This project is inspired by [nedb](https://github.com/louischatriot/nedb).
4It aims to create a flexible database without any weird syntax or rules.
5Just few APIs will make everything work smoothly.
6JDB is an append-only, in-memory, non-block IO database.
7
8It uses json to decrease database file size, which means after all javascript commands are executed,
9they will become a single json object.
10
11For further infomation goto [How it works?](#user-content-how-it-works)
12
13[![Build Status](https://travis-ci.org/ysmood/jdb.svg)](https://travis-ci.org/ysmood/jdb) [![Build status](https://ci.appveyor.com/api/projects/status/ivsm326en792xsnj)](https://ci.appveyor.com/project/ysmood/jdb)
14
15# Features
16
17* Super fast ([see the benchmark](#user-content-benchmarks)).
18
19* Light weight. Core code is only about 200 lines.
20
21* Promise support.
22
23* Use full functioned javascript to operate your data, no steep learning curve.
24
25* Make debugging inside the data possible.
26
27* Support both standalone mode (server) and in-application mode (lib).
28
29
30# Quick start
31
32### Installation
33
34Install `jdb` first.
35
36 npm install jdb
37
38### Examples
39
40Here's the embedded mode example.
41
42```coffeescript
43
44jdb = require 'jdb'
45
46# The data to play with.
47some_data = {
48 "name": {
49 "first": "Yad"
50 "last": "Smood"
51 }
52 "fav_color": "blue"
53 "languages": [
54 {
55 "name": "Chinese"
56 "level": 10
57 }
58 {
59 "name": "English"
60 "level": 8
61 "preferred": true
62 }
63 {
64 "name": "Japenese"
65 "level": 6
66 }
67 ]
68 "height": 180
69 "weight": 68
70}
71
72# Init the db file before you start.
73jdb.init()
74.then ->
75
76 # Set data.
77 jdb.exec
78 data: some_data
79 command: (jdb, data) ->
80 jdb.doc.ys = data
81 jdb.save 'saved'
82 callback: (err, data) ->
83 console.log data # output >> saved
84
85 # Or simple way to save data.
86 jdb.exec some_data, (jdb, data) ->
87 jdb.doc.arr = data.languages.map (el) -> el.name
88 jdb.save()
89 .then ->
90 console.log 'saved'
91
92 # Don't do something like this!
93 wrong = ->
94 jdb.exec command: (jdb) ->
95 # Error: the scope here should not access the variable `some_data`.
96 jdb.doc.ys = some_data
97 jdb.save()
98
99 # Get the value. Much simpler.
100 console.log jdb.doc.ys.name # output >> [ "Yad", "Smood" ]
101
102```
103
104# Http server quick start
105
106To allow JDB to serve multiple clients, you can start it as a http server (standalone mode).
107
108Install `jdb` globally.
109
110 npm install -g jdb
111
112See help info.
113
114 jdb -h
115
116Interactive mode, you have two global api.
117You can manipulate the data via `doc`, and run `save()` to permanent your change.
118
119 jdb -i
120
121Start server at port 8081.
122
123 jdb -p 8081
124
125JDB action `exec` only accepts raw `json` http request (do not url-encode the body!). For example:
126
127 POST /exec HTTP/1.1
128 Host: 127.0.0.1:8081
129 Content-Length: 88
130
131 { "data": 10, "command": "function(jdb, data) { jdb.doc.a = 1; jdb.save(jdb.doc); }" }
132
133It will return json:
134
135 {"a":1}
136
137JDB action `compactDBFile` example:
138
139 GET /compactDBFile HTTP/1.1
140 Host: 127.0.0.1:8081
141
142It will return:
143
144 OK
145
146
147# How it works?
148
149It simply executes all your js code to manipulate a `doc` object, and append each
150js code to a file. Each time when you start up the JDB, it executes all the code in the file,
151and the last time's `doc` object will come back again in the memory.
152
153****************************************************************************
154
155# API
156
157The main api of class Jdb.
158
159## `constructor ([options])`
160
161* **options**
162
163 * **dbPath** _{Boolean}_
164
165 Where to save the database file. Default value is `jdb.db`.
166
167 * **compactDBFile** _{Boolean}_
168
169 Whether to compact db file before start up or not. Default true.
170
171 * **promise** _{Boolean}_
172
173 Whether to enable promise or not. Default true.
174
175 * **error** _{Function}_
176
177 The error handler when initializing database.
178
179## `doc`
180
181The main storage object. Readonly. Do not write its property directly.
182
183## `exec ([data], command, [callback])`
184## `exec (options)`
185
186A api and the only api to interact with the data in database.
187
188* **data** _{Object}_
189
190 `data` should be serializable object. It will be send with `command`, see the `command (jdb)` part.
191
192* **command (jdb)** _{Function}_
193
194 A function or corresponding source code.
195 The code in this function is in another scope (database file scope).
196 Do not share outer variable within it, see the wrong example in quick start part.
197
198 * **jdb** _{Object}_
199
200 An object from which you access the functions of the database. Here's the list of its members.
201
202 * **jdb.data** _{Object}_
203
204 The `data` object that is sent from the `exec (options)`.
205
206 * **jdb.doc** _{Object}_
207
208 The main storage object.
209
210 * **jdb.save ([data])** _{Function}_
211
212 When your data manipulation is done, call this method to permanent your change. It will automatically call the send for you.
213
214 * **data** _{Object}_
215
216 The same as the `data` of `jdb.send`.
217
218 * **jdb.send ([data])** _{Function}_
219
220 Send data to the `callback`.
221
222 * **data** _{Object}_
223
224 Type is `Object`. It should be serializable.
225
226 * **jdb.rollback()** _{Function}_
227
228 Call it when you want to rollback the change that you made.
229
230* **callback (err, data)** _{Function}_
231
232 This function will be invoked after the `save` or `send` is called.
233
234 * **err** _{Object}_
235
236 It can only catch sync errors, you should handle async errors by yourself.
237
238 * **data** _{Function}_
239
240 The data you send from `jdb.send(data)` or `jdb.save(data)`.
241
242
243## `compactDBFile ()`
244
245Returns a promise. Reduce the size of the database file. It will calculate all the commands and save the final `doc` object to the file and delete all the other commands.
246
247## `compactDBFileSync ()`
248
249The sync version of `compactDBFile (callback)`.
250
251****************************************************************************
252
253# Unit test
254
255To use `cake`, install [coffee-script](coffeescript.org) globally: `npm install -g coffee-script`.
256
257Unit test will test all the basic functions of JDB. Before your pull request, run it first.
258
259 cake test
260
261
262# Benchmarks
263
264To run the benchmark:
265
266 cake benchmark
267
268### JDB on Intel Core i7 2.3GHz SSD
269
270* insert x 15,562 ops/sec ±4.37% (62 runs sampled)
271* query x 665,237 ops/sec ±0.83% (95 runs sampled)
272
273### MongoDB on Intel Core i7 2.3GHz SSD
274
275**JDB is much faster than MongoDB**
276
277* insert x 3,744 ops/sec ±2.63% (76 runs sampled)
278* query x 2,416 ops/sec ±3.89% (70 runs sampled)
279
280### Redis on Intel Core i7 2.3GHz SSD
281
282**JDB's query performance is faster than Redis**
283
284* insert x 10,619 ops/sec ±2.33% (77 runs sampled)
285* query x 10,722 ops/sec ±2.27% (80 runs sampled)
286
287### JDB on Digitalocean VPS 1 CPU
288
289**Even on a much slower machine JDB is still much faster than MongoDB**
290
291* insert x 9,460 ops/sec ±3.34% (78 runs sampled)
292* query x 343,502 ops/sec ±2.57% (93 runs sampled)
293
294### JDB http server on Intel Core i7 2.3GHz SSD
295
296* exec x 65,912 ops/sec ±2.84% (72 runs sampled)
297
298Though for MongoDB and Redis, most of their CPU time is ate by their DB adapters, but I think
299for some small projects, such as personal blog, or a non-cluster application, the adapter issue
300should also be taken into consideration.
301
302# Road Map
303
304* More fault tolerance support. Such as file system error handling.
305
306* Maybe simple cluster support.
307
308# License
309
310### BSD
311
312May 2014, Yad Smood