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

how do I force PouchDB to really delete records?

我正在像这样创建一个 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)
});

根据我对文档的阅读,这是 delete and remove 记录的正确方法。
而这个 SO and 似乎也暗示这就是做事的方式。

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

我不认为这不是时间问题或类似问题,因为我可以仅使用删除代码进行刷新,然后得到 404 not_found 错误


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

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

如果可以,我该怎么做?

如果没有,我可以轻松替换 PouchDB 的好的解决方案是什么?

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

正如上面评论中提到的,这还不可能,但正在努力 (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() })