@@ -58,6 +58,7 @@ - (id)init
58
58
{
59
59
if ((self = [super init ])) {
60
60
characterSetEncoding = nil ;
61
+ defaultCollationForCharacterSet = nil ;
61
62
defaultCollation = nil ;
62
63
defaultCharacterSetEncoding = nil ;
63
64
serverDefaultCollation = nil ;
@@ -83,6 +84,7 @@ - (id)init
83
84
- (void )resetAllData
84
85
{
85
86
if (characterSetEncoding != nil ) SPClear (characterSetEncoding);
87
+ if (defaultCollationForCharacterSet != nil ) SPClear (defaultCollationForCharacterSet);
86
88
if (defaultCollation != nil ) SPClear (defaultCollation);
87
89
if (defaultCharacterSetEncoding != nil ) SPClear (defaultCharacterSetEncoding);
88
90
if (serverDefaultCharacterSetEncoding) SPClear (serverDefaultCharacterSetEncoding);
@@ -117,9 +119,14 @@ - (NSArray *)getDatabaseCollations
117
119
// If that failed, get the list of collations from the hard-coded list
118
120
if (![collations count ]) {
119
121
const SPDatabaseCharSets *c = SPGetDatabaseCharacterSets ();
120
-
122
+ # warning This probably won't work as intended. See my comment in getDatabaseCollationsForEncoding:
121
123
do {
122
- [collations addObject: [NSString stringWithCString: c->collation encoding: NSUTF8StringEncoding]];
124
+ [collations addObject: @{
125
+ @" ID" : @(c->nr ),
126
+ @" CHARACTER_SET_NAME" : [NSString stringWithCString: c->name encoding: NSUTF8StringEncoding],
127
+ @" COLLATION_NAME" : [NSString stringWithCString: c->collation encoding: NSUTF8StringEncoding],
128
+ // description is not present in information_schema.collations
129
+ }];
123
130
124
131
++c;
125
132
}
@@ -139,12 +146,16 @@ - (NSArray *)getDatabaseCollationsForEncoding:(NSString *)encoding
139
146
if (encoding && ((characterSetEncoding == nil ) || (![characterSetEncoding isEqualToString: encoding]) || ([characterSetCollations count ] == 0 ))) {
140
147
141
148
[characterSetEncoding release ];
149
+ SPClear (defaultCollationForCharacterSet); // depends on encoding
142
150
[characterSetCollations removeAllObjects ];
143
151
144
152
characterSetEncoding = [[NSString alloc ] initWithString: encoding];
145
153
146
- if ([cachedCollationsByEncoding objectForKey: characterSetEncoding] && [[cachedCollationsByEncoding objectForKey: characterSetEncoding] count ])
147
- return [cachedCollationsByEncoding objectForKey: characterSetEncoding];
154
+ NSArray *cachedCollations = [cachedCollationsByEncoding objectForKey: characterSetEncoding];
155
+ if ([cachedCollations count ]) {
156
+ [characterSetCollations addObjectsFromArray: cachedCollations];
157
+ goto copy_return;
158
+ }
148
159
149
160
// Try to retrieve the available collations for the supplied encoding from the database
150
161
if ([serverSupport supportsInformationSchema ]) {
@@ -162,7 +173,9 @@ - (NSArray *)getDatabaseCollationsForEncoding:(NSString *)encoding
162
173
// If that failed, get the list of collations matching the supplied encoding from the hard-coded list
163
174
if (![characterSetCollations count ]) {
164
175
const SPDatabaseCharSets *c = SPGetDatabaseCharacterSets ();
165
-
176
+ #warning I don't think this will work. The hardcoded list is supposed to be used with pre 4.1 mysql servers, \
177
+ which don' t have information_schema or SHOW COLLATION. But before 4.1 there were no real collations and \
178
+ even the charsets had different names (e.g. charset "latin1_de" which now is "latin1" + "latin1_german2_ci")
166
179
do {
167
180
NSString *charSet = [NSString stringWithCString:c->name encoding:NSUTF8StringEncoding];
168
181
@@ -175,13 +188,38 @@ - (NSArray *)getDatabaseCollationsForEncoding:(NSString *)encoding
175
188
while (c[0].nr != 0);
176
189
}
177
190
178
- if (characterSetCollations && [characterSetCollations count ]) {
191
+ if ([characterSetCollations count]) {
179
192
[cachedCollationsByEncoding setObject:[NSArray arrayWithArray:characterSetCollations] forKey:characterSetEncoding];
180
193
}
181
194
182
195
}
183
-
184
- return characterSetCollations;
196
+ copy_return:
197
+ return [NSArray arrayWithArray:characterSetCollations]; //copy because it is a mutable array and we keep changing it
198
+ }
199
+
200
+ /** Get the collation that is marked as default for a given encoding by the server
201
+ * @param encoding The encoding, e.g. @"latin1"
202
+ * @return The default collation (e.g. @"latin1_swedish_ci") or
203
+ * nil if either encoding was nil or the server does not provide the neccesary details
204
+ */
205
+ - (NSString *)getDefaultCollationForEncoding:(NSString *)encoding
206
+ {
207
+ if(!encoding) return nil;
208
+ // if (
209
+ // - we have not yet fetched info about the default collation OR
210
+ // - encoding is different than the one we currently know about
211
+ // ) => we need to load it from server, otherwise just return cached value
212
+ if ((defaultCollationForCharacterSet == nil) || (![characterSetEncoding isEqualToString:encoding])) {
213
+ NSArray *cols = [self getDatabaseCollationsForEncoding:encoding]; //will clear stored encoding and collation if neccesary
214
+ for (NSDictionary *collation in cols) {
215
+ #warning This won' t work for the hardcoded list (see above)
216
+ if ([[[collation objectForKey: @" IS_DEFAULT" ] lowercaseString ] isEqualToString: @" yes" ]) {
217
+ defaultCollationForCharacterSet = [[NSString alloc ] initWithString: [collation objectForKey: @" COLLATION_NAME" ]];
218
+ break ;
219
+ }
220
+ }
221
+ }
222
+ return defaultCollationForCharacterSet;
185
223
}
186
224
187
225
/* *
@@ -296,7 +334,7 @@ - (NSArray *)getDatabaseCharacterSetEncodings
296
334
// If that failed, get the list of character set encodings from the hard-coded list
297
335
if (![characterSetEncodings count ]) {
298
336
const SPDatabaseCharSets *c = SPGetDatabaseCharacterSets ();
299
-
337
+ # warning This probably won't work as intended. See my comment in getDatabaseCollationsForEncoding:
300
338
do {
301
339
[characterSetEncodings addObject: [NSDictionary dictionaryWithObjectsAndKeys:
302
340
[NSString stringWithCString: c->name encoding: NSUTF8StringEncoding], @" CHARACTER_SET_NAME" ,
0 commit comments