From d4ae5719f7211781390593ae21bc4c934827e0ff Mon Sep 17 00:00:00 2001 From: Phil Bayfield Date: Tue, 1 Mar 2011 15:54:21 +0000 Subject: [PATCH] fix issue 48 and added improvements in issue 47 --- README.markdown | 7 ++++--- handler.go | 56 ++++++++++++++++++++++++++++++------------------- mysql.go | 2 +- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/README.markdown b/README.markdown index cf8eb17..c406018 100644 --- a/README.markdown +++ b/README.markdown @@ -1,5 +1,5 @@ -GoMySQL Version 0.3.0-RC -======================== +GoMySQL Version 0.3.0-RC-2 +========================== Revision History @@ -7,7 +7,8 @@ Revision History 0.3.x series [testing] -* 0.3.0-RC - Fixed TestSimple unit test and added TestSimpleStatement which performs the same tests as TestSimple but uses a prepared statement throughout. Fixed and variable length strings for normal queries now return string types not []byte, text/blobs are indistinguishable so are left in []byte format which is more efficient. All integer values in prepared statements are stored as either int64 or uint64 depending on the unsigned flag, this simplifies conversion greatly when binding the result. Added ParamCount() and RowCount() methods to statements. The built in Date, Time and DateTime types can now be bound as strings in statements. Added auto-reconnect to all methods using the network and added reconnect/recovery support to Prepare and Execute functions. Statement.Reset now frees any remaining rows or complete result sets from the connection before sending the reset command so no longer requires a call to FreeResult prior to calling. +* 0.3.0-RC-2 - Convert additional string types (issue 47). Added a check for NULL fields in the row packet handler to prevent a crash in strconv (issue 48). +* 0.3.0-RC-1 - Fixed TestSimple unit test and added TestSimpleStatement which performs the same tests as TestSimple but uses a prepared statement throughout. Fixed and variable length strings for normal queries now return string types not []byte, text/blobs are indistinguishable so are left in []byte format which is more efficient. All integer values in prepared statements are stored as either int64 or uint64 depending on the unsigned flag, this simplifies conversion greatly when binding the result. Added ParamCount() and RowCount() methods to statements. The built in Date, Time and DateTime types can now be bound as strings in statements. Added auto-reconnect to all methods using the network and added reconnect/recovery support to Prepare and Execute functions. Statement.Reset now frees any remaining rows or complete result sets from the connection before sending the reset command so no longer requires a call to FreeResult prior to calling. * 0.3.0-beta-1 - Added full statement and functions. Refactored packet handlers into generic functions. Added new BindResult/Fetch method to get result data from prepared statements. Added type conversions for similar types to populate the result pointers with values from the row data. Added simple type conversion to standard queries. Added automatic reconnect for a select number of operations. Added greater number of client errors from the MySQL manual. Added date/time types to allow date/time elements to be stored as integers and ints, making them more useful. * 0.3.0-alpha-3 - Added new error structs ClientError and ServerError. Replaced majority of os.Error/os.NewError functionality with MySQL specific ClientError objects. Server error responses now return a ServerError. Removed Client.Errno and Client.Error. Added deferred error processing to reader, writer and packets to catch and errors and always return a ClientError. Rewrote auto reconnect to check for specific MySQL error codes. * 0.3.0-alpha-2 - Added transaction wrappers, Added auto-reconnect functionality to repeatable methods. Removed mutex lock/unlocking, as it is now more appropriate that the application decides when thread safe functions are required and it's considerably safer to have a sequence such as Client.Lock(), Client.Query(...), Client.Unlock(). Added a new test which performs create, drop, select, insert and update queries on a simple demo table to test the majority of the library functionality. Added additional error messages to places where an error could be returned but there was no error number/string set. Many small changes and general improvements. diff --git a/handler.go b/handler.go index afe84b4..4fa7b19 100644 --- a/handler.go +++ b/handler.go @@ -8,6 +8,7 @@ package mysql import ( "os" "strconv" + "fmt" ) // OK packet handler @@ -111,6 +112,9 @@ func handleField(p *packetField, c *Client, r *Result) (err os.Error) { // Row packet hander func handleRow(p *packetRowData, c *Client, r *Result) (err os.Error) { + defer func() { + fmt.Printf("Error: %#v\n", err) + }() // Log field result c.log(1, "[%d] Received row packet", p.sequence) // Check sequence @@ -127,40 +131,48 @@ func handleRow(p *packetRowData, c *Client, r *Result) (err os.Error) { var field interface{} // Iterate fields to get types for i, f := range r.fields { - switch f.Type { - // Signed/unsigned ints - case FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_YEAR, FIELD_TYPE_INT24, FIELD_TYPE_LONG, FIELD_TYPE_LONGLONG: - if f.Flags&FLAG_UNSIGNED > 0 { - field, err = strconv.Atoui64(string(p.row[i].([]byte))) - } else { - field, err = strconv.Atoi64(string(p.row[i].([]byte))) - } - if err != nil { - return - } - // Floats and doubles - case FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE: - field, err = strconv.Atof64(string(p.row[i].([]byte))) - if err != nil { - return + // Check null + if len(p.row[i].([]byte)) ==0 { + field = nil + } else { + switch f.Type { + // Signed/unsigned ints + case FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_YEAR, FIELD_TYPE_INT24, FIELD_TYPE_LONG, FIELD_TYPE_LONGLONG: + if f.Flags&FLAG_UNSIGNED > 0 { + field, err = strconv.Atoui64(string(p.row[i].([]byte))) + } else { + field, err = strconv.Atoi64(string(p.row[i].([]byte))) + } + if err != nil { + return + } + // Floats and doubles + case FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE: + field, err = strconv.Atof64(string(p.row[i].([]byte))) + if err != nil { + return + } + // Strings + case FIELD_TYPE_DECIMAL, FIELD_TYPE_NEWDECIMAL, FIELD_TYPE_VARCHAR, FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING: + field = string(p.row[i].([]byte)) + // Anything else + default: + field = p.row[i] } - // Strings - case FIELD_TYPE_DECIMAL, FIELD_TYPE_NEWDECIMAL, FIELD_TYPE_VARCHAR, FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING: - field = string(p.row[i].([]byte)) - // Anything else - default: - field = p.row[i] } // Add to row row = append(row, field) } + fmt.Printf("%#v\n", row) // Stored result if r.mode == RESULT_STORED { + fmt.Println("Appending") // Cast and append the row r.rows = append(r.rows, Row(row)) } // Used result if r.mode == RESULT_USED { + fmt.Println("Overwriting") // Only save 1 row, overwrite previous r.rows = []Row{Row(row)} } diff --git a/mysql.go b/mysql.go index b03f8ec..04d6181 100644 --- a/mysql.go +++ b/mysql.go @@ -21,7 +21,7 @@ import ( // Constants const ( // General - VERSION = "0.3.0-RC" + VERSION = "0.3.0-RC-2" DEFAULT_PORT = "3306" DEFAULT_SOCKET = "/var/run/mysqld/mysqld.sock" MAX_PACKET_SIZE = 1<<24 - 1