def manuallySyncSchemaRevisions(adminSessions, schemaName, outputDir=None): """ """ removeOutputDir = False try: if not outputDir: outputDir = mkdtemp() removeOutputDir = True src, dst = reorderSessionsByEldestSchemaRev(adminSessions, schemaName) srcSession, endRev = src dstSession, beginRev = dst exports = exportIntegrationRange(srcSession, schemaName, beginRev, endRev, outputDir, getCmdLineOnly=True) exportBatchFile = open(joinPath(outputDir, 'export-%s-%s-v%d-%d.bat' % \ (srcSession._databaseSet, schemaName, beginRev, endRev)), 'w') exportBatchFile.write('\n'.join(exports)) exportBatchFile.close() print "wrote %s" % exportBatchFile.name imports = importIntegrationRange(dstSession, schemaName, outputDir, getCmdLineOnly=True, beginRev=beginRev, endRev=endRev) importsBatchFile = open(joinPath(outputDir, 'import-%s-%s-v%d-%d.bat' % \ (dstSession._databaseSet, schemaName, beginRev, endRev)), 'w') importsBatchFile.write('\n'.join(imports)) importsBatchFile.close() print "wrote %s" % importsBatchFile.name except Exception, e: if removeOutputDir: try: os.remove(outputDir) except: pass raise e
def findSql(self, prefixes, name, *args, **kwds): vendor = DatabaseVendor[self.getDatabaseVendor()] # Ugh, this is ugly. for prefix in prefixes: fileName = '%s.%s.%s.sql' % (prefix, name, vendor) if isfile(joinPath(_SqlTemplateDir, fileName)): break fileName = '%s.%s.sql' % (prefix, name) if isfile(joinPath(_SqlTemplateDir, fileName)): break return _SqlLoader.load(fileName) \ .generate(args=args, **kwds) \ .render('text')
def exportIntegrationRange(session, schemaName, beginRevision, endRevision, outputDir, getCmdLineOnly=False): """ For each revision in the range between beginRevision and endRevision, export a single integration of schemaName from session into outputDir. The export will be named '<dbset>-<schemaName>-v<revision>.txt'. (The value for dbset is automatically derived from the session parameter.) This method is intended to be used with the importIntegrationRange() method. It is useful if you want to keep the revision history of two schemas synchronised. In order to minimise the likelihood of picking up stray/unwanted schemas when running exportIntegrationRange() followed by importIntegrationRange(), a RuntimeError exception is raised if outputDir is not empty. """ for dummy in iglob(joinPath(outputDir, '*')): raise RuntimeError("output directory not empty: %s" % outputDir) kwds = dict(outputDir=outputDir, getCmdLineOnly=getCmdLineOnly) revs = xrange(beginRevision, endRevision+1) if getCmdLineOnly: return [ exportIntegration(session, schemaName, r, **kwds) for r in revs ] else: for r in revs: print "exporting revision %d of '%s' schema..." % \ (r, schemaName) exportIntegration(session, schemaName, r, **kwds)
def _findSql(session, classOrModuleName, methodName, *args, **kwds): vendor = session.getDatabaseVendorName() fileName = '%s.%s.%s.sql' % (classOrModuleName, methodName, vendor) if not isfile(joinPath(_SqlTemplateDir, fileName)): fileName = '%s.%s.sql' % (classOrModuleName, methodName) return _SqlLoader.load(fileName) \ .generate(args=args, **kwds) \ .render('text')
def importIntegrationRange(session, schemaName, outputDir, getCmdLineOnly=False, beginRev=0, endRev=0): """ Unless getCmdLineOnly is set to True, beginRev and endRev are ignored. """ if getCmdLineOnly: return [ importIntegration(session, schemaName, file, getCmdLineOnly=True) for file in [ joinPath(outputDir, '%s-%s-v%d.txt' % \ (session._databaseSet, schemaName, rev)) for rev in xrange(beginRev, endRev+1) ] ] else: files = [ f for f in iglob(joinPath(outputDir, '*.txt')) ] files.sort() for file in files: print "importing %s..." % file importIntegration(session, schemaName, file, getCmdLineOnly)
def exportIntegration(session, schemaName, beginRevision, endRevision=0, outputDir=os.getcwd(), recordTypeToRename='', getCmdLineOnly=False): """ Export an integration of @param C{str} schemaName to @param C{str} outputDir, starting at @param C{int} beginRevision and ending at @param C{int} endRevision. If endRevision is ommitted or 0, it will be set to the value of beginRevision, which results in a single schema version being exported. If @param C{bool} getCmdLineOnly is set to True, cqload.exe will not be run directly. Instead, a string will be returned that represents the command line arguments necessary to run cqload.exe manually. Usage: cqload exportintegration [-dbset dbset_name] clearquest_login clearquest_password schema_name begin_rev end_rev record_type_to_rename schema_pathname """ if not endRevision: endRevision = beginRevision rev = str(beginRevision) else: rev = '%d-%d' % (beginRevision, endRevision) file = '%s-%s-v%s.txt' % (session._databaseSet, schemaName, rev) schemaPathName = joinPath(outputDir, file) return runCQLoad(session, CQLoadOperation.ExportIntegration, getCmdLineOnly, schemaName, str(beginRevision), str(endRevision), recordTypeToRename, schemaPathName)
def _getSqlCmdExe(): p = 'Software/Microsoft/Microsoft SQL Server/90/Tools/ClientSetup/Path' exe = joinPath(readRegKey(p), 'sqlcmd.exe') if not os.path.isfile(exe): raise RuntimeError("sqlcmd.exe does not exist at: %s" % exe) return exe
class DatabaseVendorNotSupported(Exception): pass class DatabaseVendorNotDiscernableFromSQL_DBMS_NAME(Exception): pass class DatabaseError(Exception): """ Helper class for wrapping any DBI error we may encounter in a single class. """ def __init__(self, details, sql): self.args = (details, "Offending SQL:\n%s" % sql) #=============================================================================== # Globals #=============================================================================== _SqlTemplateDir = joinPath(dirname(__file__), 'sql') _SqlLoader = TemplateLoader(_SqlTemplateDir, default_class=TextTemplate, variable_lookup='strict', auto_reload=True) #=============================================================================== # Decorators #=============================================================================== def sql(mf): @wraps(mf) def decorator(f): fname = f.func_name @wraps(f) def newf(*_args, **_kwds):
def __init__(self, manager, file=None): self.manager = manager if not file: base = basename(sys.modules[manager.__module__].__file__) file = joinPath(manager.runDir, base[:base.rfind('.')] + '.ini') Config.__init__(self, file)
def getXmlFileName(self): return joinPath(self.manager.runDir, 'dynamiclists.xml')
def _data(self): name = self.__class__.__name__.lower() file = joinPath(self.manager.runDir, name + '.ini') if os.path.isfile(file): self.conf = Config(file) return self.conf.data