コード例 #1
0
ファイル: HostControl.py プロジェクト: mpice-mn/python-opsi
 def __init__(self,
              hostControlBackend,
              hostId,
              address,
              username,
              password,
              method,
              params=[],
              hostPort=0):
     KillableThread.__init__(self)
     self.hostControlBackend = hostControlBackend
     self.hostId = forceHostId(hostId)
     self.address = forceIpAddress(address)
     self.username = forceUnicode(username)
     self.password = forceUnicode(password)
     self.method = forceUnicode(method)
     self.params = forceList(params)
     self.error = None
     self.result = None
     self.started = 0
     self.ended = 0
     if hostPort:
         self.hostPort = forceInt(hostPort)
     else:
         self.hostPort = self.hostControlBackend._opsiclientdPort
コード例 #2
0
def blowfishEncrypt(key, cleartext):
    """
	Takes `cleartext` string, returns hex-encoded,
	blowfish-encrypted string.

	:raises BlowfishError: In case things go wrong.
	:rtype: unicode
	"""
    cleartext = forceUnicode(cleartext).encode('utf-8')
    key = forceUnicode(key)

    while len(cleartext) % 8 != 0:
        # Fill up with \0 until length is a mutiple of 8
        cleartext += chr(0)

    try:
        key = key.decode("hex")
    except TypeError:
        raise BlowfishError(u"Failed to hex decode key '%s'" % key)

    blowfish = Blowfish.new(key, Blowfish.MODE_CBC, BLOWFISH_IV)
    try:
        crypt = blowfish.encrypt(cleartext)
    except Exception as encryptError:
        logger.logException(encryptError, LOG_DEBUG)
        raise BlowfishError(u"Failed to encrypt")

    return unicode(crypt.encode("hex"))
コード例 #3
0
def blowfishDecrypt(key, crypt):
    """
	Takes hex-encoded, blowfish-encrypted string,
	returns cleartext string.

	:raises BlowfishError: In case things go wrong.
	:rtype: unicode
	"""

    key = forceUnicode(key)
    crypt = forceUnicode(crypt)
    try:
        key = key.decode("hex")
    except TypeError as e:
        raise BlowfishError(u"Failed to hex decode key '%s'" % key)

    crypt = crypt.decode("hex")
    blowfish = Blowfish.new(key, Blowfish.MODE_CBC, BLOWFISH_IV)
    try:
        cleartext = blowfish.decrypt(crypt)
    except Exception as decryptError:
        logger.logException(decryptError, LOG_DEBUG)
        raise BlowfishError(u"Failed to decrypt")

    # Remove possible \0-chars
    if cleartext.find('\0') != -1:
        cleartext = cleartext[:cleartext.find('\0')]

    try:
        return unicode(cleartext, 'utf-8')
    except Exception as e:
        logger.error(e)
        raise BlowfishError(u"Failed to convert decrypted text to unicode.")
コード例 #4
0
    def showMessage(self,
                    text,
                    title=_(u'Message'),
                    okLabel=_(u'OK'),
                    width=-1,
                    height=-1,
                    seconds=0):
        try:
            text = forceUnicode(text)
            title = forceUnicode(title)
            okLabel = forceUnicode(okLabel)
            width = forceInt(width)
            height = forceInt(height)
            seconds = forceInt(seconds)

            for string in self.confidentialStrings:
                text = text.replace(string, u'*** confidential ***')

            if width <= 0:
                width = self.getScreen().width - 15
            if height <= 0:
                height = len(text.split(u'\n')) + 2

            textBox = Textbox(width=width,
                              height=height,
                              text=text.encode(encoding, 'replace'),
                              scroll=1,
                              wrap=1)
            button = Button(okLabel.encode(encoding, 'replace'))
            rows = 2
            if seconds:
                rows = 1
            gridForm = GridForm(self._screen,
                                title.encode(encoding, 'replace'), 1, rows)
            gridForm.add(textBox, 0, 0)
            if seconds:
                gridForm.draw()
                self.refresh()
                time.sleep(seconds)
                self._screen.popWindow()
            else:
                gridForm.add(button, 0, 1)
                helpLine = _(
                    u"<F12> %s | <Space> select | <Up/Down> scroll text"
                ) % okLabel
                self.getScreen().pushHelpLine(
                    forceUnicode(helpLine).encode(encoding, 'replace'))
                return gridForm.runOnce()
        except Exception as e:
            self.exit()
            logger.logException(e)
            raise
コード例 #5
0
ファイル: JsonRpc.py プロジェクト: mpice-mn/python-opsi
    def getResponse(self):
        response = {}
        if self.type == 'rpc':
            response['tid'] = self.tid
            response['action'] = self.action
            response['method'] = self.method
            if self.exception:
                response['type'] = 'exception'
                response['message'] = {
                    'class': self.exception.__class__.__name__,
                    'message': forceUnicode(self.exception)
                }
                response['where'] = self.traceback
            else:
                response['type'] = 'rpc'
                response['result'] = self.result
        else:
            response['id'] = self.tid
            if self.rpcVersion == '2.0':
                response['jsonrpc'] = '2.0'

            if self.exception:
                if self.rpcVersion == '2.0':
                    try:
                        code = int(getattr(self.exception, 'errno'))
                    except Exception:
                        code = 0

                    response['error'] = {
                        'code': code,
                        'message': forceUnicode(self.exception),
                        'data': {
                            'class': self.exception.__class__.__name__
                        }
                    }
                else:
                    response['error'] = {
                        'class': self.exception.__class__.__name__,
                        'message': forceUnicode(self.exception)
                    }

                if self.rpcVersion != '2.0':  # TODO: das macht keinen Sinn!
                    response['result'] = None
            else:
                if self.rpcVersion != '2.0':
                    response['error'] = None
                response['result'] = self.result

        return response
コード例 #6
0
def testCircularDependenciesExceptionNamesConflictingProducts(
        productSequenceAlgorithm):
    '''
	A circular dependency exception should inform the user what \
products are currently conflicting.
	'''
    dependencies, products = getCircularDepedencies()

    try:
        productSequenceAlgorithm(products, dependencies)
        pytest.fail("Should not get here.")
    except OpsiProductOrderingError as error:
        assert 'firefox' in forceUnicode(error)
        assert 'javavm' in forceUnicode(error)
        assert 'ultravnc' in forceUnicode(error)
コード例 #7
0
    def setText(self, text):
        try:
            self._text = forceUnicode(text)
            for string in self._ui.confidentialStrings:
                self._text = self._text.replace(string,
                                                u'*** confidential ***')

            lines = self._text.split(u"\n")
            for i in range(len(lines)):
                pos = lines[i].find(u"\r")
                if (pos != -1):
                    parts = lines[i].split(u"\r")
                    for j in range(len(parts) - 1, -1, -1):
                        if parts[j]:
                            lines[i] = parts[j] + u"\r"
                            break
            if (lines > self._textHeight):
                self._text = u"\n".join(lines[(-1) * self._textHeight:])
            try:
                self._textbox.setText(self._text.encode(encoding, 'replace'))
            except Exception as e:
                logger.logException(e)
            self.show()
        except Exception as e:
            self._ui.exit()
            logger.logException(e)
            raise
コード例 #8
0
def non_blocking_connect_http(self, connectTimeout=0):
    ''' Non blocking connect, needed for KillableThread '''
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(3.0)
    started = time.time()
    lastError = None
    while True:
        try:
            if connectTimeout > 0 and (
                (time.time() - started) >= connectTimeout):
                raise OpsiTimeoutError(
                    u"Timed out after {0:d} seconds (last error: {1})".format(
                        connectTimeout, forceUnicode(lastError)))
            sock.connect((self.host, self.port))
            break
        except socket.error as error:
            logger.logException(error, LOG_DEBUG)
            logger.debug(error)
            if error[0] in (106, 10056):
                # Transport endpoint is already connected
                break
            if error[0] not in (114, ) or not lastError:
                lastError = error
            time.sleep(0.5)
    sock.settimeout(None)
    self.sock = sock
コード例 #9
0
def urlsplit(url):
    url = forceUnicode(url)
    scheme = None
    baseurl = u'/'
    port = None
    username = None
    password = None
    if url.find('://') != -1:
        (scheme, url) = url.split('://', 1)
        scheme = scheme.lower()
    parts = url.split('/', 1)
    host = parts[0]

    if len(parts) > 1:
        baseurl += parts[1]

    if '@' in host:
        username, host = host.split('@', 1)
        if ':' in username:
            username, password = username.split(':', 1)

    if ':' in host:
        host, port = host.split(':', 1)
        port = int(port)
    return (scheme, host, port, baseurl, username, password)
コード例 #10
0
    def sendCommand(self, cmd):
        with createUnixSocket(self.port, timeout=self.timeout) as unixSocket:
            unixSocket.send(forceUnicode(cmd).encode('utf-8'))

            result = ''
            try:
                for part in iter(lambda: unixSocket.recv(4096), ''):
                    logger.debug2("Received {!r}", part)
                    result += forceUnicode(part)
            except Exception as error:
                raise RuntimeError(u"Failed to receive: %s" % error)

        if result.startswith(ERROR_MARKER):
            raise RuntimeError(u"Command '%s' failed: %s" % (cmd, result))

        return result
コード例 #11
0
 def addText(self, text):
     try:
         self.setText(self._text + forceUnicode(text))
     except Exception as e:
         self._ui.exit()
         logger.logException(e)
         raise
コード例 #12
0
    def createMessageBox(self,
                         width=-1,
                         height=-1,
                         title=_(u'Text'),
                         text=u''):
        width = forceInt(width)
        height = forceInt(height)
        title = forceUnicode(title)
        text = forceUnicode(text)

        self.messageBox = SnackMessageBox(ui=self,
                                          width=width,
                                          height=height,
                                          title=title,
                                          text=text)
        return self.messageBox
コード例 #13
0
ファイル: Backup.py プロジェクト: mpice-mn/python-opsi
		def ask(question=WARNING_DIFF):
			"""
			Ask for a yes or no.

			Returns ``True`` if the answer is ``Yes``, false otherwise.
			"""
			fd = sys.stdin.fileno()

			oldterm = termios.tcgetattr(fd)
			newattr = termios.tcgetattr(fd)
			newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
			termios.tcsetattr(fd, termios.TCSANOW, newattr)

			oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
			fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

			self.stdout.write(question)

			try:
				while True:
					try:
						firstCharacter = sys.stdin.read(1)
						return forceUnicode(firstCharacter) in (u"y", u"Y")
					except IOError:
						pass
			finally:
				termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
				fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
コード例 #14
0
def librsyncPatchFile(oldfile, deltafile, newfile):
    logger.debug(
        u"Librsync patch: old file {!r}, delta file {!r}, new file {!r}",
        oldfile, deltafile, newfile)

    oldfile = forceFilename(oldfile)
    newfile = forceFilename(newfile)
    deltafile = forceFilename(deltafile)

    if oldfile == newfile:
        raise ValueError(u"Oldfile and newfile are the same file")
    if deltafile == newfile:
        raise ValueError(u"deltafile and newfile are the same file")
    if deltafile == oldfile:
        raise ValueError(u"oldfile and deltafile are the same file")

    bufsize = 1024 * 1024
    try:
        with open(oldfile, "rb") as of:
            with open(deltafile, "rb") as df:
                with open(newfile, "wb") as nf:
                    with closing(librsync.PatchedFile(of, df)) as pf:
                        data = True
                        while data:
                            data = pf.read(bufsize)
                            nf.write(data)
    except Exception as patchError:
        logger.debug("Patching {!r} with delta {!r} into {!r} failed: {}",
                     oldfile, deltafile, newfile, patchError)
        raise RuntimeError(u"Failed to patch file %s: %s" %
                           (oldfile, forceUnicode(patchError)))
コード例 #15
0
ファイル: HostControl.py プロジェクト: mpice-mn/python-opsi
 def hostControl_fireEvent(self, event, hostIds=[]):
     event = forceUnicode(event)
     hostIds = self._context.host_getIdents(id=hostIds,
                                            returnType='unicode')  # pylint: disable=maybe-no-member
     return self._opsiclientdRpc(hostIds=hostIds,
                                 method='fireEvent',
                                 params=[event])
コード例 #16
0
ファイル: HostControl.py プロジェクト: mpice-mn/python-opsi
 def hostControl_showPopup(self, message, hostIds=[]):
     message = forceUnicode(message)
     hostIds = self._context.host_getIdents(id=hostIds,
                                            returnType='unicode')  # pylint: disable=maybe-no-member
     return self._opsiclientdRpc(hostIds=hostIds,
                                 method='showPopup',
                                 params=[message])
コード例 #17
0
 def addConfidentialString(self, string):
     string = forceUnicode(string)
     if not string:
         raise ValueError(u"Cannot use empty string as confidential string")
     if string in self.confidentialStrings:
         return
     self.confidentialStrings.append(string)
コード例 #18
0
def randomString(length, characters=_ACCEPTED_CHARACTERS):
    """
	Generates a random string for a given length.

	:param characters: The characters to choose from. This defaults to 0-9a-Z.
	"""
    return forceUnicode(u''.join(
        random.choice(characters) for _ in range(length)))
コード例 #19
0
ファイル: Exceptions.py プロジェクト: mpice-mn/python-opsi
	def __unicode__(self):
		if self._message:
			if self.problematicRequirements:
				return u"{0}: {1} ({2})".format(self.ExceptionShortDescription, self._message, self.problematicRequirements)
			else:
				return u"{0}: {1}".format(self.ExceptionShortDescription, self._message)
		else:
			return forceUnicode(self.ExceptionShortDescription)
コード例 #20
0
    def __init__(self,
                 ui,
                 width=0,
                 height=0,
                 total=100,
                 title=_(u'Title'),
                 text=u''):
        ProgressObserver.__init__(self)

        self._ui = ui
        width = forceInt(width)
        height = forceInt(height)
        total = forceInt(total)
        title = forceUnicode(title)
        text = forceUnicode(text)

        if (width <= 0):
            width = self._ui.getScreen().width - 7
        if (height <= 0):
            height = self._ui.getScreen().height - 7

        SnackMessageBox.__init__(self, ui, width, height - 4, title, text)

        self._overallTotal = total
        self._overallState = -1
        self._overallFactor = 1
        self._overallProgressSubject = None

        self._currentTotal = 100
        self._currentState = -1
        self._currentFactor = 1
        self._currentProgressSubject = None

        self._width = width
        self._height = height

        self._gridForm = GridForm(self._ui.getScreen(),
                                  title.encode(encoding, 'replace'), 1, 3)
        self._currentScale = Scale(self._width, self._currentTotal)
        self._overallScale = Scale(self._width, self._overallTotal)

        self._gridForm.add(self._textbox, 0, 0)
        self._gridForm.add(self._currentScale, 0, 1)
        self._gridForm.add(self._overallScale, 0, 2)

        self._ui.getScreen().pushHelpLine("")
コード例 #21
0
 def hostControlSafe_fireEvent(self, event, hostIds=[]):
     if not hostIds:
         raise BackendMissingDataError(u"No matching host ids found")
     event = forceUnicode(event)
     hostIds = self._context.host_getIdents(id=hostIds,
                                            returnType='unicode')  # pylint: disable=maybe-no-member
     return self._opsiclientdRpc(hostIds=hostIds,
                                 method='fireEvent',
                                 params=[event])
コード例 #22
0
    def __init__(self,
                 smtphost=u'localhost',
                 smtpport=25,
                 subject=u'opsi product updater',
                 sender=u'',
                 receivers=[]):
        super(EmailNotifier, self).__init__()

        self.receivers = forceUnicodeList(receivers)
        if not self.receivers:
            raise ValueError(u"List of mail recipients empty")
        self.smtphost = forceUnicode(smtphost)
        self.smtpport = forceInt(smtpport)
        self.sender = forceUnicode(sender)
        self.subject = forceUnicode(subject)
        self.username = None
        self.password = None
        self.useStarttls = False
コード例 #23
0
 def hostControlSafe_showPopup(self, message, hostIds=[]):
     if not hostIds:
         raise BackendMissingDataError(u"No matching host ids found")
     message = forceUnicode(message)
     hostIds = self._context.host_getIdents(id=hostIds,
                                            returnType='unicode')  # pylint: disable=maybe-no-member
     return self._opsiclientdRpc(hostIds=hostIds,
                                 method='showPopup',
                                 params=[message])
コード例 #24
0
ファイル: Timeline.py プロジェクト: opsi-org/opsiclientd
    def addEvent(self,
                 title,
                 description='',
                 isError=False,
                 category=None,
                 durationEvent=False,
                 start=None,
                 end=None):  # pylint: disable=too-many-arguments
        if self._stopped:
            return -1

        with self._db_lock, self._sql.session() as session:
            try:
                if category:
                    category = forceUnicode(category)
                if not start:
                    start = timestamp()
                start = forceOpsiTimestamp(start)

                if end:
                    end = forceOpsiTimestamp(end)
                    durationEvent = True

                event = {
                    'title': forceUnicode(title),
                    'category': category,
                    'description': forceUnicode(description),
                    'isError': forceBool(isError),
                    'durationEvent': forceBool(durationEvent),
                    'start': start,
                    'end': end,
                }
                try:
                    return self._sql.insert(session, 'EVENT', event)
                except sqlite3.DatabaseError as db_error:
                    logger.error(
                        "Failed to add event '%s': %s, recreating database",
                        title, db_error)
                    self._sql.delete_db()
                    self._createDatabase(delete_existing=True)
                    return self._sql.insert(session, 'EVENT', event)
            except Exception as add_error:  # pylint: disable=broad-except
                logger.error("Failed to add event '%s': %s", title, add_error)
        return -1
コード例 #25
0
ファイル: Session.py プロジェクト: mpice-mn/python-opsi
 def __init__(self,
              sessionName=u'OPSISID',
              sessionMaxInactiveInterval=120,
              maxSessionsPerIp=0,
              sessionDeletionTimeout=60):
     self.sessionName = forceUnicode(sessionName)
     self.sessionMaxInactiveInterval = forceInt(sessionMaxInactiveInterval)
     self.maxSessionsPerIp = forceInt(maxSessionsPerIp)
     self.sessionDeletionTimeout = forceInt(sessionDeletionTimeout)
     self.sessions = {}
コード例 #26
0
ファイル: HostControl.py プロジェクト: mpice-mn/python-opsi
    def run(self):
        self.started = time.time()
        timeout = self.hostControlBackend._hostRpcTimeout
        if timeout < 0:
            timeout = 0

        try:
            query = toJson({
                'id': 1,
                'method': self.method,
                'params': self.params
            }).encode('utf-8')

            connection = HTTPSConnection(host=self.address,
                                         port=self.hostPort,
                                         timeout=timeout)
            with closingConnection(connection) as connection:
                non_blocking_connect_https(connection, timeout)
                connection.putrequest('POST', '/opsiclientd')
                connection.putheader('User-Agent', self._USER_AGENT)
                connection.putheader('content-type', 'application/json')
                connection.putheader('content-length', str(len(query)))
                auth = u'{0}:{1}'.format(self.username, self.password)
                connection.putheader(
                    'Authorization',
                    'Basic ' + base64.b64encode(auth.encode('latin-1')))
                connection.endheaders()
                connection.send(query)

                response = connection.getresponse()
                response = response.read()
                response = fromJson(unicode(response, 'utf-8'))

                if response and isinstance(response, dict):
                    self.error = response.get('error')
                    self.result = response.get('result')
                else:
                    self.error = u"Bad response from client: %s" % forceUnicode(
                        response)
        except Exception as e:
            self.error = forceUnicode(e)
        finally:
            self.ended = time.time()
コード例 #27
0
    def productOnClient_deleteObjects(self, productOnClients):
        errors = []
        for productOnClient in productOnClients:
            try:
                self._updateByProductOnClient(productOnClient)
            except Exception as error:
                errors.append(forceUnicode(error))

        if errors:
            raise RuntimeError(u', '.join(errors))
コード例 #28
0
ファイル: Opsirc.py プロジェクト: mpice-mn/python-opsi
def _parseConfig(filename):
    config = {}
    with codecs.open(filename, mode='r', encoding='utf-8') as opsircfile:
        for line in opsircfile:
            line = line.strip()
            if line.startswith(('#', ';')) or not line:
                continue

            try:
                key, value = line.split('=', 1)
            except ValueError:
                logger.debug2(u"Unable to split line {!r}".format(line))
                continue

            key = key.strip()
            value = value.strip()

            if not value:
                logger.warning(
                    "There is no value for {} in opsirc file {!r}, skipping.",
                    key, filename)
                continue

            if key == 'address':
                config[key] = forceUrl(value)
            elif key == 'username':
                config[key] = forceUnicode(value)
            elif key == 'password':
                value = forceUnicode(value)
                logger.addConfidentialString(value)
                config[key] = value
            elif key == 'password file':
                passwordFilePath = os.path.expanduser(value)
                value = _readPasswordFile(passwordFilePath)
                logger.addConfidentialString(value)
                config['password'] = value
            else:
                logger.debug(u"Ignoring unknown key {}", key)

    logger.debug("Found the following usable keys in {!r}: {}", filename,
                 ", ".join(config.keys()))
    return config
コード例 #29
0
    def __init__(self, ui, width=0, height=0, title=_(u'Title'), text=u''):
        MessageObserver.__init__(self)

        try:
            self._ui = ui

            width = forceInt(width)
            height = forceInt(height)
            title = forceUnicode(title)
            text = forceUnicode(text)

            self._visible = False
            self._title = title
            self._text = text

            for string in self._ui.confidentialStrings:
                self._text = self._text.replace(string,
                                                u'*** confidential ***')

            if (width <= 0):
                width = self._ui.getScreen().width - 7
            if (height <= 0):
                height = self._ui.getScreen().height - 7

            self._width = width
            self._height = self._textHeight = height

            self._gridForm = GridForm(self._ui.getScreen(),
                                      title.encode(encoding, 'replace'), 1, 1)
            self._textbox = Textbox(self._width,
                                    self._height,
                                    self._text.encode(encoding, 'replace'),
                                    scroll=0,
                                    wrap=1)
            self._gridForm.add(self._textbox, 0, 0)

            # help line
            self._ui.getScreen().pushHelpLine(u"")
        except Exception as e:
            self._ui.exit()
            logger.logException(e)
            raise
コード例 #30
0
def replaceSpecialHTMLCharacters(text):
    return forceUnicode(text)\
     .replace(u'\r', u'')\
     .replace(u'\t', u'   ')\
     .replace(u'&', u'&amp;')\
     .replace(u'"', u'&quot;')\
     .replace(u"'", u'&apos;')\
     .replace(u' ', u'&nbsp;')\
     .replace(u'<', u'&lt;')\
     .replace(u'>', u'&gt;')\
     .replace(u'\n', u'<br />\n')
コード例 #31
0
ファイル: Postgres.py プロジェクト: kochd/opsi-postgres
	def __init__(self, **kwargs):

		self._address                   = u'localhost'
		self._username                  = u'opsi'
		self._password                  = u'opsi'
		self._database                  = u'opsi'
		self._databaseCharset           = 'utf8'
		self._connectionPoolSize        = 20
		self._connectionPoolMaxOverflow = 10
		self._connectionPoolTimeout     = 30

		# Parse arguments
		for (option, value) in kwargs.items():
			option = option.lower()
			if option == 'address':
				self._address = forceUnicode(value)
			elif option == 'username':
				self._username = forceUnicode(value)
			elif option == 'password':
				self._password = forceUnicode(value)
			elif option == 'database':
				self._database = forceUnicode(value)
			elif option == 'databasecharset':
				self._databaseCharset = str(value)
			elif option == 'connectionpoolsize':
				self._connectionPoolSize = forceInt(value)
			elif option == 'connectionpoolmaxoverflow':
				self._connectionPoolMaxOverflow = forceInt(value)
			elif option == 'connectionpooltimeout':
				self._connectionPoolTimeout = forceInt(value)

		self._transactionLock = threading.Lock()
		self._pool = None

		self._createConnectionPool()
		logger.debug(u'PgSQL created: %s' % self)
コード例 #32
0
ファイル: Postgres.py プロジェクト: kochd/opsi-postgres
	def execute(self, query, conn=None, cursor=None):
		query = query.replace(' GROUP ',' "GROUP" ')

		res = None
		needClose = False
		if not conn or not cursor:
			(conn, cursor) = self.connect()
			needClose = True
		try:
			query = forceUnicode(query)
			logger.debug2(u"SQL query: %s" % query)
			res = cursor.execute(query)
			if self.doCommit:
				conn.commit()
		finally:
			if needClose:
				self.close(conn, cursor)
		return res