On 5/31/2013 6:07 AM, Arne Hormann wrote:
> Am Freitag, 31. Mai 2013 14:59:06 UTC+2 schrieb minux:
>> I have a feel that you're designing your solution against the language....
>> just a feeling, though.
>>
>
> It's not just a feeling, you're right and this is not my preferred solution.
> I need column type information from database/sql drivers and everything in
> there is wrapped.
> I proposed a safe workaround in an earlier post
> <
https://groups.google.com/forum/#!topic/golang-nuts/2aLctcVyp6Q>,
> but that requires changing the runtime.
There's a lot of dissatisfaction with Go's SQL interface.
That's why there are so many alternatives to it that do almost
the same thing. The Go SQL interface itself isn't a good fit
to Go; it's basically a warmed-over interface from another
language.
The fundamental problem is that what you get from a SQL
query is a sequence of typed values, each of which has a
type, a value, and a column name. In some languages,
like Python, this is easily represented as a tuple.
For Go, it would logically be a struct, but the form
of that struct is query dependent and not known to the SQL
package. So the Go SQL package returns an opaque type,
a "Row", for which a few functions are provided.
(The description for "func (*Row) Scan" at
"
http://golang.org/pkg/database/sql/#Row" makes
no sense. It says: "Scan copies the columns from the matched row into
the values pointed at by dest. If more than one row matches the query,
Scan uses the first row and discards the rest. If no row matches the
query, Scan returns ErrNoRows." A "Row" only contains one row.
There's a type Rows, but that's different. This description may
have been modified from that for Scan() for type Rows.)
The original poster needs to convert a Row into a struct with
the matching fields, and there's no general way to do that
without reflection. Maybe there should be.
The "...T" syntax in function calls turns a list of
parameters into a slice of type []T. But you can only do
that in function calls. It would be useful to have a general
function that can turn a struct into a slice of interface{},
and the reverse operation. Those are safe operations, and
can be written (inefficiently) with reflection.
There some other simple generic operations like that which
would run fast if implemented at compile time but are
painfully slow when done via reflections. Deep copy
for nonrecursive types is an example.
John Nagle