Creating an ID Manager and Moving Forward

--

Great news — I have solved both problems from the last entry! Yay!

Lack of auto-incrementing IDs in Realm

To address the lack of auto-incrementing IDs, I created a pretty basic ID Manager type class that stores the latest category ID assigned in the database. It gets incremented and updated with each new category created.

The plan here is to expand the manager class to include any IDs I need… for example, the item IDs are next. The implementation will be the same. I will add another type of ID to track in the database. There is a single record for the manager and it will just track each ID type I want to maintain this way.

As an aside, the question “Do I need auto-incrementing IDs, or am I just used to them?” has been asked of myself. I know some folk would use GUIDs or random values, but I am using simple Int64 values starting from 1. I don’t plan to reuse them. I want to make them consistent and easy to understand when debugging and testing. There might be a different way. A better way, even. But this is my way forward and I will keep moving on!

Errors occurring when attempting to modify an object

My error (“Attempting to modify object outside of a write transaction”) was addressed by a helpful commenter on this StackOverflow article: https://stackoverflow.com/a/33457862/663609

I noticed I was only getting it when adding a second item. The first one was always fine. What I didn’t grasp was working in the same realm as I began with can be problematic.

Effectively, my code is below… yes, it needs to be refactored, likely in more ways than I even know. But the key points are (1) I have the “updated” objects which take on the modified values that get written back into the database while using the same realm, and (2) because the ID is getting updated every time there is a new category created, the property update: .modified is set when writing back to the realm. I don’t need to do it here for the new category insertion because new categories will always be added at this point, not updated. (I’ll need to do it in the updateCategory() method when I get there though!)

func insertCategory(category: ItemCategory) throws -> Int64 {

let updatedCategory = ItemCategory()
updatedCategory.setName(name: category.getName())
var updatedIdentifictaion = DatabaseIdManager()

let ids = defaultRealm.objects(DatabaseIdManager.self)
let value : Int64
let id : DatabaseIdManager

if ids.count == 1 {
id = ids[0]
value = id.getLastCategoryIdValue()! + 1 // incrementing ID
updatedCategory.setId(value: value)
updatedIdentifictaion.setLastCategoryIdValue(value: value)

} else if ids.count == 0 {
updatedIdentifictaion = DatabaseIdManager()
value = updatedIdentifictaion.getLastCategoryIdValue()! // STARTING_CATEGORY_VALUE
updatedCategory.setId(value: value)
updatedIdentifictaion.setLastCategoryIdValue(value: value)

} else {
throw CategoryHandler.CategoryError.realmAccessError
}

try! defaultRealm.write {
defaultRealm.add(updatedCategory)
defaultRealm.add(updatedIdentifictaion, update: .modified)
}
}

What I do with the update: .modified property is called an Upsert (update/insert). I *think* I can use an upsert for the new category creation but that wasn’t my focus here… getting it working was! Something else to look at adding to a refactoring list!

I was happy enough with this progress that I actually made a commit to GitHub! Wuhhooooo! Now a few of these hurdles have been navigated there should be a bit more of that in the coming days.

What’s next? Two possible directions come to mind…. (1) do the similar-seeming Item insertion work first, while this stuff is still fresh in my brain, or (2) carry on with the categories and conquer editing and deleting, wrapping up that entire piece of the rework first. Let’s see what mood I’m in… it all needs to be done. One step at a time.

--

--

Donna Harris @ Foundational Things

Software Development Professional and Trainer (with specialties in Software Quality), completing Master of Computer Science degree in Spring 2023.