如何强制PouchDB真正删除记录?

时间:2016-09-13 13:29:13

标签: html cordova couchdb web-sql

我正在创建一个像这样的PouchDb:

var db = new PouchDB('my_db', 
        { auto_compaction: true, revs_limit: 1, adapter: 'websql' });

然后我创建并删除了许多记录:

db.put({ _id: '1'});
db.put({ _id: '2'});
db.put({ _id: '3'});

db.get('1')
.then(function(doc) {
    db.remove(doc)
});

db.get('2')
.then(function(doc) {
    db.remove(doc)
});

db.get('3')
.then(function(doc) {
    db.remove(doc)
});

从我对文档的阅读中,这是deleteremove记录的正确方法。
这个SO questionanswer似乎也表明这是做事的方式。

但是,如果我使用Chrome检查器查看我的Web SQL DB,则记录仍然存在:

The records are still visible in my Web SQL database

我不相信这不是时间问题或类似的事情,因为我只需刷新删除代码然后得到404 not_found错误

我的应用程序在本地pouchDb中创建并保存记录,直到它们已同步到中央服务器,此时我想从本地数据库中清除它们。 我正在创建大量记录,如果我无法清除它们,那么最终我将耗尽设备上的空间(它是混合HTML5移动应用程序)。

甚至可以从本地PouchDB中实际删除记录吗?

如果是这样,我该怎么做?

如果没有,我可以轻松交换什么是一个很好的解决方案来代替PouchDB?

(我真的希望这是可能的,因为我走了这条发展道路,所以如果第一个问题的答案是否定,那么我需要对第三个问题给出一个好的答案)

1 个答案:

答案 0 :(得分:1)

正如上面的评论中所提到的,这还不可能,但正在进行(source 1 source 2)。但是,您可以使用一种工作方式。

解决方法是将数据库本地复制到另一个PouchDB数据库,复制完成后,删除原始数据库。删除的文档将不会被复制(source

这是一个有效的演示:

(() => {
  // DECLARATION
  const dbName = 'testdb';
  const tmpDBName = 'tmpdb';
  const deleteFilter = (doc, req) => !doc._deleted;
  const doc1 = { _id: 'd1' };
  const doc2 = { _id: 'd2' };

  //  CREATION
  //  create database
  const maindb = new PouchDB(dbName);
  //  insert two documents
  maindb.post(doc1)
    .then(() => maindb.post(doc2))
    //  query for one document
    .then(() => maindb.get(doc1._id))
    //  delete this document
    .then((doc) => { console.log(doc); return maindb.remove(doc) })
    //  query for the same document
    .then(() => maindb.get(doc1._id))
    .catch((err) => { console.log(err) });

  //  CLEANUP
  //  delete a database with tmpdb name
  new PouchDB(tmpDBName).destroy()
    //  create a database with tmpdb name
    .then(() => Promise.resolve(new PouchDB(tmpDBName)))
    //  replicate original database to tmpdb with filter
    .then((tmpDB) => new Promise((resolve, reject) => {
      maindb.replicate.to(tmpDB, { filter: deleteFilter })
        .on('complete', () => { resolve(tmpDB) })
        .on('denied', reject)
        .on('error', reject)
    }))
    //  destroy the original db
    .then((tmpDB) => {
      console.log(tmpDB.name);
      return maindb.destroy().then(() => Promise.resolve(tmpDB))
    })
    //  create the original db
    .then((tmpDB) => new Promise((resolve, reject) => {
      console.log(tmpDB.name);
      try {
        resolve({ db: new PouchDB(dbName), tmpDB: tmpDB })
      } catch (e) {
        reject(e)
      }
    }))
    //  replicate the tmpdb to original db
    .then(({db, tmpDB}) => new Promise((resolve, reject) => {
      tmpDB.replicate.to(db)
        .on('complete', () => { resolve(tmpDB) })
        .on('denied', reject)
        .on('error', reject)
    }))
    //  destroy the tmpdb
    .then((tmpDB) => tmpDB.destroy())
    .then(() => { console.log('Cleanup complete') })
    .catch((err) => { console.log(err) });

})()

如果在执行此代码后检查数据库的状态,它将只包含一个文档。请注意,有时我必须刷新浏览器才能看到数据库的最新状态(右键单击+刷新IndexedDB是不够的。)

如果要在测试时清理数据库,可以使用以下代码段:

['testdb', 'tmpdb'].forEach((d) => { new PouchDB(d).destroy() })