Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite.swift: Best way to implement model classes representing rows of a given table?

This is only question I've asked (so far) that doesn't need much/any explanation.

I had got as far as this with solving it:

  • each class might have an initialiseTable() kind of like function which would be called when the DB schema is initialised?
  • Static constants in each class for column Expression<T>

I guess the part I'm pondering about most is filling instances of model classes with Query results.

As always, thanks in advance for help :)

Link to the awesome SQLite.swift for those who haven't come across it yet.


Update (22/4/15 14:13):

After thinking about it, I'm not sure about storing row data in iVars as it may become tricky to workout saving and updating logistics and overcomplicate things.

However, I still think having model classes to represent rows is a good idea. I think the main benefit of having model classes representing table rows is safety. Knowing that a Query has column name : Expression<String>, for example. This is great to have if you start passing Query instances around between classes

Like I said, I'm not sure if one would really want to start making a class which has iVars for each column to represent rows. If you do that, you could start to get in to ORM land which I feel takes the simplistic beauty of SQLite.swift away. The only benefit that I can think of by keeping iVars for each column would be that you could call refresh() on an instance which would retrieve the latest data from the DB, and then all other objects pointing to this instance would have the latest data without having to hit the DB theirselves.

Perhaps just having a class that subclasses Query and has a constructor that takes a Database and initialises with the correct table name? Perhaps this could have getters somehow for row columns.

I'm just thinking out loud here trying to give some food for thought. These ideas a pretty immature and young, just thinking about the limitations and benefits in my head of each approach you could take😛. Will come back and add/change more when I've refined the ideas.


Update (24/4/15 09:45):

Perhaps the model classes should just be proxies to the DB tables? Each class having a setter for each field that writes to the DB straight away so that there's no conflict in state as it's always mirroring what's in the DB. But then you wouldn't be able to manage how often you go to the DB that easily? BUT. Are you really changing values that often?

like image 501
kylejm Avatar asked Apr 21 '15 13:04

kylejm


1 Answers

Checkout http://github.com/groue/GRDB.swift. It provides a ready-made Record class, as well as focused protocols, that grant fetching and persistence methods to any of your custom struct or class:

let persons = Persons.fetchAll(db, ...)
try Person(...).insert(db)

Update: GRDB is a protocol-oriented library, which means that it favors immutable models. This is quite unlike Core Data or Realm, and there are consequences on application design. Check out How to build an iOS application with SQLite and GRDB.swift

like image 183
Gwendal Roué Avatar answered Nov 15 '22 03:11

Gwendal Roué