I'm using the library with a nosql. I provided the sql example b/c it's part of the std library. I like rog's solution(especially on the generic Resource type) but to reduce friction and make it more idiomatic I would need to be able to define the select arguments in the return func (after the query string is parsed) instead to define them manually in a struct. Defining the filters/params in a struct requires extra effort and makes the code more verbose instead to rely on the query parser. Also a query has just 1-2 filters and I don't find structs with 1-2 fields(i.e like `ByColor` struct) very idiomatic/nice to use instead of function parameters. I assume that as Ian said that kind of "variadic generic types" is not possible in Go/2 generics.
On Wednesday, October 6, 2021 at 4:17:43 PM UTC+3 ren...@ix.netcom.com wrote: > I think you can only do that if you make sql parsing a first class > language feature - or you need to construct the query using a syntax tree > of clauses which is a PITA. Sometimes a hybrid approach - not a full orm - > but an sql helper works best so > > sql.Query(table name, field list, where clauses, order by clauses) can > work but for complex sql like joins it becomes unwieldy. > > After years of doing both, I’ve settled on that using DAOs creates the > simplest and highest performing code. > > On Oct 6, 2021, at 8:07 AM, Brian Candler <b.ca...@pobox.com> wrote: > > 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...@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 > > <https://groups.google.com/d/msgid/golang-nuts/010a11a1-262b-4699-8e70-61d9e460c270n%40googlegroups.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/c47c56a6-aceb-4da7-b232-3cfa2241552dn%40googlegroups.com.