JABMoveDomainAction.m [plain text]
//
// JABMoveDomainAction.m
// ChatServer/jabber_autobuddy
//
// Created by Steve Peralta on 9/16/08.
// Copyright 2008 Apple. All rights reserved.
//
#import "JABMoveDomainAction.h"
#import "JABLogger.h"
#import "JABDatabase.h"
#import "JABDatabaseQuery.h"
#import <signal.h>
//------------------------------------------------------------------------------
// JABMoveDomainAction methods
//------------------------------------------------------------------------------
@implementation JABMoveDomainAction
@synthesize sourceDomain = _sourceDomain;
@synthesize destDomain = _destDomain;
@synthesize activeQuery = _activeQuery;
@synthesize ownerTables = _ownerTables;
@synthesize jidTables = _jidTables;
//------------------------------------------------------------------------------
- (id) initWithCommandOptions: (NSDictionary *) cmdOpts
{
self = [super initWithCommandOptions: cmdOpts];
self.sourceDomain = [cmdOpts objectForKey: CMDOPT_KEY_SRCDOMAIN];
self.destDomain = [cmdOpts objectForKey: CMDOPT_KEY_DSTDOMAIN];
self.activeQuery = [JABSelectAllActiveQuery jabSelectAllActiveQueryForAction: self];
// Define the tables for which "collection-owner" must be replaced
self.ownerTables = [NSArray arrayWithObjects:
@"logout", @"motd-times", @"privacy-items",
@"private", @"queue", @"roster-groups",
@"roster-items", @"vacation-settings",
@"active",
nil];
// Define the tables for which "jid" column must be replaced
self.jidTables = [NSArray arrayWithObjects:
@"roster-groups", @"roster-items",
nil];
return self;
}
- (void) dealloc
{
self.jidTables = nil;
self.ownerTables = nil;
self.activeQuery = nil;
self.destDomain = nil;
self.sourceDomain = nil;
[super dealloc];
}
//------------------------------------------------------------------------------
- (BOOL) requiresJid
{
return NO;
}
//------------------------------------------------------------------------------
- (void) doDBAction
{
// Move all JIDs belonging to sourceDomain into destDomain
#ifndef DEBUG
if ([self isJabberdRunning]) {
[_logger logStdErrMessage: @"\nThis operation is not available while the iChat Service is running.\n\n"];
return;
}
#endif
// get a count of all active users
NSInteger totalUsers = 0;
if (![_activeQuery startStatement])
return; // query initialization failed -- abort
NSString *ownerJid = nil;
while (nil != (ownerJid = [_activeQuery getNextActiveJid])) {
// Verify that the JID belongs to the target domain
NSArray *jidParts = [ownerJid componentsSeparatedByString: @"@"];
if (2 > [jidParts count]) continue; // malformed JID?
if (![_sourceDomain isEqualToString: [jidParts objectAtIndex: 1]])
continue; // ignore active users not in targeted domain
totalUsers++;
}
[_activeQuery finalizeStatement];
if (1 > totalUsers) {
[_logger logInfo: [NSString stringWithFormat:
@"No active users found for domain \" _sourceDomain]];
[_logger logInfo: @"*** The existing jabberd database has not been modified."];
return; // no action taken
}
// make a backup copy of the database before applying modifications
[_logger logInfo: @"Creating backup for jabberd database."];
if (![_database createBackup]) {
[_logger logInfo: @"Operation canceled: database backup could not be performed."];
return; // database backup failed -- abort
}
[_logger logInfo: [NSString stringWithFormat:
@"Moving totalUsers, _sourceDomain, _destDomain]];
// prepare a query for reading active JIDs
if (![_activeQuery startStatement])
return; // query initialization failed -- abort
NSInteger iUser = 0;
NSInteger movedUsers = 0;
BOOL bOK = YES;
while (nil != (ownerJid = [_activeQuery getNextActiveJid])) {
// Verify that the JID belongs to the target domain
NSArray *jidParts = [ownerJid componentsSeparatedByString: @"@"];
if (2 > [jidParts count]) continue; // malformed JID?
if (![_sourceDomain isEqualToString: [jidParts objectAtIndex: 1]])
continue; // ignore active users not in targeted domain
// Create the new JID from the existing user name and new domain
NSString *userName = [jidParts objectAtIndex: 0];
NSString *newJid = [userName stringByAppendingFormat: @"@
[_logger logStdErrMessage: [NSString stringWithFormat:
@"[ ++iUser, totalUsers, [userName UTF8String]]];
// Update all tables where "jid" matches the old JID
bOK = [self updateTables: _jidTables column: @"jid"
oldValue: ownerJid newValue: newJid];
if (!bOK) break; // error -- abort
// Update all tables where "collection-owner" matches the old JID
bOK = [self updateTables: _ownerTables column: @"collection-owner"
oldValue: ownerJid newValue: newJid];
if (!bOK) break; // error -- abort
[_logger logStdErrMessage: @" [done]\n"];
movedUsers++;
}
if (bOK) {
[_logger logInfo: [NSString stringWithFormat:
@" movedUsers, totalUsers]];
[_logger logInfo: [NSString stringWithFormat:
@"A copy of the original database was saved at [_database backupPath]]];
}
else {
[_logger logInfo: @"\nOperation failed due to errors."];
[_logger logInfo: @"*** The existing jabberd database has not been modified."];
}
[_activeQuery finalizeStatement];
}
//------------------------------------------------------------------------------
- (BOOL) updateTables: (NSArray *) tableList column: (NSString *) column
oldValue: (NSString *) oldVal newValue: (NSString *) newVal
{
// Replace the selected column values for all tables in the list
self.result = OPRESULT_OK;
for (NSString *tableName in tableList) {
[_database updateTable: tableName column: column
oldValue: oldVal newValue: newVal
source: __PRETTY_FUNCTION__ line: __LINE__];
if (SQLITE_OK != [_database dbResult]) {
self.result = OPRESULT_FAILED;
break;
}
// [_logger logStdErrMessage: @"."]; // indicate partial progress
} // for..in
return (OPRESULT_OK == _result);
}
@end