Level / abstract-leveldown

An abstract prototype matching the leveldown API.
MIT License
146 stars 53 forks source link

Optional location #256

Closed ralphtheninja closed 6 years ago

ralphtheninja commented 6 years ago

Closes https://github.com/Level/abstract-leveldown/issues/63

ralphtheninja commented 6 years ago

Rebased onto latest master. Needs docs too I guess.

vweevers commented 6 years ago

Can you add a note to UPGRADING.md? We'll need to add type checks to leveldown etc

ralphtheninja commented 6 years ago

Browser tests never started, restarting build.

vweevers commented 6 years ago

Entertaining two thoughts, because I think we can afford to take bigger steps.

Thought 1. Make location optional by checking arguments.length. This gives implementations the choice of supporting location without them having to do extra type checks. In addition, make the .location property optional too?

function AbstractLevelDOWN (location) {
  if (arguments.length > 0) {
    if (typeof location !== 'string') {
      throw new Error('constructor requires a location string argument')
    }

    this.location = location
  }

  this.status = 'new'
}

function MemDOWN () {
   AbstractLevelDOWN.call(this)
}

function LevelDOWN (location) {
  AbstractLevelDOWN.call(this, location)
}

function SQLDown (connection) {
  this._connection = connection
  AbstractLevelDOWN.call(this)
}

Thought 2. Remove location altogether, it's not that much code to move to leveldown:

function AbstractLevelDOWN () {
  this.status = 'new'
}

function MemDOWN () {
   AbstractLevelDOWN.call(this)
}

function LevelDOWN (location) {
  if (typeof location !== 'string') {
    throw new Error('constructor requires a location string argument')
  }

  this._location = location
  AbstractLevelDOWN.call(this)
}

function SQLDown (connection) {
  this._connection = connection
  AbstractLevelDOWN.call(this)
}

An additional benefit of either of these approaches is that we can check location !== ''. Are empty locations handled in the c++?

ralphtheninja commented 6 years ago

Entertaining two thoughts, because I think we can afford to take bigger steps.

Good call!

I like both alternatives, but I think I prefer the second. Since some implementation aren't using location I don't see why it should be stored in a base class at all. Also makes AbstractLevelDOWN a lot cleaner.

ralphtheninja commented 6 years ago

Additionally, I think we might need to change how the abstract tests are invoked as well. If location is removed from abstract-leveldown and if implementations aren't necessarily using a location, then maybe we shouldn't do e.g.

var db = leveldown(testCommon.location())

but rather

var db = factory()

So implementations pass in factory instead and can handle themselves how the instance should be created, with a location or not.

ralphtheninja commented 6 years ago

Aaah we're of course already using a factory, so we shouldn't pass testCommon.location() to it.

vweevers commented 6 years ago

A factory can also support options (#227). Two birds one stone :)

vweevers commented 6 years ago

Aaah we're of course already using a factory

So none of the current tests assume that the function has a prototype?

ralphtheninja commented 6 years ago

So none of the current tests assume that the function has a prototype?

I haven't checked all. With that you mean that we don't have to call new?

vweevers commented 6 years ago

With that you mean that we don't have to call new?

And that the tests don't do things like instanceof fn

ralphtheninja commented 6 years ago

@vweevers If you're cool with it, I'd like to close this PR and start over with removing location.

Ps. It seems to me that test/leveldown-test.js is getting more and more redundant since it will be only one test left which doesn't really test anything

https://github.com/Level/abstract-leveldown/blob/74d7340dbf85ceae4f69f7bc9ea9d541498c3a8d/test/leveldown-test.js#L21-L26