You have an existing SQLite database and have decided to import the data into a Core Data SQLite database. The importing process involves the following steps:
- Create the Object graph for the database i.e xcdatamodel based on the existing SQLite db.
- Generate entity classes from the xcdatamodel.
- Write code that use the entity classes to populate the Core Data database with entity instances.
Apart from step 2 the other two steps are manual and can be time-consuming when many entities are involved. We didn’t find any tool that could automate those steps. So we decided to create Sqlite2CoreData.
How it Works
Sqlite2Coredata is simple to use. It’s a command-line app takes the existing SQLite as input and produces corresponding xcdatamodel and Core Data SQLite file as output. The execution has broadly 3 steps:
1. Generate the xcdatamodel by gathering schema information using sqlite apis.
- The sqlite table sqlite_master provides the list of tables. The pragma table_info statement is used to extract column information like name, datatype, not-null and whether its a primary key. Table and column information is stored in SQCDTableInfo and SQCDColumnInfo objects respectively.
- Foreign key information is extracted using the pragma foreign_key_list statement. For each foreign key, two SQCDForeignKeyInfo objects are created. These objects correspond to Core Data relationship and inverse relationship. Uniqueness of the referencing column decides the cardinality (to-one or to-many) of the inverse relationship. To find out whether a column is unique, the pragma index_list and pragma index_info statements are used.
- All these objects are then used to generate the xcdatamodel xml. Important points to keep in mind:
- Columns that are foreign keys are not treated as attributes but become relationships.
- The SQCDTypeMapper is used to map sqlite datatypes to xcdatamodel types.
- Inverse relationships are made optional
- Table names and column names with underscores are camelized
- Relationship names are additionaly pluralized in the case of to-many. The NSString+Inflections API came in handy here.
- Apple’s NSXMLDocument and friends are used to generate the xml.
2. Compile the xcdatamodel to generate the momd.
- The xcdatamodel generted in previous step is passed to the XCode’s compiler momc using NSTask to produce the momd.
3. Migrate the data
- With the momd in place, the tool is now ready to create Core Data entity instances.
- Tool iterates over each table and creates a managed object for each row in sqlite. FMDB is used here for fetching rows from sqlite.
- Relationships are populated based on foreign key information from sqlite. If the table has foreign keys, destination entity instances are fetched and if not available, created.
Follow the following steps to see how to use the generated files in iOS project
- Clone Sqlite2CoreData. Extract distribution.zip or build the tool following the instructions
- Run the tool with Chinook.sqlite as input present in sample app folder. An output folder is created to which the xcdatamodel and Sqlite files are saved
- Open SampleApp iOS project present in the cloned repo
- Add Chinook.xcdatamodeld and Chinook.sqlite to the project.
- Select the xcdatamodel and generate source files for all the entities using Xcode’s Editor menu (Editor —> Create NSManagedObject Subclass…). While adding the source files make sure they are added to the SampleAppTests target too.
- Build and run the SampleAppTests target (Cmd+U). This will run the test testInsertNewAlbum. Its a simple test that attempts to create a new Album record and associate it with an Artist whose artistid is 1.