__init__.py :  » Development » SnapLogic » snaplogic » server » repository » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » SnapLogic 
SnapLogic » snaplogic » server » repository » __init__.py
# $SnapHashLicense:
# 
# SnapLogic - Open source data services
# 
# Copyright (C) 2008 - 2009 SnapLogic, Inc.  All rights reserved.
# 
# See http://www.snaplogic.org for more information about
# the SnapLogic project. 
# 
# This program is free software, distributed under the terms of
# the GNU General Public License Version 2. See the LEGAL file
# at the top of the source tree.
# 
# "SnapLogic" is a trademark of SnapLogic, Inc.
# 
# 
# $

# $Id: __init__.py 9868 2009-11-21 17:50:45Z dhiraj $

from __future__ import with_statement

"""

This package contains functionality for managing storage of resources with various backend databases.

"""
__docformat__ = "epytext en"

import os
import uuid
import threading
import errno

from snaplogic.common.snap_exceptions import *
from snaplogic.common import snap_log,version_info
from snaplogic.common.config import snap_config
from snaplogic.snapi_base import keys
from snaplogic.server.repository.request_proxy import RequestProxy
from snaplogic.server.repository import reg_keys,version_history

_store = None
_mutex = threading.Lock()
repo_log = None

repo_log = None

def get_instance():
    """
    Get a new instance of the loaded repository.

    A new proxy object instance is created to wrap the internal store with the public API used for accessing
    the repository in the main process.
    
    @return: A new instance to the loaded repository to use.
    @rtype: RequestProxy

    @raises SnapRepInitError: Repository not initialized.

    """
    with _mutex:
        if _store is not None:
            return RequestProxy(_store.clone(), repo_log)
        else:
            raise SnapRepInitError("Repository not initialized.")
    
def init():
    """
    Initialize the repository.

    The config file must be loaded and useable before this method is called. The [repository] section is
    examined in the config and the database loaded.

    @raise SnapRepInitError: There was an error parsing the config or there was an error connecting or validating
                             the store contained within the database.
                             
    """
    global repo_log, repo_elog, _store
    
    if _store is not None:
        raise SnapRepInitError("Repository already initialized.")
        
    config = snap_config.get_instance()
    main_config = config.get_section('main')

    (repo_log, repo_elog, ignore_rlog) = snap_log.get_instance().make_specific_loggers(snap_log.LOG_REPO)

    try:
        try:
            repo_config = config.get_section('repository')
        except SnapObjNotFoundError, e:
            raise SnapException.chain(e, SnapRepInitError("Repository section missing in config file."))

        _store = connect_store(repo_config)
        repo_log(snap_log.LEVEL_INFO, "Connected to repository.")
    except SnapRepError, e:
        repo_elog(e)
        raise
    except Exception, e:
        new_e = SnapException.chain(e, SnapRepInitError("Repository internal initialization failure: " + str(e)))
        repo_elog(new_e)
        raise new_e
    
def connect_store(repo_config, perform_checks=True):
    """
    Initialize a SnapStore object from the repository config.

    @param repo_config: A dictionary of repository parameters like those found in the [repository] section.
    @type repo_config: dict

    @param perform_checks: If true, perform some checks to insure the integrity of the repo. Should be off for upgrade.
    @type perform_checks: bool

    @return: Initialized SnapStore object.
    @rtype: L{snaplogic.server.repository.snap_store.SnapStore}

    @raises SnapRepInitError: Unable to open repository or invalid parameters specified.

    """
    repo_type = repo_config.get('type', None)
    if repo_type == 'sqlite':
        store = _init_sqlite(repo_config)
    elif repo_type == 'mysql':
        store = _init_mysql(repo_config)
    else:    
        raise SnapRepInitError("Unsupported repository type '%s'." % repo_type)
        
    # Check the designated version for another lock. If the lock was held by an older version, update
    # it to the current server's version.
    if perform_checks:
        check_store_integrity(store)
    
    return store
    
def _init_sqlite(repo_config):
    """
    Initialize an SQLite store from the repository config.

    @param repo_config: The [repository] section of the config.
    @type repo_config: dict
    
    @return: A SnapStore object connected to the database specified in repo_config.
    @rtype: L{snaplogic.server.repository.snap_store.SnapStore}

    @raises SnapRepInitError: Error reading config or loading or verifying the repository database.

    """
    db_path = repo_config.get('path', None)
    if db_path is None:
        raise SnapRepInitError("SQLite repository requires path for DB file")

    from snaplogic.server.repository.sqlite import SQLite
    store = SQLite()
    store.connect(db_path)
    return store
    
def _init_mysql(repo_config):
    """
    Initialize a MySQL store from the repository config.

    @param repo_config: The [repository] section of the config.
    @type repo_config: dict

    @return: A SnapStore object connected to the database specified in repo_config.
    @rtype: L{snaplogic.server.repository.snap_store.SnapStore}

    @raises SnapRepInitError: Error reading config or loading or verifying the repository database.

    """
    for key in ["host", "db", "user"]:
        if key not in repo_config or repo_config[key] is None:
            raise SnapRepInitError("Repository section missing required MySQL entry '%s'" % key)
        
    if 'port' in repo_config:
        port = int(repo_config['port'])
    else:
        port = None
    passwd = repo_config.get('password', '')
    
    from snaplogic.server.repository.mysql import MySQL
    store = MySQL()
    store.connect(repo_config['host'], port, repo_config['db'], repo_config['user'], passwd)
    return store

def check_store_integrity(store):
    """
    Check the integrity of the store.

    The first value checked is the DB schema (format) version. If this value is not exactly equal to
    the server repository version, an appropriate error is raised.
    
    If the version designation lock in the store is less than this server's version, it will be updated
    to this server's value. If the stored version is greater than this server, the repository initialization
    will be aborted. If they are equal, the store is left as is and repository initialization is allowed
    to complete.

    @param store: A repository store object.
    @type: L{snaplogic.server.repository.snap_store.SnapStore}

    @raises SnapRepInitError: Validation failed.

    """
    format_version = store.read_version()
    if format_version < version_info.repository_version:
        raise SnapRepInitError("Repository format version (%s) requires upgrade before starting server" %
                               format_version)
    elif format_version > version_info.repository_version:
        raise SnapRepInitError("Repository format version (%s) incompatible with this server version" %
                               format_version)
    
    designated_version = store.read_designated_version()
    if designated_version != version_info.server_version:
        parsed_designated = designated_version.split('.')
        parsed_server = version_info.server_version.split('.')
        if len(parsed_designated) != len(parsed_server):
            raise SnapRepInitError("Version number parsing error: incompatible version number formats")

        for i in xrange(len(parsed_designated)):
            if parsed_designated[i] > parsed_server[i]:
                raise SnapRepInitError("Repository designated version (%s) greater than server version (%s)" %
                                       (designated_version, version_info.server_version))
            elif parsed_designated[i] < parsed_server[i]:
                # Update the designation value.
                store.set_designated_version(version_info.server_version)
                if repo_log is not None:
                    repo_log(snap_log.LEVEL_INFO,
                             "Updating repository designated version to " + version_info.server_version)
                break
    
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.