aboutsummaryrefslogtreecommitdiffstats
path: root/Frameworks
diff options
context:
space:
mode:
Diffstat (limited to 'Frameworks')
-rw-r--r--Frameworks/PostgresKit/Source/PGPostgresConnection.m102
-rw-r--r--Frameworks/PostgresKit/Source/PGPostgresConnectionParameters.m46
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m278
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m126
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Field Definitions.m2
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m243
6 files changed, 392 insertions, 405 deletions
diff --git a/Frameworks/PostgresKit/Source/PGPostgresConnection.m b/Frameworks/PostgresKit/Source/PGPostgresConnection.m
index 600be9a0..5e1ac2bf 100644
--- a/Frameworks/PostgresKit/Source/PGPostgresConnection.m
+++ b/Frameworks/PostgresKit/Source/PGPostgresConnection.m
@@ -297,64 +297,62 @@ static void _PGPostgresConnectionNoticeProcessor(void *arg, const char *message)
*/
- (void)_pollConnection:(NSNumber *)isReset
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- BOOL reset = isReset && [isReset boolValue];
-
- int sock = PQsocket(_connection);
-
- if (sock == -1) {
- [pool release];
- return;
- }
-
- struct pollfd fdinfo[1];
-
- fdinfo[0].fd = sock;
- fdinfo[0].events = POLLIN|POLLOUT;
-
- PostgresPollingStatusType status;
-
- do
- {
- status = reset ? PQresetPoll(_connection) : PQconnectPoll(_connection);
-
- if (status == PGRES_POLLING_READING || status == PGRES_POLLING_WRITING) {
- if (poll(fdinfo, 1, -1) < 0) break;
- }
- }
- while (status != PGRES_POLLING_OK && status != PGRES_POLLING_FAILED);
-
- if (status == PGRES_POLLING_OK && [self isConnected]) {
-
- // Increase error verbosity
- PQsetErrorVerbosity(_connection, PQERRORS_VERBOSE);
-
- // Set notice processor
- PQsetNoticeProcessor(_connection, _PGPostgresConnectionNoticeProcessor, self);
-
- // Register or clear type extensions
- NSInteger success = reset ? PQclearTypes(_connection) : PQinitTypes(_connection);
-
- if (!success) {
- NSLog(@"PostgresKit: Error: Failed to initialise or clear type extensions. Connection might return unexpected results!");
+ @autoreleasepool {
+ BOOL reset = isReset && [isReset boolValue];
+
+ int sock = PQsocket(_connection);
+
+ if (sock == -1) {
+ [pool release];
+ return;
}
-
- [self _loadDatabaseParameters];
-
- if (reset) {
- if (_delegate && [_delegate respondsToSelector:@selector(connectionReset:)]) {
- [_delegate performSelectorOnMainThread:@selector(connectionReset:) withObject:self waitUntilDone:NO];
+
+ struct pollfd fdinfo[1];
+
+ fdinfo[0].fd = sock;
+ fdinfo[0].events = POLLIN|POLLOUT;
+
+ PostgresPollingStatusType status;
+
+ do
+ {
+ status = reset ? PQresetPoll(_connection) : PQconnectPoll(_connection);
+
+ if (status == PGRES_POLLING_READING || status == PGRES_POLLING_WRITING) {
+ if (poll(fdinfo, 1, -1) < 0) break;
}
}
- else {
- if (_delegate && [_delegate respondsToSelector:@selector(connectionEstablished:)]) {
- [_delegate performSelectorOnMainThread:@selector(connectionEstablished:) withObject:self waitUntilDone:NO];
+ while (status != PGRES_POLLING_OK && status != PGRES_POLLING_FAILED);
+
+ if (status == PGRES_POLLING_OK && [self isConnected]) {
+
+ // Increase error verbosity
+ PQsetErrorVerbosity(_connection, PQERRORS_VERBOSE);
+
+ // Set notice processor
+ PQsetNoticeProcessor(_connection, _PGPostgresConnectionNoticeProcessor, self);
+
+ // Register or clear type extensions
+ NSInteger success = reset ? PQclearTypes(_connection) : PQinitTypes(_connection);
+
+ if (!success) {
+ NSLog(@"PostgresKit: Error: Failed to initialise or clear type extensions. Connection might return unexpected results!");
+ }
+
+ [self _loadDatabaseParameters];
+
+ if (reset) {
+ if (_delegate && [_delegate respondsToSelector:@selector(connectionReset:)]) {
+ [_delegate performSelectorOnMainThread:@selector(connectionReset:) withObject:self waitUntilDone:NO];
+ }
+ }
+ else {
+ if (_delegate && [_delegate respondsToSelector:@selector(connectionEstablished:)]) {
+ [_delegate performSelectorOnMainThread:@selector(connectionEstablished:) withObject:self waitUntilDone:NO];
+ }
}
}
}
-
- [pool release];
}
/**
diff --git a/Frameworks/PostgresKit/Source/PGPostgresConnectionParameters.m b/Frameworks/PostgresKit/Source/PGPostgresConnectionParameters.m
index e179f110..dc233664 100644
--- a/Frameworks/PostgresKit/Source/PGPostgresConnectionParameters.m
+++ b/Frameworks/PostgresKit/Source/PGPostgresConnectionParameters.m
@@ -138,32 +138,30 @@
*/
- (void)_loadParameters:(id)object
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- pthread_mutex_lock(&_readLock);
-
- NSArray *parameters = (NSArray *)object;
-
- if (!_parameters) {
- _parameters = [[NSMutableDictionary alloc] initWithCapacity:[parameters count]];
- }
-
- for (NSString *parameter in parameters)
- {
- const char *value = PQparameterStatus([_connection postgresConnection], [parameter UTF8String]);
-
- if (!value) continue;
-
- NSString *stringValue = [NSString stringWithUTF8String:value];
+ @autoreleasepool {
+ pthread_mutex_lock(&_readLock);
- id paramObject = [self _isBooleanParameterValue:stringValue] ? (id)[NSNumber numberWithBool:[self _booleanForParameterValue:stringValue]] : stringValue;
-
- [_parameters setObject:paramObject forKey:parameter];
+ NSArray *parameters = (NSArray *)object;
+
+ if (!_parameters) {
+ _parameters = [[NSMutableDictionary alloc] initWithCapacity:[parameters count]];
+ }
+
+ for (NSString *parameter in parameters)
+ {
+ const char *value = PQparameterStatus([_connection postgresConnection], [parameter UTF8String]);
+
+ if (!value) continue;
+
+ NSString *stringValue = [NSString stringWithUTF8String:value];
+
+ id paramObject = [self _isBooleanParameterValue:stringValue] ? (id)[NSNumber numberWithBool:[self _booleanForParameterValue:stringValue]] : stringValue;
+
+ [_parameters setObject:paramObject forKey:parameter];
+ }
+
+ pthread_mutex_unlock(&_readLock);
}
-
- pthread_mutex_unlock(&_readLock);
-
- [pool release];
}
/**
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
index 73cadd6e..70894d05 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
@@ -735,185 +735,181 @@ asm(".desc ___crashreporter_info__, 0x10");
if (userTriggeredDisconnect) return NO;
BOOL reconnectSucceeded = NO;
- NSAutoreleasePool *reconnectionPool = [[NSAutoreleasePool alloc] init];
-
- // Check whether a reconnection attempt is already being made - if so, wait
- // and return the status of that reconnection attempt. This improves threaded
- // use of the connection by preventing reconnect races.
- if (reconnectingThread && !pthread_equal(reconnectingThread, pthread_self())) {
-
- // Loop in a panel runloop mode until the reconnection has processed; if an iteration
- // takes less than the requested 0.1s, sleep instead.
- while (reconnectingThread) {
- uint64_t loopIterationStart_t = mach_absolute_time();
+ @autoreleasepool {
+ // Check whether a reconnection attempt is already being made - if so, wait
+ // and return the status of that reconnection attempt. This improves threaded
+ // use of the connection by preventing reconnect races.
+ if (reconnectingThread && !pthread_equal(reconnectingThread, pthread_self())) {
+
+ // Loop in a panel runloop mode until the reconnection has processed; if an iteration
+ // takes less than the requested 0.1s, sleep instead.
+ while (reconnectingThread) {
+ uint64_t loopIterationStart_t = mach_absolute_time();
+
+ [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
+ if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.1) {
+ usleep(100000 - (useconds_t)(1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t)));
+ }
+ }
- [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
- if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.1) {
- usleep(100000 - (useconds_t)(1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t)));
+ // Continue only if the reconnection being waited on was a background attempt
+ if (!(state == SPMySQLConnectionLostInBackground && canRetry)) {
+ return (state == SPMySQLConnected);
}
}
- // Continue only if the reconnection being waited on was a background attempt
- if (!(state == SPMySQLConnectionLostInBackground && canRetry)) {
- [reconnectionPool drain];
- return (state == SPMySQLConnected);
+ if ([[NSThread currentThread] isCancelled]) {
+ return NO;
}
- }
- if ([[NSThread currentThread] isCancelled]) {
- [reconnectionPool release];
- return NO;
- }
+ reconnectingThread = pthread_self();
- reconnectingThread = pthread_self();
+ // Store certain details about the connection, so that if the reconnection is successful
+ // they can be restored. This has to be treated separately from _restoreConnectionDetails
+ // as a full connection reinitialises certain values from the server.
+ if (!encodingToRestore) {
+ encodingToRestore = [encoding copy];
+ encodingUsesLatin1TransportToRestore = encodingUsesLatin1Transport;
+ databaseToRestore = [database copy];
+ }
- // Store certain details about the connection, so that if the reconnection is successful
- // they can be restored. This has to be treated separately from _restoreConnectionDetails
- // as a full connection reinitialises certain values from the server.
- if (!encodingToRestore) {
- encodingToRestore = [encoding copy];
- encodingUsesLatin1TransportToRestore = encodingUsesLatin1Transport;
- databaseToRestore = [database copy];
- }
+ // If there is a connection proxy, temporarily disassociate the state change action
+ if (proxy) proxyStateChangeNotificationsIgnored = YES;
- // If there is a connection proxy, temporarily disassociate the state change action
- if (proxy) proxyStateChangeNotificationsIgnored = YES;
+ // Close the connection if it's active
+ [self _disconnect];
- // Close the connection if it's active
- [self _disconnect];
+ // Lock the connection while waiting for network and proxy
+ [self _lockConnection];
- // Lock the connection while waiting for network and proxy
- [self _lockConnection];
+ // If no network is present, wait for a short time for one to become available
+ [self _waitForNetworkConnectionWithTimeout:10];
- // If no network is present, wait for a short time for one to become available
- [self _waitForNetworkConnectionWithTimeout:10];
+ if ([[NSThread currentThread] isCancelled]) {
+ [self _unlockConnection];
+ reconnectingThread = NULL;
+ return NO;
+ }
- if ([[NSThread currentThread] isCancelled]) {
- [self _unlockConnection];
- reconnectingThread = NULL;
- [reconnectionPool release];
- return NO;
- }
+ // If there is a proxy, attempt to reconnect it in blocking fashion
+ if (proxy) {
+ uint64_t loopIterationStart_t, proxyWaitStart_t;
- // If there is a proxy, attempt to reconnect it in blocking fashion
- if (proxy) {
- uint64_t loopIterationStart_t, proxyWaitStart_t;
+ // If the proxy is not yet idle after requesting a disconnect, wait for a short time
+ // to allow it to disconnect.
+ if ([proxy state] != SPMySQLProxyIdle) {
- // If the proxy is not yet idle after requesting a disconnect, wait for a short time
- // to allow it to disconnect.
- if ([proxy state] != SPMySQLProxyIdle) {
+ proxyWaitStart_t = mach_absolute_time();
+ while ([proxy state] != SPMySQLProxyIdle) {
+ loopIterationStart_t = mach_absolute_time();
+ // If the connection timeout has passed, break out of the loop
+ if (_elapsedSecondsSinceAbsoluteTime(proxyWaitStart_t) > timeout) break;
+
+ // Allow events to process for 0.25s, sleeping to completion on early return
+ [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
+ if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.25) {
+ usleep(250000 - (useconds_t)(1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t)));
+ }
+ }
+ }
+
+ // Request that the proxy re-establishes its connection
+ [proxy connect];
+
+ // Wait while the proxy connects
proxyWaitStart_t = mach_absolute_time();
- while ([proxy state] != SPMySQLProxyIdle) {
+ while (1) {
loopIterationStart_t = mach_absolute_time();
- // If the connection timeout has passed, break out of the loop
- if (_elapsedSecondsSinceAbsoluteTime(proxyWaitStart_t) > timeout) break;
+ // If the proxy has connected, record the new local port and break out of the loop
+ if ([proxy state] == SPMySQLProxyConnected) {
+ port = [proxy localPort];
+ break;
+ }
+
+ // If the proxy connection attempt time has exceeded the timeout, break of of the loop.
+ if (_elapsedSecondsSinceAbsoluteTime(proxyWaitStart_t) > (timeout + 1)) {
+ [proxy disconnect];
+ break;
+ }
- // Allow events to process for 0.25s, sleeping to completion on early return
+ // Process events for a short time, allowing dialogs to be shown but waiting for
+ // the proxy. Capture how long this interface action took, standardising the
+ // overall time.
[[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.25) {
- usleep(250000 - (useconds_t)(1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t)));
+ usleep((useconds_t)(250000 - (1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t))));
+ }
+
+ // Extend the connection timeout by any interface time
+ if ([proxy state] == SPMySQLProxyWaitingForAuth) {
+ proxyWaitStart_t += mach_absolute_time() - loopIterationStart_t;
}
}
- }
- // Request that the proxy re-establishes its connection
- [proxy connect];
+ // Having in theory performed the proxy connect, update state
+ previousProxyState = [proxy state];
+ proxyStateChangeNotificationsIgnored = NO;
+ }
- // Wait while the proxy connects
- proxyWaitStart_t = mach_absolute_time();
- while (1) {
- loopIterationStart_t = mach_absolute_time();
+ // Unlock the connection
+ [self _unlockConnection];
- // If the proxy has connected, record the new local port and break out of the loop
- if ([proxy state] == SPMySQLProxyConnected) {
- port = [proxy localPort];
- break;
- }
+ // If not using a proxy, or if the proxy successfully connected, trigger a connection
+ if (!proxy || [proxy state] == SPMySQLProxyConnected) {
+ [self _connect];
+ }
- // If the proxy connection attempt time has exceeded the timeout, break of of the loop.
- if (_elapsedSecondsSinceAbsoluteTime(proxyWaitStart_t) > (timeout + 1)) {
- [proxy disconnect];
- break;
+ // If the reconnection succeeded, restore the connection state as appropriate
+ if (state == SPMySQLConnected && ![[NSThread currentThread] isCancelled]) {
+ reconnectSucceeded = YES;
+ if (databaseToRestore) {
+ [self selectDatabase:databaseToRestore];
+ [databaseToRestore release], databaseToRestore = nil;
}
-
- // Process events for a short time, allowing dialogs to be shown but waiting for
- // the proxy. Capture how long this interface action took, standardising the
- // overall time.
- [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
- if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.25) {
- usleep((useconds_t)(250000 - (1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t))));
- }
-
- // Extend the connection timeout by any interface time
- if ([proxy state] == SPMySQLProxyWaitingForAuth) {
- proxyWaitStart_t += mach_absolute_time() - loopIterationStart_t;
+ if (encodingToRestore) {
+ [self setEncoding:encodingToRestore];
+ [self setEncodingUsesLatin1Transport:encodingUsesLatin1TransportToRestore];
+ [encodingToRestore release], encodingToRestore = nil;
}
}
+ // If the connection failed and the connection is permitted to retry,
+ // then retry the reconnection.
+ else if (canRetry && ![[NSThread currentThread] isCancelled]) {
- // Having in theory performed the proxy connect, update state
- previousProxyState = [proxy state];
- proxyStateChangeNotificationsIgnored = NO;
- }
-
- // Unlock the connection
- [self _unlockConnection];
-
- // If not using a proxy, or if the proxy successfully connected, trigger a connection
- if (!proxy || [proxy state] == SPMySQLProxyConnected) {
- [self _connect];
- }
+ // Default to attempting another reconnect
+ SPMySQLConnectionLostDecision connectionLostDecision = SPMySQLConnectionLostReconnect;
- // If the reconnection succeeded, restore the connection state as appropriate
- if (state == SPMySQLConnected && ![[NSThread currentThread] isCancelled]) {
- reconnectSucceeded = YES;
- if (databaseToRestore) {
- [self selectDatabase:databaseToRestore];
- [databaseToRestore release], databaseToRestore = nil;
- }
- if (encodingToRestore) {
- [self setEncoding:encodingToRestore];
- [self setEncodingUsesLatin1Transport:encodingUsesLatin1TransportToRestore];
- [encodingToRestore release], encodingToRestore = nil;
- }
- }
- // If the connection failed and the connection is permitted to retry,
- // then retry the reconnection.
- else if (canRetry && ![[NSThread currentThread] isCancelled]) {
+ // If the delegate supports the decision process, ask it how to proceed
+ if (delegateSupportsConnectionLost) {
+ connectionLostDecision = [self _delegateDecisionForLostConnection];
+ }
+ // Otherwise default to reconnect, but only a set number of times to prevent a runaway loop
+ else {
+ if (reconnectionRetryAttempts < 5) {
+ connectionLostDecision = SPMySQLConnectionLostReconnect;
+ } else {
+ connectionLostDecision = SPMySQLConnectionLostDisconnect;
+ }
+ reconnectionRetryAttempts++;
+ }
- // Default to attempting another reconnect
- SPMySQLConnectionLostDecision connectionLostDecision = SPMySQLConnectionLostReconnect;
+ switch (connectionLostDecision) {
+ case SPMySQLConnectionLostDisconnect:
+ [self _updateLastErrorMessage:NSLocalizedString(@"User triggered disconnection", @"User triggered disconnection")];
+ userTriggeredDisconnect = YES;
+ break;
- // If the delegate supports the decision process, ask it how to proceed
- if (delegateSupportsConnectionLost) {
- connectionLostDecision = [self _delegateDecisionForLostConnection];
- }
- // Otherwise default to reconnect, but only a set number of times to prevent a runaway loop
- else {
- if (reconnectionRetryAttempts < 5) {
- connectionLostDecision = SPMySQLConnectionLostReconnect;
- } else {
- connectionLostDecision = SPMySQLConnectionLostDisconnect;
+ // By default attempt a reconnect
+ default:
+ reconnectingThread = NULL;
+ reconnectSucceeded = [self _reconnectAllowingRetries:YES];
}
- reconnectionRetryAttempts++;
- }
-
- switch (connectionLostDecision) {
- case SPMySQLConnectionLostDisconnect:
- [self _updateLastErrorMessage:NSLocalizedString(@"User triggered disconnection", @"User triggered disconnection")];
- userTriggeredDisconnect = YES;
- break;
-
- // By default attempt a reconnect
- default:
- reconnectingThread = NULL;
- reconnectSucceeded = [self _reconnectAllowingRetries:YES];
}
}
reconnectingThread = NULL;
- [reconnectionPool release];
return reconnectSucceeded;
}
@@ -923,14 +919,10 @@ asm(".desc ___crashreporter_info__, 0x10");
*/
- (BOOL)_reconnectAfterBackgroundConnectionLoss
{
- NSAutoreleasePool *reconnectionPool = [[NSAutoreleasePool alloc] init];
-
if (![self _reconnectAllowingRetries:NO]) {
state = SPMySQLConnectionLostInBackground;
}
- [reconnectionPool release];
-
return (state == SPMySQLConnected);
}
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m b/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m
index c0131d0d..748ef2fb 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m
@@ -322,80 +322,80 @@ typedef struct st_spmysqlstreamingrowdata {
*/
- (void)_downloadAllData
{
- NSAutoreleasePool *downloadPool = [[NSAutoreleasePool alloc] init];
- MYSQL_ROW theRow;
- unsigned long *fieldLengths;
- NSUInteger i, dataCopiedLength, rowDataLength;
- SPMySQLStreamingRowData *newRowStore;
-
- [[NSThread currentThread] setName:@"SPMySQLFastStreamingResult data download thread"];
-
- size_t sizeOfStreamingRowData = sizeof(SPMySQLStreamingRowData);
- size_t sizeOfDataLengths = (size_t)(sizeof(unsigned long) * numberOfFields);
- size_t sizeOfChar = sizeof(char);
-
- // Loop through the rows until the end of the data is reached - indicated via a NULL
- while (
- (*isConnectedPtr)(parentConnection, isConnectedSelector)
- && (theRow = mysql_fetch_row(resultSet))
- ) {
- // Retrieve the lengths of the returned data
- fieldLengths = mysql_fetch_lengths(resultSet);
- rowDataLength = 0;
- dataCopiedLength = 0;
- for (i = 0; i < numberOfFields; i++) {
- rowDataLength += fieldLengths[i];
- }
+ @autoreleasepool {
+ MYSQL_ROW theRow;
+ unsigned long *fieldLengths;
+ NSUInteger i, dataCopiedLength, rowDataLength;
+ SPMySQLStreamingRowData *newRowStore;
+
+ [[NSThread currentThread] setName:@"SPMySQLFastStreamingResult data download thread"];
+
+ size_t sizeOfStreamingRowData = sizeof(SPMySQLStreamingRowData);
+ size_t sizeOfDataLengths = (size_t)(sizeof(unsigned long) * numberOfFields);
+ size_t sizeOfChar = sizeof(char);
+
+ // Loop through the rows until the end of the data is reached - indicated via a NULL
+ while (
+ (*isConnectedPtr)(parentConnection, isConnectedSelector)
+ && (theRow = mysql_fetch_row(resultSet))
+ ) {
+ // Retrieve the lengths of the returned data
+ fieldLengths = mysql_fetch_lengths(resultSet);
+ rowDataLength = 0;
+ dataCopiedLength = 0;
+ for (i = 0; i < numberOfFields; i++) {
+ rowDataLength += fieldLengths[i];
+ }
- // Initialise memory for the row and set a NULL pointer for the next item
- newRowStore = malloc(sizeOfStreamingRowData);
- newRowStore->nextRow = NULL;
-
- // Set up the row data store - a char* - and copy in the data if there is any.
- newRowStore->data = calloc(rowDataLength, sizeOfChar);
- for (i = 0; i < numberOfFields; i++) {
- if (theRow[i] != NULL) {
- memcpy(newRowStore->data+dataCopiedLength, theRow[i], fieldLengths[i]);
- dataCopiedLength += fieldLengths[i];
- } else {
- fieldLengths[i] = NSNotFound;
+ // Initialise memory for the row and set a NULL pointer for the next item
+ newRowStore = malloc(sizeOfStreamingRowData);
+ newRowStore->nextRow = NULL;
+
+ // Set up the row data store - a char* - and copy in the data if there is any.
+ newRowStore->data = calloc(rowDataLength, sizeOfChar);
+ for (i = 0; i < numberOfFields; i++) {
+ if (theRow[i] != NULL) {
+ memcpy(newRowStore->data+dataCopiedLength, theRow[i], fieldLengths[i]);
+ dataCopiedLength += fieldLengths[i];
+ } else {
+ fieldLengths[i] = NSNotFound;
+ }
}
- }
- // Set up the memory for, and copy in, the field lengths
- newRowStore->dataLengths = memcpy(malloc(sizeOfDataLengths), fieldLengths, sizeOfDataLengths);
+ // Set up the memory for, and copy in, the field lengths
+ newRowStore->dataLengths = memcpy(malloc(sizeOfDataLengths), fieldLengths, sizeOfDataLengths);
- // Lock the data mutex
- pthread_mutex_lock(&dataLock);
+ // Lock the data mutex
+ pthread_mutex_lock(&dataLock);
- // Add the newly allocated row to end of the storage linked list
- if (lastDataStoreEntry) {
- lastDataStoreEntry->nextRow = newRowStore;
- }
- lastDataStoreEntry = newRowStore;
- if (!currentDataStoreEntry) currentDataStoreEntry = newRowStore;
+ // Add the newly allocated row to end of the storage linked list
+ if (lastDataStoreEntry) {
+ lastDataStoreEntry->nextRow = newRowStore;
+ }
+ lastDataStoreEntry = newRowStore;
+ if (!currentDataStoreEntry) currentDataStoreEntry = newRowStore;
- // Update the downloaded row count
- downloadedRowCount++;
+ // Update the downloaded row count
+ downloadedRowCount++;
- // Unlock the mutex
- pthread_mutex_unlock(&dataLock);
- }
+ // Unlock the mutex
+ pthread_mutex_unlock(&dataLock);
+ }
- // Update the connection's error statuses to reflect any errors during the content download
- [parentConnection _updateLastErrorInfos];
+ // Update the connection's error statuses to reflect any errors during the content download
+ [parentConnection _updateLastErrorInfos];
- // Unlock the parent connection now all data has been retrieved
- [parentConnection _unlockConnection];
- connectionUnlocked = YES;
+ // Unlock the parent connection now all data has been retrieved
+ [parentConnection _unlockConnection];
+ connectionUnlocked = YES;
- // If the connection query may have been cancelled with a query kill, double-check connection
- if ([parentConnection lastQueryWasCancelled] && [parentConnection serverMajorVersion] < 5) {
- [parentConnection checkConnection];
- }
+ // If the connection query may have been cancelled with a query kill, double-check connection
+ if ([parentConnection lastQueryWasCancelled] && [parentConnection serverMajorVersion] < 5) {
+ [parentConnection checkConnection];
+ }
- dataDownloaded = YES;
- [downloadPool drain];
+ dataDownloaded = YES;
+ }
}
@end
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Field Definitions.m b/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Field Definitions.m
index cf7e8a1a..c478006f 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Field Definitions.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Field Definitions.m
@@ -77,7 +77,7 @@ const SPMySQLResultCharset SPMySQLCharsetMap[] =
{30, "latin5", "latin5_turkish_ci", 1, 1},
{31, "latin1", "latin1_german2_ci", 1, 1},
{32, "armscii8", "armscii8_general_ci", 1, 1},
- {33, "utf8", "utf8_general_ci", 1, 3},
+ {33, "utf8", "utf8_general_ci", 1, 3}, //mb3
{34, "cp1250", "cp1250_czech_cs", 1, 1},
{35, "ucs2", "ucs2_general_ci", 2, 2},
{36, "cp866", "cp866_general_ci", 1, 1},
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m b/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m
index 1a0b6b25..fdabe2e2 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResultStore.m
@@ -672,148 +672,147 @@ static inline void SPMySQLStreamingResultStoreFreeRowData(SPMySQLStreamingResult
*/
- (void)_downloadAllData
{
- NSAutoreleasePool *downloadPool = [[NSAutoreleasePool alloc] init];
- MYSQL_ROW theRow;
- unsigned long *fieldLengths;
- NSUInteger i, dataCopiedLength, rowDataLength;
- SPMySQLStreamingResultStoreRowData *newRowStore;
-
- [[NSThread currentThread] setName:@"SPMySQLStreamingResultStore data download thread"];
-
- size_t sizeOfMetadata, lengthOfMetadata;
- size_t lengthOfNullRecords = (size_t)(sizeof(BOOL) * numberOfFields);
- size_t sizeOfChar = sizeof(char);
-
- // Loop through the rows until the end of the data is reached - indicated via a NULL
- while (
- (*isConnectedPtr)(parentConnection, isConnectedSelector)
- && (theRow = mysql_fetch_row(resultSet))
- ) {
- // If the load has been cancelled, skip any processing - we're only interested
- // in ensuring that mysql_fetch_row is called for all rows.
- if (loadCancelled) {
- continue;
- }
+ @autoreleasepool {
+ MYSQL_ROW theRow;
+ unsigned long *fieldLengths;
+ NSUInteger i, dataCopiedLength, rowDataLength;
+ SPMySQLStreamingResultStoreRowData *newRowStore;
+
+ [[NSThread currentThread] setName:@"SPMySQLStreamingResultStore data download thread"];
+
+ size_t sizeOfMetadata, lengthOfMetadata;
+ size_t lengthOfNullRecords = (size_t)(sizeof(BOOL) * numberOfFields);
+ size_t sizeOfChar = sizeof(char);
+
+ // Loop through the rows until the end of the data is reached - indicated via a NULL
+ while (
+ (*isConnectedPtr)(parentConnection, isConnectedSelector)
+ && (theRow = mysql_fetch_row(resultSet))
+ ) {
+ // If the load has been cancelled, skip any processing - we're only interested
+ // in ensuring that mysql_fetch_row is called for all rows.
+ if (loadCancelled) {
+ continue;
+ }
- // The row store is a single block of memory. It's made up of four blocks of data:
- // Firstly, a single char containing the type of data used to store positions.
- // Secondly, a series of those types recording the *end position* of each field
- // Thirdly, a series of BOOLs recording whether the fields are NULLS - which can't just be from length
- // Finally, a char sequence comprising the actual cell data, which can be looked up by position/length.
-
- // Retrieve the lengths of the returned data, and calculate the overall length of data
- fieldLengths = mysql_fetch_lengths(resultSet);
- rowDataLength = 0;
- for (i = 0; i < numberOfFields; i++) {
- rowDataLength += fieldLengths[i];
- }
+ // The row store is a single block of memory. It's made up of four blocks of data:
+ // Firstly, a single char containing the type of data used to store positions.
+ // Secondly, a series of those types recording the *end position* of each field
+ // Thirdly, a series of BOOLs recording whether the fields are NULLS - which can't just be from length
+ // Finally, a char sequence comprising the actual cell data, which can be looked up by position/length.
- // Depending on the length of the row, vary the metadata size appropriately. This
- // makes defining the data processing much lengthier, but is worth it to reduce the
- // overhead for small rows.
- if (rowDataLength <= UCHAR_MAX) {
- sizeOfMetadata = SPMySQLStoreMetadataAsChar;
- } else if (rowDataLength <= USHRT_MAX) {
- sizeOfMetadata = SPMySQLStoreMetadataAsShort;
- } else {
- sizeOfMetadata = SPMySQLStoreMetadataAsLong;
- }
- lengthOfMetadata = sizeOfMetadata * numberOfFields;
+ // Retrieve the lengths of the returned data, and calculate the overall length of data
+ fieldLengths = mysql_fetch_lengths(resultSet);
+ rowDataLength = 0;
+ for (i = 0; i < numberOfFields; i++) {
+ rowDataLength += fieldLengths[i];
+ }
- // Allocate the memory for the row and set the type marker
- newRowStore = malloc_zone_malloc(storageMallocZone, 1 + lengthOfMetadata + lengthOfNullRecords + (rowDataLength * sizeOfChar));
- newRowStore[0] = sizeOfMetadata;
+ // Depending on the length of the row, vary the metadata size appropriately. This
+ // makes defining the data processing much lengthier, but is worth it to reduce the
+ // overhead for small rows.
+ if (rowDataLength <= UCHAR_MAX) {
+ sizeOfMetadata = SPMySQLStoreMetadataAsChar;
+ } else if (rowDataLength <= USHRT_MAX) {
+ sizeOfMetadata = SPMySQLStoreMetadataAsShort;
+ } else {
+ sizeOfMetadata = SPMySQLStoreMetadataAsLong;
+ }
+ lengthOfMetadata = sizeOfMetadata * numberOfFields;
+
+ // Allocate the memory for the row and set the type marker
+ newRowStore = malloc_zone_malloc(storageMallocZone, 1 + lengthOfMetadata + lengthOfNullRecords + (rowDataLength * sizeOfChar));
+ newRowStore[0] = sizeOfMetadata;
+
+ // Set the data end positions. Manually unroll the logic for the different cases; messy
+ // but again worth the large memory savings for smaller rows
+ rowDataLength = 0;
+ switch (sizeOfMetadata) {
+ case SPMySQLStoreMetadataAsLong:
+ for (i = 0; i < numberOfFields; i++) {
+ rowDataLength += fieldLengths[i];
+ ((unsigned long *)(newRowStore + 1))[i] = rowDataLength;
+ ((BOOL *)(newRowStore + 1 + lengthOfMetadata))[i] = (theRow[i] == NULL);
+ }
+ break;
+ case SPMySQLStoreMetadataAsShort:
+ for (i = 0; i < numberOfFields; i++) {
+ rowDataLength += fieldLengths[i];
+ ((unsigned short *)(newRowStore + 1))[i] = rowDataLength;
+ ((BOOL *)(newRowStore + 1 + lengthOfMetadata))[i] = (theRow[i] == NULL);
+ }
+ break;
+ case SPMySQLStoreMetadataAsChar:
+ for (i = 0; i < numberOfFields; i++) {
+ rowDataLength += fieldLengths[i];
+ ((unsigned char *)(newRowStore + 1))[i] = rowDataLength;
+ ((BOOL *)(newRowStore + 1 + lengthOfMetadata))[i] = (theRow[i] == NULL);
+ }
+ break;
+ }
- // Set the data end positions. Manually unroll the logic for the different cases; messy
- // but again worth the large memory savings for smaller rows
- rowDataLength = 0;
- switch (sizeOfMetadata) {
- case SPMySQLStoreMetadataAsLong:
- for (i = 0; i < numberOfFields; i++) {
- rowDataLength += fieldLengths[i];
- ((unsigned long *)(newRowStore + 1))[i] = rowDataLength;
- ((BOOL *)(newRowStore + 1 + lengthOfMetadata))[i] = (theRow[i] == NULL);
- }
- break;
- case SPMySQLStoreMetadataAsShort:
- for (i = 0; i < numberOfFields; i++) {
- rowDataLength += fieldLengths[i];
- ((unsigned short *)(newRowStore + 1))[i] = rowDataLength;
- ((BOOL *)(newRowStore + 1 + lengthOfMetadata))[i] = (theRow[i] == NULL);
- }
- break;
- case SPMySQLStoreMetadataAsChar:
+ // If the row has content, copy it in
+ if (rowDataLength) {
+ dataCopiedLength = 1 + lengthOfMetadata + lengthOfNullRecords;
for (i = 0; i < numberOfFields; i++) {
- rowDataLength += fieldLengths[i];
- ((unsigned char *)(newRowStore + 1))[i] = rowDataLength;
- ((BOOL *)(newRowStore + 1 + lengthOfMetadata))[i] = (theRow[i] == NULL);
- }
- break;
- }
-
- // If the row has content, copy it in
- if (rowDataLength) {
- dataCopiedLength = 1 + lengthOfMetadata + lengthOfNullRecords;
- for (i = 0; i < numberOfFields; i++) {
- if (theRow[i] != NULL) {
- memcpy(newRowStore + dataCopiedLength, theRow[i], fieldLengths[i]);
- dataCopiedLength += fieldLengths[i];
+ if (theRow[i] != NULL) {
+ memcpy(newRowStore + dataCopiedLength, theRow[i], fieldLengths[i]);
+ dataCopiedLength += fieldLengths[i];
+ }
}
}
- }
- // Lock the data mutex
- pthread_mutex_lock(&dataLock);
+ // Lock the data mutex
+ pthread_mutex_lock(&dataLock);
- // Ensure that sufficient capacity is available
- SPMySQLStreamingResultStoreEnsureCapacityForAdditionalRowCount(self, 1);
+ // Ensure that sufficient capacity is available
+ SPMySQLStreamingResultStoreEnsureCapacityForAdditionalRowCount(self, 1);
- // Add the newly allocated row to the storage
- if (rowDownloadIterator < numberOfRows) {
- SPMySQLStreamingResultStoreFreeRowData(dataStorage[rowDownloadIterator]);
- }
- dataStorage[rowDownloadIterator] = newRowStore;
- rowDownloadIterator++;
+ // Add the newly allocated row to the storage
+ if (rowDownloadIterator < numberOfRows) {
+ SPMySQLStreamingResultStoreFreeRowData(dataStorage[rowDownloadIterator]);
+ }
+ dataStorage[rowDownloadIterator] = newRowStore;
+ rowDownloadIterator++;
- // Update the total row count if exceeded
- if (rowDownloadIterator > numberOfRows) {
- numberOfRows++;
- }
+ // Update the total row count if exceeded
+ if (rowDownloadIterator > numberOfRows) {
+ numberOfRows++;
+ }
- // Unlock the mutex
- pthread_mutex_unlock(&dataLock);
- }
+ // Unlock the mutex
+ pthread_mutex_unlock(&dataLock);
+ }
- // Update the total number of rows in the result set now download
- // is complete, freeing extra rows from a previous result set
- if (numberOfRows > rowDownloadIterator) {
- pthread_mutex_lock(&dataLock);
- while (numberOfRows > rowDownloadIterator) {
- SPMySQLStreamingResultStoreFreeRowData(dataStorage[--numberOfRows]);
+ // Update the total number of rows in the result set now download
+ // is complete, freeing extra rows from a previous result set
+ if (numberOfRows > rowDownloadIterator) {
+ pthread_mutex_lock(&dataLock);
+ while (numberOfRows > rowDownloadIterator) {
+ SPMySQLStreamingResultStoreFreeRowData(dataStorage[--numberOfRows]);
+ }
+ pthread_mutex_unlock(&dataLock);
}
- pthread_mutex_unlock(&dataLock);
- }
- // Update the connection's error statuses to reflect any errors during the content download
- [parentConnection _updateLastErrorInfos];
+ // Update the connection's error statuses to reflect any errors during the content download
+ [parentConnection _updateLastErrorInfos];
- // Unlock the parent connection now all data has been retrieved
- [parentConnection _unlockConnection];
- connectionUnlocked = YES;
+ // Unlock the parent connection now all data has been retrieved
+ [parentConnection _unlockConnection];
+ connectionUnlocked = YES;
- // If the connection query may have been cancelled with a query kill, double-check connection
- if ([parentConnection lastQueryWasCancelled] && [parentConnection serverMajorVersion] < 5) {
- [parentConnection checkConnection];
- }
+ // If the connection query may have been cancelled with a query kill, double-check connection
+ if ([parentConnection lastQueryWasCancelled] && [parentConnection serverMajorVersion] < 5) {
+ [parentConnection checkConnection];
+ }
- dataDownloaded = YES;
+ dataDownloaded = YES;
- // Inform the delegate the download was completed
- if ([delegate respondsToSelector:@selector(resultStoreDidFinishLoadingData:)]) {
- [delegate resultStoreDidFinishLoadingData:self];
+ // Inform the delegate the download was completed
+ if ([delegate respondsToSelector:@selector(resultStoreDidFinishLoadingData:)]) {
+ [delegate resultStoreDidFinishLoadingData:self];
+ }
}
-
- [downloadPool drain];
}
/**