From 05f1612cbb7e33cf9135a346fc2505cc0e87e853 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Thu, 23 Feb 2012 02:13:56 +0000 Subject: Warning: this branch commit is largely untested, and known to throw exceptions as database structure retrieval is currently missing! Further work on SPMySQLFramework integration: - Improve SPMySQL framework build settings including correct ppc builds and a Distribution configuration for the build distributions to match - Add new convenience querying and result methods to the framework - Amend Sequel Pro source to use the new SPMySQL.framework methods everywhere, replacing MCPKit methods where they differ and improving some functions - Remove MCPKit from the source - Fix a number of warnings on Release-style builds --- Frameworks/MCPKit/MCPFoundationKit/MCPResult.m | 1354 ------------------------ 1 file changed, 1354 deletions(-) delete mode 100644 Frameworks/MCPKit/MCPFoundationKit/MCPResult.m (limited to 'Frameworks/MCPKit/MCPFoundationKit/MCPResult.m') diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m deleted file mode 100644 index f112a02d..00000000 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m +++ /dev/null @@ -1,1354 +0,0 @@ -// -// $Id$ -// -// MCPResult.m -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 08/12/2002. -// Copyright (c) 2001 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at -// More info at - -#import "MCPConnection.h" -#import "MCPNull.h" -#import "MCPNumber.h" -#import "MCPResult.h" -#import "MCPGeometryData.h" - -NSCalendarDate *MCPYear0000; - -const OUR_CHARSET our_charsets60[] = -{ - {1, "big5","big5_chinese_ci", 1, 2}, - {3, "dec8", "dec8_swedisch_ci", 1, 1}, - {4, "cp850", "cp850_general_ci", 1, 1}, - {6, "hp8", "hp8_english_ci", 1, 1}, - {7, "koi8r", "koi8r_general_ci", 1, 1}, - {8, "latin1", "latin1_swedish_ci", 1, 1}, - {9, "latin2", "latin2_general_ci", 1, 1}, - {10, "swe7", "swe7_swedish_ci", 1, 1}, - {11, "ascii", "ascii_general_ci", 1, 1}, - {12, "ujis", "ujis_japanese_ci", 1, 3}, - {13, "sjis", "sjis_japanese_ci", 1, 2}, - {16, "hebrew", "hebrew_general_ci", 1, 1}, - {18, "tis620", "tis620_thai_ci", 1, 1}, - {19, "euckr", "euckr_korean_ci", 1, 2}, - {22, "koi8u", "koi8u_general_ci", 1, 1}, - {24, "gb2312", "gb2312_chinese_ci", 1, 2}, - {25, "greek", "greek_general_ci", 1, 1}, - {26, "cp1250", "cp1250_general_ci", 1, 1}, - {28, "gbk", "gbk_chinese_ci", 1, 2}, - {30, "latin5", "latin5_turkish_ci", 1, 1}, - {32, "armscii8", "armscii8_general_ci", 1, 1}, - {33, "utf8", "utf8_general_ci", 1, 3}, - {35, "ucs2", "ucs2_general_ci", 2, 2}, - {36, "cp866", "cp866_general_ci", 1, 1}, - {37, "keybcs2", "keybcs2_general_ci", 1, 1}, - {38, "macce", "macce_general_ci", 1, 1}, - {39, "macroman", "macroman_general_ci", 1, 1}, - {40, "cp852", "cp852_general_ci", 1, 1}, - {41, "latin7", "latin7_general_ci", 1, 1}, - {51, "cp1251", "cp1251_general_ci", 1, 1}, - {57, "cp1256", "cp1256_general_ci", 1, 1}, - {59, "cp1257", "cp1257_general_ci", 1, 1}, - {63, "binary", "binary", 1, 1}, - {92, "geostd8", "geostd8_general_ci", 1, 1}, - {95, "cp932", "cp932_japanese_ci", 1, 2}, - {97, "eucjpms", "eucjpms_japanese_ci", 1, 3}, - {2, "latin2", "latin2_czech_cs", 1, 1}, - {5, "latin1", "latin1_german_ci", 1, 1}, - {14, "cp1251", "cp1251_bulgarian_ci", 1, 1}, - {15, "latin1", "latin1_danish_ci", 1, 1}, - {17, "filename", "filename", 1, 5}, - {20, "latin7", "latin7_estonian_cs", 1, 1}, - {21, "latin2", "latin2_hungarian_ci", 1, 1}, - {23, "cp1251", "cp1251_ukrainian_ci", 1, 1}, - {27, "latin2", "latin2_croatian_ci", 1, 1}, - {29, "cp1257", "cp1257_lithunian_ci", 1, 1}, - {31, "latin1", "latin1_german2_ci", 1, 1}, - {34, "cp1250", "cp1250_czech_cs", 1, 1}, - {42, "latin7", "latin7_general_cs", 1, 1}, - {43, "macce", "macce_bin", 1, 1}, - {44, "cp1250", "cp1250_croatian_ci", 1, 1}, - {45, "utf8", "utf8_general_ci", 1, 1}, - {46, "utf8", "utf8_bin", 1, 1}, - {47, "latin1", "latin1_bin", 1, 1}, - {48, "latin1", "latin1_general_ci", 1, 1}, - {49, "latin1", "latin1_general_cs", 1, 1}, - {50, "cp1251", "cp1251_bin", 1, 1}, - {52, "cp1251", "cp1251_general_cs", 1, 1}, - {53, "macroman", "macroman_bin", 1, 1}, - {58, "cp1257", "cp1257_bin", 1, 1}, - {60, "armascii8", "armascii8_bin", 1, 1}, - {65, "ascii", "ascii_bin", 1, 1}, - {66, "cp1250", "cp1250_bin", 1, 1}, - {67, "cp1256", "cp1256_bin", 1, 1}, - {68, "cp866", "cp866_bin", 1, 1}, - {69, "dec8", "dec8_bin", 1, 1}, - {70, "greek", "greek_bin", 1, 1}, - {71, "hebew", "hebrew_bin", 1, 1}, - {72, "hp8", "hp8_bin", 1, 1}, - {73, "keybcs2", "keybcs2_bin", 1, 1}, - {74, "koi8r", "koi8r_bin", 1, 1}, - {75, "koi8u", "koi8u_bin", 1, 1}, - {77, "latin2", "latin2_bin", 1, 1}, - {78, "latin5", "latin5_bin", 1, 1}, - {79, "latin7", "latin7_bin", 1, 1}, - {80, "cp850", "cp850_bin", 1, 1}, - {81, "cp852", "cp852_bin", 1, 1}, - {82, "swe7", "swe7_bin", 1, 1}, - {93, "geostd8", "geostd8_bin", 1, 1}, - {83, "utf8", "utf8_bin", 1, 3}, - {84, "big5", "big5_bin", 1, 2}, - {85, "euckr", "euckr_bin", 1, 2}, - {86, "gb2312", "gb2312_bin", 1, 2}, - {87, "gbk", "gbk_bin", 1, 2}, - {88, "sjis", "sjis_bin", 1, 2}, - {89, "tis620", "tis620_bin", 1, 1}, - {90, "ucs2", "ucs2_bin", 2, 2}, - {91, "ujis", "ujis_bin", 1, 3}, - {94, "latin1", "latin1_spanish_ci", 1, 1}, - {96, "cp932", "cp932_bin", 1, 2}, - {99, "cp1250", "cp1250_polish_ci", 1, 1}, - {98, "eucjpms", "eucjpms_bin", 1, 3}, - {128, "ucs2", "ucs2_unicode_ci", 2, 2}, - {129, "ucs2", "ucs2_icelandic_ci", 2, 2}, - {130, "ucs2", "ucs2_latvian_ci", 2, 2}, - {131, "ucs2", "ucs2_romanian_ci", 2, 2}, - {132, "ucs2", "ucs2_slovenian_ci", 2, 2}, - {133, "ucs2", "ucs2_polish_ci", 2, 2}, - {134, "ucs2", "ucs2_estonian_ci", 2, 2}, - {135, "ucs2", "ucs2_spanish_ci", 2, 2}, - {136, "ucs2", "ucs2_swedish_ci", 2, 2}, - {137, "ucs2", "ucs2_turkish_ci", 2, 2}, - {138, "ucs2", "ucs2_czech_ci", 2, 2}, - {139, "ucs2", "ucs2_danish_ci", 2, 2}, - {140, "ucs2", "ucs2_lithunian_ci", 2, 2}, - {141, "ucs2", "ucs2_slovak_ci", 2, 2}, - {142, "ucs2", "ucs2_spanish2_ci", 2, 2}, - {143, "ucs2", "ucs2_roman_ci", 2, 2}, - {144, "ucs2", "ucs2_persian_ci", 2, 2}, - {145, "ucs2", "ucs2_esperanto_ci", 2, 2}, - {146, "ucs2", "ucs2_hungarian_ci", 2, 2}, - {147, "ucs2", "ucs2_sinhala_ci", 2, 2}, - {192, "utf8mb3", "utf8mb3_general_ci", 1, 3}, - {193, "utf8mb3", "utf8mb3_icelandic_ci", 1, 3}, - {194, "utf8mb3", "utf8mb3_latvian_ci", 1, 3}, - {195, "utf8mb3", "utf8mb3_romanian_ci", 1, 3}, - {196, "utf8mb3", "utf8mb3_slovenian_ci", 1, 3}, - {197, "utf8mb3", "utf8mb3_polish_ci", 1, 3}, - {198, "utf8mb3", "utf8mb3_estonian_ci", 1, 3}, - {119, "utf8mb3", "utf8mb3_spanish_ci", 1, 3}, - {200, "utf8mb3", "utf8mb3_swedish_ci", 1, 3}, - {201, "utf8mb3", "utf8mb3_turkish_ci", 1, 3}, - {202, "utf8mb3", "utf8mb3_czech_ci", 1, 3}, - {203, "utf8mb3", "utf8mb3_danish_ci", 1, 3}, - {204, "utf8mb3", "utf8mb3_lithunian_ci", 1, 3}, - {205, "utf8mb3", "utf8mb3_slovak_ci", 1, 3}, - {206, "utf8mb3", "utf8mb3_spanish2_ci", 1, 3}, - {207, "utf8mb3", "utf8mb3_roman_ci", 1, 3}, - {208, "utf8mb3", "utf8mb3_persian_ci", 1, 3}, - {209, "utf8mb3", "utf8mb3_esperanto_ci", 1, 3}, - {210, "utf8mb3", "utf8mb3_hungarian_ci", 1, 3}, - {211, "utf8mb3", "utf8mb3_sinhala_ci", 1, 3}, - {224, "utf8", "utf8_unicode_ci", 1, 3}, - {225, "utf8", "utf8_icelandic_ci", 1, 3}, - {226, "utf8", "utf8_latvian_ci", 1, 3}, - {227, "utf8", "utf8_romanian_ci", 1, 3}, - {228, "utf8", "utf8_slovenian_ci", 1, 3}, - {229, "utf8", "utf8_polish_ci", 1, 3}, - {230, "utf8", "utf8_estonian_ci", 1, 3}, - {231, "utf8", "utf8_spanish_ci", 1, 3}, - {232, "utf8", "utf8_swedish_ci", 1, 3}, - {233, "utf8", "utf8_turkish_ci", 1, 3}, - {234, "utf8", "utf8_czech_ci", 1, 3}, - {235, "utf8", "utf8_danish_ci", 1, 3}, - {236, "utf8", "utf8_lithuanian_ci", 1, 3}, - {237, "utf8", "utf8_slovak_ci", 1, 3}, - {238, "utf8", "utf8_spanish2_ci", 1, 3}, - {239, "utf8", "utf8_roman_ci", 1, 3}, - {240, "utf8", "utf8_persian_ci", 1, 3}, - {241, "utf8", "utf8_esperanto_ci", 1, 3}, - {242, "utf8", "utf8_hungarian_ci", 1, 3}, - {243, "utf8", "utf8_sinhala_ci", 1, 3}, - {254, "utf8mb3", "utf8mb3_general_cs", 1, 3}, - {0, NULL, NULL, 0, 0} -}; - -@implementation MCPResult - -/** - * Hold the results of a query to a MySQL database server. It correspond to the MYSQL_RES structure of the C API, and to the statement handle of the PERL DBI/DBD. - * - * Uses the !{mysql_store_result()} function from the C API. - * - * This object is generated only by a MCPConnection object, in this way (see #{MCPConnection} documentation): - * - * MCPConnection *theConnec = [MCPConnection alloc]; - * MCPResult *theRes; - * NSDictionary *theDict; - * NSArray *theColNames; - * int i, j; - * - * theConnec = [theConnec initToHost:@"albert.com" withLogin:@"toto" password:@"albert" usingPort:0]; - * [theConnec selectDB:@"db1"]; - * theRes = [theConnec queryString:@"select * from table1"]; - * theColNames = [theRes fetchFiedlsName]; - * i = 0; - * - * while (theDict = [theRes fetchRowAsDictionary]) { - * NSLog(@"Row : %d\n", i); - * for (j=0; j<[theColNames count]; j++) { - * NSLog(@" Field : %@, contain : %@\n", [theColNames objectAtIndex:j], [theDict objectForKey:[theColNames objectAtIndex:j]]); - * } - * i++; - * } - */ - -/** - * Initialize the class version to 3.0.1 - */ -+ (void)initialize -{ - if ((self = [MCPResult class])) { - [self setVersion:030001]; // Ma.Mi.Re -> MaMiRe - MCPYear0000 = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate:-63146822400.0]; - [MCPYear0000 setCalendarFormat:@"%Y"]; - } -} - -#pragma mark - -#pragma mark Initialisation - -/** - * Empty init, normaly of NO use to the user, again, MCPResult should be made through calls to MCPConnection - */ -- (id)init -{ - if ((self = [super init])) { - mEncoding = [MCPConnection defaultMySQLEncoding]; - mReturnDataAsStrings = NO; - mTimeZone = nil; - - if (mResult) { - mysql_free_result(mResult); - mResult = NULL; - } - - if (mNames) { - [mNames release]; - mNames = nil; - } - - mNumOfFields = 0; - } - - return self; -} - -/** - * Initialise a MCPResult, it is used internally by MCPConnection !{queryString:} method: the only proper - * way to get a running MCPResult object. - */ -- (id)initWithMySQLPtr:(MYSQL *)mySQLPtr encoding:(NSStringEncoding)iEncoding timeZone:(NSTimeZone *)iTimeZone -{ - if ((self = [super init])) { - mEncoding = iEncoding; - mTimeZone = [iTimeZone retain]; - mReturnDataAsStrings = NO; - - if (mResult) { - mysql_free_result(mResult); - mResult = NULL; - } - - if (mNames) { - [mNames release]; - mNames = nil; - } - - mResult = mysql_store_result(mySQLPtr); - - if (mResult) { - mNumOfFields = mysql_num_fields(mResult); - } - else { - mNumOfFields = 0; - } - } - - return self; -} - -/** - * This metod is used internally by MCPConnection object when it have already a MYSQL_RES object to initialise - * MCPResult object. Initialise a MCPResult with the MYSQL_RES pointer (returned by such a function as mysql_list_dbs). - * NB: MCPResult should be made by using one of the method of MCPConnection. - */ -- (id)initWithResPtr:(MYSQL_RES *)mySQLResPtr encoding:(NSStringEncoding)iEncoding timeZone:(NSTimeZone *)iTimeZone -{ - if ((self = [super init])) { - mEncoding = iEncoding; - mTimeZone = [iTimeZone retain]; - mReturnDataAsStrings = NO; - - if (mResult) { - mysql_free_result(mResult); - mResult = NULL; - } - - if (mNames) { - [mNames release]; - mNames = nil; - } - - mResult = mySQLResPtr; - - if (mResult) { - mNumOfFields = mysql_num_fields(mResult); - } - else { - mNumOfFields = 0; - } - } - - return self; -} - -#pragma mark - -#pragma mark Result info - -/** - * Return the number of rows selected by the query. - */ -- (my_ulonglong)numOfRows -{ - if (mResult) { - return mysql_num_rows(mResult); - } - - return 0; -} - -/** - * Return the number of fields selected by the query. As a side effect it forces an update of the number of fields. - */ -- (NSUInteger)numOfFields -{ - if (mResult) { - return mNumOfFields = mysql_num_fields(mResult); - } - - return mNumOfFields = 0; -} - -#pragma mark - -#pragma mark Rows - -/** - * Go to a precise row in the selected result. 0 is the very first row. - */ -- (void)dataSeek:(my_ulonglong)row -{ - my_ulonglong theRow = (row < 1)? 0 : row; - theRow = (theRow < [self numOfRows]) ? theRow : ([self numOfRows] - 1); - mysql_data_seek(mResult,theRow); -} - -/** - * - */ -- (id)fetchRowAsType:(MCPReturnType)aType -{ - MYSQL_ROW theRow; - unsigned long *theLengths; - MYSQL_FIELD *theField; - NSUInteger i; - id theReturn; - - if (mResult == NULL) { - // If there is no results, returns nil, as after the last row... - return nil; - } - - theRow = mysql_fetch_row(mResult); - - if (theRow == NULL) { - return nil; - } - - switch (aType) { - case MCPTypeArray: - theReturn = [NSMutableArray arrayWithCapacity:mNumOfFields]; - break; - case MCPTypeDictionary: - if (mNames == nil) { - [self fetchFieldNames]; - } - theReturn = [NSMutableDictionary dictionaryWithCapacity:mNumOfFields]; - break; - default : - NSLog (@"Unknown type : %d, will return an Array!\n", (int)aType); - theReturn = [NSMutableArray arrayWithCapacity:mNumOfFields]; - break; - } - - theLengths = mysql_fetch_lengths(mResult); - theField = mysql_fetch_fields(mResult); - - for (i=0; i= theNumFields) { - // Out of range... should raise an exception - theRet = 0; - } - else { - theRet = theField[anIndex].flags; - } - - return theRet; -} - -/** - * - */ -- (NSUInteger)fetchFlagsForKey:(NSString *)key -{ - NSUInteger theRet; - NSUInteger anIndex; - MYSQL_FIELD *theField; - - if (mResult == NULL) { - // If no results, give an empty array. Maybe it's better to give a nil pointer? - return (0); - } - - if (mNames == nil) { - [self fetchFieldNames]; - } - - theField = mysql_fetch_fields(mResult); - - if ([mNames indexOfObject:key] == NSNotFound) { - // Non existent key... should raise an exception - theRet = 0; - } - else { - anIndex = [mNames indexOfObject:key]; - - theRet = theField[anIndex].flags; - } - - return theRet; -} - -/** - * Return YES if the field with the given index is a BLOB. It should be used to discriminates between BLOBs - * and TEXTs. - * - * #{DEPRECATED}, This method is not consistent with the C API which is supposed to return YES for BOTH - * text and blob (and BTW is also deprecated)... - * - * #{NOTE} That the current version handles properly TEXT, and returns those as NSString (and not NSData as - * it used to be). - */ -- (BOOL)isBlobAtIndex:(NSUInteger)anIndex -{ - BOOL theRet; - NSUInteger theNumFields; - MYSQL_FIELD *theField; - - if (mResult == NULL) { - // If no results, give an empty array. Maybe it's better to give a nil pointer? - return (NO); - } - - theNumFields = [self numOfFields]; - theField = mysql_fetch_fields(mResult); - - if (anIndex >= theNumFields) { - // Out of range... should raise an exception - theRet = NO; - } - else { - switch(theField[anIndex].type) { - case FIELD_TYPE_TINY_BLOB: - case FIELD_TYPE_BLOB: - case FIELD_TYPE_MEDIUM_BLOB: - case FIELD_TYPE_LONG_BLOB: - theRet = (theField[anIndex].flags & BINARY_FLAG); - break; - default: - theRet = NO; - break; - } - } - - return theRet; -} - -/** - * Return YES if the field (by name) with the given index is a BLOB. It should be used to discriminates - * between BLOBs and TEXTs. - * - * #{DEPRECATED}, This method is not consistent with the C API which is supposed to return YES for BOTH - * text and blob (and BTW is also deprecated)... - * - * #{NOTE} That the current version handles properly TEXT, and returns those as NSString (and not NSData - * as it used to be). - */ -- (BOOL)isBlobForKey:(NSString *)key -{ - BOOL theRet; - NSUInteger anIndex; - MYSQL_FIELD *theField; - - if (mResult == NULL) { - // If no results, give an empty array. Maybe it's better to give a nil pointer? - return (NO); - } - - if (mNames == nil) { - [self fetchFieldNames]; - } - - theField = mysql_fetch_fields(mResult); - - if ([mNames indexOfObject:key] == NSNotFound) { - // Non existent key... should raise an exception - theRet = NO; - } - else { - anIndex = [mNames indexOfObject:key]; - - switch(theField[anIndex].type) { - case FIELD_TYPE_TINY_BLOB: - case FIELD_TYPE_BLOB: - case FIELD_TYPE_MEDIUM_BLOB: - case FIELD_TYPE_LONG_BLOB: - theRet = (theField[anIndex].flags & BINARY_FLAG); - break; - default: - theRet = NO; - break; - } - } - - return theRet; -} - -#pragma mark - -#pragma mark Conversion - -/** - * Set whether the result should return data types as strings. This may be useful - * for queries where the result may be returned in either string or data form, but - * will be converted to string for display and use anyway. - * Note that certain MySQL versions also return data types for strings - eg SHOW - * commands like SHOW CREATE TABLE or SHOW VARIABLES, and this conversion can be - * necessary there. - */ -- (void) setReturnDataAsStrings:(BOOL)alwaysConvertData -{ - mReturnDataAsStrings = alwaysConvertData; -} - -/** - * Use the string encoding to convert the returned NSData to a string (for a TEXT field). - */ -- (NSString *)stringWithText:(NSData *)theTextData -{ - NSString *theString; - - if (theTextData == nil) { - return nil; - } - - theString = [[NSString alloc] initWithData:theTextData encoding:mEncoding]; - - if (theString) { - [theString autorelease]; - } - - return theString; -} - -/** - * Return a (long) string containing the table of results, first line being the fields name, next line(s) - * the row(s). Useful to have NSLog logging a MCPResult (example). - */ -- (NSString *)description -{ - if (mResult == NULL) { - return @"This is an empty MCPResult\n"; - } - else { - NSMutableString *theString = [NSMutableString stringWithCapacity:0]; - NSUInteger i; - NSArray *theRow; - MYSQL_ROW_OFFSET thePosition; - BOOL shouldTruncateFields = [MCPConnection truncateLongField]; - - // First line, saying we are displaying a MCPResult - [theString appendFormat:@"MCPResult: (encoding : %ld, dim %ld x %ld)\n", (long)mEncoding, (long)mNumOfFields, (long)[self numOfRows]]; - - // Second line: the field names, tab separated - [self fetchFieldNames]; - - for (i=0; i<(mNumOfFields-1); i++) { - [theString appendFormat:@"%@\t", [mNames objectAtIndex:i]]; - } - - [theString appendFormat:@"%@\n", [mNames objectAtIndex:i]]; - // Next lines, the records (saving current position to put it back after the full display) - thePosition = mysql_row_tell(mResult); - [self dataSeek:0]; - - while ((theRow = [self fetchRowAsArray])) - { - id theField = [theRow objectAtIndex:i]; - - if (shouldTruncateFields) { - if (([theField isKindOfClass:[NSString class]]) && (kLengthOfTruncationForLog < [(NSString *)theField length])) { - theField = [theField substringToIndex:kLengthOfTruncationForLog]; - } - else if (([theField isKindOfClass:[NSData class]]) && (kLengthOfTruncationForLog < [(NSData *)theField length])) { - theField = [NSData dataWithBytes:[theField bytes] length:kLengthOfTruncationForLog]; - } - } - - for (i=0; i<(mNumOfFields - 1); i++) - { - [theString appendFormat:@"%@\t", theField]; - } - - [theString appendFormat:@"%@\n", theField]; - } - - // Returning to the proper row - mysql_row_seek(mResult, thePosition); - - return theString; - } -} - -/** - * For internal use only. Transform a NSString to a C type string (ended with \0) using ethe character set - * from the MCPConnection. Lossy conversions are enabled. - */ -- (const char *)cStringFromString:(NSString *)theString -{ - NSMutableData *theData; - - if (!theString) { - return (const char *)NULL; - } - - theData = [NSMutableData dataWithData:[theString dataUsingEncoding:mEncoding allowLossyConversion:YES]]; - [theData increaseLengthBy:1]; - - return (const char *)[theData bytes]; -} - -/** - * Return a NSString from a C style string encoded with the character set of theMCPConnection. - */ -- (NSString *)stringWithCString:(const char *)theCString -{ - if (theCString == NULL) return @""; - - return [NSString stringWithCString:theCString encoding:mEncoding]; -} - -#pragma mark - -#pragma mark Other - -/** - * Convert a mysql_type to a string - */ -- (NSString *)mysqlTypeToStringForType:(NSUInteger)type withCharsetNr:(NSUInteger)charsetnr withFlags:(NSUInteger)flags withLength:(unsigned long long)length -{ - // BOOL isUnsigned = (flags & UNSIGNED_FLAG) != 0; - // BOOL isZerofill = (flags & ZEROFILL_FLAG) != 0; - - switch (type) { - case FIELD_TYPE_BIT: - return @"BIT"; - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: - //return isUnsigned ? (isZerofill? @"DECIMAL UNSIGNED ZEROFILL" : @"DECIMAL UNSIGNED"): - return @"DECIMAL"; - case MYSQL_TYPE_TINY: - // return isUnsigned ? (isZerofill? @"TINYINT UNSIGNED ZEROFILL" : @"TINYINT UNSIGNED"): - return @"TINYINT"; - case MYSQL_TYPE_SHORT: - // return isUnsigned ? (isZerofill? @"SMALLINT UNSIGNED ZEROFILL" : @"SMALLINT UNSIGNED"): - return @"SMALLINT"; - case MYSQL_TYPE_LONG: - // return isUnsigned ? (isZerofill? @"INT UNSIGNED ZEROFILL" : @"INT UNSIGNED"): - return @"INT"; - case MYSQL_TYPE_FLOAT: - // return isUnsigned ? (isZerofill? @"FLOAT UNSIGNED ZEROFILL" : @"FLOAT UNSIGNED"): - return @"FLOAT"; - case MYSQL_TYPE_DOUBLE: - // return isUnsigned ? (isZerofill? @"DOUBLE UNSIGNED ZEROFILL" : @"DOUBLE UNSIGNED"): - return @"DOUBLE"; - case MYSQL_TYPE_NULL: - return @"NULL"; - case MYSQL_TYPE_TIMESTAMP: - return @"TIMESTAMP"; - case MYSQL_TYPE_LONGLONG: - // return isUnsigned ? (isZerofill? @"BIGINT UNSIGNED ZEROFILL" : @"BIGINT UNSIGNED") : - return @"BIGINT"; - case MYSQL_TYPE_INT24: - // return isUnsigned ? (isZerofill? @"MEDIUMINT UNSIGNED ZEROFILL" : @"MEDIUMINT UNSIGNED") : - return @"MEDIUMINT"; - case MYSQL_TYPE_DATE: - return @"DATE"; - case MYSQL_TYPE_TIME: - return @"TIME"; - case MYSQL_TYPE_DATETIME: - return @"DATETIME"; - case MYSQL_TYPE_TINY_BLOB:// should no appear over the wire - case MYSQL_TYPE_MEDIUM_BLOB:// should no appear over the wire - case MYSQL_TYPE_LONG_BLOB:// should no appear over the wire - case MYSQL_TYPE_BLOB: - { - BOOL isBlob = (charsetnr == MAGIC_BINARY_CHARSET_NR); - switch ((NSInteger)length/[self findCharsetMaxByteLengthPerChar:charsetnr]) { - case 255: return isBlob? @"TINYBLOB":@"TINYTEXT"; - case 65535: return isBlob? @"BLOB":@"TEXT"; - case 16777215: return isBlob? @"MEDIUMBLOB":@"MEDIUMTEXT"; - case 4294967295: return isBlob? @"LONGBLOB":@"LONGTEXT"; - default: - switch (length) { - case 255: return isBlob? @"TINYBLOB":@"TINYTEXT"; - case 65535: return isBlob? @"BLOB":@"TEXT"; - case 16777215: return isBlob? @"MEDIUMBLOB":@"MEDIUMTEXT"; - case 4294967295: return isBlob? @"LONGBLOB":@"LONGTEXT"; - default: - return @"UNKNOWN"; - } - } - } - case MYSQL_TYPE_VAR_STRING: - if (flags & ENUM_FLAG) { - return @"ENUM"; - } - if (flags & SET_FLAG) { - return @"SET"; - } - if (charsetnr == MAGIC_BINARY_CHARSET_NR) { - return @"VARBINARY"; - } - return @"VARCHAR"; - case MYSQL_TYPE_STRING: - if (flags & ENUM_FLAG) { - return @"ENUM"; - } - if (flags & SET_FLAG) { - return @"SET"; - } - if ((flags & BINARY_FLAG) && charsetnr == MAGIC_BINARY_CHARSET_NR) { - return @"BINARY"; - } - return @"CHAR"; - case MYSQL_TYPE_ENUM: - /* This should never happen */ - return @"ENUM"; - case MYSQL_TYPE_YEAR: - return @"YEAR"; - case MYSQL_TYPE_SET: - /* This should never happen */ - return @"SET"; - case MYSQL_TYPE_GEOMETRY: - return @"GEOMETRY"; - default: - return @"UNKNOWN"; - } -} - -/** - * Merge mysql_types into type groups - */ -- (NSString *)mysqlTypeToGroupForType:(NSUInteger)type withCharsetNr:(NSUInteger)charsetnr withFlags:(NSUInteger)flags -{ - switch(type){ - case FIELD_TYPE_BIT: - return @"bit"; - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_INT24: - return @"integer"; - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: - return @"float"; - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_TIMESTAMP: - return @"date"; - case MYSQL_TYPE_VAR_STRING: - if (flags & ENUM_FLAG) { - return @"enum"; - } - if (flags & SET_FLAG) { - return @"enum"; - } - if (charsetnr == MAGIC_BINARY_CHARSET_NR) { - return @"binary"; - } - return @"string"; - case MYSQL_TYPE_STRING: - if (flags & ENUM_FLAG) { - return @"enum"; - } - if (flags & SET_FLAG) { - return @"enum"; - } - if ((flags & BINARY_FLAG) && charsetnr == MAGIC_BINARY_CHARSET_NR) { - return @"binary"; - } - return @"string"; - case MYSQL_TYPE_TINY_BLOB: // should no appear over the wire - case MYSQL_TYPE_MEDIUM_BLOB: // should no appear over the wire - case MYSQL_TYPE_LONG_BLOB: // should no appear over the wire - case MYSQL_TYPE_BLOB: - { - if (charsetnr == MAGIC_BINARY_CHARSET_NR) { - return @"blobdata"; - } else { - return @"textdata"; - } - } - case MYSQL_TYPE_GEOMETRY: - return @"geometry"; - default: - return @"blobdata"; - - } -} - -/** - * Convert a mysql_charsetnr into a charset name as string - */ -- (NSString *)findCharsetName:(NSUInteger)charsetnr -{ - const OUR_CHARSET * c = our_charsets60; - - do { - if (c->nr == charsetnr) - return [self stringWithCString:c->name]; - ++c; - } while (c[0].nr != 0); - - return @"UNKNOWN"; -} - -/** - * Convert a mysql_charsetnr into a collation name as string - */ -- (NSString *)findCharsetCollation:(NSUInteger)charsetnr -{ - const OUR_CHARSET * c = our_charsets60; - - do { - if (c->nr == charsetnr) - return [self stringWithCString:c->collation]; - ++c; - } while (c[0].nr != 0); - - return @"UNKNOWN"; -} - -/** - * Return the max byte length to store a char by using - * a specific mysql_charsetnr - */ -- (NSUInteger)findCharsetMaxByteLengthPerChar:(NSUInteger)charsetnr -{ - const OUR_CHARSET * c = our_charsets60; - - do { - if (c->nr == charsetnr) - return c->char_maxlen; - ++c; - } while (c[0].nr != 0); - - return 1; -} - -#pragma mark - - -/** - * Do one really needs an explanation for this method? Which by the way you should not use... - */ -- (void) dealloc -{ - if (mResult) mysql_free_result(mResult); - if (mNames) [mNames release]; - if (mTimeZone) [mTimeZone release]; - - [super dealloc]; -} - -@end -- cgit v1.2.3