Deprecated: Assigning the return value of new by reference is deprecated in /home/bluestat/public_html/source/index.php on line 477
/*
* Tindex
* Copyright ©2002 - 2006, Blue Static
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if not,
* write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
* $Id: ServerManager.m 615 2007-02-19 22:14:41Z rsesek $
* $HeadURL: file:///Users/rsesek/SVN/macosx/Tindex/trunk/Server/ServerManager.m $
*/
#import "ServerManager.h"
#import
NSString *BlSPrefLastOpened = @"LastOpenedDB";
NSString *BlSPrefBackupLocation = @"BackupLocation";
@implementation ServerManager
/*!
* Destructor.
*/
- (void)dealloc
{
[databasePath release];
[dbConnector release];
[super dealloc];
}
/*!
* Awake from nib. Loads preference data and registers for notifications.
*/
- (void)awakeFromNib
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *lastOpenedDb;
NSString *backupDir;
// start the server
dbServer = [[DatabaseServer alloc] initWithManager: self];
[dbServer startSocket];
[dbServer startService];
[dbServer startDistributedObject];
// open db
lastOpenedDb = [prefs valueForKey: BlSPrefLastOpened];
if ([lastOpenedDb isNotEqualTo: @""] && lastOpenedDb != NULL)
{
[self openDatabase: lastOpenedDb];
}
// set backup location
backupDir = [prefs valueForKey: BlSPrefBackupLocation];
if ([backupDir isNotEqualTo: @""] && backupDir != NULL)
{
[self openBackup: backupDir];
}
// start the backup timer
[NSTimer scheduledTimerWithTimeInterval: (2 * 60 * 60) // bi-hourly
target: self
selector: @selector(executeBackup:)
userInfo: nil
repeats: YES];
// register for remote notifications
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(transactionOneWay:)
name: SQLNotificationOneWay
object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(transactionTwoWay:)
name: SQLNotificationTwoWay
object: nil];
}
/*!
* Returns the current DB-link
*
* @return SQLite The DB connector
*/
- (SQLite *)dbConnector
{
return dbConnector;
}
/*!
* Action to call up an NSOpenPanel to select the currently-served database
*
* @param id Sender
*/
- (IBAction)selectDatabase: (id)sender
{
[[NSOpenPanel openPanel] beginSheetForDirectory: nil
file: nil
types: [NSArray arrayWithObject: @"tin"]
modalForWindow: window
modalDelegate: self
didEndSelector: @selector(openPanelDidEnd: returnCode: contextInfo:)
contextInfo: @"database"];
}
/*!
* Method that receives messages when the two open panels (select database and backup) close.
* It uses contextInfo to determine the closing panel and then invokes the open* methods
* accordingly.
*
* @param NSOpenPanel The closing panel
* @param int Return code
* @param void* Contextual information
*/
- (void)openPanelDidEnd: (NSOpenPanel *)panel
returnCode: (int)returnCode
contextInfo: (void *)contextInfo
{
if (returnCode == NSOKButton)
{
if ([(NSString *)contextInfo isEqualTo: @"database"])
{
[self openDatabase: [panel filename]];
}
else if ([(NSString *)contextInfo isEqualTo: @"backup"])
{
[self openBackup: [panel filename]];
}
}
}
/*!
* Receiver that opens the database connection and allocates the SQLite class.
*
* @param NSString Database path
*/
- (void)openDatabase: (NSString *)filename
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
databasePath = filename;
[database setStringValue: databasePath];
dbConnector = [[SQLite alloc] init];
[dbConnector connect: databasePath];
[self addLog: [NSString stringWithFormat: @"Serving %@ database.", filename]];
[prefs setValue: filename
forKey: BlSPrefLastOpened];
}
/*!
* Action to select the backup location. Pops up an NSOpenPanel
*
* @param id Sender
*/
- (IBAction)selectBackupLocation: (id)sender;
{
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories: YES];
[panel setCanCreateDirectories: YES];
[panel beginSheetForDirectory: nil
file: nil
modalForWindow: window
modalDelegate: self
didEndSelector: @selector(openPanelDidEnd: returnCode: contextInfo:)
contextInfo: @"backup"];
}
/*!
* Method called by the openPanelDidEnd method to set the backup location in the plist
*
* @param NSString Backup folder location
*/
- (void)openBackup: (NSString *)filename
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
backupPath = filename;
[backupLocation setStringValue: filename];
[self addLog: [NSString stringWithFormat: @"Set backup directory to %@", filename]];
[prefs setValue: filename
forKey: BlSPrefBackupLocation];
}
/*!
* Adds a standard log message (black) to the text box.
*
* @param NSString Log message
*/
- (void)addLog: (NSString *)text
{
[log setEditable: YES];
[log insertText: [NSString stringWithFormat: @"%@\n", text]];
[log setEditable: NO];
}
/*!
* Adds an error (red) log message to the text box
*
* @param NSString Error message
*/
- (void)addError: (NSString *)text
{
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString: [NSString stringWithFormat: @"%@\n", text]];
[str addAttribute: NSForegroundColorAttributeName
value: [NSColor redColor]
range: NSMakeRange(0, [text length])];
[log setEditable: YES];
[log insertText: str];
[log setEditable: NO];
[str release];
}
/*!
* Method that is invoked when it is time to backup the database. This first makes sure the
* backup path is set (if not, it stops the backup), and then copies a new file over. Files
* are kept for 7 days in the format of [day of the week]-[hour].bak
*
* @param NSTimer The invoked timer
*/
- (void)executeBackup: (NSTimer *)timer
{
NSCalendarDate *date;
NSString *backupFile;
if ([backupPath isEqualTo: @""] || backupPath == NULL)
{
return;
}
date = [[NSDate date] dateWithCalendarFormat: @"%A-%H"
timeZone: nil];
backupFile = [NSString stringWithFormat: @"%@/%@.bak", backupPath, date];
[[NSFileManager defaultManager] copyPath: databasePath
toPath: backupFile
handler: NULL];
[[NSFileManager defaultManager] changeFileAttributes: [NSDictionary dictionaryWithObject: [NSDate date]
forKey: NSFileCreationDate]
atPath: backupFile];
[self addLog: @"Backup completed."];
}
#pragma mark -
#pragma mark Transaction receivers
/*!
* Transaction receiver for remote connections. This listens for notifications from queryWrite
* and executes them on the database.
*
* @param NSNotification Posted notification
*/
- (void)transactionOneWay: (NSNotification *)notification
{
if (![dbConnector queryWrite: [notification object]])
{
[self addError: [NSString stringWithFormat: @"Bad query <%@>. %@ (#%d)", [notification object], [dbConnector error], [dbConnector errorCode]]];
}
}
/*!
* Transaction receiver for remote two-way connections. QueryRead commands post notifications
* here and this executes the query, and posts a notification (through SQLiteRemoteTwoWayWrapper)
* back to the client for data processing.
*
* @param NSNotification Query notification
*/
- (void)transactionTwoWay: (NSNotification *)notification
{
SQLiteResult *res;
res = [dbConnector queryRead: [[notification object] query]];
if (res == nil)
{
[self addError: [NSString stringWithFormat: @"Bad query <%@>. %@ (#%d)", [[notification object] query], [dbConnector error], [dbConnector errorCode]]];
return;
}
[[NSNotificationCenter defaultCenter] postNotificationName: SQLNotificationTwoWayReturn
object: [[SQLiteRemoteTwoWayWraper alloc] initWithResult: res
transId: [[notification object] transactionId]]];
}
@end