FWIW, I like the idea of being able to write direct SQL and still have some static type checking. ORMs are OK for simple "get" and "put", but I have been bitten so many times where I *know* the exact SQL I want for a particular query, but the ORM makes it so damned hard to construct it their way.
On Wednesday, 6 October 2021 at 12:45:01 UTC+1 ren...@ix.netcom.com wrote: > Personally, I think this is overkill (the entire concept not the rog > solution) > > Even with static checking there is no way to ensure that tablex has the > needed fields. Even if you could check this at compile time - it might be > different at runtime. > > I don’t think the juice is worth the squeeze. > > Either use an ORM that generates the sql, or create DAOs and rely on test > cases to ensure the code is correct. > > Far simpler and more robust in my opinion. > > On Oct 6, 2021, at 6:35 AM, roger peppe <rogp...@gmail.com> wrote: > > > > On Wed, 6 Oct 2021 at 09:21, mi...@ubo.ro <mi...@ubo.ro> wrote: > >> Hi Ian , >> >> I've modified the example towards a more specific use case. The main idea >> in the example below is to make code related to database operations(i.e >> SELECT queries) safer and easier to read. A kind of >> json.Unmarshal/Marshal for databases, with validation (type checking, param >> numbers etc) to avoid a class of bugs/errors such invalid param >> types/numbers passed, invalid queries, invalid resource type to scan into >> etc. >> >> Currently the function returned by *Select* throws the validation >> errors at runtime (i.e. invalid param type passed etc). It would be great >> to have that class of errors checked at compile type. >> >> The only way I could achieve that kind of type checking was through >> code generation. I already built a tool to generate functions with the >> proper param types but it seems that code generation introduces a lot of >> friction to the point that I stopped using it. >> >> My hope is that one day a Go feature (i.e. a version of Generics) could >> help the function returned by *func* *Select* be type checked at compile >> time. >> >> > If you change your API slightly to use a single selector argument of > struct type, you could do something like this: > > https://go2goplay.golang.org/p/QH1VCQFxrZS > > In summary: > > type Flower struct { > Color string > Size int > Weight int > } > > type ByColor struct { > Color string > } > > var FlowerByColor = Select[Flower, ByColor]("* FROM tablex WHERE Color=$ > LIMIT 1") > > type SelectFunc[Resource, Args any] func(args Args) (Resource, error) > > // Select returns a function that executes the given SQL query, > // expecting results to contain fields matching Resource and > // using fields in Args to select rows. > // > // Both Resource and Args must be struct types; All the fields > // in Args must have matching fields in Resource. > func Select[Resource, Args any](q string) SelectFunc[Resource, Args] { > > > That is, we can use a combination of reflection and generics. The generics > keep the code type-safe. The reflection part does the more specific type > checking once only at init time, something I like to think of as "almost > statically typed". It's a powerful pattern in my view. > > cheers, > rog. > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts...@googlegroups.com. > > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/CAJhgacjQGQ%2BEuGVu8%2Bp5FLDFjeE_amrU9G4zGAjderEZAUTAnA%40mail.gmail.com > > <https://groups.google.com/d/msgid/golang-nuts/CAJhgacjQGQ%2BEuGVu8%2Bp5FLDFjeE_amrU9G4zGAjderEZAUTAnA%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/010a11a1-262b-4699-8e70-61d9e460c270n%40googlegroups.com.