Как сжать (сжать) файл базы данных SQLITE в Cordova? - PullRequest
0 голосов
/ 02 ноября 2018

Мне нужен режим «поддержки» для моего приложения Cordova, которое в настоящее время работает на Windows Mobile и iOS. Для этого мне нужно сжать файл базы данных sqlite и загрузить его на сервер. База данных должна быть сжата, поскольку она может вырасти до 250 МБ, а загрузка должна работать без подключения к Wi-Fi.

Поиск в Интернете вызвал разные подходы, но все они устарели или только решили мою проблему для iOS или Windows Mobile. Например, при использовании плагина Cordova file я столкнулся с этим в документации по плагину:

Поддерживаемые платформы

Android iOS OS X Windows * Браузер

  • Эти платформы не поддерживают ни FileReader.readAsArrayBuffer, ни FileWriter.write (blob).

Это был мой подход: Cordova - Zip-файлы и папки на iOS

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Я бы предложил вам дать FileReader () второй шанс.

В моем случае, который может быть очень похож на ваш, я читаю файл с помощью FilerReader.readAsArrayBuffer и после этого сжимаю его с помощью библиотеки JSZip: http://stuartk.com/jszip

В отличие от документации API-интерфейса плагинов cordova-file-plugin (https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/) "Windows *" -> "Эти платформы не поддерживают ни FileReader.readAsArrayBuffer, ни FileWriter.write (blob))" Я обнаружил, что readAsArrayBuffer работает на платформе Windows UWP, но медленнее.

Так что в моем случае с файлом ок. 50 м. Мне пришлось ждать почти 2 минуты, пока весь процесс не закончился!

Попробуйте следующий пример:

Вам нужно будет адаптироваться к вашим путям, но это работает для WINDOWS UWP и IOS (не проверял это с Android, но это не ваш вопрос).

Кроме того, вам необходимо реализовать собственный обработчик ошибок (errorHandler). В этом решении используются обещания, так как вам придется ждать, пока файл будет прочитан и сжат.

PS1: всегда убедитесь, что ваше «событие готовности устройства» запущено, чтобы получить доступ к плагинам.

PS2: Вы можете не иметь права доступа к файлу базы данных, это может быть связано с тем, что он используется другим процессом. Убедитесь, что база данных закрыта. SQLITE:

        var sqlite = window.sqlitePlugin.openDatabase({ name: 'yourdb.db', location: 'default' });
        sqlite.close(function () {
            console.log("DONE closing db");
        }, function (error) {
            console.log("ERROR closing db");
            console.log(JSON.stringify(error));
        });

Функция "ZIP":

    function zipFile(sourceFileName, targetFileName) {
    return new Promise(function (resolve, reject) {
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
            fs.root.getFile(sourceFileName, { create: false, exclusive: false }, function (fe) {
                fe.file(function (file) {
                    var reader = new FileReader();
                    reader.onloadend = function (data) {
                        var zip = new JSZip();
                        zip.file(sourceFileName, data.target.result);
                        zip.generateAsync({
                            type: "blob",
                            compression: "DEFLATE",
                            compressionOptions: {
                                level: 9
                            }
                            // level 9 means max. compression
                            // this may also take some time depending on the size of your file
                            // I tested it with a 50M file, it took about 65 sec.
                        }).then(

                            // following is post-zip in order to transfer the file to a server
                            function (blob) {
                                fs.root.getFile(targetFileName, { create: true, exclusive: false }, function (newzip) {
                                    writeFile(newzip, blob, "application/zip").then(function () {
                                        var f = blob;
                                        var zipReader = new FileReader();

                                        zipReader.onloadend = function (theFile) {
                                            var base64 = window.btoa(theFile.target.result);
                                            resolve(base64);
                                        };
                                        // need to "resolve" the zipped file as base64 in order to incluse it in my REST post (server-upload)
                                        zipReader.readAsBinaryString(f);
                                    });

                                });

                            }
                        )
                    };
                    reader.readAsArrayBuffer(file); 
                    // this may take some time depending on the size of your file
                    // I tested it with a 50M file, it took about 72 sec.
                }, errorHandler);
            }, errorHandler);
        });
    });
}

ex call:

if (window.cordova) {
    document.addEventListener('deviceready', function () {
        zipFile("yourDatabaseFileName.db","compressedDatabaseFile.zip");
    });
} 
0 голосов
/ 11 ноября 2018

Почему бы не использовать команду sqlite ".dump" в качестве запроса и получить результат через steam, а затем сжать вывод. Даже если текстовый дамп будет больше, при сжатии он получит разумный размер. Я думаю, что есть несколько очень хороших алгоритмов сжатия только текста,

...