For backing up the database locally:
*.cblite
and the corresponding * attachments
folderTo restore the database:
Unfortunately I have no clue, how to create new revisions of each document without modifying it's data. How could this be done?
Also I think I have to delete all documents which are newer than the backup after the sync process has finished the first time, to avoid cluttering the local database with newer remote documents? How could I be sure the initial sync has been completed after the restore has taken place?
On Nov 14, 2015, at 1:55 AM, goo...@marco.betschart.name wrote:
Unfortunately I have no clue, how to create new revisions of each document without modifying it's data. How could this be done?
Afterwards I've posted this issue in the Couchbase Forums, but there seems to be no activity in this topic.
On Nov 21, 2015, at 7:19 PM, Brendan Duddridge <bren...@gmail.com> wrote:
Are you implying in your response to this question that you can't just replace the cblite2 database package and that you must read through the backup file, restoring to the current database with the contents of the backup file? Does that mean that you would then also have to delete all the documents created since the most recent document in the backup database?
func databaseReplicationChanged(notification: NSNotification){ guard let replication = notification.object as? CBLReplication else { return } if let error = replication.lastError{ print(error) NSLog(error.localizedDescription) } let replications = replication.localDatabase.allReplications() var pendingDocumentIDCount = 0 var idleReplicationCount = 0 for repl in replications{ if let pendingIDs = repl.pendingDocumentIDs{ pendingDocumentIDCount += pendingIDs.count } if repl.status == .Idle{ idleReplicationCount++ } }
print("pendingDocumentIDCount: \(pendingDocumentIDCount) - idleReplicationCount: \(idleReplicationCount)")
if replications.count == idleReplicationCount && pendingDocumentIDCount == 0 { NSNotificationCenter.defaultCenter().postNotificationName(PersistenceManagerNotification.DatabaseCompletedReplication.rawValue, object: replication.localDatabase) }}
func databasePurgePulledDocuments(database: CBLDatabase) throws{ for repl in database.allReplications(){ if repl.pull { if let documentIDs = repl.documentIDs{ print("documentIDs to delete: \(documentIDs)") for documentID in documentIDs{ try database.deleteLocalDocumentWithID(documentID) } } break } }}
hasPullReplication: falsehasPushReplication: falsependingDocumentIDCount: 0 - idleReplicationCount: 0pendingDocumentIDCount: 0 - idleReplicationCount: 02015-11-22 11:39:53.468 biz[5379:11135826] _BSMachError: (os/kern) invalid capability (20)2015-11-22 11:39:53.468 biz[5379:11135826] _BSMachError: (os/kern) invalid name (15)pendingDocumentIDCount: 0 - idleReplicationCount: 1pendingDocumentIDCount: 0 - idleReplicationCount: 2initialReplicationCompleted: Optional((Function))2015-11-22 11:39:53.710 biz[5379:11135826] Running database update...11:39:53.903‖ WARNING: CBL_Pusher[https://sync.mandelkind.biz:4984/biz]: Couldn't get local contents of {-hZTLhYojFIQjEkOxMFgRJB #1-cefce94614ae803e05594b95a7f60f47}2015-11-22 11:39:53.922 biz[5379:11135826] Database finished.pendingDocumentIDCount: 0 - idleReplicationCount: 111:39:54.396‖ WARNING: CBL_Pusher[https://sync.mandelkind.biz:4984/biz]: Couldn't get local contents of {-_8gOVW9U7S-LxzfIBgOkbz #1-f30d143725f00a5cca94b61ed5902576}pendingDocumentIDCount: 0 - idleReplicationCount: 2
On Nov 22, 2015, at 2:57 AM, goo...@marco.betschart.name wrote:
Although the kCBLReplicationChangeNotification gets called multiple times, it's always printing that there are 0 pendingDocumentIDs that need a sync (see code below).
On Nov 22, 2015, at 2:31 AM, Brendan Duddridge <bren...@gmail.com> wrote:
Well that definitely complicates things. Perhaps another way to reset back to a previous state would be to purge all the documents on the server for a specific channel?
On Nov 22, 2015, at 3:05 AM, goo...@marco.betschart.name wrote:
11:39:53.903‖ WARNING: CBL_Pusher[https://sync.mandelkind.biz:4984/biz]: Couldn't get local contents of {-hZTLhYojFIQjEkOxMFgRJB #1-cefce94614ae803e05594b95a7f60f47}
func databaseRestoreBackup(database: CBLDatabase, from date: NSDate, withManager databaseManager: CBLManager) throws -> CBLDatabase?{ ...
//delete the old database
try databaseDelete(database, withManager: databaseManager)
//Unzip backup to the manager directory
SSZipArchive.unzipFileAtPath(sourcePath, toDestination: databaseManager.directory)
//create new revisions of the restored documents
let database = try databaseManager.databaseNamed(database.name) let enumerator = try database.createAllDocumentsQuery().run() for i in 0..<enumerator.count{ if let doc = enumerator.rowAtIndex(i).document { try doc.newRevision().save() } }
//purge all remote documents
try PersistenceManager.sharedInstance().purgeRemoteDocuments(channel: Identity.sharedInstance().tenant, completion: { (result: AnyObject?) -> Void in do{ try self.databaseStartReplication(database, completion: { (notification) -> Void in PersistenceManager.sharedInstance().databaseSetup(database, withManager: databaseManager) }) } catch let error as NSError{ NSLog(error.localizedDescription) } }) ...}
func purgeRemoteDocuments(channel channel: String, completion: CompletionHandler? = nil) throws{ guard let serverURL = self.replicationConfig["url"] as? NSURL, let serverDatabase = self.replicationConfig["database"] as? String, let serverUsername = self.replicationConfig["username"] as? String, let serverPassword = self.replicationConfig["password"] as? String else { throw PersistenceManagerError.ConfigInvalid }
Alamofire.request(.GET, serverURL .URLByAppendingPathComponent(serverDatabase) .URLByAppendingPathComponent("_all_docs"), parameters:[ "channels":"true" ]) .authenticate(user: serverUsername, password: serverPassword) .responseJSON { response in switch response.result { case .Success(let data): let json = JSON(data)
if let documents = json["rows"].array{ for document in documents{ if let channels = document["value"]["channels"].arrayObject as? [String]{ if channels.indexOf(channel) != nil{ if let docID = document["id"].string{ Alamofire.request(.DELETE, serverURL .URLByAppendingPathComponent(serverDatabase) .URLByAppendingPathComponent(docID)) .authenticate(user: serverUsername, password: serverPassword) .responseJSON { response in switch response.result { case .Success(_): NSLog("Deleted remote document with id '\(docID)'") case .Failure(let error): NSLog(error.localizedDescription) } } } } } } } if let handler = completion{ handler(result: data) } case .Failure(let error): NSLog(error.localizedDescription) if let handler = completion{ handler(result: error) } } }}
On Nov 22, 2015, at 11:41 AM, goo...@marco.betschart.name wrote:
And afterwards deleting every single document using the following request for each one:
function(doc,meta){ if( !doc._deleted && doc.channels && doc.channels.length && doc.type != 'Setting' ){ for( var i = 0; i < doc.channels.length; i++ ){ emit(doc.channels[i],doc); } }}
couchbaseClient.asyncSaveView('channels','channel',... map function code from above ...)
couchbaseClient.query('channels','channel',{ key=arguments.channelId })
<cfloop array="#local.docs#" item="local.doc" index="local.index">
<cfset future = couchbaseClient.delete(local.doc.id) />
<cfoutput>#future.getStatus().getMessage()#</cfoutput><cfabort> <!--- this outputs 'Not Found' ---->
</cfloop>
Thanks in advance
{
DOCUMENT = '',
ID = '--2szFNTpPIAxX1X68LZo3u',KEY = '9c0bb124365c49d48e5e0c5577f0000d',VALUE = '{"_sync":{"rev":"2-be773aa928134657f796ce90a02caaf1","sequence":34678,"recent_sequences":[34611,34678],"history":{"revs":["1-575fde964b77a7e916f7b3f395acb4e6","2-be773aa928134657f796ce90a02caaf1"],"parents":[-1,0],"channels":[["9c0bb124365c49d48e5e0c5577f0000d"],["9c0bb124365c49d48e5e0c5577f0000d"]]},"channels":{"9c0bb124365c49d48e5e0c5577f0000d":null},"time_saved":"2015-11-24T21:38:46.558978545+01:00"},"channels":["9c0bb124365c49d48e5e0c5577f0000d"],"type":"CostCenter","value":"Marketing"}'}