storesafe / cordova-sqlite-storage

A Cordova/PhoneGap plugin to open and use sqlite databases on Android, iOS and Windows with HTML5/Web SQL API
Other
2.15k stars 715 forks source link

Document the actual database location #426

Open brodycj opened 8 years ago

brodycj commented 8 years ago

This is already documented for iOS. This needs to be documented for Android. Also for Windows and WP(7/8) in the other project versions.

brodycj commented 8 years ago

Also from #425: guidelines how to download a database from a server, save it in the file system, and open it with this plugin.

jonathancma commented 8 years ago

Hey brodybits, Thanks for all the effort! As for this specific issue, it so happens that this is exactly what I need help with. I think it's a small matter, I just need the full cdvfile-style URL for the database file in both Android and iOS. This is so I can use the file-transfer plugin: https://github.com/apache/cordova-plugin-file-transfer I tried using the File API to browse around and search for the database file on my own, but I'm sure you can help a lot by just knowing the cdvfile:// path Will they be two different ones for Android or iOS? Cheers

jonathancma commented 8 years ago

Here's some pseudo-code to send database to PHP script. Assumes location: 2 on iOS Uses cordova-plugin-device, cordova-plugin-file, cordova-plugin-file-transfer and of course SQLite:

// do this after successful callback from db.close(cb):
     var dbFolderPath = "";

    if(device.platform == "Android")
    {
        dbFolderPath = cordova.file.applicationStorageDirectory + "databases/";
    }
    else if(device.platform == "iOS")
    {
        dbFolderPath = cordova.file.applicationStorageDirectory + "Library/LocalDatabase/";                                    
    }

    window.resolveLocalFileSystemURL(dbFolderPath, function(dbFolderEntry) 
        {
            var dbFilePath = dbFolderPath + "databaseName";

            window.resolveLocalFileSystemURL(dbFilePath, function(dbFileEntry) 
                {                       
                    var fileURL = dbFileEntry.toInternalURL();

                    var win = function (r) {

                        // Re-open the connection
                        //db = window.sqlitePlugin.openDatabase...

                        callback.call(scope, true);
                    };

                    var fail = function (error) 
                    {
                        // Re-connect to database
                        me.db.getConnection();

                        callback.call(scope, false);
                        console.log("An error has occurred: Code = " + error.code);
                        console.log("upload error source " + error.source);
                        console.log("upload error target " + error.target);
                    };

                    var options = new FileUploadOptions(); 
                    options.fileKey = "file";
                    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
                    options.mimeType = "application/octet-stream";

                    var params = {
                        usefulData: 4
                    };

                    options.params = params;

                    var ft = new FileTransfer();
                    ft.upload(fileURL, encodeURI("somewhere.com/uploadDatabase.php"), win, fail, options);
                });
        });`

Here is my PHP script:

<?php
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.

$usefulData = $_POST['usefulData'];

$uploaddir = '';
//$uploadfile = $uploaddir . basename($_FILES['file']['name']);
$uploadfile = $uploaddir . $usefulData . '-' . date('Y-m-d-H-i-s') . '.db';

echo '<pre>';
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "</pre>";

?>

For some reason files over 30MB get failed on the client, but the server got the file all the same. Will try to post back a solution. Good luck

brodycj commented 6 years ago

Here's some pseudo-code to send database to PHP script. [...]

As I said in https://github.com/litehelpers/Cordova-sqlite-help/issues/41 there is a major risk of uploading a corrupt database file. It is recommended to get a dump of the required data and upload it by normal means. Marked as a possible data loss pitfall that needs to be documented.

jonathancma commented 6 years ago

It's good to see that my comment has been flagged as dangerous in order to protect other developers. I can report from my project that if I close() the connection before uploading the file, the upload is successful. This has been used in production environment with about 100 end-points with no problems for about 1.5 years. That is not to say that it is the correct usage. Devs should do their research according to https://github.com/litehelpers/Cordova-sqlite-help/issues/41 . I'm just reporting it here to maintain order and to offer the possibility that closing the connection prior to upload could be the correct procedure, but this needs to be approved by someone who actually did the research. I have moved on to another project and don't currently have the time to do the research.

I have nothing to report on the 30MB limit. I'm sorry but I forgot what happened with that in the end. I'm pretty sure large files work fine, as my clients are uploading zipped databases which can get very large. It will be nice to have a report on that from someone.

Cheers!

brodycj commented 6 years ago

Thanks @jonathancma, my response is in litehelpers/Cordova-sqlite-help#41 (it should be OK, would need some research to confirm).

P.S. The "pseudo" JavaScript code above does look right in terms of getting the standard database location on Android and iOS. I would prefer to avoid the hardcoded "/" character by using the File API to get the desired subdirectory, despite the inefficiency. If we can also resolve this for Windows then we would have the solution ready to document.

P.S.S. I was blind to your comment:

// do this after successful callback from db.close(cb):

Most of your JavaScript just happened to be shown as a code block due to the 4-space indentation. In the future it would be extremely helpful if you can mark your JavaScript like this:

```js
// Your awesome JavaScript code ...
```

Same idea for PHP, Python, Java, C, C++, etc.

Thanks for your ideas and contribution.

jonathancma commented 6 years ago

My apologies! I edited the original comment and it is now formatted correctly. Had I taken the time to fix the formatting originally I could have spared the confusion... lesson learned. The devil is in the details.