将数据从PouchDb复制到CouchDb时失败

时间:2018-04-06 17:06:37

标签: javascript couchdb pouchdb

我的代码

那是我当前代码的简短版本。:

['tableA', 'tableB', 'tableC'].forEach(name => {
    let local = new PouchDB(name, { auto_compaction: true })
    let server = new PouchDB(serverUrl + name)

    var filtro = {
      include_docs: true,
      filter: 'replication/by_dispositivo',
      query_params: { 'dispositivo_id': obj.deviceId }
    }
    local.replicate.from(server, filtro).on('complete', report => {
      var sync = local.sync(server, {
        live: true,
        retry: true,
        ...filtro
      })
    })
})

我试图进行实时复制,但出于某种原因,这并没有将本地数据复制到服务器,奇怪的是,PouchDb没有抛出任何异常。

检查Network上的Dev Tools标签,我可以看到以下请求:

URL: ${serverUrl}/{name}/_revs_diff
Response: {
    "4b0ea507-cd88-4998-baf0-01629b50516b": {
        "missing": [
            "2-2133d30de8d44ebd958cee2b68726ffb"
        ],
        "possible_ancestors": [
            "1-39904a7e55b1cb266c840a2acf34fdc2"
        ]
    }
}

好的,PouchDb检测到服务器中缺少某些东西,必须复制。

审核同步

正在搜索有关正在发生的事情的提示,我修改了我的代码以记录completeerror事件。:

['tableA', 'tableB', 'tableC'].forEach(name => {
    let local = new PouchDB(name, { auto_compaction: true })
    let server = new PouchDB(serverUrl + name)

    let filtro = {
      include_docs: true,
      filter: 'replication/by_dispositivo',
      query_params: { 'dispositivo_id': obj.deviceId }
    }
    local.replicate.from(server, filtro).on('complete', report => {
      let sync = local.sync(server, {
        live: true,
        retry: true,
        ...filtro
      })
      sync.on('error', (error) => {
        console.error(error)
        console.error(JSON.stringify(error, null, 2))
      }).on('complete', (result) => {
        console.log(result)
        console.log(JSON.stringify(result, null, 2))
      })
      window.setTimeout(function (evt) {
        state.syncProcess[database].cancel()
      }, 15000)
    })
})

catch事件中我没有error任何内容,complete事件没有显示任何错误,如下所示。

{
  "push": {
    "ok": true,
    "start_time": "2018-04-06T15:00:42.266Z",
    "docs_read": 0,
    "docs_written": 0,
    "doc_write_failures": 0,
    "errors": [],
    "status": "cancelled",
    "end_time": "2018-04-06T15:00:42.266Z",
    "last_seq": 0
  },
  "pull": {
    "ok": true,
    "start_time": "2018-04-06T15:00:26.422Z",
    "docs_read": 0,
    "docs_written": 0,
    "doc_write_failures": 0,
    "errors": [],
    "last_seq": "17-g1AAAAJDeJyd0EsOgjAQBuAqJj52nkCPILGldCU3UaYzBA3CQl3rTfQmehO9CRZKAiaGiJtpMs18mX8SxtgodpBNdXbSMUKQZDpM4uxwTMxXP2Qwy_N8Fzsh25vGMILIA62QjU8pUrRNCVvGYW4qrCphUgoCfMVd_W2mTQoKaV1JjpWWIUcuu0qbQjp_pBKeUESLH1OlA1PZxTwGudb7EC1dQt5xH6vdrHYvtF6pSZK-4Oov7WG1Z53QUy56UnRK-LJK406-TxIAm8ruDdzts44",
    "status": "cancelled",
    "end_time": "2018-04-06T15:00:41.427Z"
  }
}

手动调用一次本地服务器复制

这是我第二次尝试捕获有用的东西。我尝试audit local.replicate.to method

['tableA', 'tableB', 'tableC'].forEach(name => { let local = new PouchDB(name, { auto_compaction: true }) let server = new PouchDB(serverUrl + name) let filtro = { include_docs: true, filter: 'replication/by_dispositivo', query_params: { 'dispositivo_id': obj.deviceId } } local.replicate.from(server, filtro).on('complete', report => { local.replicate.to(server, filtro).on('complete', report => { console.log(report) console.log(JSON.stringify(report, null, 2)) let sync = local.sync(server, { live: true, retry: true, ...filtro }) }).on('error', (error) => { console.error(error) console.error(JSON.stringify(error, null, 2)) }) }) })
complete

那个时间event error没有被解雇,我抓到了{ "result": { "ok": false, "start_time": "2018-04-06T15:07:19.105Z", "docs_read": 1, "docs_written": 0, "doc_write_failures": 0, "errors": [], "status": "aborting", "end_time": "2018-04-06T15:07:19.768Z", "last_seq": 3 } } ,但这太过于通用了,并没有提供任何有关最新情况的线索。

var deviceId = ''
var listLocal = []
var listServer = []

getDeviceId().then(response => {
    deviceId = response
    return local.find({ selector: { dispositivo_id: deviceId } })
}).then(response => {
    listLocal = response.docs
    return server.find({ selector: { dispositivo_id: deviceId } })
}).then(response => {
    listServer = response.docs

    var tlocal = listLocal[0]
    var tServer = listServer[0]
    Object.keys(tServer).forEach(key => {
      if (key.indexOf("_") !== 0) {
        tServer[key] = undefined
      }
    })
    Object.keys(tlocal).forEach(key => {
      if (key.indexOf("_") !== 0) {
        tServer[key] = tlocal[key]
      }
    })

    return server.put(tServer).then(result => {
      console.log(result)
      console.log(JSON.stringify(result, null, 2))
    }).catch(error => {
      console.error(error)
      console.error(JSON.stringify(error, null, 2))
    })
})

将本地数据放入服务器

那是我的最后一次尝试。:

  • 我会查询本地和远程数据库(在特定情况下,我只有一个文档)
  • 将字段从本地文档复制到远程文档。
  • 将更新的远程文档分发到远程数据库

我的垃圾代码

{
  "ok": true,
  "id": "4b0ea507-cd88-4998-baf0-01629b50516b",
  "rev": "2-d9363f28e53fdc145610f5ad3f75a043"
}

垃圾代码按预期工作,我收到了回复。

{
  "_id": "_design/replication",
  "_rev": "1-42df919aaee8ed3fb309bbda999ba03d",
  "language": "javascript",
  "filters": {
    "by_dispositivo": "function(doc, req) {\r\n  return doc._id === '_design/replication' || (doc.dispositivo_id === req.query.dispositivo_id && !doc._deleted)\r\n}",
    "by_situacao_remote": "function(doc, req) {\r\n  return [2, 3, 4, 5].indexOf(doc.situacao) !== -1 && !doc._deleted\r\n}"
  }
}

其他信息

我在CouchDb中的设计文档

_design /复制

{
  "_id": "_design/authorization",
  "_rev": "9-64c4a22645d783c9089c95d69e9424ad",
  "language": "javascript",
  "validate_doc_update": "..."
}

_design /授权

function(newDoc, oldDoc, userCtx) {
  var isAdmin = userCtx.roles.indexOf('_admin') !== -1 || userCtx.roles.indexOf('admin') !== -1;
  if (!isAdmin) {
    if (newDoc._deleted) {
      if (oldDoc.dispositivo_id !== userCtx.name) {
        throw({forbidden: "..." });
      }
    } 
    else {
      if (!newDoc.dispositivo_id || !newDoc.dispositivo_id.trim())
        throw({forbidden: "..." });
      if (newDoc.dispositivo_id !== userCtx.name) {
        throw({forbidden: "..." });
      }

      if (oldDoc && oldDoc.dispositivo_id !== userCtx.name) {
        throw({forbidden: "..." });
      }

      var isRequired = function (prop, msg) {
        var value = newDoc[prop];
        if (!value)
            throw({forbidden: '...' });
      }

      var isDate = function (prop, msg, allow_null) {
        if (!allow_null) 
            isRequired(prop, msg)
        var value = newDoc[prop];
        if (value) {
            var date = new Date(value);
            var isDate = date !== "Invalid Date" && !isNaN(date);
            if (!isDate) {
              throw({forbidden: msg });
            }
        }
      }

      var isFloat = function (prop, msg, allow_null) {
        if (!allow_null) 
            isRequired(prop, msg)
        var value = newDoc[prop];
        if (value) {
            var numero = new Number(value);
            if (!numero || isNaN(numero) || !isFinite(numero)) {
              throw({forbidden: msg });
            }
        }
      }

      var isInteger = function (prop, msg, allow_null) {
        isFloat(prop, msg, allow_null)
        var value = newDoc[prop];
        if (value) {
            var numero = new Number(value);
            var isInteger = Math.floor(numero) == numero;
            if (!isInteger) {
              throw({forbidden: msg });
            }
        }
      }

      isRequired("talao_id", "...");
      isRequired("equipe_id", "...");

      isInteger("situacao", '...');
      isDate("data_envio", "...");
      isDate("data_recebimento", "...", true);
      isDate("data_decisao", "...", true);

      isRequired("tipo_ocorrencia_codigo", "...");
      isRequired("tipo_ocorrencia_descricao", "...");
      isInteger("talao_codigo", "...");
      isRequired("talao_descricao", "...");
      isRequired("talao_solicitante", "...");
      isRequired("talao_endereco", "...");
    }
  }
  else if (!newDoc._deleted) {
    if (!newDoc.dispositivo_id || !newDoc.dispositivo_id.trim())
      throw({forbidden: "..." });
  }
}

授权/ validate_doc_update

public class customReader implements ItemReader<List<T>>{


@Autowired
customDao customDao;


static List<T> CCTransDlyLg = null;

 @Override
    public List<T> read() throws Exception {
         if(CCTransDlyLg==null || (CCTransDlyLg!=null && CCTransDlyLg.size()==0)){
             CCTransDlyLg=customDao.getList();      
         }
             log.info("CCTransDlyLg List:"+CCTransDlyLg.size());
        return CCTransDlyLg.size()==0 ? null : CCTransDlyLg;

 }

1 个答案:

答案 0 :(得分:1)

stack trace分析exception投掷的local.replicate.to时,我注意到reason: promise.all is not a function

所以我用谷歌搜索了一段时间,发现了主题Webpack: Promise is not a constructor。我只需将workaround贝娄复制到我的webpack.config,一切都像魅力一样。:

resolve: {
  alias: {
    'pouchdb-promise$': "pouchdb-promise/lib/index.js"
  }
}