def cmd(self, operation): """ put a mapi command on the line""" logger.debug("executing command %s" % operation) if self.state != STATE_READY: raise ProgrammingError self._putblock(operation) response = self._getblock() if not len(response): return "" elif response.startswith(MSG_OK): return response[3:].strip() or "" if response == MSG_MORE: # tell server it isn't going to get more return self.cmd("") if response[0] in [MSG_Q, MSG_HEADER, MSG_TUPLE]: return response elif response[0] == MSG_ERROR: raise OperationalError(response[1:]) elif (self.language == 'control' and not self.hostname): if response.startswith("OK"): return response[2:].strip() or "" else: return response else: raise ProgrammingError("unknown state: %s" % response)
def cmd(self, operation, f=None): """ put a mapi command on the line""" logger.debug("executing command %s" % operation) if self.state != STATE_READY: raise ProgrammingError while True: self._putblock(operation) response = self._getblock() if not len(response): return "" elif response.startswith(MSG_OK): return response[3:].strip() or "" elif response == MSG_MORE: if f is not None: operation = f.read(4096) if operation != "": continue return self.cmd("") elif response[0] in [MSG_Q, MSG_HEADER, MSG_TUPLE]: return response elif response[0] == MSG_ERROR: raise OperationalError(response[1:]) elif (self.language == 'control' and not self.hostname): if response.startswith("OK"): return response[2:].strip() or "" else: return response else: raise ProgrammingError("unknown state: %s" % response)
def __getbytes(self, bytes_): """Read an amount of bytes from the socket""" result = StringIO() count = bytes_ while count > 0: recv = self.socket.recv(count) if len(recv) == 0: raise OperationalError("Server closed connection") count -= len(recv) result.write(recv) return result.getvalue()
def _login(self, iteration=0): """ Reads challenge from line, generate response and check if everything is okay """ challenge = self._getblock() response = self._challenge_response(challenge) self._putblock(response) prompt = self._getblock().strip() if len(prompt) == 0: # Empty response, server is happy pass elif prompt == MSG_OK: pass elif prompt.startswith(MSG_INFO): logger.info("%s" % prompt[1:]) elif prompt.startswith(MSG_ERROR): logger.error(prompt[1:]) raise DatabaseError(prompt[1:]) elif prompt.startswith(MSG_REDIRECT): # a redirect can contain multiple redirects, for now we only use # the first redirect = prompt.split()[0][1:].split(':') if redirect[1] == "merovingian": logger.debug("restarting authentication") if iteration <= 10: self._login(iteration=iteration + 1) else: raise OperationalError("maximal number of redirects " "reached (10)") elif redirect[1] == "monetdb": self.hostname = redirect[2][2:] self.port, self.database = redirect[3].split('/') self.port = int(self.port) logger.info("redirect to monetdb://%s:%s/%s" % (self.hostname, self.port, self.database)) self.socket.close() self.connect(hostname=self.hostname, port=self.port, username=self.username, password=self.password, database=self.database, language=self.language) else: raise ProgrammingError("unknown redirect: %s" % prompt) else: raise ProgrammingError("unknown state: %s" % prompt)
def parse_statusline(line): """ parses a sabdb format status line. Support v1 and v2. """ if line.startswith("="): line = line[1:] if not line.startswith('sabdb:'): raise OperationalError('wrong result received') code, prot_version, rest = line.split(":", 2) if prot_version not in ["1", "2"]: raise InterfaceError("unsupported sabdb protocol") else: prot_version = int(prot_version) subparts = rest.split(',') sub_iter = iter(subparts) info = {} info['name'] = next(sub_iter) info['path'] = next(sub_iter) info['locked'] = next(sub_iter) == "1" info['state'] = int(next(sub_iter)) info['scenarios'] = next(sub_iter).split("'") if prot_version == 1: next(sub_iter) info['start_counter'] = int(next(sub_iter)) info['stop_counter'] = int(next(sub_iter)) info['crash_counter'] = int(next(sub_iter)) info['avg_uptime'] = int(next(sub_iter)) info['max_uptime'] = int(next(sub_iter)) info['min_uptime'] = int(next(sub_iter)) last_crash = int(next(sub_iter)) info['last_crash'] = dt.fromtimestamp( int(last_crash)) if last_crash >= 0 else None info['last_start'] = dt.fromtimestamp(int(next(sub_iter))) if prot_version > 1: value = int(next(sub_iter)) if value > -1: info['last_stop'] = dt.fromtimestamp(value) else: info['last_stop'] = None info['crash_avg1'] = next(sub_iter) == "1" info['crash_avg10'] = float(next(sub_iter)) info['crash_avg30'] = float(next(sub_iter)) return info
def _getbytes(self, bytes_): """Read an amount of bytes from the socket""" result = BytesIO() count = bytes_ while count > 0: if self.var_async: parent = greenlet.getcurrent().parent # Switch to parent greenlet if var_async and no data ready to read while parent and not select([self.socket.fileno()], [], [], 0)[0]: parent.switch(POLL_READ) recv = self.socket.recv(count) if len(recv) == 0: self.connectionclosed = True raise OperationalError("Server closed connection") count -= len(recv) result.write(recv) return result.getvalue()
def __getbytes(self, bytes): """Read an amount of bytes from the socket""" result = StringIO() count = bytes try: while count > 0: ready_to_read = [] while len(ready_to_read) == 0: ready_to_read, _, _ = select.select([self.socket], [], [], 0) if len(ready_to_read) > 0: recv = ready_to_read[0].recv(bytes, flags) if recv == '': self.disconnect() raise socket.error(_, 'Connection closed unexpectedly') logger.debug("II: package size: %i payload: %s" % (len(recv), recv)) count -= len(recv) result.write(recv) except socket.error, error: raise OperationalError(error[1])
def parse_statusline(line): """ parses a sabdb format status line. Support v1 and v2. """ if not line.startswith('=sabdb:'): raise OperationalError('wrong result recieved') prot_version, rest = line.split(":", 2)[1:] if prot_version not in ["1", "2"]: raise InterfaceError("unsupported sabdb protocol") else: prot_version = int(prot_version) subparts = rest.split(',') sub_iter = iter(subparts) info = {} info['name'] = sub_iter.__next__() info['path'] = sub_iter.__next__() info['locked'] = sub_iter.__next__() == "1" info['state'] = int(sub_iter.__next__()) info['scenarios'] = sub_iter.__next__().split("'") if prot_version == 1: sub_iter.__next__() info['start_counter'] = int(sub_iter.__next__()) info['stop_counter'] = int(sub_iter.__next__()) info['crash_counter'] = int(sub_iter.__next__()) info['avg_uptime'] = int(sub_iter.__next__()) info['max_uptime'] = int(sub_iter.__next__()) info['min_uptime'] = int(sub_iter.__next__()) info['last_crash'] = int(sub_iter.__next__()) info['last_start'] = int(sub_iter.__next__()) if prot_version > 1: info['last_stop'] = int(sub_iter.__next__()) info['crash_avg1'] = sub_iter.__next__() == "1" info['crash_avg10'] = float(sub_iter.__next__()) info['crash_avg30'] = float(sub_iter.__next__()) return info
def isempty(result): """ raises an exception if the result is not empty""" if result != "": raise OperationalError(result) else: return True