@@ -5,17 +5,67 @@ const multihashing = require('multihashing-async')
55const CID = require ( 'cids' )
66const callbackify = require ( 'callbackify' )
77const errCode = require ( 'err-code' )
8+ const all = require ( 'async-iterator-all' )
9+ const { PinTypes } = require ( './pin/pin-manager' )
810
911module . exports = function block ( self ) {
10- return {
11- get : callbackify . variadic ( async ( cid , options ) => { // eslint-disable-line require-await
12- options = options || { }
12+ async function * rmAsyncIterator ( cids , options ) {
13+ options = options || { }
1314
14- try {
15+ if ( ! Array . isArray ( cids ) ) {
16+ cids = [ cids ]
17+ }
18+
19+ // We need to take a write lock here to ensure that adding and removing
20+ // blocks are exclusive operations
21+ const release = await self . _gcLock . writeLock ( )
22+
23+ try {
24+ for ( let cid of cids ) {
1525 cid = cleanCid ( cid )
16- } catch ( err ) {
17- throw errCode ( err , 'ERR_INVALID_CID' )
26+
27+ const result = {
28+ hash : cid . toString ( )
29+ }
30+
31+ try {
32+ const pinResult = await self . pin . pinManager . isPinnedWithType ( cid , PinTypes . all )
33+
34+ if ( pinResult . pinned ) {
35+ if ( CID . isCID ( pinResult . reason ) ) { // eslint-disable-line max-depth
36+ throw errCode ( new Error ( `pinned via ${ pinResult . reason } ` ) )
37+ }
38+
39+ throw errCode ( new Error ( `pinned: ${ pinResult . reason } ` ) )
40+ }
41+
42+ // remove has check when https://github.com/ipfs/js-ipfs-block-service/pull/88 is merged
43+ const has = await self . _blockService . _repo . blocks . has ( cid )
44+
45+ if ( ! has ) {
46+ throw errCode ( new Error ( 'block not found' ) , 'ERR_BLOCK_NOT_FOUND' )
47+ }
48+
49+ await self . _blockService . delete ( cid )
50+ } catch ( err ) {
51+ if ( ! options . force ) {
52+ result . error = `cannot remove ${ cid } : ${ err . message } `
53+ }
54+ }
55+
56+ if ( ! options . quiet ) {
57+ yield result
58+ }
1859 }
60+ } finally {
61+ release ( )
62+ }
63+ }
64+
65+ return {
66+ get : callbackify . variadic ( async ( cid , options ) => { // eslint-disable-line require-await
67+ options = options || { }
68+ cid = cleanCid ( cid )
1969
2070 if ( options . preload !== false ) {
2171 self . _preload ( cid )
@@ -66,31 +116,13 @@ module.exports = function block (self) {
66116 release ( )
67117 }
68118 } ) ,
69- rm : callbackify ( async ( cid ) => {
70- try {
71- cid = cleanCid ( cid )
72- } catch ( err ) {
73- throw errCode ( err , 'ERR_INVALID_CID' )
74- }
75-
76- // We need to take a write lock here to ensure that adding and removing
77- // blocks are exclusive operations
78- const release = await self . _gcLock . writeLock ( )
79-
80- try {
81- await self . _blockService . delete ( cid )
82- } finally {
83- release ( )
84- }
119+ rm : callbackify . variadic ( async ( cids , options ) => { // eslint-disable-line require-await
120+ return all ( rmAsyncIterator ( cids , options ) )
85121 } ) ,
122+ _rmAsyncIterator : rmAsyncIterator ,
86123 stat : callbackify . variadic ( async ( cid , options ) => {
87124 options = options || { }
88-
89- try {
90- cid = cleanCid ( cid )
91- } catch ( err ) {
92- throw errCode ( err , 'ERR_INVALID_CID' )
93- }
125+ cid = cleanCid ( cid )
94126
95127 if ( options . preload !== false ) {
96128 self . _preload ( cid )
@@ -112,5 +144,9 @@ function cleanCid (cid) {
112144 }
113145
114146 // CID constructor knows how to do the cleaning :)
115- return new CID ( cid )
147+ try {
148+ return new CID ( cid )
149+ } catch ( err ) {
150+ throw errCode ( err , 'ERR_INVALID_CID' )
151+ }
116152}
0 commit comments