__revision__ = "$Id: __init__.py,v 1.18 2005/04/07 20:05:56 jkloth Exp $"

from Ft.Server.Server import FtServerServerException, Error

import FtssDriver

# A mapping of driver modules to their low-level drivers. The None value
# is used to show that no additional driver is needed (or already checked).
_drivers = {
    'FlatFile' : None,
    'Postgres' : '_pg',
    'Psyco' : 'psycopg',
    'Oracle' : 'DCOracle2',
    'Odbc' : 'odbc',
    'MetaKit' : 'metakit',    
    'MySQL' : 'MySQLdb',
    'BerkeleyDB' : 'bsddb3'
}

_modules = {}

def Begin(logger, properties):
    """
    Create a new transaction with a new driver.  Properties are read
    straight from the config file.  Use them to create a new driver,
    then start the TX, and return the adapter.
    """
    module = LoadDriverModule(properties['Driver']['TYPE'])

    # Create the adapter for use in the server
    return FtssDriver.FtssDriver(logger, module, properties)


def LoadDriverModule(driverName):
    if driverName in _modules:
        return _modules[driverName]

    try:
        module = _drivers[driverName]
    except KeyError:
        # No driver for the type specified in the configuration file.
        raise FtServerServerException(Error.UNKNOWN_DRIVER_ERROR,
                                      driver=driverName)

    # If there is a third-party module for this driver, check if it
    # is available.  Done here to simplify the driver modules.
    if module:
        try:
            __import__(module)
        except ImportError, error:
            raise FtServerServerException(Error.DRIVER_UNAVAILABLE,
                                          driver=driverName,
                                          reason=str(error))

        # Only need to check dependency once but only if it succeeds
        _drivers[driverName] = None
        
    # Get the module for the given driver type
    module = __import__(__name__ + '.' + driverName, {}, {},
                        ['InitializeModule'])
    module.InitializeModule()
    _modules[driverName] = module
    return module
    
