root/galaxy-central/eggs/sqlalchemy_migrate-0.5.4-py2.6.egg/migrate/versioning/repository.py

リビジョン 3, 5.7 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1"""
2   SQLAlchemy migrate repository management.
3"""
4import os
5import shutil
6import string
7from pkg_resources import resource_string, resource_filename
8
9from migrate.versioning import exceptions, script, version, pathed, cfgparse
10from migrate.versioning.template import template
11from migrate.versioning.base import *
12
13
14class Changeset(dict):
15    """A collection of changes to be applied to a database.
16
17    Changesets are bound to a repository and manage a set of logsql
18    scripts from that repository.
19
20    Behaves like a dict, for the most part. Keys are ordered based on
21    start/end.
22    """
23
24    def __init__(self, start, *changes, **k):
25        """
26        Give a start version; step must be explicitly stated.
27        """
28        self.step = k.pop('step', 1)
29        self.start = version.VerNum(start)
30        self.end = self.start
31        for change in changes:
32            self.add(change)
33
34    def __iter__(self):
35        return iter(self.items())
36
37    def keys(self):
38        """
39        In a series of upgrades x -> y, keys are version x. Sorted.
40        """
41        ret = super(Changeset, self).keys()
42        # Reverse order if downgrading
43        ret.sort(reverse=(self.step < 1))
44        return ret
45
46    def values(self):
47        return [self[k] for k in self.keys()]
48
49    def items(self):
50        return zip(self.keys(), self.values())
51
52    def add(self, change):
53        key = self.end
54        self.end += self.step
55        self[key] = change
56
57    def run(self, *p, **k):
58        for version, script in self:
59            script.run(*p, **k)
60
61
62class Repository(pathed.Pathed):
63    """A project's change script repository"""
64    _config = 'migrate.cfg'
65    _versions = 'versions'
66
67    def __init__(self, path):
68        log.info('Loading repository %s...' % path)
69        self.verify(path)
70        super(Repository, self).__init__(path)
71        self.config=cfgparse.Config(os.path.join(self.path, self._config))
72        self.versions=version.Collection(os.path.join(self.path,
73                                                      self._versions))
74        log.info('Repository %s loaded successfully' % path)
75        log.debug('Config: %r' % self.config.to_dict())
76
77    @classmethod
78    def verify(cls, path):
79        """
80        Ensure the target path is a valid repository.
81
82        :raises: :exc:`InvalidRepositoryError` if not valid
83        """
84        # Ensure the existance of required files
85        try:
86            cls.require_found(path)
87            cls.require_found(os.path.join(path, cls._config))
88            cls.require_found(os.path.join(path, cls._versions))
89        except exceptions.PathNotFoundError, e:
90            raise exceptions.InvalidRepositoryError(path)
91
92    @classmethod
93    def prepare_config(cls, pkg, rsrc, name, **opts):
94        """
95        Prepare a project configuration file for a new project.
96        """
97        # Prepare opts
98        defaults=dict(
99            version_table='migrate_version',
100            repository_id=name,
101            required_dbs=[], )
102        for key, val in defaults.iteritems():
103            if (key not in opts) or (opts[key] is None):
104                opts[key]=val
105
106        tmpl = resource_string(pkg, rsrc)
107        ret = string.Template(tmpl).substitute(opts)
108        return ret
109
110    @classmethod
111    def create(cls, path, name, **opts):
112        """Create a repository at a specified path"""
113        cls.require_notfound(path)
114
115        pkg, rsrc = template.get_repository(as_pkg=True)
116        tmplpkg = '.'.join((pkg, rsrc))
117        tmplfile = resource_filename(pkg, rsrc)
118        config_text = cls.prepare_config(tmplpkg, cls._config, name, **opts)
119        # Create repository
120        try:
121            shutil.copytree(tmplfile, path)
122            # Edit config defaults
123            fd = open(os.path.join(path, cls._config), 'w')
124            fd.write(config_text)
125            fd.close()
126            # Create a management script
127            manager = os.path.join(path, 'manage.py')
128            manage(manager, repository=path)
129        except:
130            log.error("There was an error creating your repository")
131        return cls(path)
132
133    def create_script(self, description, **k):
134        self.versions.create_new_python_version(description, **k)
135
136    def create_script_sql(self, database, **k):
137        self.versions.create_new_sql_version(database, **k)
138
139    latest=property(lambda self: self.versions.latest)
140    version_table=property(lambda self: self.config.get('db_settings',
141                                                        'version_table'))
142    id=property(lambda self: self.config.get('db_settings', 'repository_id'))
143
144    def version(self, *p, **k):
145        return self.versions.version(*p, **k)
146
147    @classmethod
148    def clear(cls):
149        super(Repository, cls).clear()
150        version.Collection.clear()
151
152    def changeset(self, database, start, end=None):
153        """
154        Create a changeset to migrate this dbms from ver. start to end/latest.
155        """
156        start = version.VerNum(start)
157        if end is None:
158            end = self.latest
159        else:
160            end = version.VerNum(end)
161        if start <= end:
162            step = 1
163            range_mod = 1
164            op = 'upgrade'
165        else:
166            step = -1
167            range_mod = 0
168            op = 'downgrade'
169        versions = range(start+range_mod, end+range_mod, step)
170        changes = [self.version(v).script(database, op) for v in versions]
171        ret = Changeset(start, step=step, *changes)
172        return ret
173
174
175def manage(file, **opts):
176    """Create a project management script"""
177    pkg, rsrc = template.manage(as_pkg=True)
178    tmpl = resource_string(pkg, rsrc)
179    vars = ",".join(["%s='%s'" % vars for vars in opts.iteritems()])
180    result = tmpl%dict(defaults=vars)
181
182    fd = open(file, 'w')
183    fd.write(result)
184    fd.close()
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。