Slide 1

Slide 1 text

Live Objects with Realm 1

Slide 2

Slide 2 text

2

Slide 3

Slide 3 text

3

Slide 4

Slide 4 text

What is this? Some Sort of Buzzword? 4

Slide 5

Slide 5 text

Let me answer that by answering: What They Are Not? 5

Slide 6

Slide 6 text

(Immutable | Value) Objects 6

Slide 7

Slide 7 text

These are neat: 4 Simple 4 Automatically Thread-Safe 7

Slide 8

Slide 8 text

But: 4 Expensive 4 Limitations 4 Modifications of Large Trees can be Cumbersome!* 8

Slide 9

Slide 9 text

Swift struct InventoryItem { var name: String var quantity: Int = 1 var category: Category } 9

Slide 10

Slide 10 text

Objective-C @interface InventoryItem : NSObject @property (nonatomic, copy) NSString *name; @property (nonatomic, assign) NSInteger quantity; @property (nonatomic, strong) Category *category; - (instancetype)itemWithName:(NSString *)name quantity:(NSInteger)quantity category:(Category *)category; @end 10

Slide 11

Slide 11 text

- (InventoryItem *)itemWithName:(NSString *)name { return [Item itemWithName:name quantity:self.quantity category:self.category]; } 11

Slide 12

Slide 12 text

Java public final class InventoryItem { private final String name; private final Int quantity; private final Category category; public InventoryItem(String name, Int quantity, Category category) { this.name = name; this.quantity = quantity; this.category = category; } public String getName() { return name; } public Int getQuantity() { return quantity; } public Category getCategory() { return category; } } 12

Slide 13

Slide 13 text

How to Interact with These? e.g. Retrieve an InventoryItem from a database, modify the quantity, persist the change in the database. 13

Slide 14

Slide 14 text

Retrieve Cursor c = db.query("inventory_items", { "name", "quantity", "categoryId" }, "name = ?", { "Drilling machine" }, null, null, null, 1); c.moveToFirst(); String name = c.getString(c.getColumnIndexOrThrow("name")); Int quantity = c.getInt(c.getColumnIndexOrThrow("quantity")); Long categoryId = c.getLong(c.getColumnIndexOrThrow("categoryId")); Category category = getCategoryById(categoryId); InventoryItem item = InventoryItem(name, quantity, category); 14

Slide 15

Slide 15 text

Modify InventoryItem modifiedItem = InventoryItem(item.name, quantity+1, item.category); 15

Slide 16

Slide 16 text

Persist // New value for one column ContentValues values = new ContentValues(); values.put("name", modifiedItem.name); values.put("categoryId", modifiedItem.category.id); values.put("quantity", modifiedItem.quantity); int count = db.update( "inventory_items", values, "name = ?", { item.name }); 16

Slide 17

Slide 17 text

Underlying Principle Push To & Pull From the Database 17

Slide 18

Slide 18 text

You can Limit State and Side-Effects in your Application But it is still there … 18

Slide 19

Slide 19 text

The Alternative: Embrace State 19

Slide 20

Slide 20 text

Live Objects 4 Fundamentally Different 4 Always Represent the Latest State 4 Navigatable 4 But Not Necessarily Thread-Safe 20

Slide 21

Slide 21 text

Example import RealmSwift class InventoryItem : Object { dynamic var name: String dynamic var quantity: Int = 1 dynamic var category: Category? } 21

Slide 22

Slide 22 text

Retrieve, Persist, Modify let results = realm.objects(InventoryItem) .filter("name = %@", "Drilling machine") let obj = results.first! realm.write { obj.quantity += 1 } 22

Slide 23

Slide 23 text

How does that work? 23

Slide 24

Slide 24 text

! Objects store a reference to their row under the hood. They always carry identity. 24

Slide 25

Slide 25 text

! Properties are dynamically implemented at runtime. 25

Slide 26

Slide 26 text

!→ " !"#→ ✅ Modifications are only allowed within write transactions and directly occur on the database. 26

Slide 27

Slide 27 text

!" MVCC algorithm keeps all versions around that are necessary. 27

Slide 28

Slide 28 text

MVCC? 28

Slide 29

Slide 29 text

Multi-Version- Concurrency-Control 29

Slide 30

Slide 30 text

30

Slide 31

Slide 31 text

31

Slide 32

Slide 32 text

32

Slide 33

Slide 33 text

! On every commit all accessors are updated across threads and processes. 33

Slide 34

Slide 34 text

! Change Notifications are sent. Per Object / Collection (taking applied filters into account!) 34

Slide 35

Slide 35 text

! MVCC algorithm disposes old commits which are not necessary anymore. 35

Slide 36

Slide 36 text

Does this mean the whole data is copied every time? 36

Slide 37

Slide 37 text

! Not necessary by Copy-on-Write 37

Slide 38

Slide 38 text

!"# The Birds and The B-Trees 38

Slide 39

Slide 39 text

What are my Advantages? 39

Slide 40

Slide 40 text

Advantages of Realm's Live Objects Concept 4 Single source of truth for your model schema 4 No overhead of mapping data around 4 Change notifications for free 40

Slide 41

Slide 41 text

Demo 41

Slide 42

Slide 42 text

for question in questions { question.ask()! } 42

Slide 43

Slide 43 text

Thanks for your attention! @mrackwitz [email protected] 43