New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Database.copy throwing an error #444
Comments
Thanks for filing this issue! There were a few issues with the example code, and I have rewritten it: import 'dart:io';
import 'package:archive/archive_io.dart';
import 'package:cbl/cbl.dart';
import 'package:flutter/services.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
Future<void> installMyPrebuiltDatabase() async {
final zipArchive =
await rootBundle.load('asset/database/my-database-prebuilt.zip');
final documentsDirectory = await getApplicationDocumentsDirectory();
final databasesDirectory = path.join(documentsDirectory.path, 'databases');
await installPrebuiltDatabase(
zipArchive: Uint8List.sublistView(zipArchive),
nameInArchive: 'my-database',
name: 'my-database',
config: DatabaseConfiguration(directory: databasesDirectory),
);
}
/// Installs a prebuilt database from a [zipArchive].
///
/// The prebuilt database must have the name specified by [nameInArchive] and be
/// located at the root of the archive.
///
/// To create the archive, use the `zip` command line tool:
///
/// ```sh
/// zip -r my-database-prebuilt.zip my-database.cblite2
/// ```
///
/// [name] and [config] are used to install the database.
Future<void> installPrebuiltDatabase({
required Uint8List zipArchive,
required String nameInArchive,
required DatabaseConfiguration config,
required String name,
}) async {
// Dont't overwrite an existing database.
if (await Database.exists(name, directory: config.directory)) {
return;
}
// Use a temporary directory for unpacking the prebuilt database to avoid
// naming conflicts.
final tempDirectory =
await Directory(config.directory).createTemp('prebuilt-');
final prebuiltDatabaseFileName =
path.join(tempDirectory.path, '$nameInArchive.cblite2');
try {
// Unpack the prebuilt database.
final archive = ZipDecoder().decodeBytes(zipArchive);
await extractArchiveToDiskAsync(archive, tempDirectory.path);
// Make a copy of the prebuilt database.
await Database.copy(
from: prebuiltDatabaseFileName,
name: name,
config: config,
);
} finally {
// Clean up the temporary directory.
await tempDirectory.delete(recursive: true);
}
}
Future<void> extractArchiveToDiskAsync(
Archive archive,
String outDirectory,
) async {
for (final file in archive.files) {
final fileName = path.join(outDirectory, file.name);
if (file.isFile) {
final ioFile = File(fileName);
await ioFile.create(recursive: true);
await ioFile.writeAsBytes(file.content as List<int>);
} else {
await Directory(fileName).create(recursive: true);
}
}
} Could you take a look at it and try it out? |
Hi @blaugold - thanks for taking a look into this. I tried using the code that you provided. I made one small change to create the databases directory first before creating the temp directory. The zip file gets extracted to the temp directory successfully. However, the same exception is still being raised during the
|
Thanks for trying this. I understand the error to mean that we are trying to copy a file ( In the first error message I haven't tried to replicate the issue on Android yet, so I'll try that too. It might be specific to that OS. |
I removed the line to delete the temp directory and then using adb saved the cblite2 file that was extracted. I can confirm that the file is still intact and returns all the document ids when running |
I wrote using a prebuild database for our learning path, and when I tested it on both iOS and Android, it worked fine (of course, this was a few weeks ago). My code is here: I wrote how to do this as part of our learning path for Flutter using CBL-Dart, which is a work in progress but was tested about a month ago. Not sure if this helps or not. |
@PritamSangani Thanks for letting me know. @biozal Definitely good to know that you got it working! I hadn't seen the learning path on the developer portal yet. Very cool! |
@blaugold - it's still a work in progress I have 2 things to finish up on it, but some App Services stuff has been chewing my free time. My plan is to finish it up with 3 more sections in the next few weeks. |
@biozal - Thanks for sharing. The learning path is really interesting and I like that it is a complex app, which really showcases what can be done with couchbase! The example repo you posted seems to be working for ios but it doesn't work for android. For android, I am getting the same error at the I double checked the log output for android and ios and I noticed that the directory that the database is being copied to is different for android and ios. Using the example from the link that @biozal posted, For ios the copy was happening from However, for android the copy is happening from I think the database should be copied to I believe there is a bug in how the |
@blaugold - have you had a chance to take a look at whether this is an issue in this library or the native cblite c library? |
Sorry for not responding earlier. I found the problem but forgot to update the issue. The Couchbase Lite C SDK expects the path to the source database to end with a path separator, e.g. I would classify that as a bug, since the expected format is not documented and is not super common. I think the Couchbase Lite C SDK should take paths with and without trailing slash, but I can implement a fix in CBL Dart meanwhile. |
This worked! Thanks for your help and quick responses @blaugold! |
Describe the bug
I am trying to copy a pre-built database (zipped up) using the Database.copy method using code from the bottom of this page as a guide https://cbl-dart.dev/prebuilt-database/#creating-pre-built-database.
When unzipped the prebuilt database folder structure is like:
with the arrows representing the hierachy of the folder.
The database gets loaded into the app directory succesfully and I have verified this by using the adb file explorer. However, when the code gets to the Database.copy step an unhandled exception is thrown. The exception looks like this:
To Reproduce
The code I am using is very similar to what is on the page I have linked above, but I'll post the relevant code here anyway (leaving out the part of checking if db exists)
Expected behavior
The database should get copied over successfully
Screenshots
If applicable, add screenshots to help explain your problem.
Environment (please complete the following information):
Additional context
I have verified that the database got built successfully by running
cblite ls
on the.cblite2
file and all the document ids were logged.The text was updated successfully, but these errors were encountered: