aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/SPTextView.h16
-rw-r--r--Source/SPTextView.m172
-rw-r--r--Source/SPUserManager.h3
-rw-r--r--Source/SPUserManager.m87
4 files changed, 169 insertions, 109 deletions
diff --git a/Source/SPTextView.h b/Source/SPTextView.h
index 07e42e43..4289bd40 100644
--- a/Source/SPTextView.h
+++ b/Source/SPTextView.h
@@ -38,6 +38,18 @@
@class SPCopyTable;
@class NoodleLineNumberView;
+typedef struct {
+ NSInteger location; // snippet location
+ NSInteger length; // snippet length
+ NSInteger task; // snippet task : -1 not valid, 0 select snippet
+} SnippetControlInfo;
+
+typedef struct {
+ NSInteger snippet; // mirrored snippet index
+ NSInteger location; // mirrored snippet location
+ NSInteger length; // mirrored snippet length
+} MirrorControlInfo;
+
@interface SPTextView : NSTextView <NSTextStorageDelegate>
{
IBOutlet SPDatabaseDocument *tableDocumentInstance;
@@ -71,8 +83,8 @@
SPMySQLConnection *mySQLConnection;
NSInteger mySQLmajorVersion;
- NSInteger snippetControlArray[20][3];
- NSInteger snippetMirroredControlArray[20][3];
+ SnippetControlInfo snippetControlArray[20];
+ MirrorControlInfo snippetMirroredControlArray[20];
NSInteger snippetControlCounter;
NSInteger snippetControlMax;
NSInteger currentSnippetIndex;
diff --git a/Source/SPTextView.m b/Source/SPTextView.m
index 970869c1..3c6d7b53 100644
--- a/Source/SPTextView.m
+++ b/Source/SPTextView.m
@@ -1552,18 +1552,20 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
NSInteger i, j, k, deltaLength;
NSRange mirroredRange;
+ SnippetControlInfo *currentSnippetRef = &snippetControlArray[currentSnippetIndex];
// Go through each defined mirrored snippet and update it
for(i=0; i<=mirroredCounter; i++) {
- if(snippetMirroredControlArray[i][0] == currentSnippetIndex) {
+ MirrorControlInfo *mirrorRef = &snippetMirroredControlArray[i];
+ if(mirrorRef->snippet == currentSnippetIndex) {
- deltaLength = snippetControlArray[currentSnippetIndex][1]-snippetMirroredControlArray[i][2];
+ deltaLength = currentSnippetRef->length - mirrorRef->length;
- mirroredRange = NSMakeRange(snippetMirroredControlArray[i][1], snippetMirroredControlArray[i][2]);
+ mirroredRange = NSMakeRange(mirrorRef->location, mirrorRef->length);
NSString *mirroredString = nil;
// For safety reasons
@try{
- mirroredString = [[self string] substringWithRange:NSMakeRange(snippetControlArray[currentSnippetIndex][0], snippetControlArray[currentSnippetIndex][1])];
+ mirroredString = [[self string] substringWithRange:NSMakeRange(currentSnippetRef->location, currentSnippetRef->length)];
}
@catch(id ae) {
NSLog(@"Error while parsing for mirrored snippets. %@", [ae description]);
@@ -1576,26 +1578,26 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
[self shouldChangeTextInRange:mirroredRange replacementString:mirroredString];
[self replaceCharactersInRange:mirroredRange withString:mirroredString];
- snippetMirroredControlArray[i][2] = snippetControlArray[currentSnippetIndex][1];
+ mirrorRef->length = currentSnippetRef->length;
// If a completion list is open adjust the theCharRange and theParseRange if a mirrored snippet
// was updated which is located before the initial position
- if(completionIsOpen && snippetMirroredControlArray[i][1] < (NSInteger)completionParseRangeLocation)
+ if(completionIsOpen && mirrorRef->location < (NSInteger)completionParseRangeLocation)
[completionPopup adjustWorkingRangeByDelta:deltaLength];
// Adjust all other snippets accordingly
for(j=0; j<=snippetControlMax; j++) {
- if(snippetControlArray[j][0] > -1) {
- if(snippetControlArray[j][0]+snippetControlArray[j][1]>=snippetMirroredControlArray[i][1]) {
- snippetControlArray[j][0] += deltaLength;
+ if(snippetControlArray[j].location > -1) {
+ if(snippetControlArray[j].location+snippetControlArray[j].length >= mirrorRef->location) {
+ snippetControlArray[j].location += deltaLength;
}
}
}
// Adjust all mirrored snippets accordingly
for(k=0; k<=mirroredCounter; k++) {
if(i != k) {
- if(snippetMirroredControlArray[k][1] > snippetMirroredControlArray[i][1]) {
- snippetMirroredControlArray[k][1] += deltaLength;
+ if(snippetMirroredControlArray[k].location > mirrorRef->location) {
+ snippetMirroredControlArray[k].location += deltaLength;
}
}
}
@@ -1625,15 +1627,16 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
// Place the caret at the end of the query favorite snippet
// and finish snippet editing
if(currentSnippetIndex == snippetControlMax) {
- [self setSelectedRange:NSMakeRange(snippetControlArray[snippetControlMax][0] + snippetControlArray[snippetControlMax][1], 0)];
+ [self setSelectedRange:NSMakeRange(snippetControlArray[snippetControlMax].location + snippetControlArray[snippetControlMax].length, 0)];
[self endSnippetSession];
return;
}
- if(currentSnippetIndex >= 0 && currentSnippetIndex < 20) {
- if(snippetControlArray[currentSnippetIndex][2] == 0) {
+ if(currentSnippetIndex >= 0 && currentSnippetIndex < COUNT_OF(snippetControlArray)) {
+ SnippetControlInfo *currentSnippetRef = &snippetControlArray[currentSnippetIndex];
+ if(currentSnippetRef->task == 0) {
- NSRange r1 = NSMakeRange(snippetControlArray[currentSnippetIndex][0], snippetControlArray[currentSnippetIndex][1]);
+ NSRange r1 = NSMakeRange(currentSnippetRef->location, currentSnippetRef->length);
NSRange r2;
// Ensure the selection for nested snippets if it is at very end of the text buffer
@@ -1718,13 +1721,9 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
mirroredCounter = -1;
// reset snippet array
- for(i=0; i<20; i++) {
- snippetControlArray[i][0] = -1; // snippet location
- snippetControlArray[i][1] = -1; // snippet length
- snippetControlArray[i][2] = -1; // snippet task : -1 not valid, 0 select snippet
- snippetMirroredControlArray[i][0] = -1; // mirrored snippet index
- snippetMirroredControlArray[i][1] = -1; // mirrored snippet location
- snippetMirroredControlArray[i][2] = -1; // mirrored snippet length
+ for(i=0; i<COUNT_OF(snippetControlArray); i++) {
+ snippetControlArray[i] = (SnippetControlInfo){ -1, -1, -1};
+ snippetMirroredControlArray[i] = (MirrorControlInfo){-1, -1, -1};
}
if(theSnippet == nil || ![theSnippet length]) return;
@@ -1861,24 +1860,25 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
[snip flushCachedRegexData];
// Store found snippet range
- snippetControlArray[snipCnt][0] = snipRange.location + targetRange.location;
- snippetControlArray[snipCnt][1] = [theHintString length];
- snippetControlArray[snipCnt][2] = 0;
+ snippetControlArray[snipCnt].location = snipRange.location + targetRange.location;
+ snippetControlArray[snipCnt].length = [theHintString length];
+ snippetControlArray[snipCnt].task = 0;
[theHintString release];
// Adjust successive snippets
- for(i=0; i<20; i++)
- if(snippetControlArray[i][0] > -1 && i != snipCnt && snippetControlArray[i][0] > snippetControlArray[snipCnt][0])
- snippetControlArray[i][0] -= 3+((snipCnt>9)?2:1);
+ for(i=0; i<COUNT_OF(snippetControlArray); i++)
+ if(snippetControlArray[i].location > -1 && i != snipCnt && snippetControlArray[i].location > snippetControlArray[snipCnt].location)
+ snippetControlArray[i].location -= 3+((snipCnt>9)?2:1);
}
// Parse for mirrored snippets
while([snip isMatchedByRegex:mirror_re]) {
mirroredCounter++;
- if(mirroredCounter > 19) {
- NSLog(@"Only 20 mirrored snippet placeholders allowed.");
+ if(mirroredCounter >= COUNT_OF(snippetMirroredControlArray)) {
+ NSLog(@"Only %lu mirrored snippet placeholders allowed.",COUNT_OF(snippetMirroredControlArray));
+ mirroredCounter--; //go back by one or the code below will do an out-of-bounds array access
NSBeep();
break;
} else {
@@ -1897,14 +1897,14 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
[snip flushCachedRegexData];
// Store found mirrored snippet range
- snippetMirroredControlArray[mirroredCounter][0] = snipCnt;
- snippetMirroredControlArray[mirroredCounter][1] = snipRange.location + targetRange.location;
- snippetMirroredControlArray[mirroredCounter][2] = 0;
+ snippetMirroredControlArray[mirroredCounter].snippet = snipCnt;
+ snippetMirroredControlArray[mirroredCounter].location = snipRange.location + targetRange.location;
+ snippetMirroredControlArray[mirroredCounter].length = 0;
// Adjust successive snippets
- for(i=0; i<20; i++)
- if(snippetControlArray[i][0] > -1 && snippetControlArray[i][0] > snippetMirroredControlArray[mirroredCounter][1])
- snippetControlArray[i][0] -= 1+((snipCnt>9)?2:1);
+ for(i=0; i<COUNT_OF(snippetControlArray); i++)
+ if(snippetControlArray[i].location > -1 && snippetControlArray[i].location > snippetMirroredControlArray[mirroredCounter].location)
+ snippetControlArray[i].location -= 1+((snipCnt>9)?2:1);
[snip flushCachedRegexData];
}
@@ -1912,28 +1912,29 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
// Preset mirrored snippets with according snippet content
if(mirroredCounter > -1) {
for(i=0; i<=mirroredCounter; i++) {
- if(snippetControlArray[snippetMirroredControlArray[i][0]][0] > -1 && snippetControlArray[snippetMirroredControlArray[i][0]][1] > 0) {
- [snip replaceCharactersInRange:NSMakeRange(snippetMirroredControlArray[i][1]-targetRange.location, snippetMirroredControlArray[i][2])
- withString:[snip substringWithRange:NSMakeRange(snippetControlArray[snippetMirroredControlArray[i][0]][0]-targetRange.location, snippetControlArray[snippetMirroredControlArray[i][0]][1])]];
- snippetMirroredControlArray[i][2] = snippetControlArray[snippetMirroredControlArray[i][0]][1];
+ MirrorControlInfo *mirrorRef = &snippetMirroredControlArray[i];
+ SnippetControlInfo *snippetRef = &snippetControlArray[mirrorRef->snippet];
+ if(snippetRef->location > -1 && snippetRef->length > 0) {
+ NSRange copyToRange = NSMakeRange(mirrorRef->location-targetRange.location, mirrorRef->length);
+ NSRange copyFromRange = NSMakeRange(snippetRef->location-targetRange.location, snippetRef->length);
+ [snip replaceCharactersInRange:copyToRange withString:[snip substringWithRange:copyFromRange]];
+ mirrorRef->length = snippetRef->length;
}
// Adjust successive snippets
- for(j=0; j<20; j++)
- if(snippetControlArray[j][0] > -1 && snippetControlArray[j][0] > snippetMirroredControlArray[i][1])
- snippetControlArray[j][0] += snippetControlArray[snippetMirroredControlArray[i][0]][1];
+ for(j=0; j<COUNT_OF(snippetControlArray); j++)
+ if(snippetControlArray[j].location > -1 && snippetControlArray[j].location > mirrorRef->location)
+ snippetControlArray[j].location += snippetRef->length;
// Adjust successive mirrored snippets
for(j=0; j<=mirroredCounter; j++)
- if(snippetMirroredControlArray[j][1] > snippetMirroredControlArray[i][1])
- snippetMirroredControlArray[j][1] += snippetControlArray[snippetMirroredControlArray[i][0]][1];
+ if(snippetMirroredControlArray[j].location > mirrorRef->location)
+ snippetMirroredControlArray[j].location += snippetRef->length;
}
}
if(snippetControlCounter > -1) {
// Store the end for tab out
snippetControlMax++;
- snippetControlArray[snippetControlMax][0] = targetRange.location + [snip length];
- snippetControlArray[snippetControlMax][1] = 0;
- snippetControlArray[snippetControlMax][2] = 0;
+ snippetControlArray[snippetControlMax] = (SnippetControlInfo){targetRange.location + [snip length], 0, 0};
}
// unescape escaped snippets and re-adjust successive snippet locations : \${1:a} → ${1:a}
@@ -1945,13 +1946,13 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
NSInteger loc = escapeRange.location + targetRange.location;
[snip flushCachedRegexData];
for(i=0; i<=snippetControlMax; i++)
- if(snippetControlArray[i][0] > -1 && snippetControlArray[i][0] > loc)
- snippetControlArray[i][0]--;
+ if(snippetControlArray[i].location > -1 && snippetControlArray[i].location > loc)
+ snippetControlArray[i].location--;
// Adjust mirrored snippets
if(mirroredCounter > -1)
for(i=0; i<=mirroredCounter; i++)
- if(snippetMirroredControlArray[i][0] > -1 && snippetMirroredControlArray[i][1] > loc)
- snippetMirroredControlArray[i][1]--;
+ if(snippetMirroredControlArray[i].snippet > -1 && snippetMirroredControlArray[i].location > loc)
+ snippetMirroredControlArray[i].location--;
}
}
@@ -1980,8 +1981,8 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
if(snippetControlCounter > -1) {
// Find and select first defined snippet
currentSnippetIndex = 0;
- // Look for next defined snippet since snippet numbers must not serial like 1, 5, and 12 e.g.
- while(snippetControlArray[currentSnippetIndex][0] == -1 && currentSnippetIndex < 20)
+ // Look for next defined snippet since snippet numbers might not be serial like 1, 5, and 12 e.g.
+ while(snippetControlArray[currentSnippetIndex].location == -1 && currentSnippetIndex < COUNT_OF(snippetControlArray))
currentSnippetIndex++;
[self selectCurrentSnippet];
}
@@ -2026,9 +2027,9 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
for(i=0; i<=snippetControlMax; i++) {
j++;
foundSnippetIndices[j] = 0;
- if(snippetControlArray[i][0] != -1
- && caretPos >= snippetControlArray[i][0]
- && caretPos <= snippetControlArray[i][0] + snippetControlArray[i][1]) {
+ if(snippetControlArray[i].location != -1
+ && caretPos >= snippetControlArray[i].location
+ && caretPos <= snippetControlArray[i].location + snippetControlArray[i].length) {
foundSnippetIndices[j] = 1;
if(i == currentSnippetIndex)
@@ -2049,11 +2050,11 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
if(foundSnippetIndices[i] == 1) {
if(curIndex == -1) {
curIndex = i;
- smallestLength = snippetControlArray[i][1];
+ smallestLength = snippetControlArray[i].length;
} else {
- if(smallestLength > snippetControlArray[i][1]) {
+ if(smallestLength > snippetControlArray[i].length) {
curIndex = i;
- smallestLength = snippetControlArray[i][1];
+ smallestLength = snippetControlArray[i].length;
}
}
}
@@ -2192,13 +2193,13 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
currentSnippetIndex--;
- // Look for previous defined snippet since snippet numbers must not serial like 1, 5, and 12 e.g.
- while(snippetControlArray[currentSnippetIndex][0] == -1 && currentSnippetIndex > -2)
+ // Look for previous defined snippet since snippet numbers might not be serial like 1, 5, and 12 e.g.
+ while(snippetControlArray[currentSnippetIndex].location == -1 && currentSnippetIndex > -2)
currentSnippetIndex--;
if(currentSnippetIndex < 0) {
currentSnippetIndex = 0;
- while(snippetControlArray[currentSnippetIndex][0] == -1 && currentSnippetIndex < 20)
+ while(snippetControlArray[currentSnippetIndex].location == -1 && currentSnippetIndex < COUNT_OF(snippetControlArray))
currentSnippetIndex++;
NSBeep();
}
@@ -2210,8 +2211,8 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
currentSnippetIndex++;
- // Look for next defined snippet since snippet numbers must not serial like 1, 5, and 12 e.g.
- while(snippetControlArray[currentSnippetIndex][0] == -1 && currentSnippetIndex < 20)
+ // Look for next defined snippet since snippet numbers might not be serial like 1, 5, and 12 e.g.
+ while(snippetControlArray[currentSnippetIndex].location == -1 && currentSnippetIndex < COUNT_OF(snippetControlArray))
currentSnippetIndex++;
if(currentSnippetIndex > snippetControlMax) { // for safety reasons
@@ -2978,7 +2979,7 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
// Is the caret still inside a snippet
if([self checkForCaretInsideSnippet]) {
for(NSInteger i=0; i<snippetControlMax; i++) {
- if(snippetControlArray[i][0] > -1) {
+ if(snippetControlArray[i].location > -1) {
// choose the colors for the snippet parts
if(i == currentSnippetIndex) {
[[NSColor colorWithCalibratedRed:1.0f green:0.6f blue:0.0f alpha:0.4f] setFill];
@@ -2987,7 +2988,7 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
[[NSColor colorWithCalibratedRed:1.0f green:0.8f blue:0.2f alpha:0.2f] setFill];
[[NSColor colorWithCalibratedRed:1.0f green:0.8f blue:0.2f alpha:0.5f] setStroke];
}
- NSBezierPath *snippetPath = [self roundedBezierPathAroundRange: NSMakeRange(snippetControlArray[i][0],snippetControlArray[i][1]) ];
+ NSBezierPath *snippetPath = [self roundedBezierPathAroundRange: NSMakeRange(snippetControlArray[i].location,snippetControlArray[i].length) ];
[snippetPath fill];
[snippetPath stroke];
}
@@ -3334,20 +3335,19 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
// Re-calculate snippet ranges if snippet session is active
if(snippetControlCounter > -1 && !snippetWasJustInserted && !isProcessingMirroredSnippets) {
// Remove any fully nested snippets relative to the current snippet which was edited
- NSInteger currentSnippetLocation = snippetControlArray[currentSnippetIndex][0];
- NSInteger currentSnippetMaxRange = snippetControlArray[currentSnippetIndex][0] + snippetControlArray[currentSnippetIndex][1];
+ SnippetControlInfo *currentSnippetRef = &snippetControlArray[currentSnippetIndex];
+ NSInteger currentSnippetLocation = currentSnippetRef->location;
+ NSInteger currentSnippetMaxRange = currentSnippetRef->location + currentSnippetRef->length;
NSInteger i;
for(i=0; i<snippetControlMax; i++) {
- if(snippetControlArray[i][0] > -1
+ if(snippetControlArray[i].location > -1
&& i != currentSnippetIndex
- && snippetControlArray[i][0] >= currentSnippetLocation
- && snippetControlArray[i][0] <= currentSnippetMaxRange
- && snippetControlArray[i][0] + snippetControlArray[i][1] >= currentSnippetLocation
- && snippetControlArray[i][0] + snippetControlArray[i][1] <= currentSnippetMaxRange
+ && snippetControlArray[i].location >= currentSnippetLocation
+ && snippetControlArray[i].location <= currentSnippetMaxRange
+ && snippetControlArray[i].location + snippetControlArray[i].length >= currentSnippetLocation
+ && snippetControlArray[i].location + snippetControlArray[i].length <= currentSnippetMaxRange
) {
- snippetControlArray[i][0] = -1;
- snippetControlArray[i][1] = -1;
- snippetControlArray[i][2] = -1;
+ snippetControlArray[i] = (SnippetControlInfo){-1, -1, -1};
}
}
@@ -3355,26 +3355,26 @@ static inline NSPoint SPPointOnLine(NSPoint a, NSPoint b, CGFloat t) { return NS
NSUInteger changeInLength = [textStore changeInLength];
// Adjust length change to current snippet
- snippetControlArray[currentSnippetIndex][1] += changeInLength;
+ currentSnippetRef->length += changeInLength;
// If length < 0 break snippet input
- if(snippetControlArray[currentSnippetIndex][1] < 0) {
+ if(currentSnippetRef->length < 0) {
[self endSnippetSession];
} else {
// Adjust start position of snippets after caret position
for(i=0; i<=snippetControlMax; i++) {
- if(snippetControlArray[i][0] > -1 && i != currentSnippetIndex) {
- if(editStartPosition < snippetControlArray[i][0]) {
- snippetControlArray[i][0] += changeInLength;
- } else if(editStartPosition >= snippetControlArray[i][0] && editStartPosition <= snippetControlArray[i][0] + snippetControlArray[i][1]) {
- snippetControlArray[i][1] += changeInLength;
+ if(snippetControlArray[i].location > -1 && i != currentSnippetIndex) {
+ if(editStartPosition < snippetControlArray[i].location) {
+ snippetControlArray[i].location += changeInLength;
+ } else if(editStartPosition >= snippetControlArray[i].location && editStartPosition <= snippetControlArray[i].location + snippetControlArray[i].length) {
+ snippetControlArray[i].length += changeInLength;
}
}
}
// Adjust start position of mirrored snippets after caret position
if(mirroredCounter > -1)
for(i=0; i<=mirroredCounter; i++) {
- if(editStartPosition < snippetMirroredControlArray[i][1]) {
- snippetMirroredControlArray[i][1] += changeInLength;
+ if(editStartPosition < snippetMirroredControlArray[i].location) {
+ snippetMirroredControlArray[i].location += changeInLength;
}
}
}
diff --git a/Source/SPUserManager.h b/Source/SPUserManager.h
index 3bee8636..6338145f 100644
--- a/Source/SPUserManager.h
+++ b/Source/SPUserManager.h
@@ -80,6 +80,9 @@
BOOL isSaving;
BOOL isInitializing;
NSMutableString *errorsString;
+
+ // MySQL 5.7.6 removes the "Password" columns and only uses the "plugin"+"authentication_string" columns
+ BOOL requiresPost576PasswordHandling;
}
@property (nonatomic, retain) SPMySQLConnection *connection;
diff --git a/Source/SPUserManager.m b/Source/SPUserManager.m
index 6f42ac75..a5a83cbe 100644
--- a/Source/SPUserManager.m
+++ b/Source/SPUserManager.m
@@ -159,6 +159,9 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn";
// Select users from the mysql.user table
SPMySQLResult *result = [connection queryString:@"SELECT * FROM mysql.user ORDER BY user"];
[result setReturnDataAsStrings:YES];
+ //TODO: improve user feedback
+ NSAssert(([[result fieldNames] firstObjectCommonWithArray:@[@"Password",@"authentication_string"]] != nil), @"Resultset from mysql.user contains neither 'Password' nor 'authentication_string' column!?");
+ requiresPost576PasswordHandling = ![[result fieldNames] containsObject:@"Password"];
[usersResultArray addObjectsFromArray:[result getAllRows]];
[self _initializeTree:usersResultArray];
@@ -244,9 +247,9 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn";
// for each user currently in the database.
for (NSUInteger i = 0; i < [items count]; i++)
{
- NSString *username = [[items objectAtIndex:i] objectForKey:@"User"];
- NSArray *parentResults = [[self _fetchUserWithUserName:username] retain];
NSDictionary *item = [items objectAtIndex:i];
+ NSString *username = [item objectForKey:@"User"];
+ NSArray *parentResults = [[self _fetchUserWithUserName:username] retain];
SPUserMO *parent;
SPUserMO *child;
@@ -266,8 +269,16 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn";
// original values for comparison purposes
[parent setPrimitiveValue:username forKey:@"user"];
[parent setPrimitiveValue:username forKey:@"originaluser"];
- [parent setPrimitiveValue:[item objectForKey:@"Password"] forKey:@"password"];
- [parent setPrimitiveValue:[item objectForKey:@"Password"] forKey:@"originalpassword"];
+ if(requiresPost576PasswordHandling) {
+ [parent setPrimitiveValue:[item objectForKey:@"plugin"] forKey:@"plugin"];
+ NSString *pwHash = [item objectForKey:@"authentication_string"];
+ [parent setPrimitiveValue:pwHash forKey:@"authentication_string"];
+ if([pwHash length]) [parent setPrimitiveValue:@"sequelpro_dummy_password" forKey:@"password"]; // for the UI dialog
+ }
+ else {
+ [parent setPrimitiveValue:[item objectForKey:@"Password"] forKey:@"password"];
+ [parent setPrimitiveValue:[item objectForKey:@"Password"] forKey:@"originalpassword"];
+ }
}
// Setup the NSManagedObject with values from the dictionary
@@ -360,7 +371,7 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn";
NSNumber *value = [NSNumber numberWithInteger:[[item objectForKey:key] integerValue]];
[child setValue:value forKey:key];
}
- else if (![key isEqualToString:@"User"] && ![key isEqualToString:@"Password"])
+ else if (![key isInArray:@[@"User",@"Password",@"plugin",@"authentication_string"]])
{
NSString *value = [item objectForKey:key];
[child setValue:value forKey:key];
@@ -807,7 +818,7 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn";
{
if (![user parent]) {
[user setPrimitiveValue:[user valueForKey:@"user"] forKey:@"originaluser"];
- [user setPrimitiveValue:[user valueForKey:@"password"] forKey:@"originalpassword"];
+ if(!requiresPost576PasswordHandling) [user setPrimitiveValue:[user valueForKey:@"password"] forKey:@"originalpassword"];
}
}
}
@@ -961,20 +972,43 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn";
}
// If the password has been changed, use the same password on all hosts
- if (![[user valueForKey:@"password"] isEqualToString:[user valueForKey:@"originalpassword"]]) {
-
- for (SPUserMO *child in hosts)
- {
- NSString *changePasswordStatement = [NSString stringWithFormat:
- @"SET PASSWORD FOR %@@%@ = PASSWORD(%@)",
- [[user valueForKey:@"user"] tickQuotedString],
- [[child host] tickQuotedString],
- ([user valueForKey:@"password"]) ? [[user valueForKey:@"password"] tickQuotedString] : @"''"];
-
- [connection queryString:changePasswordStatement];
+ if(requiresPost576PasswordHandling) {
+ // the UI password field is bound to the password field, so this is still where the new plaintext value comes from
+ NSString *newPass = [[user changedValues] objectForKey:@"password"];
+ if(newPass) {
+ // 5.7.6+ can update all users at once
+ NSMutableString *alterStmt = [NSMutableString stringWithString:@"ALTER USER "];
+ BOOL first = YES;
+ for (SPUserMO *child in hosts)
+ {
+ if(!first) [alterStmt appendString:@", "];
+ [alterStmt appendFormat:@"%@@%@ IDENTIFIED WITH %@ BY %@", //note: "BY" -> plaintext, "AS" -> hash
+ [[user valueForKey:@"user"] tickQuotedString],
+ [[child host] tickQuotedString],
+ [[user valueForKey:@"plugin"] tickQuotedString],
+ (![newPass isNSNull] && [newPass length]) ? [newPass tickQuotedString] : @"''"];
+ first = NO;
+ }
+ [connection queryString:alterStmt];
if(![self _checkAndDisplayMySqlError]) return NO;
}
}
+ else {
+ if (![[user valueForKey:@"password"] isEqualToString:[user valueForKey:@"originalpassword"]]) {
+
+ for (SPUserMO *child in hosts)
+ {
+ NSString *changePasswordStatement = [NSString stringWithFormat:
+ @"SET PASSWORD FOR %@@%@ = PASSWORD(%@)",
+ [[user valueForKey:@"user"] tickQuotedString],
+ [[child host] tickQuotedString],
+ ([user valueForKey:@"password"]) ? [[user valueForKey:@"password"] tickQuotedString] : @"''"];
+
+ [connection queryString:changePasswordStatement];
+ if(![self _checkAndDisplayMySqlError]) return NO;
+ }
+ }
+ }
}
else {
// If the hostname has changed, remane the detail before editing details
@@ -1038,14 +1072,25 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn";
// same affect as CREATE USER. That is, a new user with no privleges.
NSString *host = [[user valueForKey:@"host"] tickQuotedString];
- if ([user parent] && [[user parent] valueForKey:@"user"] && [[user parent] valueForKey:@"password"]) {
+ if ([user parent] && [[user parent] valueForKey:@"user"] && ([[user parent] valueForKey:@"password"] || [[user parent] valueForKey:@"authentication_string"])) {
NSString *username = [[[user parent] valueForKey:@"user"] tickQuotedString];
- NSString *password = [[[user parent] valueForKey:@"password"] tickQuotedString];
+
+ NSString *idString;
+ if(requiresPost576PasswordHandling) {
+ //copy the hash from the parent. if the parent password changes at the same time, updateUser: will take care of it afterwards
+ NSString *plugin = [[[user parent] valueForKey:@"plugin"] tickQuotedString];
+ NSString *hash = [[[user parent] valueForKey:@"authentication_string"] tickQuotedString];
+ idString = [NSString stringWithFormat:@"IDENTIFIED WITH %@ AS %@",plugin,hash];
+ }
+ else {
+ NSString *password = [[[user parent] valueForKey:@"password"] tickQuotedString];
+ idString = [NSString stringWithFormat:@"IDENTIFIED BY %@%@",[[user parent] valueForKey:@"originaluser"]?@"PASSWORD ":@"", password];
+ }
createStatement = ([serverSupport supportsCreateUser]) ?
- [NSString stringWithFormat:@"CREATE USER %@@%@ IDENTIFIED BY %@%@", username, host, [[user parent] valueForKey:@"originaluser"]?@"PASSWORD ":@"", password] :
- [NSString stringWithFormat:@"GRANT SELECT ON mysql.* TO %@@%@ IDENTIFIED BY %@%@", username, host, [[user parent] valueForKey:@"originaluser"]?@"PASSWORD ":@"", password];
+ [NSString stringWithFormat:@"CREATE USER %@@%@ %@", username, host, idString] :
+ [NSString stringWithFormat:@"GRANT SELECT ON mysql.* TO %@@%@ %@", username, host, idString];
}
else if ([user parent] && [[user parent] valueForKey:@"user"]) {