FAQ
http://play.golang.org/p/njPBsg0JjD
On Sunday, April 15, 2012 7:13:35 PM UTC+2, Peter Kleiweg wrote:


I wrote this function to print the results from a query with
database/sql. The function doesn't now how many columns there
are. All it nows is that all columns are of type string.

My question is, can this be done in a better or simpler way? I
am not sure if the use of new() is correct, I have never used
new() before. And I think *(fields[i].(*string)) looks a bit
convoluted.


func printTable(rows *sql.Rows) {
cols, _ := rows.Columns()
n := len(cols)

for i := 0; i < n; i++ {
fmt.Print(cols[i], "\t")
}
fmt.Println()

var fields []interface{}
for i := 0; i < n; i++ {
fields = append(fields, new(string))
}
for rows.Next() {
rows.Scan(fields...)
for i := 0; i < n; i++ {
fmt.Print(*(fields[i].(*string)), "\t")
}
fmt.Println()
}
}



--
Peter Kleiweg
http://pkleiweg.home.xs4all.nl/
--
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Julien Schmidt at Apr 15, 2013 at 8:46 am
    Oh, this is just a snippet. This doesn't compile like this ;)
    Based on https://github.com/Go-SQL-Driver/MySQL/wiki/Examples#rawbytes
    On Monday, April 15, 2013 10:43:48 AM UTC+2, Julien Schmidt wrote:

    http://play.golang.org/p/njPBsg0JjD
    On Sunday, April 15, 2012 7:13:35 PM UTC+2, Peter Kleiweg wrote:


    I wrote this function to print the results from a query with
    database/sql. The function doesn't now how many columns there
    are. All it nows is that all columns are of type string.

    My question is, can this be done in a better or simpler way? I
    am not sure if the use of new() is correct, I have never used
    new() before. And I think *(fields[i].(*string)) looks a bit
    convoluted.


    func printTable(rows *sql.Rows) {
    cols, _ := rows.Columns()
    n := len(cols)

    for i := 0; i < n; i++ {
    fmt.Print(cols[i], "\t")
    }
    fmt.Println()

    var fields []interface{}
    for i := 0; i < n; i++ {
    fields = append(fields, new(string))
    }
    for rows.Next() {
    rows.Scan(fields...)
    for i := 0; i < n; i++ {
    fmt.Print(*(fields[i].(*string)), "\t")
    }
    fmt.Println()
    }
    }



    --
    Peter Kleiweg
    http://pkleiweg.home.xs4all.nl/
    --
    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 [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dougx at Apr 15, 2013 at 2:19 pm
    Oh, that's quite elegant.

    Wish you didn't always get byte[] back from Scan() though; eg. if
    http://play.golang.org/p/jxza3pbqq9 could print out the actual types, you
    could use the switch statement to cast the interface value to the
    appropriate type and return a strongly typed map[string]interface{}.

    Alas, that doesn't seem to be possible~

    ~
    Doug.
    On Monday, April 15, 2013 4:43:48 PM UTC+8, Julien Schmidt wrote:

    http://play.golang.org/p/njPBsg0JjD
    On Sunday, April 15, 2012 7:13:35 PM UTC+2, Peter Kleiweg wrote:


    I wrote this function to print the results from a query with
    database/sql. The function doesn't now how many columns there
    are. All it nows is that all columns are of type string.

    My question is, can this be done in a better or simpler way? I
    am not sure if the use of new() is correct, I have never used
    new() before. And I think *(fields[i].(*string)) looks a bit
    convoluted.


    func printTable(rows *sql.Rows) {
    cols, _ := rows.Columns()
    n := len(cols)

    for i := 0; i < n; i++ {
    fmt.Print(cols[i], "\t")
    }
    fmt.Println()

    var fields []interface{}
    for i := 0; i < n; i++ {
    fields = append(fields, new(string))
    }
    for rows.Next() {
    rows.Scan(fields...)
    for i := 0; i < n; i++ {
    fmt.Print(*(fields[i].(*string)), "\t")
    }
    fmt.Println()
    }
    }



    --
    Peter Kleiweg
    http://pkleiweg.home.xs4all.nl/
    --
    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 [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.
  • Mike Hughes at Apr 17, 2013 at 12:40 pm
    Yeah, I wonder if that limitation is coming from the DB driver level, or
    "database/sql" package level. There should be a way for the query results
    to include the nearest equivalent golang type (although I'm sure there
    would be much debate over what maps to what!)

    I just threw together http://play.golang.org/p/gPM36Atkal (just an
    extension of Julien's post with reflection to test types) and it seems that
    everything except date/time values is actually of type []uint8 ! This is
    using the github.com/bmizerany/pq postgresql driver.
    On Tuesday, April 16, 2013 12:19:28 AM UTC+10, Dougx wrote:

    Oh, that's quite elegant.

    Wish you didn't always get byte[] back from Scan() though; eg. if
    http://play.golang.org/p/jxza3pbqq9 could print out the actual types, you
    could use the switch statement to cast the interface value to the
    appropriate type and return a strongly typed map[string]interface{}.

    Alas, that doesn't seem to be possible~

    ~
    Doug.
    On Monday, April 15, 2013 4:43:48 PM UTC+8, Julien Schmidt wrote:

    http://play.golang.org/p/njPBsg0JjD
    On Sunday, April 15, 2012 7:13:35 PM UTC+2, Peter Kleiweg wrote:


    I wrote this function to print the results from a query with
    database/sql. The function doesn't now how many columns there
    are. All it nows is that all columns are of type string.

    My question is, can this be done in a better or simpler way? I
    am not sure if the use of new() is correct, I have never used
    new() before. And I think *(fields[i].(*string)) looks a bit
    convoluted.


    func printTable(rows *sql.Rows) {
    cols, _ := rows.Columns()
    n := len(cols)

    for i := 0; i < n; i++ {
    fmt.Print(cols[i], "\t")
    }
    fmt.Println()

    var fields []interface{}
    for i := 0; i < n; i++ {
    fields = append(fields, new(string))
    }
    for rows.Next() {
    rows.Scan(fields...)
    for i := 0; i < n; i++ {
    fmt.Print(*(fields[i].(*string)), "\t")
    }
    fmt.Println()
    }
    }



    --
    Peter Kleiweg
    http://pkleiweg.home.xs4all.nl/
    --
    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 [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.
  • Mike Hughes at Apr 17, 2013 at 3:10 pm
    Upon further testing, it seems it does depend on the driver. In
    github.com/bmizerany/pq it looks like the "decode" function in
    https://github.com/bmizerany/pq/blob/master/encode.go assigns fairly
    reasonable types for everything, but there doesn't seem to be any
    separation of strings and arrays of bytes. I suppose there doesn't really
    need to be, but it seems that the pgsql oid types are already listed in
    https://github.com/bmizerany/pq/blob/master/types.go so it may just be a
    matter of extending the switch function in encode.go to cast certain oids
    to certain types if you really needed to.
    On Wednesday, April 17, 2013 10:40:21 PM UTC+10, Mike Hughes wrote:

    Yeah, I wonder if that limitation is coming from the DB driver level, or
    "database/sql" package level. There should be a way for the query results
    to include the nearest equivalent golang type (although I'm sure there
    would be much debate over what maps to what!)

    I just threw together http://play.golang.org/p/gPM36Atkal (just an
    extension of Julien's post with reflection to test types) and it seems that
    everything except date/time values is actually of type []uint8 ! This is
    using the github.com/bmizerany/pq postgresql driver.
    On Tuesday, April 16, 2013 12:19:28 AM UTC+10, Dougx wrote:

    Oh, that's quite elegant.

    Wish you didn't always get byte[] back from Scan() though; eg. if
    http://play.golang.org/p/jxza3pbqq9 could print out the actual types,
    you could use the switch statement to cast the interface value to the
    appropriate type and return a strongly typed map[string]interface{}.

    Alas, that doesn't seem to be possible~

    ~
    Doug.
    On Monday, April 15, 2013 4:43:48 PM UTC+8, Julien Schmidt wrote:

    http://play.golang.org/p/njPBsg0JjD
    On Sunday, April 15, 2012 7:13:35 PM UTC+2, Peter Kleiweg wrote:


    I wrote this function to print the results from a query with
    database/sql. The function doesn't now how many columns there
    are. All it nows is that all columns are of type string.

    My question is, can this be done in a better or simpler way? I
    am not sure if the use of new() is correct, I have never used
    new() before. And I think *(fields[i].(*string)) looks a bit
    convoluted.


    func printTable(rows *sql.Rows) {
    cols, _ := rows.Columns()
    n := len(cols)

    for i := 0; i < n; i++ {
    fmt.Print(cols[i], "\t")
    }
    fmt.Println()

    var fields []interface{}
    for i := 0; i < n; i++ {
    fields = append(fields, new(string))
    }
    for rows.Next() {
    rows.Scan(fields...)
    for i := 0; i < n; i++ {
    fmt.Print(*(fields[i].(*string)), "\t")
    }
    fmt.Println()
    }
    }



    --
    Peter Kleiweg
    http://pkleiweg.home.xs4all.nl/
    --
    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 [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.
  • Julien Schmidt at Apr 17, 2013 at 10:36 pm
    This is not really a limitation but the effect of a design choice by the
    database/sql/driver package which says the that the driver might return any
    of the following types:

    int64
    float64
    bool
    []byte
    string [*] everywhere except from Rows.Next.
    time.Time

    Source: http://golang.org/pkg/database/sql/driver/#Value

    Since most drivers communicate via a text protocol with the server, the
    obvious choice is []bytes most of the times. But there are a few
    exceptions. For example the database/sql package is currently not able to
    convert from strings / []byte to time.Time, so the driver must do this to
    support time.Time. Moreover the database/sql package is not able to convert
    from time.Time to []byte / string / sql.RawBytes. For performance-critical
    applications is sql.RawBytes often a must. This is the reason why
    Go-MySQL-Driver currently does not not return time.Time values for date /
    datetime mysql values (But it will be able to do this optionally in Release
    Candidate 1).
    But there are further exceptions (inconsistencies). For example MySQL uses
    a binary protocol for prepared statements instead of the text protocol. In
    this case the driver returns an int64 or float64 for numeric values while
    it returns []byte for 'normal' queries.
    On Wednesday, April 17, 2013 2:40:21 PM UTC+2, Mike Hughes wrote:

    Yeah, I wonder if that limitation is coming from the DB driver level, or
    "database/sql" package level. There should be a way for the query results
    to include the nearest equivalent golang type (although I'm sure there
    would be much debate over what maps to what!)

    I just threw together http://play.golang.org/p/gPM36Atkal (just an
    extension of Julien's post with reflection to test types) and it seems that
    everything except date/time values is actually of type []uint8 ! This is
    using the github.com/bmizerany/pq postgresql driver.
    On Tuesday, April 16, 2013 12:19:28 AM UTC+10, Dougx wrote:

    Oh, that's quite elegant.

    Wish you didn't always get byte[] back from Scan() though; eg. if
    http://play.golang.org/p/jxza3pbqq9 could print out the actual types,
    you could use the switch statement to cast the interface value to the
    appropriate type and return a strongly typed map[string]interface{}.

    Alas, that doesn't seem to be possible~

    ~
    Doug.
    On Monday, April 15, 2013 4:43:48 PM UTC+8, Julien Schmidt wrote:

    http://play.golang.org/p/njPBsg0JjD
    On Sunday, April 15, 2012 7:13:35 PM UTC+2, Peter Kleiweg wrote:


    I wrote this function to print the results from a query with
    database/sql. The function doesn't now how many columns there
    are. All it nows is that all columns are of type string.

    My question is, can this be done in a better or simpler way? I
    am not sure if the use of new() is correct, I have never used
    new() before. And I think *(fields[i].(*string)) looks a bit
    convoluted.


    func printTable(rows *sql.Rows) {
    cols, _ := rows.Columns()
    n := len(cols)

    for i := 0; i < n; i++ {
    fmt.Print(cols[i], "\t")
    }
    fmt.Println()

    var fields []interface{}
    for i := 0; i < n; i++ {
    fields = append(fields, new(string))
    }
    for rows.Next() {
    rows.Scan(fields...)
    for i := 0; i < n; i++ {
    fmt.Print(*(fields[i].(*string)), "\t")
    }
    fmt.Println()
    }
    }



    --
    Peter Kleiweg
    http://pkleiweg.home.xs4all.nl/
    --
    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 [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedApr 15, '13 at 8:43a
activeApr 17, '13 at 10:36p
posts6
users3
websitegolang.org

People

Translate

site design / logo © 2023 Grokbase