Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

abstract-nosql

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

abstract-nosql

An abstract prototype for nosql database(LevelDOWN API)

  • 1.0.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
6
decreased by-90.32%
Maintainers
1
Weekly downloads
 
Created
Source

Abstract NoSQL Database Build Status

NPM NPM

Abstract-nosql package is modified from abstract-leveldown to enhance the synchronous methods supports for development a node nosql database quickly and using easily.

abstract-nosql Interface is neutral. There is no bias neither synchronous bias nor asynchronous bias. So that more people choose according to their own manner. For myself, I am not very concerned about the performance of javascript, I am more concerned about the efficiency of its development, as well as through functional programming (functions, closures such a simple concept) extend out of the rich and wonderful world. I still can not help but to think about performance issues. Asynchronous itself produces a small gap, because javascript reason this gap is magnified.

just saying that the asynchronous and synchronous consideration, if a function is only 1% of the opportunity to visit the IO, most of the time (99%) are in memory access. I want to different considerations, have different choices. And this decision is unlikely that done by the interface instead.

Synchronous operation converts into asynchronous operation is easy, and almost no performance loss, in turn, may not. Conversion are many ways, setImmediate is not the best, but it is the simplest one. ES6 generator or node-fibers could be a better way. the coroutine/fiber is lighter and more efficient than thread.

The setImmediate package could be extended to use different implementation(setImmediate, nextTick, ES6 generator, node-fiber) in different environment. So the simulated asynchronous uses this way, if you do not implement the asynchronous methods.

About LevelDOWN

An abstract prototype matching the LevelDOWN API. Useful for extending LevelUP functionality by providing a replacement to LevelDOWN.

As of version 0.7, LevelUP allows you to pass a 'db' option when you create a new instance. This will override the default LevelDOWN store with a LevelDOWN API compatible object.

Abstract LevelDOWN provides a simple, operational noop base prototype that's ready for extending. By default, all operations have sensible "noops" (operations that essentially do nothing). For example, simple operations such as .open(callback) and .close(callback) will simply invoke the callback (on a next tick). More complex operations perform sensible actions, for example: .get(key, callback) will always return a 'NotFound' Error on the callback.

You add functionality by implementing the underscore versions of the operations. For example, to implement a put() operation you add a _put() method to your object. Each of these underscore methods override the default noop operations and are always provided with consistent arguments, regardless of what is passed in by the client.

Additionally, all methods provide argument checking and sensible defaults for optional arguments. All bad-argument errors are compatible with LevelDOWN (they pass the LevelDOWN method arguments tests). For example, if you call .open() without a callback argument you'll get an Error('open() requires a callback argument'). Where optional arguments are involved, your underscore methods will receive sensible defaults. A .get(key, callback) will pass through to a ._get(key, options, callback) where the options argument is an empty object.

Changes

  • DB constructor allows no location.
  • Add synchronous methods supports.
    • Add the synchronous methods support now. You can implement the synchronous methods only.
    • The asynchronous methods will be simulated via these synchronous methods. If you wanna
    • support the asynchronous methods only, just do not implement these synchronous methods.
    • But if you wanna support the synchronous only, you should override the asynchronous methods to disable it.

Example

A simplistic in-memory LevelDOWN replacement

use sync methods:

var util = require('util')
  , AbstractLevelDOWN = require('./').AbstractLevelDOWN

// constructor, passes through the 'location' argument to the AbstractLevelDOWN constructor
function FakeLevelDOWN (location) {
  AbstractLevelDOWN.call(this, location)
}

// our new prototype inherits from AbstractLevelDOWN
util.inherits(FakeLevelDOWN, AbstractLevelDOWN)

// implement some methods

FakeLevelDOWN.prototype._openSync = function (options) {
  this._store = {}
  return true
}

FakeLevelDOWN.prototype._putSync = function (key, value, options) {
  key = '_' + key // safety, to avoid key='__proto__'-type skullduggery 
  this._store[key] = value
  return true
}

FakeLevelDOWN.prototype._get = function (key, options) {
  var value = this._store['_' + key]
  if (value === undefined) {
    // 'NotFound' error, consistent with LevelDOWN API
    throw new Error('NotFound')
  }
  return value
}

FakeLevelDOWN.prototype._del = function (key, options) {
  delete this._store['_' + key]
  return true
}

// now use it in LevelUP

var levelup = require('levelup')

var db = levelup('/who/cares/', {
  // the 'db' option replaces LevelDOWN
  db: function (location) { return new FakeLevelDOWN(location) }
})

//async:
db.put('foo', 'bar', function (err) {
  if (err) throw err
  db.get('foo', function (err, value) {
    if (err) throw err
    console.log('Got foo =', value)
  })
})

//sync:
db.put('foo', 'bar')
console.log(db.get('foo'))

use async methods(no sync supports):

var util = require('util')
  , AbstractLevelDOWN = require('./').AbstractLevelDOWN

// constructor, passes through the 'location' argument to the AbstractLevelDOWN constructor
function FakeLevelDOWN (location) {
  AbstractLevelDOWN.call(this, location)
}

// our new prototype inherits from AbstractLevelDOWN
util.inherits(FakeLevelDOWN, AbstractLevelDOWN)

// implement some methods

FakeLevelDOWN.prototype._open = function (options, callback) {
  // initialise a memory storage object
  this._store = {}
  // optional use of nextTick to be a nice async citizen
  process.nextTick(function () { callback(null, this) }.bind(this))
}

FakeLevelDOWN.prototype._put = function (key, value, options, callback) {
  key = '_' + key // safety, to avoid key='__proto__'-type skullduggery 
  this._store[key] = value
  process.nextTick(callback)
}

FakeLevelDOWN.prototype._get = function (key, options, callback) {
  var value = this._store['_' + key]
  if (value === undefined) {
    // 'NotFound' error, consistent with LevelDOWN API
    return process.nextTick(function () { callback(new Error('NotFound')) })
  }
  process.nextTick(function () {
    callback(null, value)
  })
}

FakeLevelDOWN.prototype._del = function (key, options, callback) {
  delete this._store['_' + key]
  process.nextTick(callback)
}

// now use it in LevelUP

var levelup = require('levelup')

var db = levelup('/who/cares/', {
  // the 'db' option replaces LevelDOWN
  db: function (location) { return new FakeLevelDOWN(location) }
})

db.put('foo', 'bar', function (err) {
  if (err) throw err
  db.get('foo', function (err, value) {
    if (err) throw err
    console.log('Got foo =', value)
  })
})

See MemDOWN if you are looking for a complete in-memory replacement for LevelDOWN.

Extensible API

Remember that each of these methods, if you implement them, will receive exactly the number and order of arguments described. Optional arguments will be converted to sensible defaults.

AbstractLevelDOWN(location)

Sync Methods

AbstractLevelDOWN#_openSync(options)

AbstractLevelDOWN#_getSync(key, options)

AbstractLevelDOWN#_putSync(key, value, options)

AbstractLevelDOWN#_delSync(key, options)

AbstractLevelDOWN#_batchSync(array, options)

Async Methods

AbstractLevelDOWN#_open(options, callback)

AbstractLevelDOWN#_close(callback)

AbstractLevelDOWN#_get(key, options, callback)

AbstractLevelDOWN#_put(key, value, options, callback)

AbstractLevelDOWN#_del(key, options, callback)

AbstractLevelDOWN#_batch(array, options, callback)

If batch() is called without argument or with only an options object then it should return a Batch object with chainable methods. Otherwise it will invoke a classic batch operation.

the batch should be rename to transact more accurate.

batch() can be used for very fast bulk-write operations (both put and delete). The array argument should contain a list of operations to be executed sequentially, although as a whole they are performed as an atomic operation inside LevelDB. Each operation is contained in an object having the following properties: type, key, value, where the type is either 'put' or 'del'. In the case of 'del' the 'value' property is ignored. Any entries with a 'key' of null or undefined will cause an error to be returned on the callback and any 'type': 'put' entry with a 'value' of null or undefined will return an error.

var ops = [
    { type: 'del', key: 'father' }
  , { type: 'put', key: 'name', value: 'Yuri Irsenovich Kim' }
  , { type: 'put', key: 'dob', value: '16 February 1941' }
  , { type: 'put', key: 'spouse', value: 'Kim Young-sook' }
  , { type: 'put', key: 'occupation', value: 'Clown' }
]

db.batch(ops, function (err) {
  if (err) return console.log('Ooops!', err)
  console.log('Great success dear leader!')
})

AbstractLevelDOWN#_chainedBatch()

By default an batch() operation without argument returns a blank AbstractChainedBatch object. The prototype is available on the main exports for you to extend. If you want to implement chainable batch operations then you should extend the AbstractChaindBatch and return your object in the _chainedBatch() method.

AbstractLevelDOWN#_approximateSize(start, end, callback)

AbstractLevelDOWN#IteratorClass

You can override the IteratorClass to your Iterator. After override this, it is not necessary to implement the "_iterator()" method.

AbstractLevelDOWN#_iterator(options)

By default an iterator() operation returns a blank AbstractIterator object. The prototype is available on the main exports for you to extend. If you want to implement iterator operations then you should extend the AbstractIterator and return your object in the _iterator(options) method.

AbstractIterator implements the basic state management found in LevelDOWN. It keeps track of when a next() is in progress and when an end() has been called so it doesn't allow concurrent next() calls, it does it allow end() while a next() is in progress and it doesn't allow either next() or end() after end() has been called.

AbstractIterator(db)

Provided with the current instance of AbstractLevelDOWN by default.

Sync methods:

AbstractIterator#_nextSync()

return

  • if any result: return a two elements of array
    • the first is the key
    • the second is the value
  • or return false, if no any data yet.
AbstractIterator#_endSync()

Async methods:

AbstractIterator#_next(callback)
AbstractIterator#_end(callback)

AbstractChainedBatch

Provided with the current instance of AbstractLevelDOWN by default.

AbstractChainedBatch#_put(key, value)

AbstractChainedBatch#_del(key)

AbstractChainedBatch#_clear()

AbstractChainedBatch#_write(options, callback)

Contributing

Abstract LevelDOWN is an OPEN Open Source Project. This means that:

Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.

See the CONTRIBUTING.md file for more details.

Contributors

Abstract LevelDOWN is only possible due to the excellent work of the following contributors:

Rod VaggGitHub/rvaggTwitter/@rvagg
John ChesleyGitHub/cheslesTwitter/@chesles
Jake VerbatenGitHub/raynosTwitter/@raynos2
Dominic TarrGitHub/dominictarrTwitter/@dominictarr
Max OgdenGitHub/maxogdenTwitter/@maxogden
Lars-Magnus SkogGitHub/ralphtheninjaTwitter/@ralphtheninja
David BjörklundGitHub/keslaTwitter/@david_bjorklund
Julian GruberGitHub/juliangruberTwitter/@juliangruber
Paolo FragomeniGitHub/hij1nxTwitter/@hij1nx
Anton WhalleyGitHub/No9Twitter/@antonwhalley
Matteo CollinaGitHub/mcollinaTwitter/@matteocollina
Pedro TeixeiraGitHub/pgteTwitter/@pgte
James HallidayGitHub/substackTwitter/@substack
Thomas Watson SteenGitHub/watsonTwitter/@wa7son

Copyright (c) 2012-2014 Abstract LevelDOWN contributors (listed above).

Abstract LevelDOWN is licensed under the MIT license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details.

Keywords

FAQs

Package last updated on 04 Dec 2014

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc