Skip to content

Add functionality to copy feed and append to it. #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ node_js:
- "4.0"
- "0.12"
- "0.11"
- "0.10"
- "iojs"
6 changes: 6 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var level = require('level')
var hypercore = require('hypercore')
var createImportPipeline = require('./lib/import.js')
var FeedOperations = require('./lib/feedOperations.js')

module.exports = Jawn

Expand All @@ -14,3 +15,8 @@ function Jawn (opts) {
Jawn.prototype.createImportPipeline = function (opts) {
return createImportPipeline(this, opts)
}

Jawn.prototype.createAppendableFeed = function (feedId, data) {
var feed = new FeedOperations(this.core).appendableFeed(feedId)
return feed
}
80 changes: 80 additions & 0 deletions lib/feedOperations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
module.exports = FeedOperations

function FeedOperations (core) {
this.core = core
this.replicate = copyOriginal

function copyOriginal (refFeed, newFeed, resolve, reject) {
loop(null)

function loop (err) {
if (err) {
console.log(err)
if (reject) {
return reject()
}
}

refFeed.get(newFeed.blocks, function (err, block) {
if (err) {
console.log(err)
}

if (!block) {
return resolve()
}

newFeed.append(block, loop)
})
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might append blocks in the wrong order as this is async. you probably wanna do this

loop(null)
function loop (err) {
  if (err) return reject(err)
  refFeed.get(newFeed.blocks, function (err, block) {
    if (err) return cb(err)
    if (!block) return resolve() // done
    newFeed.append(block, loop)
  })
}

}
}

FeedOperations.prototype.appendableFeed = function (feedId) {
var refFeed = this.core.get(feedId)
var newFeed = this.core.add()

newFeed.append_p = function (data) {
return new Promise(function (resolve, reject) {
newFeed.append(data, resolve)
})
}

newFeed.finalize_p = function () {
return new Promise(function (resolve, reject) {
newFeed.finalize(resolve)
})
}

var copyOriginal = this.replicate

newFeed.initialize = function () {
return new Promise(function (resolve, reject) {
copyOriginal(refFeed, newFeed, resolve, reject)
})
}

return newFeed
}

FeedOperations.prototype.replicateFeed = function (feedId, callback) {
var refFeed = this.core.get(feedId)
var newFeed = this.core.add()

this.replicate(refFeed, newFeed, callback)
return newFeed
}

// Copies data from reference feed, appends data to new feed and finalizes it
FeedOperations.prototype.append = function (feedId, data, callback) {
var refFeed = this.core.get(feedId)
var newFeed = this.core.add()

this.replicate(refFeed, newFeed, function () {
newFeed.append(data, function () {
newFeed.finalize(callback)
})
})

return newFeed
}
147 changes: 147 additions & 0 deletions test/feedOperations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
var test = require('tape')
var Jawn = require('../')
var memdb = require('memdb')
var FeedOps = require('../lib/feedOperations.js')

test('Create appendable feed and copy data from reference feed', function (t) {
var jawn = freshJawn()
var feed = jawn.core.add()

storeDataInFeed(feed, ['hello'])
.then(function () {
// Verify feed was finalized and has an id
console.log('Finalized with id ' + feed.id.toString('hex'))
// Create appendable feed
var feedOperations = new FeedOps(jawn.core)
var appfeed = feedOperations.appendableFeed(feed.id)
// Copy data from reference feed, finalize it, then verify the feed has the same number of blocks as the reference
appfeed.initialize().then(function () {
return appfeed.finalize_p()
})
.then(function () {
t.same(appfeed.blocks, feed.blocks, 'testing')
t.end()
})
})
})

test('Create appendable feeed, copy data from reference feed and append to feed', function (t) {
var jawn = freshJawn()
var feed = jawn.core.add()
var expected = ['hello', 'there', 'goodbye']

storeDataInFeed(feed, ['hello', 'there'])
.then(function () {
console.log('Finalized with id ' + feed.id.toString('hex'))

var appfeed = new FeedOps(jawn.core).appendableFeed(feed.id)

// Copy data from original feed with initialize(), then append an additional block and finalize
appfeed.initialize().then(function () {
return appfeed.append_p('goodbye')
})
.then(function () {
return appfeed.finalize_p()
})
.then(function () {
// Verify the feed has the correct number of blocks, and the blocks match what was expected
t.same(appfeed.blocks, expected.length, 'Correct number of blocks')

for (var i = 0; i < appfeed.blocks; i++) {
appfeed.get(i, function (err, block) {
if (err) {
console.log(err)
}
t.same(block.toString(), expected.shift(), 'Feed block match')
if (expected.length === 0) {
t.end()
}
})
}
})
})
})

test('Create appendable feed without promises, copy data from reference feed', function (t) {
var jawn = freshJawn()
var feed = jawn.core.add()

storeDataInFeed(feed, ['hello', 'there'])
.then(function () {
var appFeed = new FeedOps(jawn.core).replicateFeed(feed.id, finalizeCallback)
function finalizeCallback () {
appFeed.finalize(function () {
t.same(appFeed.blocks, feed.blocks, 'Correct number of blocks')
t.end()
})
}
})
})

test('Append data to feed without promises', function (t) {
var jawn = freshJawn()
var feed = jawn.core.add()
var expected = ['hello', 'there', 'goodbye']

storeDataInFeed(feed, ['hello', 'there'])
.then(function () {
var appFeed = new FeedOps(jawn.core).append(feed.id, ['goodbye'], testCallback)
function testCallback () {
t.same(appFeed.blocks, expected.length, 'Correct number of blocks in appended feed')
testFeedContents(appFeed, expected, t)
}
})
})

function testFeedContents (feed, expected, t) {
var blockNumber = 0
feed.get(0, loop)

function loop (err, block) {
if (err) {
console.log(err)
}

blockNumber += 1

if (block) {
t.same(block.toString(), expected.shift(), 'Feed block matches expected value')
}

if (expected.length === 0) {
return t.end()
}

feed.get(blockNumber, loop)
}
}

// Create a feed, store data in it and finalize it.
function storeDataInFeed (feed, data) {
feed.pappend = function (data) {
return new Promise(function (resolve, reject) {
feed.append(data, resolve)
})
}

feed.pfinalize = function () {
return new Promise(function (resolve, reject) {
feed.finalize(resolve)
})
}

return new Promise(function (resolve, reject) {
feed.pappend(data).then(function () {
console.log('Appended')
return feed
})
.then(function (feed) {
return feed.pfinalize()
})
.then(resolve)
})
}

function freshJawn () {
return new Jawn({db: memdb()})
}
2 changes: 1 addition & 1 deletion test/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ test('import json to jawn', function (t) {
test('import csv to jawn', function (t) {
var jawn = freshJawn()
importFromFile(jawn, 'sample.csv', {'format': 'csv'})
var importStream = importFromFile(jawn, 'sample.csv', {'format': 'csv'}, verify)
var importStream = importFromFile(jawn, 'sample.csv', {'format': 'csv'})
var expected = [
'{"Type of Experience":"Writing software in any programming language","Little/No Experience":"1","Some Experience":"5","Very Familiar":"4"}',
'{"Type of Experience":"Frontend Web Development","Little/No Experience":"4","Some Experience":"3","Very Familiar":"3"}',
Expand Down