aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m35
-rw-r--r--Source/SPCustomQuery.m4
-rw-r--r--Source/SPSQLExporter.m11
-rw-r--r--Source/SPTableContent.m33
4 files changed, 61 insertions, 22 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
index 3b39738b..be09ed44 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
@@ -45,8 +45,12 @@
@interface MCPStreamingResult (PrivateAPI)
+
+const char *_int2bin(unsigned int n, unsigned long len, char *buf);
+
- (void) _downloadAllData;
- (void) _freeAllDataWhenDone;
+
@end
@implementation MCPStreamingResult : MCPResult
@@ -159,7 +163,7 @@
- (NSArray *)fetchNextRowAsArray
{
MYSQL_ROW theRow;
- char *theRowData;
+ char *theRowData, *buf;
unsigned long *fieldLengths;
NSInteger i, copiedDataLength;
NSMutableArray *returnArray;
@@ -242,7 +246,12 @@
copiedDataLength += fieldLengths[i] + 1;
}
}
-
+
+ // If the field is of type BIT, then allocate the binary buffer
+ if (fieldDefinitions[i].type == FIELD_TYPE_BIT) {
+ buf = malloc(fieldDefinitions[i].length + 1);
+ }
+
// If the data hasn't already been detected as NULL - in which case it will have been
// set to NSNull - process the data by type
if (cellData == nil) {
@@ -283,7 +292,12 @@
break;
case FIELD_TYPE_BIT:
- cellData = (theData != NULL) ? [NSString stringWithFormat:@"%u", theData[0]] : @"";
+ // Get a binary representation of the data
+ _int2bin(theData[1], fieldDefinitions[i].length, buf);
+
+ cellData = (theData != NULL) ? [NSString stringWithUTF8String:buf] : @"";
+
+ free(buf);
break;
case FIELD_TYPE_TINY_BLOB:
@@ -414,6 +428,21 @@
@implementation MCPStreamingResult (PrivateAPI)
/**
+ * Provides a binary representation of the supplied integer (n) in the supplied buffer (buf). The resulting
+ * binary representation will be zero-padded according to the supplied field length (len).
+ */
+const char *_int2bin(unsigned int n, unsigned long len, char *buf)
+{
+ for (int i = (len - 1); i >= 0; --i)
+ {
+ buf[i] = (n & 1) ? '1' : '0';
+ n >>= 1;
+ }
+
+ buf[len] = '\0';
+}
+
+/**
* Used internally to download results in a background thread
*/
- (void)_downloadAllData
diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m
index ebc4f726..02cd25ff 100644
--- a/Source/SPCustomQuery.m
+++ b/Source/SPCustomQuery.m
@@ -1671,7 +1671,7 @@
} else if([anObject isEqualToString:[prefs stringForKey:SPNullValue]]) {
newObject = @"NULL";
} else if ([[columnDefinition objectForKey:@"typegrouping"] isEqualToString:@"bit"]) {
- newObject = ((![[anObject description] length] || [[anObject description] isEqualToString:@"0"])?@"0":@"1");
+ newObject = [NSString stringWithFormat:@"b'%@'", ((![[anObject description] length] || [[anObject description] isEqualToString:@"0"]) ? @"0" : [anObject description])];
} else if ([[columnDefinition objectForKey:@"typegrouping"] isEqualToString:@"date"]
&& [[anObject description] isEqualToString:@"NOW()"]) {
newObject = @"NOW()";
@@ -1681,7 +1681,7 @@
}
[mySQLConnection queryString:
- [NSString stringWithFormat:@"UPDATE %@.%@ SET %@.%@.%@=%@ %@ LIMIT 1",
+ [NSString stringWithFormat:@"UPDATE %@.%@ SET %@.%@.%@ = %@ %@ LIMIT 1",
[[columnDefinition objectForKey:@"db"] backtickQuotedString], [tableForColumn backtickQuotedString],
[[columnDefinition objectForKey:@"db"] backtickQuotedString], [tableForColumn backtickQuotedString], [columnName backtickQuotedString], newObject, fieldIDQueryString]];
diff --git a/Source/SPSQLExporter.m b/Source/SPSQLExporter.m
index ad16a119..683e3a48 100644
--- a/Source/SPSQLExporter.m
+++ b/Source/SPSQLExporter.m
@@ -365,11 +365,17 @@
}
id object = NSArrayObjectAtIndex(row, t);
-
+
// Add NULL values directly to the output row
if ([object isMemberOfClass:[NSNull class]]) {
[sqlString appendString:@"NULL"];
}
+ // If the field is off type BIT, the values need a binary prefix of b'x'.
+ else if ([[NSArrayObjectAtIndex([tableDetails objectForKey:@"columns"], t) objectForKey:@"type"] isEqualToString:@"BIT"]) {
+ [sqlString appendString:@"b'"];
+ [sqlString appendString:[object description]];
+ [sqlString appendString:@"'"];
+ }
// Add data types directly as hex data
else if ([object isKindOfClass:[NSData class]]) {
@@ -400,8 +406,7 @@
if ([cellValue length] == 0) {
[sqlString appendString:@"''"];
}
- else {
- // If this is a numeric column type, add the number directly.
+ else {
if ([NSArrayObjectAtIndex(tableColumnNumericStatus, t) boolValue]) {
[sqlString appendString:cellValue];
}
diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m
index 4af8685e..15f4df31 100644
--- a/Source/SPTableContent.m
+++ b/Source/SPTableContent.m
@@ -2150,7 +2150,7 @@
if ([[rowObject description] isEqualToString:@"CURRENT_TIMESTAMP"]) {
[rowValue setString:@"CURRENT_TIMESTAMP"];
} else if ([[NSArrayObjectAtIndex(dataColumns, i) objectForKey:@"typegrouping"] isEqualToString:@"bit"]) {
- [rowValue setString:((![[rowObject description] length] || [[rowObject description] isEqualToString:@"0"])?@"0":@"1")];
+ [rowValue setString:[NSString stringWithFormat:@"b'%@'", ((![[rowObject description] length] || [[rowObject description] isEqualToString:@"0"]) ? @"0" : [rowObject description])]];
} else if ([[NSArrayObjectAtIndex(dataColumns, i) objectForKey:@"typegrouping"] isEqualToString:@"date"]
&& [[rowObject description] isEqualToString:@"NOW()"]) {
[rowValue setString:@"NOW()"];
@@ -2161,12 +2161,11 @@
}
[fieldValues addObject:[NSString stringWithString:rowValue]];
}
-
+
// Use INSERT syntax when creating new rows - no need to do not loaded checking, as all values have been entered
if ( isEditingNewRow ) {
queryString = [NSString stringWithFormat:@"INSERT INTO %@ (%@) VALUES (%@)",
- [selectedTable backtickQuotedString], [[tableDataInstance columnNames] componentsJoinedAndBacktickQuoted], [fieldValues componentsJoinedByString:@","]];
-
+ [selectedTable backtickQuotedString], [[tableDataInstance columnNames] componentsJoinedAndBacktickQuoted], [fieldValues componentsJoinedByString:@","]];
// Use UPDATE syntax otherwise
} else {
BOOL firstCellOutput = NO;
@@ -2179,7 +2178,7 @@
if (firstCellOutput) [queryString appendString:@", "];
else firstCellOutput = YES;
- [queryString appendString:[NSString stringWithFormat:@"%@=%@",
+ [queryString appendString:[NSString stringWithFormat:@"%@ = %@",
[[NSArrayObjectAtIndex(dataColumns, i) objectForKey:@"name"] backtickQuotedString], [fieldValues objectAtIndex:i]]];
}
[queryString appendString:[NSString stringWithFormat:@" WHERE %@", [self argumentForRow:-2]]];
@@ -2332,7 +2331,6 @@
id tempValue;
NSMutableString *value = [NSMutableString string];
NSMutableString *argument = [NSMutableString string];
- // NSString *columnType;
NSArray *columnNames;
NSInteger i;
@@ -2384,18 +2382,25 @@
tempValue = [tableValues cellDataAtRow:row column:[[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"datacolumnindex"] integerValue]];
// Otherwise use the oldRow
- } else {
+ }
+ else {
tempValue = [oldRow objectAtIndex:[[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"datacolumnindex"] integerValue]];
}
- if ( [tempValue isNSNull] ) {
+ if ([tempValue isNSNull]) {
[argument appendString:[NSString stringWithFormat:@"%@ IS NULL", [NSArrayObjectAtIndex(keys, i) backtickQuotedString]]];
- } else if ( [tempValue isSPNotLoaded] ) {
+ }
+ else if ([tempValue isSPNotLoaded]) {
NSLog(@"Exceptional case: SPNotLoaded object found for method “argumentForRow:”!");
return @"";
- } else {
-
- if ( [tempValue isKindOfClass:[NSData class]] )
+ }
+ else {
+ // If the field is of type BIT then it needs a binary prefix
+ if ([[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"type"] isEqualToString:@"BIT"]) {
+ [value setString:[NSString stringWithFormat:@"b'%@'", [mySQLConnection prepareString:tempValue]]];
+ }
+ // BLOB/TEXT data
+ else if ([tempValue isKindOfClass:[NSData class]])
[value setString:[NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:tempValue]]];
else
[value setString:[NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:tempValue]]];
@@ -2435,7 +2440,7 @@
{
NSInteger i;
NSMutableArray *fields = [NSMutableArray array];
-
+
if (([prefs boolForKey:SPLoadBlobsAsNeeded]) && ([dataColumns count] > 0)) {
NSArray *columnNames = [tableDataInstance columnNames];
@@ -2443,7 +2448,7 @@
for (i = 0 ; i < [columnNames count]; i++)
{
if (![tableDataInstance columnIsBlobOrText:[NSArrayObjectAtIndex(dataColumns, i) objectForKey:@"name"]] ) {
- [fields addObject:[NSArrayObjectAtIndex(columnNames, i) backtickQuotedString]];
+ [fields addObject:[NSArrayObjectAtIndex(columnNames, i) backtickQuotedString]];
}
else {
// For blob/text fields, select a null placeholder so the column count is still correct