all files / couch/couch/database/ design.js

65.91% Statements 29/44
56.25% Branches 9/16
85.71% Functions 6/7
65.91% Lines 29/44
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95                            72× 72× 16×   64× 32× 32× 48×   32× 32×     24×                     18×       10× 10× 10×     10×     10×                                                              
import Ember from 'ember';
import buildDeepEqual from '../../util/deep-equal';
 
const deepEqual = buildDeepEqual({ allowEmberObjects: false });
 
const {
  merge,
  typeOf,
  RSVP: { reject }
} = Ember;
 
export default Ember.Object.extend({
 
  database: null,
 
  _stringify(arg) {
    let type = typeOf(arg);
    if(type === 'array') {
      let ret = [];
      for(let i = 0; i < arg.length; i++) {
        ret.push(this._stringify(arg[i]));
      }
      return ret;
    } else if(type === 'object') {
      let ret = {};
      for(let key in arg) {
        ret[key] = this._stringify(arg[key]);
      }
      return ret;
    } else if(type === 'function') {
      let string = arg.toString();
      // es6 transpiler adds function name, CouchDB doesn't like it
      string = string.replace(/(function) ([\w]+)/g, '$1');
      return string;
    }
    return arg;
  },
 
  _build(name, hash) {
    return merge({ _id: this.id(name), language: 'javascript' }, this._stringify(hash));
  },
 
  _deepEqual(a, b) {
    return deepEqual(a, b);
  },
 
  id(name) {
    return `_design/${name}`;
  },
 
  load(name, opts) {
    opts = merge({ optional: false }, opts);
    let id = this.id(name);
    return this.get('database').load(id, { encoded: true }).then((doc) => {
      return doc;
    }, (err) => {
      Iif(opts.optional && err.status === 404) {
        return;
      }
      return reject(err);
    });
  },
 
  save(name, hash) {
    let doc = this._build(name, hash);
    return this.load(name, { encoded: true, optional: true }).then((cur) => {
      if(cur) {
        doc._rev = cur._rev;
        if(this._deepEqual(doc, cur)) {
          return { ok: true, id: doc._id, rev: doc._rev, saved: false };
        }
      }
      return this.get('database').save(doc, { encoded: true }).then((data) => {
        data.saved = true;
        return data;
      });
    });
  },
 
  delete(name, opts) {
    opts = merge({ optional: false }, opts);
    return this.load(name, { optional: opts.optional }).then((cur) => {
      if(cur) {
        return this.get('database').delete(cur._id, cur._rev, { encoded: true }).then((data) => {
          data.deleted = true;
          return data;
        });
      }
      return { ok: true, id: this.id(name), deleted: false };
    });
  },
 
});