aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <post@wickenrode.com>2014-03-05 03:36:32 +0100
committerMax <post@wickenrode.com>2014-03-05 03:36:32 +0100
commitb67728258595b7ce256ea50485ee6e6cb8137ac8 (patch)
treeeab934d5e0ddfd4a10b35760876d4e1b76c4d879
parent5c0212a51d21f06f3beb62059b0b17c6ee1d8c91 (diff)
downloadsequelpro-b67728258595b7ce256ea50485ee6e6cb8137ac8.tar.gz
sequelpro-b67728258595b7ce256ea50485ee6e6cb8137ac8.tar.bz2
sequelpro-b67728258595b7ce256ea50485ee6e6cb8137ac8.zip
Add support for SQLSTATE
This commit adds the backend code to get the mysql SQLSTATE error code (to be used when displaying errors).
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQL Private APIs.h1
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Databases & Tables.m2
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.h1
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m37
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h1
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m4
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m1
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m1
8 files changed, 48 insertions, 0 deletions
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQL Private APIs.h b/Frameworks/SPMySQLFramework/Source/SPMySQL Private APIs.h
index cb89ef4d..199d4790 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQL Private APIs.h
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQL Private APIs.h
@@ -84,6 +84,7 @@
- (void)_flushMultipleResultSets;
- (void)_updateLastErrorMessage:(NSString *)theErrorMessage;
- (void)_updateLastErrorID:(NSUInteger)theErrorID;
+- (void)_updateLastSqlstate:(NSString *)theSqlstate;
@end
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Databases & Tables.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Databases & Tables.m
index dd84ff55..0b9651f6 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Databases & Tables.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Databases & Tables.m
@@ -63,11 +63,13 @@
if (encodingChangeRequired) {
NSString *theErrorString = [self lastErrorMessage];
NSUInteger theErrorID = [self lastErrorID];
+ NSString *theSqlstate = [self lastSqlstate];
[self restoreStoredEncoding];
[self _updateLastErrorMessage:theErrorString];
[self _updateLastErrorID:theErrorID];
+ [self _updateLastSqlstate:theSqlstate];
}
return NO;
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.h b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.h
index 4509fdc9..a595cfb2 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.h
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.h
@@ -56,6 +56,7 @@
- (BOOL)queryErrored;
- (NSString *)lastErrorMessage;
- (NSUInteger)lastErrorID;
+- (NSString *)lastSqlstate;
+ (BOOL)isErrorIDConnectionError:(NSUInteger)theErrorID;
// Query cancellation
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m
index 80cc798d..6fce5361 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m
@@ -227,6 +227,7 @@
double queryExecutionTime;
NSString *theErrorMessage;
NSUInteger theErrorID;
+ NSString *theSqlstate;
lastQueryWasCancelled = NO;
lastQueryWasCancelledUsingReconnect = NO;
@@ -299,6 +300,7 @@
if (!queryStatus) {
theErrorMessage = nil;
theErrorID = 0;
+ theSqlstate = nil;
break;
// If the query failed, determine whether to reattempt the query
@@ -307,6 +309,7 @@
// Store the error state
theErrorMessage = [self _stringForCString:mysql_error(mySQLConnection)];
theErrorID = mysql_errno(mySQLConnection);
+ theSqlstate = [self _stringForCString:mysql_sqlstate(mySQLConnection)];
// Prevent retries if the query was cancelled or not a connection error
if (lastQueryWasCancelled || ![SPMySQLConnection isErrorIDConnectionError:mysql_errno(mySQLConnection)]) {
@@ -319,6 +322,7 @@
if (![self checkConnection]) {
[self _updateLastErrorMessage:theErrorMessage];
[self _updateLastErrorID:theErrorID];
+ [self _updateLastSqlstate:theSqlstate];
return nil;
}
[self _lockConnection];
@@ -365,6 +369,7 @@
// Update the error message, if appropriate, to reflect result store errors or overall success
theErrorMessage = [self _stringForCString:mysql_error(mySQLConnection)];
theErrorID = mysql_errno(mySQLConnection);
+ theSqlstate = [self _stringForCString:mysql_sqlstate(mySQLConnection)];
} else {
theResult = [[SPMySQLEmptyResult alloc] init];
}
@@ -379,6 +384,7 @@
if (lastQueryWasCancelled) {
theErrorMessage = NSLocalizedString(@"Query cancelled.", @"Query cancelled error");
theErrorID = 1317;
+ theSqlstate = @"70100";
// If the query was cancelled on a MySQL <5 server, check the connection to allow reconnects
// after query kills. This is also handled within the class for internal cancellations, but
@@ -403,6 +409,7 @@
// Update error string and ID, and the rows affected
[self _updateLastErrorMessage:theErrorMessage];
[self _updateLastErrorID:theErrorID];
+ [self _updateLastSqlstate:theSqlstate];
lastQueryAffectedRowCount = theAffectedRowCount;
// Store the result time on the response object
@@ -474,6 +481,12 @@
return [NSString stringWithString:queryErrorMessage];
}
+- (NSString *)lastSqlstate
+{
+ if(!querySqlstate) return nil;
+ return [NSString stringWithString:querySqlstate];
+}
+
/**
* If the last query (or connection) triggered an error, returns the error
* ID; if the last query did not error, 0 is returned.
@@ -687,4 +700,28 @@
}
}
+/**
+ * Update the MySQL SQLSTATE for this connection.
+ * @param thSqlstate If a SQLSTATE is supplied it will be stored and returned to
+ * anything asking the instance for the last SQLSTATE;
+ * if nil is supplied, the connection will be used to derive
+ * (or clear) the SQLSTATE string;
+ * if @"" is supplied the SQLSTATE will only be cleared.
+ */
+- (void)_updateLastSqlstate:(NSString *)theSqlstate
+{
+ // If a SQLSTATE wasn't supplied, select one from the connection
+ if(!theSqlstate) {
+ theSqlstate = [self _stringForCString:mysql_sqlstate(mySQLConnection)];
+ }
+
+ // Clear the last SQLSTATE stored on the instance
+ if(querySqlstate) [querySqlstate release], querySqlstate = nil;
+
+ // If we have a SQLSTATE *with a length*, update the instance SQLSTATE
+ if(theSqlstate && [theSqlstate length]) {
+ querySqlstate = [[NSString alloc] initWithString:theSqlstate];
+ }
+}
+
@end
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h
index bf15d5b4..34b21043 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h
@@ -104,6 +104,7 @@
// Error state for the last query or connection state
NSUInteger queryErrorID;
NSString *queryErrorMessage;
+ NSString *querySqlstate;
// Query details
unsigned long long lastQueryAffectedRowCount;
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
index cf08f749..79d5060a 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
@@ -165,6 +165,7 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS
// Start with a blank error state
queryErrorID = 0;
queryErrorMessage = nil;
+ querySqlstate = nil;
// Start with empty cancellation details
lastQueryWasCancelled = NO;
@@ -231,6 +232,7 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS
if (databaseToRestore) [databaseToRestore release], databaseToRestore = nil;
if (serverVersionString) [serverVersionString release], serverVersionString = nil;
if (queryErrorMessage) [queryErrorMessage release], queryErrorMessage = nil;
+ if (querySqlstate) [querySqlstate release], querySqlstate = nil;
[delegateDecisionLock release];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
@@ -465,6 +467,7 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS
// Clear the connection error record
[self _updateLastErrorID:NSNotFound];
[self _updateLastErrorMessage:nil];
+ [self _updateLastSqlstate:nil];
// Unlock the connection
[self _unlockConnection];
@@ -566,6 +569,7 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS
if (isMaster) {
[self _updateLastErrorMessage:[self _stringForCString:mysql_error(theConnection)]];
[self _updateLastErrorID:mysql_errno(theConnection)];
+ [self _updateLastSqlstate:[self _stringForCString:mysql_sqlstate(theConnection)]];
}
return NULL;
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m b/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m
index 9b98a703..705b3daf 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m
@@ -393,6 +393,7 @@ typedef struct st_spmysqlstreamingrowdata {
// Update the connection's error statuses to reflect any errors during the content download
[parentConnection _updateLastErrorID:NSNotFound];
[parentConnection _updateLastErrorMessage:nil];
+ [parentConnection _updateLastSqlstate:nil];
// Unlock the parent connection now all data has been retrieved
[parentConnection _unlockConnection];
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m b/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m
index eda82e87..447cf19b 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m
@@ -811,6 +811,7 @@ static inline void SPMySQLStreamingResultStoreFreeRowData(SPMySQLStreamingResult
// Update the connection's error statuses to reflect any errors during the content download
[parentConnection _updateLastErrorID:NSNotFound];
[parentConnection _updateLastErrorMessage:nil];
+ [parentConnection _updateLastSqlstate:nil];
// Unlock the parent connection now all data has been retrieved
[parentConnection _unlockConnection];