From e124a1d0fb576c311a6ac601b1c08e6ce51bcd30 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Mon, 3 Sep 2012 10:22:17 +0000 Subject: Initial commit of PostgresKit, our new Postgres framework as a start towards adding PostgreSQL support to Sequel Pro. Note, that the framerwork is by no means feature complete and in it's current state has quite a few limitations: - No support for Postgres' asynchronous query API - Only supports the very basic data types (char/text and numerics) - No support (outide of libpq) for re-establishing dropped connections Current feature support includes: - Basic connection handling - Query execution - Prepared statement execution - Encoding support similar to SPMySQL's --- .../Source/FLXPostgresConnectionQueryPreparation.m | 131 +++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m (limited to 'Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m') diff --git a/Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m b/Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m new file mode 100644 index 00000000..d8bf59b7 --- /dev/null +++ b/Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m @@ -0,0 +1,131 @@ +// +// $Id$ +// +// FLXPostgresConnectionQueryPreparation.m +// PostgresKit +// +// Copyright (c) 2008-2009 David Thorpe, djt@mutablelogic.com +// +// Forked by the Sequel Pro Team on July 22, 2012. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#import "FLXPostgresConnectionQueryPreparation.h" +#import "FLXPostgresConnectionTypeHandling.h" +#import "FLXPostgresConnectionPrivateAPI.h" +#import "FLXPostgresStatement.h" +#import "FLXPostgresException.h" + +@implementation FLXPostgresConnection (FLXPostgresConnectionQueryPreparation) + +/** + * Quotes the supplied object in accordance with it's data type. + * + * @param object The object to quote. + * + * @return A string representation of the quoted object. + */ +- (NSString *)quote:(NSObject *)object +{ + if (!object || [object isKindOfClass:[NSNull class]]) return @"NULL"; + + id handler = [self typeHandlerForClass:[object class]]; + + if (!handler) { + [FLXPostgresException raise:FLXPostgresConnectionErrorDomain + reason:[NSString stringWithFormat:@"Unsupported class '%@'", NSStringFromClass([object class])]]; + + return nil; + } + + return [handler quotedStringFromObject:object]; +} + +/** + * Creates a prepared statment from the supplied query. + * + * @param query The query to create the statement from. + * + * @return The prepared statement instance. + */ +- (FLXPostgresStatement *)prepare:(NSString *)query +{ + if (!query || ![query length]) return nil; + + return [[[FLXPostgresStatement alloc] initWithStatement:query] autorelease]; +} + +/** + * Creates a prepared statment from the supplied query format and values. + * + * @param query The query to create the statement from. + * @param ... Any values to insert into the query (optional). + * + * @return The prepared statement instance. + */ +- (FLXPostgresStatement *)prepareWithFormat:(NSString *)query, ... +{ + if (!query || ![query length]) return nil; + + va_list args; + va_start(args, query); + + NSMutableString *string = [[NSMutableString alloc] initWithFormat:query arguments:args]; + + va_end(args); + + FLXPostgresStatement *statement = [self prepare:string]; + + [string release]; + + return statement; +} + +#pragma mark - +#pragma mark Private API + +/** + * Actually prepares the supplied statement against the database. + * + * @param statement The statement to prepare. + * @param paranNum The number of parameters the statement contains. + * @param paramTypes Any of Postgres parameter types. + * + * @return A BOOL indicating succes. Returns NO if there's no statement, statement name or current connection. + */ +- (BOOL)_prepare:(FLXPostgresStatement *)statement num:(int)paramNum types:(FLXPostgresOid *)paramTypes +{ + if (!statement || ![statement name] || ![self isConnected]) return NO; + + NSString *name = [[NSProcessInfo processInfo] globallyUniqueString]; + + PGresult *result = PQprepare(_connection, [name UTF8String], [statement UTF8Statement], paramNum, paramTypes); + + if (!result) return NO; + + ExecStatusType resultStatus = PQresultStatus(result); + + if (resultStatus == PGRES_BAD_RESPONSE || resultStatus == PGRES_FATAL_ERROR) { + PQclear(result); + + return NO; + } + + PQclear(result); + + [statement setName:name]; + + return YES; +} + +@end -- cgit v1.2.3