Twitter: cfjedimaster


Address: Lafayette, LA, USA

Guest Blog Post: Shipping a populated SQLite DB with PhoneGap

07-27-2012 8,343 views Mobile 18 Comments

This is my second "Guest Blog Post" for the month. Sorry I've been a bit slow on my own content lately! Today's post comes from Scott Buckel. He and I shared a conversation earlier this month about databases and PhoneGap. PhoneGap makes it pretty darn easy to create and work with a database in your application. What isn't so trivial is actually shipping a prepopulated database with the app itself. I wasn't able to help him as much as I'd like - but he worked at it until he came up with a solution. Here is what he discovered.

These instructions are very raw, and not optimized.

  1. I used this plugin: https://github.com/chbrody/Cordova-SQLitePlugin/

  2. Copy your sqlite db file to /assets folder of PhoneGap.

  3. Then, follow instructions here: http://gauravstomar.blogspot.com/2011/08/prepopulate-sqlite-in-phonegap.html to copy the file to native storage. Change this.copy("Databases.db","/data/data/"+pName+"/app_database/");
    1. Instead of Databases.db, use your database filename.
    2. Instead of app_database, use "databases"
    3. You'll probably want to delete the file from /assets, since it is duplicated and no longer needed. My app was double the size it needed to be.

  4. (Not sure if this step is necessary, I'm getting out of the office for the day). Edit SQLitePlugin.java
    1. Lines 176, I edited 1==1 so that if statement is always executed. Line 179 I changed this.setStorage(appPackage, false); to this.setStorage(appPackage, true);
  5. You can then use the following command to open the DB and use it as any other PhoneGap database
    1. var db = window.sqlitePlugin.openDatabase("[full_database_name_including_extension]", "1.0", "PhoneGap Demo", 200000);

10 hours of work later, I have a working database!

Feel free to use this information on a blog, I feel it would help a LOT of people out. Step #4 is weird, I'm sure there's a "prettier" way to do it. If used, just give Scott Buckel @ Corporate Zen credit please :).

18 Comments

  • Vitgas #
    Commented on 08-02-2012 at 5:38 AM
    May you upload some screenshots showing how your proyect is organized and those changes you remark?
    Thanks!
  • Commented on 08-03-2012 at 2:19 PM
    Vitgas, feel free to email me directly and I'd be glad to help. I'll have Ray update the blog after I understand your questions.
  • Commented on 08-08-2012 at 3:32 PM
    Here's an updated version on how I did this. Thanks to Ray for all of his help!
  • Commented on 08-08-2012 at 3:34 PM
    Did you mean to post a link?
  • Commented on 08-08-2012 at 3:36 PM
    Here is the link he meant: http://www.corporatezen.com/shipping_prepopulated_...
  • Jeremy #
    Commented on 09-30-2012 at 9:53 AM
    Thanks so much for this post! It helped point me in the right direction for my own project. For any iOS developers, I found the linked instructions in http://gauravstomar.blogspot.com/2011/08/prepopula... to be a little out of date.

    When using the Cordova-SQLitePlugin, it looks in the Documents directory, and Gaurav Tomar's instructions refers to WebKit/Databases directory (which I believe is no longer used because of an iOS 5.1 change).

    I found the following works instead:

    NSString *databaseName = @"Database.db";

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *databasePath = [documentPaths objectAtIndex:0];

    NSString *databaseFile = [databasePath stringByAppendingPathComponent:databaseName];
    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

    NSFileManager *fileManager = [NSFileManager defaultManager];

    if ([fileManager fileExistsAtPath:databaseFile] == NO) {
       [fileManager copyItemAtPath:databasePathFromApp toPath:databaseFile error:nil];
       [fileManager release];
    }

    Thanks again for pointing me in the right direction!
  • Commented on 10-05-2012 at 4:17 PM
    You can use the working steps here to create prepopulated databases with PhoneGap:
    http://iphonedevlog.wordpress.com/2012/10/05/insta...
    or
    http://iphonedevlog.wordpress.com/2012/08/21/prepo...

    Regards,
    Steve Husting
  • Vaibhav #
    Commented on 01-22-2013 at 12:07 PM
    What is the best way to use this data to create knockout JS bindings on the underlying HTML. do i need to create separate JSON object first with the data that i get from the queries or is there an easier way to integrate this with knockout.js?
  • Commented on 01-22-2013 at 12:39 PM
    Unfortunately, I have not had a chance yet to play with Knockout. Therefore, I've definitely not used it with PhoneGap either.
  • Kristen #
    Commented on 02-13-2013 at 1:46 PM
    Wow! Thank you so much! I have been trying to get this working forever. Your example worked like a charm and I'm finally up and running.
  • Commented on 03-08-2013 at 4:52 AM
    Wow from me too!! We got this sorted via this post. Thanks a bunch guys!! :-)
  • Commented on 04-08-2013 at 12:26 AM
    Correct me if I am wrong (haven't really tested the code), but the example here would overwrite the database with the preshipped version everytime the app loads. Is that right? If we are building an app with persistent storage, should we check to see if the database files already exist before doing this.copy(...) or perhaps modify this.copy()?
  • Commented on 04-24-2013 at 5:32 PM
    If anyone is looking to use a pre populated db with iOS here is updated plugin SQLitePlugin-iOS. You dont need to do any of the steps above. All you need to do is put your db in the root of your XCode project and it does everything for you. Android you still need to do the steps above.

    https://github.com/jarlehansen/PhoneGap-SQLitePlug...
  • Commented on 04-25-2013 at 8:26 AM
    This is how my MyPhoneGapActivity.java looks like

    package com.rkadukar.database;

    import org.apache.cordova.DroidGap;
    import android.os.Bundle;

    public class MyPhoneGapActivity extends DroidGap {
       @Override
       public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          super.loadUrl("file:///android_asset/www/index.html");
       }
    }

    where do I add the code from Gaurav Tomar's site after I make the changes suggested by you
  • Commented on 04-25-2013 at 8:31 AM
    Thanks for sharing that John.
  • shashank dwivedi #
    Commented on 05-06-2013 at 4:58 AM
    How can I use this with phonegap build? Any idea.....
  • Commented on 05-06-2013 at 7:34 AM
    You can't. PGB supports a limited set of plugins only.
  • Commented on 05-06-2013 at 7:55 AM
    I've successfully implement this on a simple POS app. Now I have a different requirement -- nothing to do with the previous POS app.

    Is there a way for me to download a SQLite file and do SQL operations on that SQLite database file? Here's why I need that. My app will be downloading a huge document, and for searching purpose, I am thinking of implementing the index using the SQLite database file.

    Got ideas on how I can do this?

Post Reply

Please refrain from posting large blocks of code as a comment. Use Pastebin or Gists instead.

Leave this field empty