Skip to content
This repository has been archived by the owner on Aug 11, 2021. It is now read-only.

Commit

Permalink
feat: .getMany (#81)
Browse files Browse the repository at this point in the history
* chore: update aegir

* feat: .getMany

* test: refactor offline tests

* chore: fix jsdocs

* chore: apply CR
  • Loading branch information
daviddias authored Oct 27, 2018
1 parent b405a91 commit 8aa9e0a
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 65 deletions.
5 changes: 0 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@
"coverage-publish": "aegir coverage --provider coveralls",
"docs": "aegir docs"
},
"pre-commit": [
"lint",
"test"
],
"repository": {
"type": "git",
"url": "git+https://github.com/ipfs/js-ipfs-block-service.git"
Expand All @@ -44,7 +40,6 @@
"lodash": "^4.17.11",
"multihashing-async": "~0.5.1",
"ncp": "^2.0.0",
"pre-commit": "^1.2.2",
"rimraf": "^2.6.2"
},
"engines": {
Expand Down
35 changes: 27 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict'

const asyncMap = require('async/map')

/**
* BlockService is a hybrid block datastore. It stores data in a local
* datastore and may retrieve data from a remote Exchange.
Expand Down Expand Up @@ -57,10 +59,10 @@ class BlockService {
*/
put (block, callback) {
if (this.hasExchange()) {
return this._bitswap.put(block, callback)
this._bitswap.put(block, callback)
} else {
this._repo.blocks.put(block, callback)
}

this._repo.blocks.put(block, callback)
}

/**
Expand All @@ -72,10 +74,10 @@ class BlockService {
*/
putMany (blocks, callback) {
if (this.hasExchange()) {
return this._bitswap.putMany(blocks, callback)
this._bitswap.putMany(blocks, callback)
} else {
this._repo.blocks.putMany(blocks, callback)
}

this._repo.blocks.putMany(blocks, callback)
}

/**
Expand All @@ -87,10 +89,27 @@ class BlockService {
*/
get (cid, callback) {
if (this.hasExchange()) {
return this._bitswap.get(cid, callback)
this._bitswap.get(cid, callback)
} else {
this._repo.blocks.get(cid, callback)
}
}

return this._repo.blocks.get(cid, callback)
/**
* Get multiple blocks back from an array of cids.
*
* @param {Array<CID>} cids
* @param {function(Error, Block)} callback
* @returns {void}
*/
getMany (cids, callback) {
if (!Array.isArray(cids)) {
callback(new Error('first arg must be an array of cids'))
} else if (this.hasExchange()) {
this._bitswap.getMany(cids, callback)
} else {
asyncMap(cids, (cid, cb) => this._repo.blocks.get(cid, cb), callback)
}
}

/**
Expand Down
106 changes: 54 additions & 52 deletions test/block-service-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,78 +17,80 @@ const BlockService = require('../src')
module.exports = (repo) => {
describe('block-service', () => {
let bs
let testBlocks

before(() => {
before((done) => {
bs = new BlockService(repo)

const data = [
Buffer.from('1'),
Buffer.from('2'),
Buffer.from('3'),
Buffer.from('A random data block')
]

map(data, (d, cb) => {
multihashing(d, 'sha2-256', (err, hash) => {
expect(err).to.not.exist()
cb(null, new Block(d, new CID(hash)))
})
}, (err, blocks) => {
expect(err).to.not.exist()
testBlocks = blocks
done()
})
})

describe('offline', () => {
describe('fetch only from local Repo', () => {
it('store and get a block', (done) => {
const data = Buffer.from('A random data block')
multihashing(data, 'sha2-256', (err, hash) => {
expect(err).to.not.exist()
const b = new Block(data, new CID(hash))
const b = testBlocks[3]

waterfall([
(cb) => bs.put(b, cb),
(cb) => bs.get(b.cid, cb),
(res, cb) => {
expect(res).to.be.eql(b)
cb()
}
], done)
})
waterfall([
(cb) => bs.put(b, cb),
(cb) => bs.get(b.cid, cb),
(res, cb) => {
expect(res).to.eql(b)
cb()
}
], done)
})

it('get a non existent block', (done) => {
const data = Buffer.from('Not stored')
it('get a non stored yet block', (done) => {
const b = testBlocks[2]

multihashing(data, 'sha2-256', (err, hash) => {
expect(err).to.not.exist()
bs.get(new CID(hash), (err, block) => {
expect(err).to.exist()
expect(block).to.not.exist()
done()
})
bs.get(b.cid, (err, block) => {
expect(err).to.exist()
expect(block).to.not.exist()
done()
})
})

it('store many blocks', (done) => {
const data = [Buffer.from('1'), Buffer.from('2'), Buffer.from('3')]
map(data, (d, cb) => {
multihashing(d, 'sha2-256', (err, hash) => {
expect(err).to.not.exist()
cb(null, new Block(d, new CID(hash)))
})
}, (err, blocks) => {
bs.putMany(testBlocks, done)
})

it('get many blocks through .get', (done) => {
map(testBlocks, (b, cb) => bs.get(b.cid, cb), (err, blocks) => {
expect(err).to.not.exist()
bs.putMany(blocks, done)
expect(blocks).to.eql(testBlocks)
done()
})
})

it('get many blocks', (done) => {
const data = [Buffer.from('1'), Buffer.from('2'), Buffer.from('3')]
waterfall([
(cb) => map(data, (d, cb) => {
multihashing(d, 'sha2-256', (err, hash) => {
expect(err).to.not.exist()
cb(null, new Block(d, new CID(hash)))
})
}, cb),
(blocks, cb) => map(
blocks,
(b, cb) => bs.get(b.cid, cb),
(err, res) => {
expect(err).to.not.exist()
expect(res).to.be.eql(blocks)
cb()
}
)
], done)
it('get many blocks through .getMany', (done) => {
map(testBlocks, (b, cb) => cb(null, b.cid), (err, cids) => {
expect(err).to.not.exist()
bs.getMany(cids, (err, _blocks) => {
expect(err).to.not.exist()
expect(testBlocks).to.eql(_blocks)
done()
})
})
})

it('delete a block', (done) => {
const data = Buffer.from('Will not live that much')

multihashing(data, 'sha2-256', (err, hash) => {
expect(err).to.not.exist()
const b = new Block(data, new CID(hash))
Expand Down Expand Up @@ -140,7 +142,7 @@ module.exports = (repo) => {
})
})

describe('has exchange', () => {
describe('fetch through Bitswap (has exchange)', () => {
beforeEach(() => {
bs = new BlockService(repo)
})
Expand Down

0 comments on commit 8aa9e0a

Please sign in to comment.