我如何强制 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() })
我正在像这样创建一个 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
但是,如果我使用 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() })