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 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 convert(data): """ Calls the appropriate convertion function based upon the python type """ try: return mapping[type(data)](data) except KeyError: raise ProgrammingError("type %s not supported as value" % type(data))
def _extract_timezone(data): sign_symbol = data[-6] if sign_symbol == '+': sign = 1 elif sign_symbol == '-': sign = -1 else: raise ProgrammingError("no + or - in %s" % data) return data[:-6], datetime.timedelta(hours=sign * int(data[-5:-3]), minutes=sign * int(data[-2:]))
def convert(data, type_code): """ Calls the appropriate convertion function based upon the python type """ # null values should always be replaced by None type if data == "NULL": return None try: return mapping[type_code](data) except KeyError: raise ProgrammingError("type %s is not supported" % type_code)
def convert(data): """ Return the appropriate convertion function based upon the python type. """ if type(data) in mapping_dict: return mapping_dict[type(data)](data) else: for type_, func in mapping: if issubclass(type(data), type_): return func(data) #if hasattr(data, '__str__'): # return monet_escape raise ProgrammingError("type %s not supported as value" % type(data))
def py_timestamptz(data): """ Returns a python Timestamp where data contains a tz code """ if data.find('+') != -1: (dt, tz) = data.split("+") (tzhour, tzmin) = [int(x) for x in tz.split(':')] elif data.find('-') != -1: (dt, tz) = data.split("-") (tzhour, tzmin) = [int(x) for x in tz.split(':')] tzhour *= -1 tzmin *= -1 else: raise ProgrammingError("no + or - in %s" % data) (datestr, timestr) = dt.split(" ") date = [int(float(x)) for x in datestr.split('-')] time = [int(float(x)) for x in timestr.split(':')] year, month, day = date hour, minute, second = time return Timestamp(year, month, day, hour + tzhour, minute + tzmin, second)