norm icon indicating copy to clipboard operation
norm copied to clipboard

[Feature Request] Enum Support

Open aMOPel opened this issue 1 year ago • 2 comments

You've already indirectly talked about enum support in https://github.com/moigagoo/norm/issues/34#issuecomment-544385989

Enums feel like a rather important thing in nim to me, so I think it would great to support it out of the box.

Since Postgres has an enumtype it should be kinda straight forward.

Regarding your question how to handle enums in sqlite: I have this in my project atm, which encodes enums as strings and parses them back using std/strutils.parseEnum

func dbType*(T: typedesc[enum]): string = "STRING"
func dbValue*(val: enum): DbValue = DbValue(kind: dvkString, s: $val)
func to*(dbVal: DbValue, T: typedesc[enum]): T = parseEnum[T](dbVal.s)

I imagine this could be rather costly for huge databases, so I don't know if it's a great solution. However the benefit is, that the meaning of the value is preserved in the database.

The alternative would be to encode the enum as ints, obviously. Probably that is the better default choice. The best way would be, to enable norm users to choose I guess.

Thanks for all the work put into norm. It's great!

aMOPel avatar Aug 17 '22 13:08 aMOPel

This is not strictly helpful to you since you already stumbled upon how to add enum support, but for others:

There now is norm documentation that details how to add support for whatever data-type you have, including enums.

I'm conflicted on providing a default when this feels like a decision the user might want to specify themselves (not that my opinion matters, I merely wanted to voice it). If a default must be provided I'd vote for storing as int, with the user having to provide their own dbType/dbValue/to procs if they want something else.

Luckily, as you noted, adding default enum support isn't really difficult, literally just defining these 3 procs once for sqlite and once for postgres and then writing some test-cases for it (which should include a test-case where the default procs get overwritten by user-defined procs for a specific enum, just to make sure that works).

PhilippMDoerner avatar Sep 13 '22 08:09 PhilippMDoerner

I agree with the previous comment.

Summary:

  1. Supporting arbitrary types is as easy as implementing three procs.
  2. Norm doesn't have to cover all types there are. Norm covers the obvious types (string is TEXT, int is INTEGER, etc.).
  3. I'm not against adding enum support to the core. PRs are welcome.
  4. If someone chooses to implement this, please store enum values as ints.

moigagoo avatar Sep 14 '22 08:09 moigagoo