Logo Search packages:      
Sourcecode: adun.app version File versions  Download package

ULDatabaseInterface.m

/*
   Project: UL

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   Created: 2005-07-12 15:24:33 +0200 by michael johnston

   This application 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 application 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
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/

#include "ULFramework/ULDatabaseInterface.h"

static id databaseInterface;

@implementation ULDatabaseInterface

+ (id) databaseInterface
{
      //check if we have already created the databaseInterface

      if(databaseInterface != nil)
            return databaseInterface;
      else
      {
            databaseInterface = [self new];
            return databaseInterface;
      }
}

- (BOOL) _isAvailableSQLDatabaseBackend
{
      NSBundle *sqlBackendBundle;
      
      //check if the AdunSQLDatabase bundle is available

      sqlBackendBundle = [NSBundle bundleWithPath: 
                        [NSHomeDirectory() stringByAppendingPathComponent:
                        @"GNUstep/Library/Bundles/ULSQLDatabaseBackend.bundle"]];
      if(sqlBackendBundle == nil)
            return NO;
      else
            return YES;

}

- (void) _loadSQLDatabaseBackend
{
      NSBundle *sqlBackendBundle;

      sqlBackendBundle = [NSBundle bundleWithPath: 
                        [NSHomeDirectory() stringByAppendingPathComponent:
                        @"GNUstep/Library/Bundles/ULSQLDatabaseBackend.bundle"]];


      if(ULSQLDatabaseBackend = [sqlBackendBundle principalClass])
            NSDebugLLog(@"ULDatabaseInterface", @"Found SQL backend bundle.\n");
      else
            [NSException raise: NSInternalInconsistencyException 
                  format: @"Specified plugin has no principal class"];
}

- (void) _initSQLBackends
{
      //Removed for 0.6
}

- (id) init
{
      id name;

      if(databaseInterface != nil)
            return databaseInterface;

      if(self = [super init])
      {
            //loadup the necessary backends - use sqlclient to create 
            //a connection to available database and then use that
            //connection to initialise the backend

            backends = [NSMutableDictionary new];
            fileSystemBackend = [ULFileSystemDatabaseBackend new];
            [backends setObject: fileSystemBackend forKey: [fileSystemBackend clientName]];
            availableClients = [NSMutableArray new];
            [availableClients addObject: [fileSystemBackend clientName]];
            databaseInterface = self;

            //Disabling backend bundle loading for UL0.52
      /*    if([self _isAvailableSQLDatabaseBackend])
            {
                  NSLog(@"SQLDatabase Bundle Available");
                  [self _loadSQLDatabaseBackend];
                  [self _initSQLBackends];
            }
            else
            {
                  NSWarnLog(@"AdunSQLDatabase bundle not available.");
                  NSWarnLog(@"SQL backend support disabled");
            
            }*/
                  
            //register for the various notification from the backends

            [[NSNotificationCenter defaultCenter] addObserver: self
                  selector: @selector(_handleBackendNotification:)
                  name: @"ULDatabaseBackendDidAddObjectNotification"
                  object: nil];
            [[NSNotificationCenter defaultCenter] addObserver: self
                  selector: @selector(_handleBackendNotification:)
                  name: @"ULDatabaseBackendAdditionFailedNotification"
                  object: nil];
            [[NSNotificationCenter defaultCenter] addObserver: self
                  selector: @selector(_handleBackendNotification:)
                  name: @"ULDatabaseBackendConnectionDidDieNotification"
                  object: nil];
      }

      return self;
}

- (void) dealloc
{
      databaseInterface = nil;
      [fileSystemBackend release];
      [backends release];
      [availableClients release];
      [super dealloc];
}

//FIXME: Implement all notification handling.
//Also have to add notifications for failure to update metadata or output references
//due to a connection failing (Clients must be able to handle the above situations aswell).
- (void) _handleBackendNotification: (NSNotification*) aNotification
{
      if([[aNotification name] isEqual: @"ULDatabaseBackendDidAddObjectNotification"])
      {
            [[NSNotificationCenter defaultCenter]
                        postNotificationName: @"ULDatabaseInterfaceDidAddObjectNotification"
                        object: self];
      }
      else if([[aNotification name] isEqual: @"ULDatabaseBackendAdditionFailedNotification"])
      {
            NSWarnLog(@"Recieved %@ notification - Handling not implemented",
                  [aNotification name]);  
      }
      else if([[aNotification name] isEqual: @"ULDatabaseBackendConnectionDidDieNotification"])
      {
            NSWarnLog(@"Recieved %@ notification - Handling not implemented",
                  [aNotification name]);  
      }

      //FIXME: handle connection failures and addition failures
}                 

- (id) backendForClient: (NSString*) clientName
{
      return [backends objectForKey: clientName];
}

- (void) addObject: (id) object 
            toSchema: (NSString*) schema
            ofClient: (id) clientName
{
      backend = [self backendForClient: clientName];
      [backend addObject: object toSchema: schema];
}

- (void) addObjectToFileSystemDatabase: (id) object
{
      [fileSystemBackend addObject: object toSchema: nil];
}

- (BOOL) objectInFileSystemDatabase: (id) object
{
      return [fileSystemBackend objectInDatabase: object];
}

- (void) updateMetadataForObject: (id) object 
            inSchema: (NSString*) schema
            ofClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      [backend updateMetadataForObject: object inSchema: schema];
}

- (void) updateOutputReferencesForObject: (id) object
{
      id client;

      client = [object valueForVolatileMetadataKey: @"DatabaseClient"];
      if(client == nil)
            [NSException raise: NSInternalInconsistencyException
                  format: @"Object has no DatabaseClient attribute. Cannot update output refereneces"];

      backend = [self backendForClient: client];
      [backend updateOutputReferencesForObject: object];
}

- (void) removeObjectOfClass: (id) className 
            withID: (NSString*) ident
            fromSchema: (NSString*) schema
            ofClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      [backend removeObjectOfClass: className withID: ident fromSchema: schema];
}

- (void) removeObjectsOfClass: (id) className   
            withIDs: (NSArray*) idents
            fromSchema: (NSString*) schema
            ofClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      [backend removeObjectsOfClass: className withIDs: idents fromSchema: schema];
}

- (id) unarchiveObjectWithID: (NSString*) ident 
      ofClass: (NSString*) className 
      fromSchema: (NSString*) schema
      ofClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      return [backend unarchiveObjectWithID: ident ofClass: className fromSchema: schema];
}

- (NSArray*) availableObjectsOfClass: (NSString*) className
            inSchema: (NSString*) schema
            ofClient: (NSString*) clientName
{
      id retval;

      backend = [self backendForClient: clientName];
      retval = [backend availableObjectsOfClass: className inSchema: schema];
      return retval;
}

- (NSArray*) contentTypeInformationForSchema: (NSString*) schema
            ofClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      return [backend contentTypeInformationForSchema: schema];
}

- (id) metadataForObjectWithID: (NSString*) ident 
      ofClass: (NSString*)  className
      inSchema: (NSString*) schema
      ofClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      return [backend metadataForObjectWithID: ident 
                  ofClass: className
                  inSchema: schema];
}

- (id) outputReferencesForObjectWithID: (NSString*) ident 
      ofClass: (NSString*) className
      inSchema: (NSString*) schema
      ofClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      [backend outputReferencesForObjectWithID: ident 
            ofClass: className
            inSchema: schema];
}

- (id) inputReferencesForObjectWithID: (NSString*) ident 
      ofClass: (NSString*)  className
      inSchema: (NSString*) schema
      ofClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      [backend inputReferencesForObjectWithID: 
            ident ofClass: className
            inSchema: schema];
}

//have to handle unavailable databases here
//FIXME: Only works with file system database at the moment.

- (void) removeOutputReferencesToObjectWithID: ident
            ofClass: (id) className
            inSchema: (NSString*) schema
            ofClient: (NSString*) clientName;
{
      NSEnumerator *inputReferencesEnum;
      id inputReference;

      //The arguements input references are the objects we are looking for.
      inputReferencesEnum = [[self inputReferencesForObjectWithID: ident
                        ofClass: className
                        inSchema: schema
                        ofClient: clientName] objectEnumerator];
      while(inputReference = [inputReferencesEnum nextObject])
      {
            [fileSystemBackend removeOutputReferenceToObjectWithID: ident
                  fromObjectWithID: [inputReference objectForKey: @"Identification"]
                  ofClass: [inputReference objectForKey: @"Class"]
                  inSchema: [inputReference objectForKey: @"Schema"]];
      }
}

- (NSArray*) availableClients
{
      return availableClients;
}

- (NSArray*) schemaInformationForClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      return [backend schemaInformation];
}

- (NSString*) userForClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      return [backend user];
}

- (NSString*) databaseForClient: (NSString*) clientName
{
      backend = [self backendForClient: clientName];
      return [backend database];
}

- (void) saveDatabase
{
      NSEnumerator* backendsEnum = [backends objectEnumerator];

      while(backend = [backendsEnum nextObject])
            [backend saveDatabase];
}

- (id) createFileSystemStorageForSimulation: (id) object
{
      return [fileSystemBackend createStorageForSimulation: object];
}

@end

Generated by  Doxygen 1.6.0   Back to index