Copy Pre-populated Database and channels

I have a database that contains over 600MB of attachments. I need to embed the mobile database WITHOUT the attachments into my app. So I created two channels: data and att. Documents without attachments are set to the data channel. Those with attachments are set to the att channel.

I have a Windows program that opens the database using only the “data” channel to give me all the data but NO documents. I then embed this database into my app.
Now, in my app, when I start my replicator using BOTH channels, nothing gets synced. I would expect the attachments to start coming over but they do not,

What am I missing?

I’m using Couchbase.Lite 2.8.6 and C# / Xamarin Forms

An example of a “att” channel document:
{
“$id”: “366312”,
“CreateDate”: “0001-01-01T00:00:00+00:00”,
“CreateUserId”: “00000000-0000-0000-0000-000000000000”,
“Error”: null,
“ErrorMessage”: null,
“IsSelected”: false,
“ModifyDate”: null,
“ModifyUserId”: null,
“RowId”: “002725c5-03fc-40af-abbe-4a8d10e7f95d”,
“Type”: “DocWithAttachment”,
attachments": {
"blob
/Image”: {
“content_type”: “image/png”,
“digest”: “sha1-7HTSGN5Ct9ihtW1YXLtWJuK41P0=”,
“length”: 84691,
“revpos”: 2,
“stub”: true
}
},
“channels”: [
“att”
]
}

@blimkemann Can you share us the sync part of cbl logs? You can find them in info log.

From the server or the device?

@blimkemann From the device (CBL Logs) please. Besides Info log, I am also interested to see if there is any error log as well.

I don’t see any logs on the device. How do I enable logging so it writes to a file - and what log levels do I need?

@blimkemann Here is the info about how to use our logging: Using Logs for Troubleshooting | Couchbase Docs
I would suggest we set the log level at info so we can track sync activities or error if there is any.
By the way, your sync gateway config has configured with the proper channels I believe?

Yes, sync gateway allows all channels.
I will generate the logs and get back to you…

The error log is the only thing showing anything interesting:
17:53:31.904766| [Sync] ERROR: {IncomingBlob#40} Got LiteCore error: POSIX error 13 “Permission denied”
It looks like it hits this (and FYI a few “att” documents are coming over) and then stops.

@blimkemann Usually Posix error 13 “Permission denied” relates to filesystem error. It means you probably don’t have permission to read the canned database files.
Maybe you probably need to check out this first: Pre-built Database | Couchbase Docs

@blimkemann Please ignore above comments. I missed the IncomingBlob part in the log. The error actually means possibly the attachments directory has no write permission. Still a file system error.

Then why would I get some files and not others? They all go to the same directory, right?

I think the actual problem is a crash in LiteCore that occurs AFTER copying the database and opening the destination one and starting the replicator. My copy code is below. Once I open the copied database and the replicator has started, I get a System.AccessViolationException in Couchbase.Lite.dll.

Note that in a previous version of this app, I was just using a file copy rather than Database.Copy and this crash did not happen. I think this is all related somehow…

UPDATE: same issue happens with a File.Copy as well. And I tried 2.8.4 as well as 2.8.6 and the same issue happens. It this a threading issue perhaps?

var db = new global::Couchbase.Lite.Database(Database.Current.EBookCB.DatabaseName, new DatabaseConfiguration { Directory = Settings.EBookPath });
var path = db.Path;
db.Close();
global::Couchbase.Lite.Database.Delete(DatabaseEBook.EBookDatabaseName, Settings.EBookPath);

			await Task.Run(() =>
			{
				var stream = typeof(Settings).Assembly.GetManifestResourceStream("Redbook.Mobile.Assets.EBook.db.zip");
				if (stream == null)
					throw new Exception("Embedded database file not found.");

				var tempPath = Path.Combine(Settings.EBookPath, "temp");
				if (System.IO.Directory.Exists(tempPath))
					System.IO.Directory.Delete(tempPath, true);

				using (var archive = ZipFile.Read(stream))
				{
					archive.ExtractProgress += Archive_ExtractProgress;
					archive.ZipError += Archive_ZipError;
					foreach (var entry in archive.Entries)
						TotalArchiveSize += entry.UncompressedSize;

					foreach (var entry in archive.Entries)
						entry.Extract(tempPath, ExtractExistingFileAction.OverwriteSilently);
				}

				if (!tempPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
					tempPath = tempPath + Path.DirectorySeparatorChar.ToString();
				System.Diagnostics.Debug.WriteLine($"Copying from {tempPath} to {Settings.EBookPath} using name \"{Database.Current.EBookCB.DatabaseName}\"");
				global::Couchbase.Lite.Database.Copy($"{tempPath}", Database.Current.EBookCB.DatabaseName, new DatabaseConfiguration { Directory = Settings.EBookPath });
			});

Error log states:
---- CouchbaseLite/2.8.6 (.NET; UWP 10.0.19043.1165; Dell Inc. G5 5505) Build/6 LiteCore/2.8.6 (3) Commit/d28a0c4c ----
07:39:41.208553| [WS] ERROR: {C4SocketImpl#18} WebSocket failed to connect! (reason=WebSocket/HTTP status 1000)
07:39:41.223980| [Sync] ERROR: {Repl#16} Got LiteCore error: WebSocket error 1001 “WebSocket connection closed by peer”
07:39:41.231048| [Sync] ERROR: {C4Replicator#17} State: connecting, progress=0.00%, error=WebSocket error 1001 “WebSocket connection closed by peer”
07:39:41.269959| [Sync] ERROR: {C4Replicator#17} State: stopped, progress=0.00%, error=WebSocket error 1001 “WebSocket connection closed by peer”

@blimkemann Can you set the log level to verbose? The error in the log is related to websocket connection failed. Verbose log will show more info besides syncing issue.

The problem is that I was actually starting a replicator twice! Oddly, this has worked for many months, but once I added channels to it that crash started appearing. Now that I’m starting it only once things seem fine.

Thanks for the help.

Odd. Usually starting a started replicator will result in no-op. Oh well. Glad you fix the issue!