BRORM - SQLite Object Relational Mapping

In vielen Projekten verwenden wir FMDB als SQLite Wrapper. FMDB ist sehr leichtgewichtig und trägt kaum auf. Eigentlich ist es nur ein Objective-C wrapper auf das C-Interface. Der Vorteil: Man kann alles machen, was man mit SQLite so machen will. Der Nachteil: Was auch immer man machen will, man muss SQLite Queries schreiben. An dieser Stelle setzt BROrm an. BROrm ist ein Object-Relational-Mapping, dass die einfachen Queries die man im täglichen Leben so braucht in schöne kleine Objekte mappt und dabei ein paar performance Optimierungen durchführt (lazysave, transactional save, …). zum Projekt auf GitHub

Setup

Installation

BRORM kann jetzt auch mit CocoaPod installiert werden. Einfach die folgende Zeile in das Podfile übernehmen.

pod 'BRORM', '~> 0.1'

Zuerst muss eine default databaseQueue geöffnet werden. Alle Queries und Updates finden nun per default in dieser queue statt.

NSString *databasePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"database.sqlite"];
_databaseQueue = [FMDatabaseQueue databaseQueueWithPath:databasePath];
[BROrm setDefaultQueue:_databaseQueue];

Nun erstellt man sich für jedes Model eine BRModel Unterklasse. In dieser kann man dann die default-Werte für den Tabellennamen und die id-Spalte bei bedarf überschreiben und Validierung u.Ä. durchführen.

@interface Person : BRModel
@end
@implementation BRTesttable
+ (NSString*)getTableName{
    return @"person";
}
+ (NSString*)idColumn{
    return @"id";
}
@end

Lesen

Zum lesen und schreiben wird ein BROrmWrapper mit dem Klassennamen des Models angelegt..

Find Many gibt alle Ergebnisse zurück

  • w.limit: default kein Limit
  • w.tableAlias: default der selbe wie tableName
  • w.distinct: default nein
BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
NSArray *persons = [w findMany];

Find One setzt das limit der Abfrage auf 1 und gibt das Ergebnis zurück.

BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
Person *person = (Person*)[w findOne];

Find One By Id

BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
Person *person = (Person*)[w findOne:@(2)];

Count

BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
int personCount = [w count];

Anlegen

Erstellt ein neues Objekt. Die Daten können entweder beim Anlegen des Objektes per NSDictionary, im Nachhinein per NSDictionary oder im Nachhinein einzeln gesetzt werden. Oder eine Kombination von alledem.

BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
Person *p = [w create:@{@"prename":@"Jason",@"age":@(27)}];
p[@"surname"] = @"Keller";
BOOL success = [p save];

Schreiben

Beim verändern von Daten wird eine Liste von veränderten Feldern aufgestellt. Wenn man ein Feld mit dem gleichen Wert überschreibt, so hat sich dieses nicht verändert und wird auch nicht gemerkt. Beim speichern werden nur die veränderten Felder geschrieben. Wenn sich nichts ändert, so wird auch nichts geschrieben.

BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
Person *p = (Person*)[w findOne:@"2"];
[p setFromDictionary:@{@"street":@"Some Ave. 1234",@"city":@"somecity"}]
p[@"prename"] = @"Jason";
BOOL success = [p save];

Löschen

BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
Person *p = (Person*)[w findOne:@"2"];
BOOL success = [p destroy];

Filter

BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
[w whereEquals:@"prename" value:@"Jason"];
// [w whereNotEquals:@"prename" value:@"Jason"];
// [w whereLike:@"prename" value:@"Ja%"];
// [w whereNotLike:@"prename" value:@"Ja%"];
// [w whereIdIs:@(1)];
NSArray *jasons = [w findMany];

Beziehungen

hasOneOrMany
BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
Person *t = (Person*)[w findOne:@"1"];
NSArray *customer = [[t hasOneOrMany:@"Customer"] findMany];
hasAndBelongsToMany
BROrmWrapper *w = [BROrmWrapper factoryForClassName:@"Person"];
Person *t = (Person*)[w findOne:@"1"];
NSArray *customer = [[t hasMany:@"Customer" through:@"customer_person" withForeignKey:@"customer_identifier" andBaseKey:@"person_identifier"] findMany];

Todos

  • Dokumentation verbessern
  • having, offset und group by hinzufügen