Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Database Not Updating with App Update

It appears that when you install a database in your app, it puts it in the user's data folder in the iOS. Database changes don't get pulled into the app without deleting and reinstalling the app (an app update leaves the user's data intact).

What's the best way to make sure your app pulls in the new database on subsequent app updates?

— asked September 10th 2010 by Clifton Labrum
  • database
0 Comments

11 Answers

  • I realized that since your users will update at random intervals (some skip 1.1 and upgrade when they see 1.2 or something) then you don't want to keep your version number in the database name (airports1, airports2, etc.). But it works just as well to just use the same DB name every time. The cached file still gets removed and reinstalled. This also means you don't need a one-time-only condition like I do. So the final code would look like this:

    //Reference prior, cached database
    var dbOLD = Titanium.Database.install('airports.db', 'airports');
    //Destroy it
    dbOLD.remove();
    //Install new database
    var db = Titanium.Database.install('airports.db', 'airports');
    

    So even first-time users will install the DB twice, but it's just to make sure a cached version isn't in there.

    I find that I have to build my app a couple times after a DB change for it to start showing up, so don't worry if your first build doesn't seem to have the DB changes.

    — answered September 30th 2010 by Clifton Labrum
    permalink
    2 Comments
    • Yep, I think this should do the trick. Good solution.

      — commented September 30th 2010 by Randy Hall
    • I'm using this code, but it doesn't seem to use my new database until I've closed and opened the application once… why is that?

      — commented February 14th 2011 by Ted Sundin
  • Okay, I think I've got it. Let me know what you think of this:

    //Reference prior, cached database
    var dbOLD = Titanium.Database.install('stuff10.db', 'stuff');
    //Destroy it
    dbOLD.remove();
    //Install new database
    var db = Titanium.Database.install('stuff11.db', 'stuff');
    

    Thoughts?

    — answered September 10th 2010 by Clifton Labrum
    permalink
    2 Comments
    • As long as you don't have user-generated info in the database, then removing the old DB is fine. If you do, and you don't want to go through the SQL change route I suggested earlier, another solution I saw someone propose was to upload the user's data to a web database, replace the local DB as you suggested, then download their data into the new DB.

      — commented September 10th 2010 by Tim Poulsen
    • This database is read-only in my app. I do settings and user data with properties.

      Thanks for your help, Tim. :)

      — commented September 10th 2010 by Clifton Labrum
  • Okay, I think I've finally got this figured out.

    When you use the Database.install function, it copies the database from your Resources folder into the app's cache (~/Library/Application Support/iPhone Simulator/4.x/Applications/1234ABCetc/Library/Application Support/database).

    Hang on while I catch my breath after typing that path. Okay.

    It copies it there and names it whatever is in the 2nd attribute of the install function:

    var db = Titanium.Database.install('airports.db', 'airports123');
    

    So the cached version of the DB will be airports123.sql.

    So here's how you remove the cached version and update to the latest database. Keep in mind that you never rename your core DB that's in the Resources folder. That's the primary data source.

    //Put everything in an if statement controlled by a flag 
    you so you only execute this once per app build
    
    var firstTime = Titanium.App.Properties.getString('firstTime');
    
    if(firstTime != 'no'){
        Titanium.App.Properties.setString('firstTime','no');
    
    //Reference prior, cached database
    var dbOLD = Titanium.Database.install('airports.db', 'airports1');
    //Destroy it
    dbOLD.remove();
    //Install new database
    var db = Titanium.Database.install('airports.db', 'airports2');
    
    }
    

    This will make a new copy of your DB with the airports2 name and your users will have fresh data when they update to this version.

    Good luck!

    — answered September 29th 2010 by Clifton Labrum
    permalink
    0 Comments
  • I've yet to deal with this in my app. But I need to before I publish. From what I've seen in other postings is that you have to handle this within your app. For example, you might create a db table with a single record containing your app's database schema version number. When the app launches, it can check that version and if it should be newer, then your app would go through an upgrade routine. This gives you the flexibility to update the code without going through a database change (if your updates didn't involve any DB changes).

    Tim

    — answered September 10th 2010 by Tim Poulsen
    permalink
    3 Comments
    • Interesting idea. But how would you do an upgrade routine with Titanium?

      All we can do is install:

      var db = Titanium.Database.install('stuff.db', 'stuff');
      

      My app already does that, but it doesn't load the new database, it loads the cached one. I'm not familiar with any methods on the Database module that allow deleting and re-installing. :(

      — commented September 10th 2010 by Clifton Labrum
    • Something like:

      var dbShouldBeVersion = 2;
      var currentDBVersion = 999999; // arbitrary starting number
      var resultSet = conn.execute('SELECT schemaVersion FROM appProperties LIMIT 1');
      if (resultSet.isValidRow()) {
          currentDBVersion = resultSet.fieldByName("schemaVersion");
      } 
      resultSet.close();
      if(dbShouldBeVersion > currentDBVersion) {
          // issue SQL commands to modify the table here
          conn.execute('ALTER TABLE foo ...');
          // then, update your database with new version number
          conn.execute('UPDATE appProperties SET schemaVersion = ? WHERE rowID = 1',dbShouldBeVersion);
      }
      

      Tim

      — commented September 10th 2010 by Tim Poulsen
    • Innovative. I like it.

      But I usually push a database change after making a whole bunch of changes in a tool like Base and I don't want to have to line up a bunch of update queries just to tweak the data (especially if there are lots of changes). Know what I mean?

      — commented September 10th 2010 by Clifton Labrum
  • -subscribing-

    — answered September 26th 2010 by Jicks Steen
    permalink
    0 Comments
  • I've been getting errors and crashes trying to use the db.remove() technique. Unfortunately I have yet to find a consistent, reliable way to update the database with an app update. Even renaming the database hasn't worked for me yet.

    — answered September 29th 2010 by Clifton Labrum
    permalink
    0 Comments
  • Hi,

    I use this function for get the path to sql file generate by Ti.Database.install

    // sqlFile is the name of database
    // example : 
    // If your code like this - > Ti.Database.install('iphone.sqlite', 'main');
    // you write this - > getSqlFilePath('main');
    
    function getSqlFilePath(sqlFile) {
    
        sqlFile = sqlFile + '.sql';
    
        var path = Ti.Filesystem.applicationDataDirectory;
    
        path = path.replace('Documents', 'Library');
    
        path = path + 'Private%20Documents/'+sqlFile;
    
        return path;
    }
    

    and for delete this, you must just write this ->

    var sqlFilePath = getSqlFilePath('main');
    
    var oldBddSql = Ti.Filesystem.getFile(sqlFilePath);
    
    oldBddSql.deleteFile();
    

    This code work fine only on iOS < 6.1.4
    On 6.1.4, the sql file exist too but deleteFile() has no effect.

    my code :

     oldBddSql.deleteFile();
    Ti.API.info(oldBddSql.exists()); // return true...
    

    maybe sql file is protected ? have you an idea?

    Tanks.

    — answered July 11th 2013 by Decaillot Julien
    permalink
    0 Comments
  • -subscribing-

    — answered July 8th 2011 by ilan perez
    permalink
    0 Comments
  • -subscribing-

    — answered September 10th 2010 by danno watts
    permalink
    0 Comments
  • One possibility is to give your database a new name with each release, but I imagine this will build up a pile of unused databases in the user's data folder.

    var db = Titanium.Database.install(&#39;stuff10.db&#39;, &#39;stuff&#39;);

    var db = Titanium.Database.install(&#39;stuff11.db&#39;, &#39;stuff&#39;);

    var db = Titanium.Database.install(&#39;stuff12.db&#39;, &#39;stuff&#39;);

    etc.

    Seems so dirty…

    — answered September 10th 2010 by Clifton Labrum
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.