Pretend that you’re building an application to do something like... oh I don’t know, track employee time. Applications like this exist in almost every company on the face of the earth. After all, time == money, duh!
Lets also pretend one requirement of your time tracker is to keep track of the employee’s regular work hours - meaning their start/end times and the days of the week they work. Again, seems like a pretty simple and intuitive requirement for a time tracking system.
So, here’s my question: how would you go about storing the days the employee works in your data store? Just to narrow the possible answers, assume that we’re using a database for persistence.
Seen in the wild
Whatever you’re thinking, I hope you’re not thinking that storing it in a 7-character, ordered, case sensitive, nullable string character array is the right answer!
That’s right the string character array in the WorkDays column uses the first letter of the day of the week, going from Sunday to Saturday, left to right, as a quasi-data-mask to hold the possible values. A lower-case letter means that day is NOT selected, and a capital letter means the day IS selected.
Using that magic decoding logic the employee corresponding to the 2nd row of data work Sunday, Monday, Wednesday, and Friday. I don’t know about you, but I smell something awfully funky with that code. Yikes!
How would I do it?
Any developer worth anything knows that the only right answer* is to use a integer (representing a bitmask) in the database and then map that to an enum decorated with the FlagsAttribute in the code. Something like
That’s what you would have done too, right?
Is the 1st way really that bad?
When I started writing this post I intended to show an example of some insane code du jour that I found in the wild. But then I realized that the case sensitive character array might not be a horrible solution under some very particular circumstances and assumptions.
However, the solutions quickly breaks down when some of those assumptions change. Like if you need to JOIN on that data field, or use it to filter your data in a SELECT statement. In cases like that you’re really going to want something like a bitmask to help keep your queries cleaner and easier to parse... parse by your eyes that is.
Unfortunately I’m working on an existing production system and they’re not going to let me change the field to a bitmask. But maybe you’ll have better luck! :)