* Returns an "abstract" mapreduce object of the form: * * { * query: queryFun, * viewCleanup: viewCleanupFun * } * * Arguments are: * * localDoc: string * This is for the local doc that gets saved in order to track the * "dependent" DBs and clean them up for viewCleanup. I
(localDocName, mapper, reducer, ddocValidator)
| 8175 | * indexer is invalid. |
| 8176 | */ |
| 8177 | function createAbstractMapReduce(localDocName, mapper, reducer, ddocValidator) { |
| 8178 | |
| 8179 | function tryMap(db, fun, doc) { |
| 8180 | // emit an event if there was an error thrown by a map function. |
| 8181 | // putting try/catches in a single function also avoids deoptimizations. |
| 8182 | try { |
| 8183 | fun(doc); |
| 8184 | } catch (e) { |
| 8185 | emitError(db, e, {fun, doc}); |
| 8186 | } |
| 8187 | } |
| 8188 | |
| 8189 | function tryReduce(db, fun, keys, values, rereduce) { |
| 8190 | // same as above, but returning the result or an error. there are two separate |
| 8191 | // functions to avoid extra memory allocations since the tryCode() case is used |
| 8192 | // for custom map functions (common) vs this function, which is only used for |
| 8193 | // custom reduce functions (rare) |
| 8194 | try { |
| 8195 | return {output : fun(keys, values, rereduce)}; |
| 8196 | } catch (e) { |
| 8197 | emitError(db, e, {fun, keys, values, rereduce}); |
| 8198 | return {error: e}; |
| 8199 | } |
| 8200 | } |
| 8201 | |
| 8202 | function sortByKeyThenValue(x, y) { |
| 8203 | const keyCompare = collate(x.key, y.key); |
| 8204 | return keyCompare !== 0 ? keyCompare : collate(x.value, y.value); |
| 8205 | } |
| 8206 | |
| 8207 | function sliceResults(results, limit, skip) { |
| 8208 | skip = skip || 0; |
| 8209 | if (typeof limit === 'number') { |
| 8210 | return results.slice(skip, limit + skip); |
| 8211 | } else if (skip > 0) { |
| 8212 | return results.slice(skip); |
| 8213 | } |
| 8214 | return results; |
| 8215 | } |
| 8216 | |
| 8217 | function rowToDocId(row) { |
| 8218 | const val = row.value; |
| 8219 | // Users can explicitly specify a joined doc _id, or it |
| 8220 | // defaults to the doc _id that emitted the key/value. |
| 8221 | const docId = (val && typeof val === 'object' && val._id) || row.id; |
| 8222 | return docId; |
| 8223 | } |
| 8224 | |
| 8225 | function readAttachmentsAsBlobOrBuffer(res$$1) { |
| 8226 | for (const row of res$$1.rows) { |
| 8227 | const atts = row.doc && row.doc._attachments; |
| 8228 | if (!atts) { |
| 8229 | continue; |
| 8230 | } |
| 8231 | for (const filename of Object.keys(atts)) { |
| 8232 | const att = atts[filename]; |
| 8233 | atts[filename].data = b64ToBluffer(att.data, att.content_type); |
| 8234 | } |
no test coverage detected
searching dependent graphs…