git ssb

1+

Dominic / secure-scuttlebutt



Tree: 8e8434f441e3e179672053fbde29570a4fcf6981

Files: 8e8434f441e3e179672053fbde29570a4fcf6981 / create.js

4885 bytesRaw
1'use strict'
2
3var join = require('path').join
4var EventEmitter = require('events')
5//var ViewLevel = require('flumeview-level')
6var ltgt = require('ltgt')
7
8var pull = require('pull-stream')
9var ref = require('ssb-ref')
10var ssbKeys = require('ssb-keys')
11
12var u = require('./util')
13
14function isString (s) {
15 return typeof s === 'string'
16}
17
18function errorCB (err) {
19 if (err) throw err
20}
21
22module.exports = function (path, opts, keys) {
23 //_ was legacy db. removed that, but for backwards compatibilty reasons do not change interface
24 if(!path) throw new Error('path must be provided')
25
26 keys = keys || ssbKeys.generate()
27
28 var db = require('./db')(join(opts.path || path, 'flume'), keys, opts)
29
30 // UGLY HACK, but...
31 // fairly sure that something up the stack expects ssb to be an event emitter.
32 db.__proto__ = new EventEmitter() // eslint-disable-line
33
34 db.opts = opts
35
36 db.id = keys.id
37
38 var _get = db.get
39
40 db.get = function (key, cb) {
41 let isPrivate = false
42 let unbox
43 let meta = false
44 if (typeof key === 'object') {
45 isPrivate = key.private === true
46 unbox = key.unbox
47 meta = key.meta
48 key = key.id
49 }
50
51 if (ref.isMsg(key)) {
52 return db.keys.get(key, function (err, data) {
53 if (err) return cb(err)
54
55 if (isPrivate && unbox) {
56 data = db.unbox(data, unbox)
57 }
58
59 let result
60
61 if (isPrivate) {
62 result = data.value
63 } else {
64 result = u.originalValue(data.value)
65 }
66
67 cb(null, !meta ? result : {key: data.key, value: result, timestamp: data.timestamp})
68 })
69 } else if (ref.isMsgLink(key)) {
70 var link = ref.parseLink(key)
71 return db.get({
72 id: link.link,
73 private: true,
74 unbox: link.query.unbox.replace(/\s/g, '+'),
75 meta: link.query.meta
76 }, cb)
77 } else if (Number.isInteger(key)) {
78 _get(key, cb) // seq
79 } else {
80 throw new Error('ssb-db.get: key *must* be a ssb message id or a flume offset')
81 }
82 }
83
84 db.add = function (msg, cb) {
85 db.queue(msg, function (err, data) {
86 if (err) cb(err)
87 else db.flush(function () { cb(null, data) })
88 })
89 }
90
91 //would like to remove this, but loads of tests use it.
92 db.createFeed = function (keys) {
93 console.error('deprecated api used: db.createFeed, please use db.publish directly')
94 if (!keys) keys = ssbKeys.generate()
95 function add (content, cb) {
96 // LEGACY: hacks to support add as a continuable
97 if (!cb) { return function (cb) { add(content, cb) } }
98
99 db.append({ content: content, keys: keys }, cb)
100 }
101 return {
102 add: add,
103 publish: add,
104 id: keys.id,
105 keys: keys
106 }
107 }
108
109 db.createRawLogStream = function (opts) {
110 opts = opts || {}
111 var isPrivate = opts.private === true
112 return pull(
113 db.stream(opts),
114 pull.map(function (data) {
115 if (isPrivate) {
116 return data
117 } else {
118 if(opts.seqs)
119 return {
120 seq: data.seq,
121 value: {
122 key: data.value.key,
123 value: u.originalValue(data.value.value),
124 timestamp: data.value.timestamp
125 }
126 }
127 else
128 return {
129 key: data.key,
130 value: u.originalValue(data.value),
131 timestamp: data.timestamp
132 }
133 }
134 })
135 )
136 }
137
138 // called with [id, seq] or "<id>:<seq>" (used by ssb-edb replication)
139 db.getAtSequence = function (seqid, cb) {
140 // will NOT expose private plaintext
141 const parts = isString(seqid) ? seqid.split(':') : seqid
142 const id = parts[0], seq = parts[1]
143 db.clock.get(function (err, state) {
144 if(err) cb(err)
145 else if(!state[id] || state[id][seq] == null)
146 cb(new Error('not found: getAtSequence([' + id + ', '+seq+'])'))
147 else
148 db.get(state[id][seq], cb)
149 })
150 }
151
152 db.getVectorClock = function (_, cb) {
153 if (!cb) cb = _
154 db.last.get(function (err, h) {
155 if (err) return cb(err)
156 var clock = {}
157 for (var k in h) { clock[k] = h[k].sequence }
158 cb(null, clock)
159 })
160 }
161
162// db
163// .use('time', ViewLevel(2, function (data) {
164// return [data.timestamp]
165// }))
166//
167 db.createLogStream = function (opts) {
168 opts = u.options(opts)
169 if (opts.raw) { return db.stream(opts) }
170
171 var keys = opts.keys; delete opts.keys
172 var values = opts.values; delete opts.values
173 if (opts.gt == null) { opts.gt = 0 }
174
175 return pull(
176 //XXX not scalable, only usable for a proof of concept!
177 // a binary search would be better!
178 db.stream({seqs: false, live: opts.live, reverse: opts.reverse}),
179 pull.filter(function (data) {
180 return ltgt.contains(opts, data.timestamp, cmp)
181 }),
182 u.Format(keys, values, opts.private)
183 )
184 }
185
186
187 return db
188}
189
190
191
192
193
194

Built with git-ssb-web