# Leveldb-addon

Leveldb addon for Node.js, supports synchronous and asynchronous invocation, and supports event emitter

### FEATURES

* Support synchronization method call **Leveldb**, code logic more clear
* Also supports asynchronous method call **Leveldb** to make running more efficient
* Asynchronous calls use **Promise** to make the code clearer

## INSTALLATION

```shell
npm install leveldb-addon --save
```

## API

* [**new Leveldb([options])**](#new-ldb-options)

  #### Properties
    * [Leveldb.prototype.**location**]() *Reflects the string of  the database path*

    * [Leveldb.prototype.**isOpen**]() *Reflects the boolearn of the database is available*

    * [Leveldb.prototype.**stateCode**]() *Reflects the number of the databease status , whenever a database change changes*

  #### Methods

  * [Leveldb.prototype.**open**(location, [options])](#Leveldb-prototype-open-location-options)
  * [Leveldb.prototype.**close**()](#Leveldb-prototype-close)
  * [Leveldb.prototype.**put**( key, value ) ](#Leveldb-prototype-put-key-value-or-Leveldb-prototype-put-json)  **or**   [Ldb.prototype.**put**( json )](#Leveldb-prototype-put-key-value-or-Leveldb-prototype-put-json) *return Boolean when execution succeeds return true*
  * [Ldb.prototype.**del**( key )](#Leveldb-prototype-del-key-or-Leveldb-prototype-del-keys)  **or**   [Ldb.prototype.**del**( keys )](#Leveldb-prototype-del-key-or-Leveldb-prototype-del-keys) *return Boolean when execution succeeds return true*
  * [Ldb.prototype.**get**( key )](#Leveldb-prototype-get-key-or-Leveldb-prototype-get-keys)   **or**   [Ldb.prototype.**get**( keys )](#Leveldb-prototype-get-key-or-Leveldb-prototype-get-keys) *return [values]*
  * [Ldb.prototype.**forEach**( callback, [iteratorOptions] )](#Leveldb-prototype-forEach-callback-iterator_options)
  * [Ldb.prototype.**asyncPut**()](#Leveldb-prototype-asyncPut)  *return Promise object*
  * [Ldb.prototype.**asyncDel**()](#Leveldb-prototype-asyncDel) *return Promise object*
  * [Ldb.prototype.**asyncGet**()](#Leveldb-prototype-asyncGet) *return Promise object*
  * [Ldb.prototype.**asyncForEach**( callback, [iteratorOptions] )](#Leveldb-prototype-asyncForEach-callback-iterator_options)
  * [Ldb.prototype.**getIterator**([iteratorOptions])](#Leveldb-prototype-getIterator-iterator_options) *return Leveldb.Iterator*
  * [Ldb.prototype.**addListener**( type, callback, once )](#Leveldb-prototype-addtListener-type-callback-once)
  * [Ldb.prototype.**removeListener**( type, callback )](#Leveldb-prototype-removeListener-type-callback)
  * [Ldb.prototype.**match**(prefix, offset) ]()



* [Ldb.**open(location, options)**](#Leveldb-open-location-options) *return Leveldb instance*
* [Ldb.**destroy(location)**](#Leveldb-destroy-location)
* [Ldb.**repair(location)**](#Leveldb-repair-location)
* [Ldb.**isExist(location)**]()
* [**IteratorOptions**](#Iterator_Options)

  * start
  * end
  * prefix
  * reverse
  * snapshot: default true
* [**Leveldb.Iterator**](#Leveldb-prototype-getIterator-iterator_options)
  * Iterator.**read**() *If the iterator is valid to return itself, the invalid returns undefined*
  * Iterator.**key**
  * Iterator.**value** 
  * Iterator.**isEnd**
  * [iterator.**break**()](#Leveldb-prototype-forEach-callback-iterator_options) *release iterator*

### new Leveldb([options])

```javascript
const Leveldb = require('leveldb-addon');
let options = {
  // base settings
  "location" : './test.db',
  "writeSync" : false,
  "readFillCache" : true,
  
  // Levedb default settings
  "createIfMissing" : true,
  "errorIfExists" : false,
  "compression" : true,
  "writeBufferSize" : 4194304,
  "blockSize" : 4096,
  "maxOpenFiles" : 1000,
  "blockRestartInterval" :16,
  "maxFileSize" : 2097152,
  "block_cache" : 8388608,
  "filterPolicy" : 10,
  
  // EventListener
  "onReady" : ()=>{},
  "onCreate" : ()=>{},
  "onChanged" : ()=> {},
  "onError" : ()=>{},
  "onClosed" : ()=>{}
};

let ldb = new Leveldb(options);
```

For information about setting items, see the [Leveldb documentation](https://github.com/google/leveldb/blob/master/doc/index.md)

### Leveldb.prototype.open(location, [options])

```javascript
ldb.open('./test.db', {});
```

### Leveldb.prototype.close()

```javascript
ldb.close();
```

### Leveldb.prototype.put( key, value ) or Leveldb.prototype.put( json )

```javascript
if (ldb.put("abc", 123)) {
    console.log('ok');
}
ldb.put({
  "abc": null, // delete abc
  "def": 456,
  "ghi": [7, 8, 9]
});
```

### Leveldb.prototype.del( key ) or Leveldb.prototype.del( keys )

```javascript
ldb.del("abc");
ldb.del(["abc", "def"]);
```

### Leveldb.prototype.get( key ) or Leveldb.prototype.get( keys )

```javascript
let value = ldb.get("abc");
let value_json = ldb.get(["abc", "def", "ghi"]);
```

### Leveldb.prototype.forEach( callback, [iteratorOptions] )

```javascript
ldb.put({"a1": 1, "a2": 2, "b1": 3, "b2": 4, "c1": 5, "c2" : 6, "d.1": 7, "d.2": 8});

ldb.forEach((iter)=>{
  	if(!/b/.test(iter.key)){
        iter.break();
    }else{
       	console.log(iter.key, iter.value); 
    }
});

let callback = (iter) => {console.log(iter.key, ":", iter.value);}

ldb.forEach(callback, {start: "b"});
// print: b1:3, b2:4, c1:5, c2:6, d.1:7, d.2:8

ldb.forEach(callback, {start: "b", end:"c"});
// print: b1:3, b2:4

ldb.forEach(callback, {start: "c", end:"b", reverse:true});
// print: c1:5, c2:6

ldb.forEach(callback, {prefix: "d."});
// print: d.1:7, d.2:8

```

### Leveldb.prototype.asyncPut()

```javascript
ldb.asyncPut("abc", 123).then(()=>{
    ...
}).catch((error)=>{
  	console.log(error);  
});
```

```javascript
(async ()=>{
  await ldb.asyncPut("abc", 1234);
})()
```

### Leveldb.prototype.asyncDel()

```javascript
ldb.asyncDel("abc").then(()=>{
    ...
});
```

```javascript
(async ()=>{
  await ldb.asyncDel("abc")
})()
```

### Leveldb.prototype.asyncGet()

```javascript
ldb.asyncGet("abc", 123).then((value)=>{
    console.log(value)
});
```

```javascript
(async ()=>{
  let value = await ldb.asyncGet("abc");
})()
```

### Leveldb.prototype.asyncForEach( callback, [iterator_options] )

```javascript
ldb.forEach((iter)=>{
    console.log(iter.key, iter.value);
});
```

### Leveldb.prototype.getIterator([iterator_options])

```javascript
let iter = ldb.getIterator({start: "b"});
while(iter.read()){
    console.log(iter.key, iter.value);
}
```

### Leveldb.prototype.addListener( type, callback, once )

* type :
  * `ready` Trigger event after database open
  * `create` Triggers an event when the database is created
  * `changed`  Triggers an event when the put or del operation is executed
  * `error` Triggers an event when an error occurs
  * `closed` Trigger event after database shutdown

```javascript
ldb.addEventListener("changed", (info)=>{
  	console.log( info.from, info.key );
  	// print: put "abc"
});

ldb.put("abc", 123);
```

### Leveldb.prototype.removeListener( type, callback )

```javascript
ldb.removeEventListener("ready", func);
```

### Leveldb.open(location, options)

```javascript
let ldb = Leveldb.open("./test.db")
```

### Leveldb.destroy(location)

```javascript
Leveldb.destroy("./test.db")
```

### Leveldb.repair(location)

```javascript
Leveldb.repair("./test.db")
```

### Iterator Options

```javascript
let options = {
    "start":"a",
  	"end": "b",
  	"prefix": "c",
  	"reverse": true,
  	"limit":
}
```

