Example #1
0
    def runBuild(self, buildGroupList, options):
        if not buildGroupList:
            return
        buildGroupList = set(buildGroupList)
        # by default fail if a table couldn't be built
        options['noFail'] = False
        if 'all' in buildGroupList or 'allAvail' in buildGroupList:
            if 'allAvail' in buildGroupList:
                if len(buildGroupList) == 1:
                    # don't fail on non available
                    options['noFail'] = True
                else:
                    # allAvail not compatible with others, as allAvail means not
                    # failing if build fails, but others will need failing when
                    # explicitly named
                    raise ValueError("group 'allAvail' can't be specified " \
                        + "together with other groups.")
            # if generic group given get list
            buildGroupList = build.DatabaseBuilder.getSupportedTables()

        deprecatedGroups = self._getDeprecated() & set(buildGroupList)
        if deprecatedGroups:
            warnings.warn("Group(s) '%s' is (are) deprecated" %
                          "', '".join(deprecatedGroups) +
                          " and will disappear from future versions.",
                          category=DeprecationWarning)

        # unpack groups
        groups = []
        while len(buildGroupList) != 0:
            group = buildGroupList.pop()
            if self.BUILD_GROUPS.has_key(group):
                buildGroupList.update(self.BUILD_GROUPS[group])
            else:
                groups.append(group)

        # re-add builders preferred by default, in case overwritten by user
        preferredBuilderNames = options.get('prefer', [])
        if preferredBuilderNames:
            options['prefer'] = self._combinePreferred(preferredBuilderNames,
                                                       self.DB_PREFER_BUILDERS)

        # get database connection
        configuration = dbconnector.getDefaultConfiguration()
        configuration['sqlalchemy.url'] = options.pop(
            'databaseUrl', configuration['sqlalchemy.url'])
        configuration['attach'] = [
            attach for attach in options.pop('attach',
                                             configuration.get('attach', []))
            if attach
        ]
        if 'registerUnicode' in options:
            configuration['registerUnicode'] = options.pop('registerUnicode')
        try:
            db = dbconnector.DatabaseConnector(configuration)
        except ValueError, e:
            print >> sys.stderr, "Error: %s" % e
            return False
Example #2
0
    def install(self, dictionaryName, **options):
        """
        Installs the given dictionary to a database.

        Different installation methods are possible:

        - by default a global installation is done, a single database file
            if installed for SQLite, for other engines the database is
            installed to the same database as cjklib's,
        - if ``local`` is set, the database file for SQLite is installed to
            the user's home directory,
        - ``databaseUrl`` can be speficied for a user defined database,
        - ``dbConnectInst`` can be given to write to an open database
            instance.

        :param options: extra options
        :keyword databaseUrl: database connection setting in the format
            ``driver://user:pass@host/database``.
        :keyword dbConnectInst: instance of a
            :class:`~cjklib.dbconnector.DatabaseConnector`
        :keyword local: if ``True`` the SQLite file will be installed in the
            user's home directory.
        :keyword prefix: installation prefix for a global install (Unix only).
        :keyword forceUpdate: dictionary will be installed even if a newer
            version already exists
        :keyword quiet: if ``True`` no status information will be printed to
            stdout
        """
        # get database connection
        configuration = {}

        local = options.pop('local', False)
        prefix = options.pop('prefix', None)
        configuration['sqlalchemy.url'] = options.pop('databaseUrl', None)

        if 'dbConnectInst' in options:
            db = options.pop('dbConnectInst')
        else:
            if not configuration['sqlalchemy.url']:
                configuration['sqlalchemy.url'] = self.getDefaultDatabaseUrl(
                    dictionaryName, local=local, prefix=prefix)

            # for sqlite check if directory exists
            url = make_url(configuration['sqlalchemy.url'])
            if url.drivername == 'sqlite':
                if url.database:
                    databaseFile = url.database
                    directory, _ = os.path.split(databaseFile)
                    if not os.path.exists(directory):
                        os.makedirs(directory)

            configuration['attach'] = options.pop('attach', [])
            if 'registerUnicode' in options:
                configuration['registerUnicode'] = options.pop(
                    'registerUnicode')

            db = dbconnector.DatabaseConnector(configuration)

        # download
        downloader = getDownloader(dictionaryName, quiet=self.quiet)

        # check if we already have newest version
        forceUpdate = options.pop('forceUpdate', False)
        if not forceUpdate and db.hasTable(dictionaryName):
            if db.hasTable('Version'):
                table = db.tables['Version']
                curVersion = db.selectScalar(
                    select([table.c.ReleaseDate],
                           table.c.TableName == dictionaryName))

                newestVersion = downloader.getVersion()
                if isinstance(newestVersion, date):
                    newestVersion = datetime.combine(newestVersion, time(0))

                if newestVersion and curVersion and newestVersion <= curVersion:
                    if not self.quiet: warn("Newest version already installed")
                    return configuration['sqlalchemy.url']

        filePath = downloader.download(temporary=True)

        # create builder instance
        options['quiet'] = self.quiet
        dbBuilder = build.DatabaseBuilder(dbConnectInst=db,
                                          filePath=filePath,
                                          **options)

        try:
            tables = [dictionaryName]
            if not db.mainHasTable('Version'):
                tables.append('Version')
            dbBuilder.build(tables)

            table = db.tables['Version']
            db.execute(
                table.delete().where(table.c.TableName == dictionaryName))

            version = downloader.getVersion()
            if version:
                db.execute(table.insert().values(TableName=dictionaryName,
                                                 ReleaseDate=version))
        finally:
            # remove temporary tables
            dbBuilder.clearTemporary()

        return configuration['sqlalchemy.url']
Example #3
0
 def setUp(self):
     self.db = dbconnector.DatabaseConnector(
         {'sqlalchemy.url': 'sqlite://', 'attach': ['cjklib']})