Skip to content

Commit 148a5ec

Browse files
committed
Sequel Pro will now actually change the SQL_MODE of the connection during SQL export to match the generated file (#2955)
1 parent bc3b8ab commit 148a5ec

File tree

1 file changed

+53
-43
lines changed

1 file changed

+53
-43
lines changed

Source/SPSQLExporter.m

+53-43
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,15 @@ - (void)exportOperation
112112

113113
NSMutableDictionary *viewSyntaxes = [NSMutableDictionary dictionary];
114114

115+
NSString *oldSqlMode = nil;
116+
115117
// Check that we have all the required info before starting the export
116118
if ((![self sqlExportTables]) || ([[self sqlExportTables] count] == 0) ||
117119
(![self sqlDatabaseHost]) || ([[self sqlDatabaseHost] isEqualToString:@""]) ||
118120
(![self sqlDatabaseName]) || ([[self sqlDatabaseName] isEqualToString:@""]) ||
119121
(![self sqlDatabaseVersion] || ([[self sqlDatabaseName] isEqualToString:@""])))
120122
{
121-
[errors release];
122-
[sqlString release];
123-
return;
123+
goto end_cleanup;
124124
}
125125

126126
// Inform the delegate that the export process is about to begin
@@ -138,11 +138,7 @@ - (void)exportOperation
138138
for (NSArray *item in [self sqlExportTables])
139139
{
140140
// Check for cancellation flag
141-
if ([self isCancelled]) {
142-
[errors release];
143-
[sqlString release];
144-
return;
145-
}
141+
if ([self isCancelled]) goto end_cleanup;
146142

147143
switch ([NSArrayObjectAtIndex(item, 4) intValue]) {
148144
case SPTableTypeProc:
@@ -196,7 +192,7 @@ - (void)exportOperation
196192
}
197193

198194
[metaString appendString:@"/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n"];
199-
[metaString appendString:@"/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;\n"];
195+
200196
/* A note on SQL_MODE:
201197
*
202198
* BEFORE 3.23.6
@@ -228,6 +224,40 @@ - (void)exportOperation
228224
* (trivia: internally it has become MODE_NOT_USED: 16 = "?")
229225
*
230226
*/
227+
228+
BOOL sqlModeIsValid = NO;
229+
//fetch old sql mode to restore it later
230+
{
231+
SPMySQLResult *result = [connection queryString:@"SHOW VARIABLES LIKE 'sql_mode'"];
232+
if(![connection queryErrored]) {
233+
[result setReturnDataAsStrings:YES];
234+
NSArray *row = [result getRowAsArray];
235+
oldSqlMode = [[row objectAtIndex:1] unboxNull];
236+
}
237+
}
238+
//set sql mode for export
239+
if([@"" isEqualToString:oldSqlMode]) {
240+
// the current sql_mode is already the one we want (empty string), no need to change+revert it
241+
oldSqlMode = nil;
242+
sqlModeIsValid = YES;
243+
}
244+
else {
245+
[connection queryString:@"SET SQL_MODE=''"]; //mysqldump uses a conditional comment for 40100 here, but we want to see the error, since it can't simply be ignored (also ANSI mode is supported before 4.1)
246+
if (![connection queryErrored]) {
247+
sqlModeIsValid = YES;
248+
}
249+
else {
250+
[errors appendFormat:@"%@ (%@)\n", NSLocalizedString(@"The server's SQL_MODE could not be changed to one suitable for export. The export may be missing important details or may not be importable at all!", @"sql export : 'set @@sql_mode' query failed message"), [connection lastErrorMessage]];
251+
[self writeUTF8String:[NSString stringWithFormat:@"# SET SQL_MODE Error: %@\n\n\n", [connection lastErrorMessage]]];
252+
//if we couldn't change it, we don't need to restore it either
253+
oldSqlMode = nil;
254+
}
255+
}
256+
// there is no point in writing out that the file should use a specific SQL mode when we don't even know which one was active during export
257+
if(sqlModeIsValid) {
258+
[metaString appendString:@"/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;\n"];
259+
}
260+
231261
[metaString appendString:@"/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;\n\n\n"];
232262

233263
[self writeString:metaString];
@@ -236,11 +266,7 @@ - (void)exportOperation
236266
for (NSArray *table in tables)
237267
{
238268
// Check for cancellation flag
239-
if ([self isCancelled]) {
240-
[errors release];
241-
[sqlString release];
242-
return;
243-
}
269+
if ([self isCancelled]) goto end_cleanup;
244270

245271
[self setSqlCurrentTableExportIndex:[self sqlCurrentTableExportIndex]+1];
246272
tableName = NSArrayObjectAtIndex(table, 0);
@@ -415,12 +441,10 @@ - (void)exportOperation
415441
[streamingResult cancelResultLoad];
416442
[streamingResult release];
417443
[sqlExportPool release];
418-
[errors release];
419-
[sqlString release];
420444
free(useRawDataForColumnAtIndex);
421445
free(useRawHexDataForColumnAtIndex);
422446

423-
return;
447+
goto end_cleanup;
424448
}
425449

426450
// Update the progress
@@ -581,11 +605,7 @@ - (void)exportOperation
581605
for (s = 0; s < [queryResult numberOfRows]; s++)
582606
{
583607
// Check for cancellation flag
584-
if ([self isCancelled]) {
585-
[errors release];
586-
[sqlString release];
587-
return;
588-
}
608+
if ([self isCancelled]) goto end_cleanup;
589609

590610
NSDictionary *triggers = [[NSDictionary alloc] initWithDictionary:[queryResult getRowAsDictionary]];
591611

@@ -627,11 +647,7 @@ - (void)exportOperation
627647
for (tableName in viewSyntaxes)
628648
{
629649
// Check for cancellation flag
630-
if ([self isCancelled]) {
631-
[errors release];
632-
[sqlString release];
633-
return;
634-
}
650+
if ([self isCancelled]) goto end_cleanup;
635651

636652
[metaString setString:@"\n\n"];
637653

@@ -647,11 +663,7 @@ - (void)exportOperation
647663
for (NSString *procedureType in @[@"PROCEDURE", @"FUNCTION"])
648664
{
649665
// Check for cancellation flag
650-
if ([self isCancelled]) {
651-
[errors release];
652-
[sqlString release];
653-
return;
654-
}
666+
if ([self isCancelled]) goto end_cleanup;
655667

656668
// Retrieve the array of selected procedures or functions, and skip export if not selected
657669
NSMutableArray *items;
@@ -677,11 +689,7 @@ - (void)exportOperation
677689
for (s = 0; s < [queryResult numberOfRows]; s++)
678690
{
679691
// Check for cancellation flag
680-
if ([self isCancelled]) {
681-
[errors release];
682-
[sqlString release];
683-
return;
684-
}
692+
if ([self isCancelled]) goto end_cleanup;
685693

686694
NSDictionary *proceduresList = [[NSDictionary alloc] initWithDictionary:[queryResult getRowAsDictionary]];
687695
NSString *procedureName = [NSString stringWithFormat:@"%@", [proceduresList objectForKey:@"Name"]];
@@ -693,9 +701,7 @@ - (void)exportOperation
693701
// Check for cancellation flag
694702
if ([self isCancelled]) {
695703
[proceduresList release];
696-
[errors release];
697-
[sqlString release];
698-
return;
704+
goto end_cleanup;
699705
}
700706

701707
if ([NSArrayObjectAtIndex(item, 0) isEqualToString:procedureName]) {
@@ -811,9 +817,6 @@ - (void)exportOperation
811817
// Set export errors
812818
[self setSqlExportErrors:errors];
813819

814-
[errors release];
815-
[sqlString release];
816-
817820
// Close the file
818821
[[self exportOutputFile] close];
819822

@@ -822,6 +825,13 @@ - (void)exportOperation
822825

823826
// Inform the delegate that the export process is complete
824827
[delegate performSelectorOnMainThread:@selector(sqlExportProcessComplete:) withObject:self waitUntilDone:NO];
828+
829+
end_cleanup:
830+
if(oldSqlMode) {
831+
[connection queryString:[NSString stringWithFormat:@"SET SQL_MODE=%@",[oldSqlMode tickQuotedString]]];
832+
}
833+
[errors release];
834+
[sqlString release];
825835
}
826836

827837
/**

0 commit comments

Comments
 (0)