示例#1
0
文件: db.py 项目: NumentaCorp/liquipy
 def __init__(self, host=DEFAULT["host"],
                    port=DEFAULT["port"],
                    database=DEFAULT["database"],
                    username=DEFAULT["username"],
                    password=DEFAULT["password"],
                    tempDir=None):
   self.liquibaseExecutor = LiquibaseExecutor(host, port, database, username,
                                              password)
   self.tempDir = tempDir
   self.changes = None
示例#2
0
 def __init__(self,
              host=DEFAULT["host"],
              port=DEFAULT["port"],
              database=DEFAULT["database"],
              username=DEFAULT["username"],
              password=DEFAULT["password"],
              tempDir=None):
     self.liquibaseExecutor = LiquibaseExecutor(host, port, database,
                                                username, password)
     self.tempDir = tempDir
     self.changes = None
示例#3
0
class LiquipyDatabase(object):
    """
  Main interface for Liquipy
  """

    _GENERATED_CHANGELOG_FILE_NAME = "liquipy_changelog.xml"
    """ This is the name of the generated changlog xml file """
    def __init__(self,
                 host=DEFAULT["host"],
                 port=DEFAULT["port"],
                 database=DEFAULT["database"],
                 username=DEFAULT["username"],
                 password=DEFAULT["password"],
                 tempDir=None):
        self.liquibaseExecutor = LiquibaseExecutor(host, port, database,
                                                   username, password)
        self.tempDir = tempDir
        self.changes = None

    def initialize(self, yamlPath):
        self.changes = self.inputYamlToChangeSets(yamlPath)

    def inputYamlToChangeSets(self, yamlPath):
        rawYaml = open(yamlPath, "r").read()
        try:
            changes = yaml.load(rawYaml)
        except yaml.scanner.ScannerError as e:
            msg = "Error parsing input YAML file %r:\n%r" % (yamlPath, e)
            raise Exception(msg)
        if "include" in changes.keys():
            relativeTargetDir = changes["include"]["directory"]
            currentDir = os.path.join(os.path.split(yamlPath)[:-1])[0]
            targetDir = os.path.join(currentDir, relativeTargetDir)
            try:
                dirFiles = os.listdir(targetDir)
            except Exception as e:
                raise Exception("Included directory %r does not exist (%r)" %
                                (targetDir, e))
            migrationFiles = [
                os.path.join(targetDir, f) for f in dirFiles
                if f.endswith(".yml")
            ]
            for includedMigration in migrationFiles:
                includeChanges = self.inputYamlToChangeSets(includedMigration)
                # TODO Need validation to make sure that the same ID is not reused!
                #   Issue https://github.com/GrokSolutions/liquipy/issues/15
                changes.update(includeChanges)
            del changes["include"]
        return changes

    def _getTempXMLChangeLogFilePath(self):
        """
    retval: filepath to be used for the generated ChangeLog XML file; MOTE: if
      tempDir was not specified by the user via constructor (self.tempDir is
      None), then an empty file will be created via tempfile.mkstemp as a
      place-holder for avoiding tempfile race conditions, and the caller is
      responsible for deleting that file
    """
        if self.tempDir is not None:
            # Generate the path inside user-supplied tempDir
            tempXMLChangeLogFilePath = os.path.join(
                self.tempDir, self._GENERATED_CHANGELOG_FILE_NAME)
        else:
            # Safely create a temp file and return its path
            (tempFD, tempXMLChangeLogFilePath) = tempfile.mkstemp(
                suffix=self._GENERATED_CHANGELOG_FILE_NAME)
            # Don't need the fd, so close it
            os.close(tempFD)

        return tempXMLChangeLogFilePath

    def update(self):
        g_logger.info("Running all migrations on db=%s",
                      self.liquibaseExecutor.database)

        tempXMLChangeLogFilePath = self._getTempXMLChangeLogFilePath()
        try:
            ChangeSetWriter(tempXMLChangeLogFilePath).write(self.changes)

            self.liquibaseExecutor.run(tempXMLChangeLogFilePath, "update")
        except:
            # On error, leave the genearted changelog file in place for debugging
            raise
        else:
            # Delete the generated changelog file if the user didn't provide tempDir
            if self.tempDir is None:
                os.unlink(tempXMLChangeLogFilePath)

    def rollback(self, tagName):
        g_logger.info("Rolling back db=%s to tag=%s",
                      self.liquibaseExecutor.database, tagName)

        tempXMLChangeLogFilePath = self._getTempXMLChangeLogFilePath()
        try:
            ChangeSetWriter(tempXMLChangeLogFilePath).write(self.changes)

            self.liquibaseExecutor.run(tempXMLChangeLogFilePath, "rollback",
                                       tagName)
        except:
            # On error, leave the genearted changelog file in place for debugging
            raise
        else:
            # Delete the generated changelog file if the user didn't provide tempDir
            if self.tempDir is None:
                os.unlink(tempXMLChangeLogFilePath)

    def getTags(self):
        return [{
            "tag": self.changes[c]["tag"],
            "changeSet": c
        } for c in self.changes.keys() if "tag" in self.changes[c]]
示例#4
0
文件: db.py 项目: NumentaCorp/liquipy
class LiquipyDatabase(object):
  """
  Main interface for Liquipy
  """

  _GENERATED_CHANGELOG_FILE_NAME = "liquipy_changelog.xml"
  """ This is the name of the generated changlog xml file """

  def __init__(self, host=DEFAULT["host"],
                     port=DEFAULT["port"],
                     database=DEFAULT["database"],
                     username=DEFAULT["username"],
                     password=DEFAULT["password"],
                     tempDir=None):
    self.liquibaseExecutor = LiquibaseExecutor(host, port, database, username,
                                               password)
    self.tempDir = tempDir
    self.changes = None


  def initialize(self, yamlPath):
    self.changes = self.inputYamlToChangeSets(yamlPath)


  def inputYamlToChangeSets(self, yamlPath):
    rawYaml = open(yamlPath, "r").read()
    try:
      changes = yaml.load(rawYaml)
    except yaml.scanner.ScannerError as e:
      msg = "Error parsing input YAML file %r:\n%r" % (yamlPath, e)
      raise Exception(msg)
    if "include" in changes.keys():
      relativeTargetDir = changes["include"]["directory"]
      currentDir = os.path.join(os.path.split(yamlPath)[:-1])[0]
      targetDir = os.path.join(currentDir, relativeTargetDir)
      try:
        dirFiles = os.listdir(targetDir)
      except Exception as e:
        raise Exception("Included directory %r does not exist (%r)" % (
          targetDir, e))
      migrationFiles = [
        os.path.join(targetDir, f)
        for f in dirFiles
        if f.endswith(".yml")
      ]
      for includedMigration in migrationFiles:
        includeChanges = self.inputYamlToChangeSets(includedMigration)
        # TODO Need validation to make sure that the same ID is not reused!
        #   Issue https://github.com/GrokSolutions/liquipy/issues/15
        changes.update(includeChanges)
      del changes["include"]
    return changes


  def _getTempXMLChangeLogFilePath(self):
    """
    retval: filepath to be used for the generated ChangeLog XML file; MOTE: if
      tempDir was not specified by the user via constructor (self.tempDir is
      None), then an empty file will be created via tempfile.mkstemp as a
      place-holder for avoiding tempfile race conditions, and the caller is
      responsible for deleting that file
    """
    if self.tempDir is not None:
      # Generate the path inside user-supplied tempDir
      tempXMLChangeLogFilePath = os.path.join(
        self.tempDir,
        self._GENERATED_CHANGELOG_FILE_NAME)
    else:
      # Safely create a temp file and return its path
      (tempFD, tempXMLChangeLogFilePath) = tempfile.mkstemp(
        suffix=self._GENERATED_CHANGELOG_FILE_NAME)
      # Don't need the fd, so close it
      os.close(tempFD)

    return tempXMLChangeLogFilePath


  def update(self):
    g_logger.info("Running all migrations on db=%s",
                  self.liquibaseExecutor.database)

    tempXMLChangeLogFilePath = self._getTempXMLChangeLogFilePath()
    try:
      ChangeSetWriter(tempXMLChangeLogFilePath).write(self.changes)

      self.liquibaseExecutor.run(tempXMLChangeLogFilePath, "update")
    except:
      # On error, leave the genearted changelog file in place for debugging
      raise
    else:
      # Delete the generated changelog file if the user didn't provide tempDir
      if self.tempDir is None:
        os.unlink(tempXMLChangeLogFilePath)


  def rollback(self, tagName):
    g_logger.info("Rolling back db=%s to tag=%s",
                  self.liquibaseExecutor.database, tagName)

    tempXMLChangeLogFilePath = self._getTempXMLChangeLogFilePath()
    try:
      ChangeSetWriter(tempXMLChangeLogFilePath).write(self.changes)

      self.liquibaseExecutor.run(tempXMLChangeLogFilePath, "rollback",
                                 tagName)
    except:
      # On error, leave the genearted changelog file in place for debugging
      raise
    else:
      # Delete the generated changelog file if the user didn't provide tempDir
      if self.tempDir is None:
        os.unlink(tempXMLChangeLogFilePath)


  def getTags(self):
    return [
      {"tag": self.changes[c]["tag"], "changeSet": c}
      for c in self.changes.keys()
      if "tag" in self.changes[c]
    ]