Permalink
Browse files

added reconnect to all methods using network

  • Loading branch information...
1 parent 4f85a48 commit 8f796723501f0ba4630a7dad3f3e9c88e8dd55a9 Philio committed Feb 28, 2011
Showing with 71 additions and 1 deletion.
  1. +14 −1 README.markdown
  2. +29 −0 mysql.go
  3. +28 −0 statement.go
View
@@ -7,7 +7,7 @@ Revision History
0.3.x series [testing]
-* 0.3.0-RC - Fixed SimpleTest unit test. Fixed and variable length strings for normal queries now return string types not []byte, text/blobs are indistinguishable so are left in []byte format. 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.
+* 0.3.0-RC - Fixed SimpleTest unit test. Fixed and variable length strings for normal queries now return string types not []byte, text/blobs are indistinguishable so are left in []byte format. 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.
* 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.
@@ -347,6 +347,19 @@ Usage examples
}
+Auto-reconnect functionality
+----------------------------
+
+As of version 0.3.0 the library can detect network failures and try and reconnect automatically. Any methods that use the network connection support reconnect but may still return a network error (as the process is too complicated to recover) while a number of core methods are able to attempt to reconnect and recover the operation. The default setting for the feature is OFF.
+
+Methods supporting recovery:
+
+* Client.ChangeDb - Will attempt to reconnect and rerun the changedb command.
+* Client.Query - Will attempt to reconnect and rerun the query.
+* Statement.Prepare - Will attempt to reconnect and prepare the statement again.
+* Statement.Execute - Will attempt to reconnect, prepare and execute the statement again. **Long data packets are not resent!**
+
+
Prepared statement notes (previously limitations)
-------------------------------------------------
View
@@ -243,6 +243,10 @@ func (c *Client) Query(sql string) (err os.Error) {
// Fetch all rows for a result and store it, returning the result set
func (c *Client) StoreResult() (result *Result, err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = c.simpleReconnect(err)
+ }()
// Log store result
c.log(1, "=== Begin store result ===")
// Check result
@@ -266,6 +270,10 @@ func (c *Client) StoreResult() (result *Result, err os.Error) {
// Use a result set, does not store rows
func (c *Client) UseResult() (result *Result, err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = c.simpleReconnect(err)
+ }()
// Log use result
c.log(1, "=== Begin use result ===")
// Check result
@@ -283,6 +291,10 @@ func (c *Client) UseResult() (result *Result, err os.Error) {
// Free the current result
func (c *Client) FreeResult() (err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = c.simpleReconnect(err)
+ }()
// Log free result
c.log(1, "=== Begin free result ===")
// Check result
@@ -318,6 +330,10 @@ func (c *Client) MoreResults() bool {
// Move to the next available result
func (c *Client) NextResult() (more bool, err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = c.simpleReconnect(err)
+ }()
// Log next result
c.log(1, "=== Begin next result ===")
// Pre-run checks
@@ -682,6 +698,19 @@ func (c *Client) auth() (err os.Error) {
return
}
+// Simple non-recovered reconnect
+func (c *Client) simpleReconnect(err os.Error) os.Error {
+ if err != nil && c.checkNet(err) && c.Reconnect {
+ c.log(1, "!!! Lost connection to server !!!")
+ c.connected = false
+ rcErr := c.reconnect()
+ if rcErr != nil {
+ return rcErr
+ }
+ }
+ return err
+}
+
// Perform reconnect if a network error occurs
func (c *Client) reconnect() (err os.Error) {
// Log auto reconnect
View
@@ -209,6 +209,10 @@ func (s *Statement) BindParams(params ...interface{}) (err os.Error) {
// Send long data
func (s *Statement) SendLongData(num int, data []byte) (err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = s.c.simpleReconnect(err)
+ }()
// Log send long data
s.c.log(1, "=== Begin send long data ===")
// Check prepared
@@ -374,6 +378,10 @@ func (s *Statement) RowCount() uint64 {
// Fetch next row
func (s *Statement) Fetch() (eof bool, err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = s.c.simpleReconnect(err)
+ }()
// Log fetch
s.c.log(1, "=== Begin fetch ===")
// Check prepared
@@ -466,6 +474,10 @@ func (s *Statement) Fetch() (eof bool, err os.Error) {
// Store result
func (s *Statement) StoreResult() (err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = s.c.simpleReconnect(err)
+ }()
// Log store result
s.c.log(1, "=== Begin store result ===")
// Check prepared
@@ -489,6 +501,10 @@ func (s *Statement) StoreResult() (err os.Error) {
// Free result
func (s *Statement) FreeResult() (err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = s.c.simpleReconnect(err)
+ }()
// Log free result
s.c.log(1, "=== Begin free result ===")
// Check prepared
@@ -519,6 +535,10 @@ func (s *Statement) MoreResults() bool {
// Next result
func (s *Statement) NextResult() (more bool, err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = s.c.simpleReconnect(err)
+ }()
// Log next result
s.c.log(1, "=== Begin next result ===")
// Check prepared
@@ -544,6 +564,10 @@ func (s *Statement) NextResult() (more bool, err os.Error) {
// Reset statement
func (s *Statement) Reset() (err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = s.c.simpleReconnect(err)
+ }()
// Log next result
s.c.log(1, "=== Begin reset statement ===")
// Check prepared
@@ -569,6 +593,10 @@ func (s *Statement) Reset() (err os.Error) {
// Close statement
func (s *Statement) Close() (err os.Error) {
+ // Auto reconnect
+ defer func() {
+ err = s.c.simpleReconnect(err)
+ }()
// Log next result
s.c.log(1, "=== Begin close statement ===")
// Check prepared

0 comments on commit 8f79672

Please sign in to comment.