tciuro / NanoStore

NanoStore is an open source, lightweight schema-less local key-value document store written in Objective-C for Mac OS X and iOS.
Other
404 stars 39 forks source link

Migration from older version of NanoStore #78

Closed siuying closed 11 years ago

siuying commented 11 years ago

I have an app using NanoStore for some time. When upgraded to latest version, I found I can no longer open existing database.

The app crash when opening database:

2013-02-21 15:00:49.527 iPhoneTest[16648:907] *** -[NSFNanoStore openWithError:]: the SQL statements could not be prepared when opening database: /var/mobile/Applications/C3287912-20F6-42B7-A1AA-D7BBDDCCB859/iPhoneTest.app/clipper.db

Upon investigation, i found the changes at: https://github.com/tciuro/NanoStore/blob/master/Classes/Public/NSFNanoStore.m#L821

The new version create a database with:

CREATE TABLE NSFKeys(ROWID INTEGER PRIMARY KEY, NSFKey TEXT, NSFKeyedArchive BLOB, NSFCalendarDate TEXT, NSFObjectClass TEXT);

while the older version create database with:

CREATE TABLE NSFKeys(ROWID INTEGER PRIMARY KEY, NSFKey TEXT, NSFPlist TEXT, NSFCalendarDate TEXT, NSFObjectClass TEXT);

My problem is: are there any sensible way to migrate existing data from old version to new version? OR I have to destroy old database and move on?

tciuro commented 11 years ago

Francis, I'm afraid there is no sensible way. You could open the db with the older NanoStore engine, export the data (NSDictionaries) and then re-import them with the new engine.

siuying commented 11 years ago

@tciuro Thanks. Do you think manually iterate the table and convert NSFPlist field to NSFKeyedArchive could work?

tciuro commented 11 years ago

I don't think so, because the new file format prevents from opening an older database. This is why I was suggeting:

1) opening the database with the older engine 2) export the data 3) opening the new database with the latest NanoStore version 4) Import the data and let NanoStore store the objects using NSFKeyedArchive

I hope this helps.

siuying commented 11 years ago

Thanks, but this export data and import data will not work for distributed apps. On the other hand embed 2 different version of NanoStore to a single app would be difficult.

Therefore I'm thinking a solution like this:

  1. When open the database, check for schema, if it is older format, use alter table to add missing column
  2. for each column, read plist field and convert it into keyed archive format
  3. remove the column plist

The problem is i dont sure if i can simply convert the plist field to keyed archive field.

JanC commented 11 years ago

Hi, I'm in the same situation. What are the advantages of migrating to the new format? If there are not big improvements, I'd rather stick with the older version of the lib.

cheers

tciuro commented 11 years ago

The plist if now stored in binary format, which is more compact. That means faster load times, queries and a lower memory footprint.