Don't like Core Data? Neither to I. SQLitePersistentObjects is an object persistence layer that uses sqlite and offers simple querying. It also hasn't seen updates in over a year. A few mirrors have existed on github for a while, with little to no activity. So I've started another.

I use SQLitePersistentObjects on a day to day basis in my apps, and have been incrementally making improvements over the past few years. Some have come from the 'net (from sources I can not, for the life of me, reproduce) and others have simply come about from requirements of the project I'm working on at the time. Here is a modest list of the improvements:

Arbitrary Select


+[SQLitePersistentObject pairedArraysForProperties: withCriteria:] is one of the most handy optimization tools when you start moving from prototype into production development. It allows you to get paired arrays of values for a list of properties that match a criteria, and allows you to get them very quickly.

I've added +[SQLitePersistentObject pairedArraySelect: fields:], which allows you to get paired arrays for an arbitrary query (allowing you to include joins and sub-selects in your criteria). It requires a full SELECT statement:

// fields is how many fields are returned in your query
NSArray *results = [YMContact pairedArraySelect:
   @"SELECT c.contactid, (SELECT COUNT(messageid) "
   "  FROM messages WHERE contact=c.contactid) "
   "FROM contacts AS c" fields:2];

Multi-Database Support


I've often had the need to silo off a few collections of objects for several reasons, be it thread safety (sqlite3* pointers aren't thread safe, if you're using transactions), or the requirement to maintain those collections separately from the rest. SQLitePersistentObject has gained +database and +manager methods. To have your object collection stored in it's own database file instead of the default file, implement the +manager method.

// implementation of a model
@implementation YMContact

+ manager
{
  static id __manager = nil;
  if (!__manager) {
    __manager = [[SQLiteInstanceManager alloc] init];
    __manager.databaseName = @"contacts.sqlite3";
  }
  return __manager;
}

@end

Those objects will now be stored "contacts.sqlite3" in your documents/sandbox/current directory (wherever the default database ends up). Keep in mind that foreign keys to these objects can not be used. Use +manager when you need an SQLiteInstanceManager that can see this database instead of +[SQLiteInstanceManager sharedManager]

Performance Improvements


A bunch of performance improvements have been made throughout: by using statics where it should, taking shortcuts for expensive operations when it's makes sense, decreasing overall allocations, and using the cache more efficiently. +findByPk is now probably the fastest way to query the database (looks in cache directly). Specifically, remember to use DECLARE_PROPERTIES, it will help speed up many CRUD operations:

@implementation YMContact

DECLARE_PROPERTIES(
  DECLARE_PROPERTY(@"lol", @"@\"NSString\"")
)

@end

It also plays nicer with newer versions of Mac OS X and iOS.

If you've got improvements to your copy of SQLitePersistentObjects please let me know. Fork the project, send in patches, whatever. If it comes with tests, great, if not, it'll make it in when I or someone else writes some. Also, expect to see some cache improvements (max resident memory, more intelligent invalidation, etc). A query cache would be nice.

SQLitePersistentObjects on github