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

feat: .getMany #81

Merged
merged 5 commits into from
Oct 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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