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.cand...@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.
> 
> -- 
> 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.

-- 
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/F4A25FE5-B4D1-40A8-B2D2-4D0F0FBFB0AA%40ix.netcom.com.

Reply via email to