BaseTen has been designed with Core Data users in mind. Our goal has been to use familiar concepts, APIs and semantics while offering the additional functionality of a real, multi-user relational database management system. That said, it's not possible or even desirable for BaseTen to offer full Core Data source compatibility. This page describes some of the differences between BaseTen and Core Data.

Schema discovery

In Core Data, the database schema is declared either in a data model file created in Xcode, or programmatically by using NSManagedObjectModel and related classes. In BaseTen, the database schema is discovered at runtime by querying the database.

The only thing BaseTen is not able to gather from the database is the table to class mapping; that is, if you want to use a custom subclass of BXDatabaseObject for a given table. See how this can be accomplished in code and in Interface Builder.

The primary key

In Core Data, each object has an object ID distinct from the actual data stored by the object. When defining a Core Data schema, you don't have to worry about how your objects will be identified or referred to -- they will always have this object ID.

In BaseTen, each of the tables you work with needs to have a primary key. It's up to you to decide what kind of data would best suit the purpose of identifying your objects. The primary key can be of any type supported by the system, and it can even consist of multiple columns. So, if you are working with the user database of a web site, the username or an email address would be a natural choice for the primary key of the user table. If you are building a database of people, a composite primary key of the full name and birthday would be one option.

Note, however, that if you use the BaseTen Setup Assistant to import a Core Data schema, the assistant will automatically create the primary key columns for you. If you don't want a SERIAL type primary key, you need to design your schema by hand.

Relationships

In Core Data, attribute and relationship properties are considered separate. In BaseTen, they overlap. When foreign key constraints are defined in the underlying PostgreSQL database, the relationship name and the referring columns on each side of the relationship are specified. In BaseTen, you can access both the referring column values and the actual relationship. For example, consider the following foreign key constraint specified in a schema:

  ALTER TABLE siteuser ADD FOREIGN KEY inviter (inviter_email) REFERENCES siteuser (email); 

The constraint refers to a user table with two columns. The email column is the primary key, holding the user's email address. The inviter_email column contains the email address of the person who invited our user into this invite-only system. If you had a BXDatabaseObject representing this user, you could access the keys "email" and "inviter_email" to get NSStrings of the email addresses, but the ALTER TABLE command above adds a third key, "inviter", that returns the object on the other side of the foreign key relationship. For example:

  NSString *inviterEmail = [anUser valueForKey:@"inviter_email"];
  BXDatabaseObject *inviter = [anUser valueForKey:@"inviter"];

As with table columns and column types, the foreign key relationships are automatically discovered by BaseTen from the database schema, and don't have to be declared in code.

Autocommit mode

In Core Data, your data is saved on disk only when you call -[NSManagedObjectContext save:]. For document-based applications, this is fine. The save operation maps neatly to the Save command invoked by the user. But for non-document-based Mac applications, "Save" or "Apply" buttons are not customary, so you end up calling the save: method in code after each change.

BXDatabaseContext, the BaseTen equivalent to NSManagedObjectContext, has the same save: and rollback methods, so migration should be simple in that regard. But additionally, BXDatabaseContext offers an autocommit mode where all changes to your database objects are immediately propagated to the database. BaseTen's full NSUndoManager integration works in the autocommit mode as well, so even automatically committed changed can be undone at will.

You are not alone

Arguably the biggest change in BaseTen is the fact that it has been designed from the ground up for multi-user systems. This changes a lot of things, but for the most part, things should just work as you expect them to. The two things you need to take into consideration are: your object properties might change "by themselves", and properties might be locked by other users. More detail to come.