[Mysql-cocoa-commits] CVS: SMySQL SMySQLConnection.h,1.4,1.5 SMySQLConnection.m,1.4,1.5 SMySQLResult
Brought to you by:
sergecohen
From: Serge C. <ser...@us...> - 2002-05-03 09:36:42
|
Update of /cvsroot/mysql-cocoa/SMySQL In directory usw-pr-cvs1:/tmp/cvs-serv31519 Modified Files: SMySQLConnection.h SMySQLConnection.m SMySQLResult.h SMySQLResult.m Log Message: Added methods listDBs, listTables, listFields. First test for supporting proper charset encoding. Still some strange bug on queryString. Serge Cohen; MySQL Cocoa Project, May 3rd 2002. Index: SMySQLConnection.h =================================================================== RCS file: /cvsroot/mysql-cocoa/SMySQL/SMySQLConnection.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** SMySQLConnection.h 10 Apr 2002 15:12:08 -0000 1.4 --- SMySQLConnection.h 3 May 2002 09:36:39 -0000 1.5 *************** *** 30,35 **** #define kSMySQL_default_option CLIENT_COMPRESS ! #define kSMySQLConnectionDefaultSocket "/tmp/mysql.sock" ! #define kMySQLConnection_error_not_inited 1000 @interface SMySQLConnection : NSObject { --- 30,35 ---- #define kSMySQL_default_option CLIENT_COMPRESS ! #define kSMySQLConnectionDefaultSocket MYSQL_UNIX_ADDR ! #define kSMySQLConnection_error_not_inited 1000 @interface SMySQLConnection : NSObject { *************** *** 38,43 **** NSStringEncoding mEncoding; /*"The encoding used by MySQL server, to ISO-1 default"*/ } ! + (NSDictionary *) getMySQLLocales; /*" Initialisation --- 38,48 ---- NSStringEncoding mEncoding; /*"The encoding used by MySQL server, to ISO-1 default"*/ } ! /*" ! Getting default of MySQL ! "*/ + (NSDictionary *) getMySQLLocales; + + (NSStringEncoding) encodingForMySQLEncoding:(const char *) mysqlEncoding; + + (NSStringEncoding) defaultMySQLEncoding; + /*" Initialisation *************** *** 78,81 **** --- 83,95 ---- - (my_ulonglong)insertId; + + /*" + Getting description of the database structure + "*/ + - (SMySQLResult *)listDBs:(NSString *)dbsName; + - (SMySQLResult *)listTables:(NSString *)tablesName; + - (SMySQLResult *)listFields:(NSString *)fieldsName forTable:(NSString *)tableName; + + /*" Server information *************** *** 93,96 **** --- 107,115 ---- - (void)disconnect; - (void)dealloc; + + /*" + Private methods, internam use only + "*/ + - (const char *)cStringFromString:(NSString *)theString; @end Index: SMySQLConnection.m =================================================================== RCS file: /cvsroot/mysql-cocoa/SMySQL/SMySQLConnection.m,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** SMySQLConnection.m 10 Apr 2002 15:12:08 -0000 1.4 --- SMySQLConnection.m 3 May 2002 09:36:39 -0000 1.5 *************** *** 59,62 **** --- 59,102 ---- + + (NSStringEncoding) encodingForMySQLEncoding:(const char *) mysqlEncoding + /*"From the name a charset in mysql format return the proper NSStringEncoding corresponding to this charset. + This method is not complete for the moment, I hope people using non "supported" encoding will addd them when one needs it, and send me back the modification. + + As off version 4.0 of MySQL, choice in : + big5 cp1251 cp1257 croat czech danish dec8 dos estonia euc_kr gb2312 gbk german1 greek hebrew hp8 hungarian koi8_ru koi8_ukr latin1 latin1_de latin2 latin5 sjis swe7 tis620 ujis usa7 win1250 win1251ukr + "*/ + { + if (!strcmp(mysqlEncoding, "latin1")) { + return NSISOLatin1StringEncoding; + } + if (!strcmp(mysqlEncoding, "latin2")) { + return NSISOLatin2StringEncoding; + } + if (!strcmp(mysqlEncoding, "win1250")) { + return NSWindowsCP1250StringEncoding; + } + if (!strcmp(mysqlEncoding, "cp1251")) { + return NSWindowsCP1251StringEncoding; + } + if (!strcmp(mysqlEncoding, "euc_kr")) { + return NSJapaneseEUCStringEncoding; + } + if (!strcmp(mysqlEncoding, "sjis")) { + return NSShiftJISStringEncoding; + } + + // default to iso latin 1, even if it is not exact (throw an exception?) + return NSISOLatin1StringEncoding; + } + + + + (NSStringEncoding) defaultMySQLEncoding + /*"Return the default charset of the library mysqlclient used. + "*/ + { + return [SMySQLConnection encodingForMySQLEncoding:MYSQL_CHARSET]; + } + + - (id)init /*" *************** *** 174,178 **** - (void)setEncoding:(NSStringEncoding) theEncoding /*" ! Select the encoding used by the server for data transfert. This usefull for the output NSString (query result) to be Ok even for character which are not ASCII "*/ { --- 214,218 ---- - (void)setEncoding:(NSStringEncoding) theEncoding /*" ! Select the encoding used by the server for data transfert. This is usefull for the output NSString (query result) to be Ok even for character which are not ASCII "*/ { *************** *** 207,210 **** --- 247,251 ---- { #warning What to do if one of the string is a nil pointer? + #warning What about the encoding? const char *theHost = [host UTF8String]; const char *theLogin = [login UTF8String]; *************** *** 224,227 **** --- 265,269 ---- return mConnected = NO; } + mEncoding = [SMySQLConnection encodingForMySQLEncoding:mysql_character_set_name(mConnection)]; return mConnected = YES; } *************** *** 242,245 **** --- 284,288 ---- { #warning What to do if one of the string is a nil pointer? + #warning What about the encoding? const char *theSocket = [socket UTF8String]; const char *theLogin = [login UTF8String]; *************** *** 259,262 **** --- 302,306 ---- return mConnected = NO; } + mEncoding = [SMySQLConnection encodingForMySQLEncoding:mysql_character_set_name(mConnection)]; return mConnected = YES; } *************** *** 276,279 **** --- 320,324 ---- } if (mConnected) { + #warning What about the encoding? const char *theDBName = [dbName UTF8String]; if (mysql_select_db(mConnection, theDBName) == NULL) { *************** *** 291,294 **** --- 336,340 ---- { if (mConnection) { + #warning What about the encoding? return [NSString stringWithUTF8String:mysql_error(mConnection)]; } *************** *** 306,310 **** return mysql_errno(mConnection); } ! return kMySQLConnection_error_not_inited; } --- 352,356 ---- return mysql_errno(mConnection); } ! return kSMySQLConnection_error_not_inited; } *************** *** 337,340 **** --- 383,387 ---- mysql_real_escape_string(mConnection, theCEscBuffer, theCDataBuffer, theLength); + #warning What about the encoding? theReturn = [NSString stringWithUTF8String:theCEscBuffer]; free (theCEscBuffer); *************** *** 346,356 **** /*" Takes a query string and return an SMySQLResult object holding the result of the query. "*/ { SMySQLResult *theResult = [SMySQLResult alloc]; ! const char *theCQuery = [query UTF8String]; ! if (mysql_query(mConnection, theCQuery) == NULL) { theResult = [theResult initWithMySQLPtr:mConnection encoding:mEncoding]; if (theResult) { [theResult autorelease]; --- 393,408 ---- /*" Takes a query string and return an SMySQLResult object holding the result of the query. + The returned SMySQLResult is not retained, the client is responsible for that (it's autoreleased before being returned) "*/ { SMySQLResult *theResult = [SMySQLResult alloc]; ! #warning We should get a proper encoding for the string (more likely iso latin-1) (done?) ! const char *theCQuery = [self cStringFromString:query]; ! int theQueryCode; ! NSLog (@"in queryString query is : %s -in ObjC : %@-\n", theCQuery, query); ! if ((theQueryCode = mysql_query(mConnection, theCQuery)) == NULL) { theResult = [theResult initWithMySQLPtr:mConnection encoding:mEncoding]; + NSLog (@"the SMySQLResult is %@\n", theResult); if (theResult) { [theResult autorelease]; *************** *** 358,361 **** --- 410,419 ---- return theResult; } + else { + NSLog (@"Problem in queryString error code is : %d, query is : %s -in ObjC : %@-\n", theQueryCode, theCQuery, query); + } + if (theResult) { + [theResult release]; + } return nil; } *************** *** 384,387 **** --- 442,534 ---- + - (SMySQLResult *)listDBs:(NSString *)dbsName + /*" + Return a list of database which name correspond to the string dbsName. The comparison is done with wild card extension : % and _. The result should correspond to the queryString:@"SHOW databases [LIKE wild]"; but implemented with mysql_list_dbs. + If an empty string of nil is passed as dbsName, all databases will be shown. + "*/ + { + SMySQLResult *theResult = [SMySQLResult alloc]; + MYSQL_RES *theResPtr; + + if ((dbsName == nil) || ([dbsName isEqualToString:@""])) { + if (theResPtr = mysql_list_dbs(mConnection, NULL)) { + [theResult initWithResPtr: theResPtr encoding: mEncoding]; + } + else { + [theResult init]; + } + } + else { + const char *theCDBsName = (const char *)[[dbsName dataUsingEncoding: mEncoding allowLossyConversion: YES] bytes]; + if (theResPtr = mysql_list_dbs(mConnection, theCDBsName)) { + [theResult initWithResPtr: theResPtr encoding: mEncoding]; + } + else { + [theResult init]; + } + } + if (theResult) { + [theResult autorelease]; + } + return theResult; + } + + + - (SMySQLResult *)listTables:(NSString *)tablesName + /*" + From within a database, give back the list of table which name correspond to tablesName (with wild card %, _ extension). Correspond to queryString:@"SHOW tables [LIKE wild]"; uses mysql_list_tables function. + If an empty string of nil is passed as tablesName, all tables will be shown. + "*/ + { + SMySQLResult *theResult = [SMySQLResult alloc]; + MYSQL_RES *theResPtr; + + if ((tablesName == nil) || ([tablesName isEqualToString:@""])) { + if (theResPtr = mysql_list_tables(mConnection, NULL)) { + [theResult initWithResPtr: theResPtr encoding: mEncoding]; + } + else { + [theResult init]; + } + } + else { + const char *theCTablesName = (const char *)[[tablesName dataUsingEncoding: mEncoding allowLossyConversion: YES] bytes]; + if (theResPtr = mysql_list_tables(mConnection, theCTablesName)) { + [theResult initWithResPtr: theResPtr encoding: mEncoding]; + } + else { + [theResult init]; + } + } + if (theResult) { + [theResult autorelease]; + } + return theResult; + } + + + - (SMySQLResult *)listFields:(NSString *)fieldsName forTable:(NSString *)tableName + /*" + Show all the fields of the table tableName which name correspond to fieldsName (with wild card expansion : %,_). Indeed, and as recommanded from mysql reference, this method is NOT using mysql_list_fields but the queryString:@"" method. + If an empty string of nil is passed as fieldsName, all fields (of tableName) will be returned. + "*/ + { + SMySQLResult *theResult; + + if ((fieldsName == nil) || ([fieldsName isEqualToString:@""])) { + NSString *theQuery = [NSString stringWithFormat:@"SHOW COLUMNS FROM %@", tableName]; + theResult = [self queryString:theQuery]; + } + else { + NSString *theQuery = [NSString stringWithFormat:@"SHOW COLUMNS FROM %@ LIKE '%@'", tableName, fieldsName]; + theResult = [self queryString:theQuery]; + } + if (theResult) { + [theResult autorelease]; + } + return theResult; + } + + - (NSString *)serverInfo /*" *************** *** 390,393 **** --- 537,541 ---- { if (mConnected) { + #warning Is the string is really encoded in UTF8 : NO, in iso latin1 return [NSString stringWithUTF8String: mysql_get_server_info(mConnection)]; } *************** *** 438,441 **** --- 586,603 ---- [super dealloc]; return; + } + + + - (const char *)cStringFromString:(NSString *)theString + /*" + For internal use only. Transform a NSString to a C type string (ended with \0) using ethe character set from the SMySQLConnection. + Lossy conversions are enabled. + "*/ + { + NSMutableData *theData = [NSMutableData dataWithCapacity:0]; + [theData appendData:[theString dataUsingEncoding: mEncoding allowLossyConversion: YES]]; + + [theData increaseLengthBy:1]; + return (const char *)[theData bytes]; } Index: SMySQLResult.h =================================================================== RCS file: /cvsroot/mysql-cocoa/SMySQL/SMySQLResult.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** SMySQLResult.h 15 Jan 2002 18:52:34 -0000 1.2 --- SMySQLResult.h 3 May 2002 09:36:39 -0000 1.3 *************** *** 39,43 **** Init used #{only} by #{SMySQLConnection} "*/ ! - (id)initWithMySQLPtr:(MYSQL*)mySQLPtr encoding:(NSStringEncoding)theEncoding; /*" --- 39,46 ---- Init used #{only} by #{SMySQLConnection} "*/ ! ! - (id)initWithMySQLPtr:(MYSQL *)mySQLPtr encoding:(NSStringEncoding)theEncoding; ! - (id)initWithResPtr:(MYSQL_RES *)mySQLResPtr encoding:(NSStringEncoding)theEncoding; ! - (id)init; /*" *************** *** 54,58 **** - (void)dataSeek:(my_ulonglong)row; - //- (SMySQLRow *)fetchRow; - (NSDictionary *)fetchRowAsDictionary; - (NSArray *)fetchRowAsArray; --- 57,60 ---- *************** *** 69,72 **** --- 71,79 ---- - (BOOL)isBlobAtIndex:(unsigned int)index; - (BOOL)isBlobForKey:(NSString *)key; + + /*" + Utility method + "*/ + - (NSString *)description; /*" Index: SMySQLResult.m =================================================================== RCS file: /cvsroot/mysql-cocoa/SMySQL/SMySQLResult.m,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** SMySQLResult.m 15 Jan 2002 18:52:34 -0000 1.2 --- SMySQLResult.m 3 May 2002 09:36:39 -0000 1.3 *************** *** 75,78 **** --- 75,103 ---- } mResult = mysql_store_result(mySQLPtr); + if (mMySQLLocales == NULL) { + mMySQLLocales = [[SMySQLConnection getMySQLLocales] retain]; + } + return self; + } + + + - (id)initWithResPtr:(MYSQL_RES *)mySQLResPtr encoding:(NSStringEncoding)theEncoding + /*" + This metod it is used internally by SMySQLConnection object when it have already a MYSQL_RES object to initialise SMySQLResult object. + Initialise a SMySQLResult with the MYSQL_RES pointer (returned by such a function as mysql_list_dbs). + NB: SMySQLResult should be made by using one of the method of SMySQLConnection. + "*/ + { + self = [super init]; + mEncoding = theEncoding; + if (mResult) { + mysql_free_result(mResult); + mResult = NULL; + } + if (mNames) { + [mNames release]; + mNames = NULL; + } + mResult = mySQLResPtr; if (mResult == NULL) { [self autorelease]; *************** *** 82,88 **** mMySQLLocales = [[SMySQLConnection getMySQLLocales] retain]; } ! return self; } - (my_ulonglong)numOfRows /*" --- 107,135 ---- mMySQLLocales = [[SMySQLConnection getMySQLLocales] retain]; } ! return self; } + - (id)init + /*" + Empty init, normaly of NO use to the user, again, SMySQLResult should be made through calls to SMySQLConnection + "*/ + { + self = [super init]; + mEncoding = [SMySQLConnection defaultMySQLEncoding]; + if (mResult) { + mysql_free_result(mResult); + mResult = NULL; + } + if (mNames) { + [mNames release]; + mNames = NULL; + } + if (mMySQLLocales == NULL) { + mMySQLLocales = [[SMySQLConnection getMySQLLocales] retain]; + } + return self; + } + + - (my_ulonglong)numOfRows /*" *************** *** 96,99 **** --- 143,147 ---- } + - (unsigned int)numOfFields /*" *************** *** 110,114 **** - (void)dataSeek:(my_ulonglong)row /*" ! Go to a precise row in the selected result. "*/ { --- 158,162 ---- - (void)dataSeek:(my_ulonglong)row /*" ! Go to a precise row in the selected result. 0 is the very first row "*/ { *************** *** 120,130 **** - /* - - (SMySQLRow *)fetchRow - { - } - */ - - - (NSDictionary *)fetchRowAsDictionary /*" --- 168,171 ---- *************** *** 183,186 **** --- 224,228 ---- // a switch on theLength[i] would do that... // Here it will crash if it's not default presentation : TIMESTAMP(14) + #warning What about the encoding? For all the rest of the method theCurrentObj = [NSCalendarDate dateWithString:[NSString stringWithUTF8String:theData] calendarFormat:@"%Y%m%d%H%M%S"]; break; *************** *** 286,289 **** --- 328,332 ---- // a switch on theLength[i] would do that... // Here it will crash if it's not default presentation : TIMESTAMP(14) + #warning What about the encoding? For all the rest of the method theCurrentObj = [NSCalendarDate dateWithString:[NSString stringWithUTF8String:theData] calendarFormat:@"%Y%m%d%H%M%S"]; break; *************** *** 361,364 **** --- 404,408 ---- theField = mysql_fetch_fields(mResult); for (i=0; i<theNumFields; i++) { + #warning What about the encoding? For all the rest of the method NSString *theName = [NSString stringWithUTF8String:theField[i].name]; [theNamesArray addObject:theName]; *************** *** 647,650 **** --- 691,733 ---- } + + - (NSString *)description + /*" + 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 a SMySQLResult (example). + "*/ + { + if (mResult == NULL) { + return @"This is an empty SMySQLResult\n"; + } + else { + NSMutableString *theString = [NSMutableString stringWithCapacity:0]; + int i, numFields; + NSArray *theRow; + MYSQL_ROW_OFFSET thePosition; + + // First line, saying we are displaying a SMySQLResult + [theString appendString:@"SMySQLResult:\n"]; + // Second line: the field names, tab separated + [self fetchFieldsName]; + for (i=0; i<((numFields = [mNames count])-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]) { + for (i=0; i<(numFields - 1); i++) { + [theString appendFormat:@"%@\t", [theRow objectAtIndex:i]]; + } + [theString appendFormat:@"%@\n", [theRow objectAtIndex:i]]; + } + // Returning to the proper row + mysql_row_seek(mResult,thePosition); + return theString; + } + } + + - (void)dealloc /* *************** *** 652,661 **** */ { ! if (mResult){ mysql_free_result(mResult); } ! if (mNames){ [mNames autorelease]; } [super dealloc]; return; --- 735,748 ---- */ { ! if (mResult) { mysql_free_result(mResult); } ! if (mNames) { [mNames autorelease]; } + if (mMySQLLocales) { + [mMySQLLocales autorelease]; + } + [super dealloc]; return; |