[baseten-users] Response to Christoph's request for changing the database at runtime
Kevin Palser
kpalser at sonrie.com
Sat Mar 20 16:27:13 EET 2010
Hi Christoph,
>I am about to write a program that shall manage persons, but since my Father
>(who is to use the program) is a company physician for several companies the
>program needs to connect to different databases at Runtime. Like "OK, I finished
>the work for this company, now I want to edit the data for another company". The
>databases may be local or on some remote machine.
I'm going to assume that you have finished the tutorial and you don't know how to
programatically specify a database. I e-mailed you a project of a BaseTen
version of the Aaron Hillegass example for the Department / Employee CoreData
project. In this project I added a preference pane to specify the database
connection. With some simple modifications the project can be changed so that you
can open and close new connections. Consider the following:
You could have a Cocoa Application project (not document based). The application
delegate could then have something like the following:
///// In App Delegate.h
#import <Cocoa/Cocoa.h>
@class BXDatabaseContext;
@interface AppDelegate : NSObject
// use a precompiler directive to distinguish between
// SDK prior to Mac OS 10.6
#if __MAC_OS_X_VERSION_MIN_REQUIRED > 1050
<NSApplicationDelegate>
#endif
{
NSWindow *window;
// Outlet connected to the context in the MainMenu.xib
IBOutlet BXDatabaseContext *databaseContext;
}
///// In App Delegate.m
#import "App Delegate.h"
#import <BaseTen/BaseTen.h>
// methods to handle the notifications when asynchronously connecting to the database
- (void)handleSuccesfulConnection:(NSNotification *)note {
// you're connected!
// update the user interface etc...
}
- (void)handleFailedConnection:(NSNotification *)note {
// show a dialog displaying a connection problem and ask for the new connection
// values before calling [self connect]; again.
}
// generate the URI: pgsql://username:password@hostname/database_name/
- (NSString*)databaseURI {
NSUserDefaults *defaults;
// get the connection values from the applications user defaults.
// Storing usernames and passwords in a real application is
// not clever for the security conscious.
defaults = [NSUserDefaults standardUserDefaults];
return [NSString stringWithFormat:@"pgsql://%@:%@@%@/%@/",
[defaults stringForKey:PREFuserNameKey],
[defaults stringForKey:PREFpasswordKey],
[defaults stringForKey:PREFhostNameKey],
[defaults stringForKey:PREFdatabaseNameKey]];
}
- (void)connect {
@try
{
// try to set the URI
NSURL *nsurl = [NSURL URLWithString: [self databaseURI]];
[databaseContext setDatabaseURI:nsurl];
// connect asynchronously - this class will respond to the
// resulting notifications:
kBXConnectionSuccessfulNotification or kBXConnectionFailedNotification
[databaseContext connectAsync];
}
@catch (NSException *theErr)
{
// an exception has occurred so display the preference panel to
// give the user opportunity to review the connection values
[self showPreferences:self];
}
@finally
{
//...
// the housekeeping domain
//...
}
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Register the notification observers
[[databaseContext notificationCenter] addObserver: self
selector: @selector (handleFailedConnection:)
name: kBXConnectionFailedNotification object: nil];
[[databaseContext notificationCenter] addObserver: self
selector: @selector (handleSuccesfulConnection:)
name: kBXConnectionSuccessfulNotification object: nil];
[self connect];
}
Of course call a method to disconnect:
- (void)disconnect {
[databaseContext disconnect];
}
In Interface Builder don't have "Connects on awakeFromNib" ticked for the
BXDatabaseContext. Bear in mind that you could also programatically create an
instance of BXDatabaseContext without having it in the Nib/Xib.
Christoph if I've confused you more than I've helped you then please buy a copy
of the Aaron Hillegass book and work through the two core data examples.
>Just a warning: My Cocoa skills aren't that good so please be lenient with me...I
>find the ArrayController/CoreData/Binding etc. stuff a bit confusing...
Even the most seasoned programmers can find CoreData and binding have a very steep
learning curve because the official Apple documentation needs to be drastically
clarified with more examples.
Speaking of examples, if the BaseTen team is reading this I'd love to collaborate
by creating a tutorial for Department / Employee example in the Aaron Hillegass
Book. I wanted to add my work in progress example to wiki but I'm not sure what
to specify for the secret key in the registration process.
>I hope my English is comprehendible, I am a bit rusty in writing in english
>(although I read quite a lot in english in the last months) and since it is not my
>native language I am always a bit worried if I write comprehendible.
Relax, your English is great - it barely shows that your a non-native speaker.
Regards,
Kevin Palser
More information about the baseten-users
mailing list