What is the proper way to install a pre-built database

Ok, so this code does not work with Android… I get a crash where the exception says:

 CouchbaseLiteException (POSIXDomain / 21): Is a directory."

Not sure what that is about - but just noting that I get this on the Database.Copy() method…

What code? What is not working?

Thiis code works, fer sure:

… and, fwiw, in the time that I spent in Copenhagen, I frequently found that the local’s English was as good, if not better than mine. “dived”, not “dove” is the correct past tense of “dive”. My complements, if not my surprise, are in order.

This code (for an existing app)
… and this code (for a new db):

var dftFolder = Service.GetInstance<IDefaultDirectoryResolver>().DefaultDirectory();
await seedService.CopyDatabaseAsync(dftFolder);
options.Directory = Path.Combine(dftFolder, "data");
Database.Copy(Path.Combine(dftFolder, "angler.cblite2"), "angler", options);

And this is the full stack trace

Couchbase.Lite.CouchbasePosixException: CouchbaseLiteException (POSIXDomain / 21): Is a directory.
  at Angler.Services.DbDataStore.InitAsync () [0x003a8] in /Users/jda/Developer/Git/DTU Aqua/app2/Angler/src/Angler/Services/DbDataStore.cs:117
  at Angler.ViewModels.LauncherPageViewModel.PrepareDb () [0x00025] in /Users/jda/Developer/Git/DTU Aqua/app2/Angler/src/Angler/ViewModels/LauncherPageViewModel.cs:72
  at AsyncAwaitBestPractices.SafeFireAndForgetExtensions.HandleSafeFireAndForget[TException] (System.Threading.Tasks.Task task, System.Boolean continueOnCapturedContext, System.Action`1[T] onException) [0x0006f] in <63bee8e7afc14051bfc24f7fd7c5ed2c>:0
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
  at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in /Users/builder/azdo/_work/278/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36
  at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in /Users/builder/azdo/_work/278/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36
  at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/builder/azdo/_work/278/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-29/mcw/Java.Lang.IRunnable.cs:84
  at at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.26(intptr,intptr)

It is C# - so there are some small differences, but when I look at the sample you provided I cannot see where the difference is…

The first parameter to the Copy method should be the cb2lite directory, right? That seems also to be the case in the Java code

The exact same code works on iOS

SOLUTION:
I left the above “reply in progress” for reference - if someone later runs into the same problem…

So after a long afternoon with trial-and-error coding I have now found a solution that seems to work for both platforms. And it is dead-simple…

The key is that you have to add a directory delimiter to the end of the .cblite2 text. So this line:

Database.Copy(Path.Combine(dftFolder, "angler.cblite2"), "angler", options);

MUST be changed to:

Database.Copy(Path.Combine(dftFolder, "angler.cblite2/"), "angler", options);

Just a small difference by adding ‘/’ to the end of the ‘.cblite2’ string… :slight_smile:

I have tested on both platforms and this seems to be the solution when you use C#/.net.

Interesting!

Yes, a Couchbase Lite database is a directory, not a single file.

1 Like

My point is that perhaps the documentation should show this :innocent:
Perhaps also mention in the documentation that the Database.Copy() does not move the database and that you manually have to delete the source…

Yes. It is a copy, not a move. Perhaps re-iterating that in the documentation would be a good idea. Will mention it to our docs team.

1 Like

Raised ticket to cover change work – https://issues.couchbase.com/browse/DOC-8554

I would also like to make a change so that the trailing slash is not required. This is a side effect of our core library handling generic paths and guessing where you meant a file called X or a directory called X. The platform knows that this should always be a directory and so it should add a slash if it is not there.

As far as documentation goes isn’t the fact that the method is called Copy enough to indicate that it does not move anything? The only platform this becomes an issue on is Android. Other platforms simply expect that you copy directly out of a read only source area and thus literally cannot move it.

2 Likes

Makes sense that either it is specified that you need the trailing slash - or that you don’t need it. And it should be consistent across platforms…

I agree that the name “Copy” should be enough to indicate that that is in fact what it does. It is probably just because of the way that we discussed it in the other thread that I was confused to believe that it did a “move”. Perhaps due to the sample that created a prebuilt database from the resources - and not a zipped database bundled with the app that first needs to unpack and then copy it… and the sample to do that did not contain the copy method. I guess it probably should (or at least mention it).

We will take care of fixing the samples

1 Like