// // $Id: PGPostgresConnectionParameters.m 3848 2012-09-12 12:19:31Z stuart02 $ // // PGPostgresConnectionParameters.m // PostgresKit // // Created by Stuart Connolly (stuconnolly.com) on August 29, 2012. // Copyright (c) 2012 Stuart Connolly. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. #import "PGPostgresConnectionParameters.h" #import "PGPostgresKitPrivateAPI.h" #import "PGPostgresConnection.h" @interface PGPostgresConnectionParameters () - (void)_loadParameters:(id)object; - (BOOL)_isBooleanParameterValue:(NSString *)value; - (BOOL)_booleanForParameterValue:(NSString *)value; @end @implementation PGPostgresConnectionParameters @synthesize connection = _connection; #pragma mark - - (id)init { return [self initWithConnection:nil]; } /** * Initialise a parameters instance with the supplied connection. * * @param connection The connection to use. * * @return The initialised instance. */ - (id)initWithConnection:(PGPostgresConnection *)connection { if ((self = [super init])) { _connection = connection; pthread_mutex_init(&_readLock, NULL); } return self; } #pragma mark - #pragma mark Public API /** * Loads the database parameters. * * @return A BOOL indicating the success of the load. */ - (BOOL)loadParameters { pthread_mutex_lock(&_readLock); if (!_connection || ![_connection isConnected]) { pthread_mutex_unlock(&_readLock); return NO; } if (!_parameterNames) { _parameterNames = [[NSMutableArray alloc] init]; [_parameterNames addObject:PGPostgresParameterServerEncoding]; [_parameterNames addObject:PGPostgresParameterClientEncoding]; [_parameterNames addObject:PGPostgresParameterSuperUser]; [_parameterNames addObject:PGPostgresParameterTimeZone]; [_parameterNames addObject:PGPostgresParameterIntegerDateTimes]; } pthread_mutex_unlock(&_readLock); [self performSelectorInBackground:@selector(_loadParameters:) withObject:_parameterNames]; return YES; } /** * Gets the object for the supplied parameter. * * @param parameter The name of the parameter to lookup. * * @return The parameter value or nil if parameters haven't been loaded or it can't be found. */ - (id)valueForParameter:(NSString *)parameter { pthread_mutex_lock(&_readLock); if (!_parameters || ![_parameters count]) { pthread_mutex_unlock(&_readLock); return nil; } id value = [_parameters objectForKey:parameter]; pthread_mutex_unlock(&_readLock); return value; } #pragma mark - #pragma mark Private API /** * Loads the values of the supplied array of parameters by query the current connection. * * @param object The parameters to load. */ - (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]; id paramObject = [self _isBooleanParameterValue:stringValue] ? (id)[NSNumber numberWithBool:[self _booleanForParameterValue:stringValue]] : stringValue; [_parameters setObject:paramObject forKey:parameter]; } pthread_mutex_unlock(&_readLock); [pool release]; } /** * Determines whether or not the supplied value is a boolean value. * * @param value The value to look at. * * @return A BOOL indicating if the value is a boolean type. */ - (BOOL)_isBooleanParameterValue:(NSString *)value { value = [value uppercaseString]; return [value isEqualToString:@"ON"] || [value isEqualToString:@"YES"] || [value isEqualToString:@"TRUE"] || [value isEqualToString:@"OFF"] || [value isEqualToString:@"NO"] || [value isEqualToString:@"FALSE"]; } /** * Determines the boolean value for the supplied boolean string representation. * * @param value The value to look at. * * @return A BOOL indicating the value of the string representation. */ - (BOOL)_booleanForParameterValue:(NSString *)value { value = [value uppercaseString]; return [value isEqualToString:@"ON"] || [value isEqualToString:@"YES"] || [value isEqualToString:@"TRUE"]; } #pragma mark - - (void)dealloc { _connection = nil; pthread_mutex_destroy(&_readLock); if (_parameters) [_parameters release], _parameters = nil; if (_parameterNames) [_parameterNames release], _parameterNames = nil; [super dealloc]; } @end