aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPTableData.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/SPTableData.m')
-rw-r--r--Source/SPTableData.m76
1 files changed, 43 insertions, 33 deletions
diff --git a/Source/SPTableData.m b/Source/SPTableData.m
index d3af3580..17316fbf 100644
--- a/Source/SPTableData.m
+++ b/Source/SPTableData.m
@@ -42,6 +42,7 @@
@interface SPTableData (PrivateAPI)
- (void)_loopWhileWorking;
+- (NSDictionary *)parseCreateStatement:(NSString *)tableDef ofType:(NSString *)tableType;
@end
@@ -437,21 +438,12 @@
}
/**
- * Retrieve the CREATE TABLE string for a table and analyse it to extract the field
- * details, primary key, unique keys, and table encoding.
- * In future this could also be used to retrieve the majority of index information
- * assuming information like cardinality isn't needed.
- * This function is rather long due to the painful parsing required, but is fast.
- * Returns a boolean indicating success.
+ * Retrieve the CREATE statement for a table/view and return extracted table
+ * structure information.
+ * @attention This method will interact with the UI on errors/connection loss!
*/
- (NSDictionary *) informationForTable:(NSString *)tableName
{
- SPSQLParser *createTableParser, *fieldsParser, *fieldParser;
- NSMutableArray *tableColumns, *fieldStrings;
- NSMutableDictionary *tableColumn, *tableData;
- NSString *encodingString = nil;
- NSUInteger i, stringStart;
- unichar quoteCharacter;
BOOL changeEncoding = ![[mySQLConnection encoding] isEqualToString:@"utf8"];
// Catch unselected tables and return nil
@@ -527,27 +519,46 @@
}
tableCreateSyntax = [[NSString alloc] initWithString:[syntaxResult objectAtIndex:1]];
- createTableParser = [[SPSQLParser alloc] initWithString:[syntaxResult objectAtIndex:1]];
+
+ NSDictionary *tableData = [self parseCreateStatement:tableCreateSyntax ofType:[resultFieldNames objectAtIndex:0]];
+
+ if (changeEncoding) [mySQLConnection restoreStoredEncoding];
+
+ return tableData;
+}
+
+/**
+ * Analyse a CREATE TABLE tring to extract the field details, primary key, unique keys, and table encoding.
+ * @param tableDef @"CREATE TABLE ..."
+ * @param tableType Can either be Table or View. Value is copied to the result and not used otherwise
+ * @return A dict containing info about the table's structure
+ *
+ * In future this could also be used to retrieve the majority of index information
+ * assuming information like cardinality isn't needed.
+ * This function is rather long due to the painful parsing required, but is fast.
+ */
+- (NSDictionary *)parseCreateStatement:(NSString *)tableDef ofType:(NSString *)tableType
+{
+ SPSQLParser *createTableParser = [[SPSQLParser alloc] initWithString:tableDef];
// Extract the fields definition string from the CREATE TABLE syntax
- fieldsParser = [[SPSQLParser alloc] initWithString:[createTableParser trimAndReturnStringFromCharacter:'(' toCharacter:')' trimmingInclusively:YES returningInclusively:NO skippingBrackets:YES]];
+ SPSQLParser *fieldsParser = [[SPSQLParser alloc] initWithString:[createTableParser trimAndReturnStringFromCharacter:'(' toCharacter:')' trimmingInclusively:YES returningInclusively:NO skippingBrackets:YES]];
// Split the fields and keys string into an array of individual elements
- fieldStrings = [[NSMutableArray alloc] initWithArray:[fieldsParser splitStringByCharacter:',' skippingBrackets:YES]];
+ NSMutableArray *fieldStrings = [[NSMutableArray alloc] initWithArray:[fieldsParser splitStringByCharacter:',' skippingBrackets:YES]];
// fieldStrings should now hold unparsed field and key strings, while tableProperty string holds unparsed
// table information. Proceed further by parsing the field strings.
- tableColumns = [[NSMutableArray alloc] init];
- tableColumn = [[NSMutableDictionary alloc] init];
- fieldParser = [[SPSQLParser alloc] init];
+ NSMutableArray *tableColumns = [[NSMutableArray alloc] init];
+ NSMutableDictionary *tableColumn = [[NSMutableDictionary alloc] init];
NSCharacterSet *whitespaceAndNewlineSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSCharacterSet *quoteSet = [NSCharacterSet characterSetWithCharactersInString:@"`'\""];
NSCharacterSet *bracketSet = [NSCharacterSet characterSetWithCharactersInString:@"()"];
- tableData = [NSMutableDictionary dictionary];
+ NSMutableDictionary *tableData = [NSMutableDictionary dictionary];
- for (i = 0; i < [fieldStrings count]; i++) {
+ for (NSUInteger i = 0; i < [fieldStrings count]; i++) {
// Take this field/key string, trim whitespace from both ends and remove comments
[fieldsParser setString:[NSArrayObjectAtIndex(fieldStrings, i) stringByTrimmingCharactersInSet:whitespaceAndNewlineSet]];
@@ -559,7 +570,7 @@
// If the first character is a quote character, this is a field definition.
if ([quoteSet characterIsMember:[fieldsParser characterAtIndex:0]]) {
- quoteCharacter = [fieldsParser characterAtIndex:0];
+ unichar quoteCharacter = [fieldsParser characterAtIndex:0];
// Capture the area between the two backticks as the name
// Set the parser to ignoreCommentStrings since a field name can contain # or /*
@@ -734,11 +745,11 @@
[primaryKeyFields addObject:primaryFieldName];
for (NSMutableDictionary *theTableColumn in tableColumns) {
if ([[theTableColumn objectForKey:@"name"] isEqualToString:primaryFieldName]) {
- [theTableColumn setObject:@1 forKey:@"isprimarykey"];
- break;
+ [theTableColumn setObject:@1 forKey:@"isprimarykey"];
+ break;
+ }
}
- }
- }
+ }
[tableData setObject:primaryKeyFields forKey:@"primarykeyfield"];
}
}
@@ -752,9 +763,9 @@
NSString *uniqueFieldName = [[SPSQLParser stringWithString:quotedUniqueKey] unquotedString];
for (NSMutableDictionary *theTableColumn in tableColumns) {
if ([[theTableColumn objectForKey:@"name"] isEqualToString:uniqueFieldName]) {
- [theTableColumn setObject:@1 forKey:@"unique"];
- break;
- }
+ [theTableColumn setObject:@1 forKey:@"unique"];
+ break;
+ }
}
}
}
@@ -769,12 +780,14 @@
[tableColumn release];
// Extract the encoding from the table properties string - other details come from TABLE STATUS.
+ NSString *encodingString = nil;
NSRange charsetDefinitionRange = [createTableParser rangeOfString:@"CHARSET=" options:NSCaseInsensitiveSearch];
if (charsetDefinitionRange.location == NSNotFound) {
charsetDefinitionRange = [createTableParser rangeOfString:@"CHARACTER SET=" options:NSCaseInsensitiveSearch];
}
if (charsetDefinitionRange.location != NSNotFound) {
- stringStart = NSMaxRange(charsetDefinitionRange);
+ NSUInteger stringStart = NSMaxRange(charsetDefinitionRange);
+ NSUInteger i;
for (i = stringStart; i < [createTableParser length]; i++) {
if ([createTableParser characterAtIndex:i] == ' ') break;
}
@@ -795,10 +808,9 @@
}
[createTableParser release];
- [fieldParser release];
// this will be 'Table' or 'View'
- [tableData setObject:[resultFieldNames objectAtIndex:0] forKey:@"type"];
+ [tableData setObject:tableType forKey:@"type"];
[tableData setObject:[NSString stringWithString:encodingString] forKey:@"encoding"];
[tableData setObject:[NSArray arrayWithArray:tableColumns] forKey:@"columns"];
[tableData setObject:[NSArray arrayWithArray:constraints] forKey:@"constraints"];
@@ -806,8 +818,6 @@
[encodingString release];
[tableColumns release];
- if (changeEncoding) [mySQLConnection restoreStoredEncoding];
-
return tableData;
}