def pull(self, n, qid, records): """ Enqueue a PULL message. :param n: number of records to pull (-1 means all) :param qid: the query for which to pull records (-1 means the query immediately preceding) :param records: list-like container into which records may be appended :return: :class:`.QueryResponse` object """ v = self.bolt_version if v >= 4: args = {"n": n} if qid >= 0: args["qid"] = qid log.debug("C: PULL %r", args) self.requests.append(Structure(CLIENT[v]["PULL"], args)) elif n >= 0 or qid >= 0: raise ProtocolError("Reactive PULL is not available in " "Bolt v%d" % v) else: log.debug("C: PULL_ALL") self.requests.append(Structure(CLIENT[v]["PULL_ALL"])) response = QueryResponse(v, records) self.responses.append(response) return response
def run(self, statement, parameters=None, metadata=None): parameters = parameters or {} metadata = metadata or {} if self.bolt_version >= 3: log.debug("C: RUN %r %r %r", statement, parameters, metadata) run = Structure(CLIENT[self.bolt_version]["RUN"], statement, parameters, metadata) elif metadata: raise ProtocolError("RUN metadata is not available in Bolt v%d" % self.bolt_version) else: log.debug("C: RUN %r %r", statement, parameters) run = Structure(CLIENT[self.bolt_version]["RUN"], statement, parameters) self.requests.append(run) response = QueryResponse(self.bolt_version) self.responses.append(response) return response
def reset(self): log.debug("C: RESET") self.requests.append(Structure(CLIENT[self.bolt_version]["RESET"])) self.send_all() response = Response(self.bolt_version) self.responses.append(response) while not response.complete(): self.fetch_one()
def rollback(self): if self.bolt_version >= 3: log.debug("C: ROLLBACK") self.requests.append(Structure(CLIENT[self.bolt_version]["ROLLBACK"])) else: raise ProtocolError("ROLLBACK is not available in Bolt v%d" % self.bolt_version) response = QueryResponse(self.bolt_version) self.responses.append(response) return response
def commit(self): if self.bolt_version >= 3: log.debug("C: COMMIT") self.requests.append(Structure(CLIENT[self.bolt_version]["COMMIT"])) else: raise ProtocolError("COMMIT is not available in Bolt v%d" % self.bolt_version) response = QueryResponse(self.bolt_version) self.responses.append(response) return response
def begin(self, metadata=None): metadata = metadata or {} if self.bolt_version >= 3: log.debug("C: BEGIN %r", metadata) self.requests.append(Structure(CLIENT[self.bolt_version]["BEGIN"], metadata)) else: raise ProtocolError("BEGIN is not available in Bolt v%d" % self.bolt_version) response = QueryResponse(self.bolt_version) self.responses.append(response) return response
def __init__(self, s, bolt_version, auth, user_agent=None): self.socket = s self.address = AddressList([self.socket.getpeername()]) self.bolt_version = bolt_version log.debug("Opened connection to «%s» using Bolt v%d", self.address, self.bolt_version) self.requests = [] self.responses = [] try: user, password = auth except (TypeError, ValueError): user, password = "******", "" if user_agent is None: user_agent = self.default_user_agent() if bolt_version >= 3: args = { "scheme": "basic", "principal": user, "credentials": password, "user_agent": user_agent, } log.debug("C: HELLO %r" % dict(args, credentials="...")) request = Structure(CLIENT[self.bolt_version]["HELLO"], args) else: auth_token = { "scheme": "basic", "principal": user, "credentials": password, } log.debug("C: INIT %r %r", user_agent, dict(auth_token, credentials="...")) request = Structure(CLIENT[self.bolt_version]["INIT"], user_agent, auth_token) self.requests.append(request) response = Response(self) self.responses.append(response) self.send_all() self.fetch_all() self.server_agent = response.metadata["server"]
def discard(self, n, qid): """ Enqueue a DISCARD message. :param n: number of records to discard (-1 means all) :param qid: the query for which to discard records (-1 means the query immediately preceding) :return: :class:`.QueryResponse` object """ v = self.bolt_version if v >= 4: args = {"n": n} if qid >= 0: args["qid"] = qid log.debug("C: DISCARD %r", args) self.requests.append(Structure(CLIENT[v]["DISCARD"], args)) elif n >= 0 or qid >= 0: raise ProtocolError("Reactive DISCARD is not available in " "Bolt v%d" % v) else: log.debug("C: DISCARD_ALL") self.requests.append(Structure(CLIENT[v]["DISCARD_ALL"])) response = QueryResponse(v) self.responses.append(response) return response
def reset(self): log.debug("C: RESET") self.requests.append(Structure(CLIENT[self.bolt_version]["RESET"])) self.send_all() response = Response(self) self.responses.append(response)
def handle_request(self, sock): v = self.peers[sock].bolt_version chunked_data = b"" message_data = b"" chunk_size = -1 debug = [] while chunk_size != 0: chunk_header = sock.recv(2) if len(chunk_header) == 0: self.stop() return chunked_data += chunk_header chunk_size, = raw_unpack(UINT_16, chunk_header) if chunk_size > 0: chunk = sock.recv(chunk_size) chunked_data += chunk message_data += chunk else: chunk = b"" debug.append(" [%s] %s" % (h(chunk_header), h(chunk))) request = unpack(message_data) if self.script.match_request(request): # explicitly matched log.debug("C: %s", message_repr(v, request)) elif self.script.match_auto_request(request): # auto matched log.debug("C! %s", message_repr(v, request)) else: # not matched if self.script.lines: expected = message_repr(v, self.script.lines[0].message) else: expected = "END OF SCRIPT" log.debug("C: %s", message_repr(v, request)) log.error("Message mismatch (expected <%s>, " "received <%s>)", expected, message_repr(v, request)) self.stop() raise SystemExit(EXIT_OFF_SCRIPT) responses = self.script.match_responses() if not responses and self.script.match_auto_request(request): # These are hard-coded and therefore not very future-proof. if request.tag in (CLIENT[v].get("HELLO"), CLIENT[v].get("INIT")): responses = [ Structure( SERVER[v]["SUCCESS"], {"server": server_agents.get(v, "Neo4j/9.99.999")}) ] elif request.tag == CLIENT[v].get("GOODBYE"): log.debug("S: <EXIT>") self.stop() raise SystemExit(EXIT_OK) elif request.tag == CLIENT[v]["RUN"]: responses = [Structure(SERVER[v]["SUCCESS"], {"fields": []})] else: responses = [Structure(SERVER[v]["SUCCESS"], {})] for response in responses: if isinstance(response, Structure): data = pack(response) self.send_chunk(sock, data) self.send_chunk(sock) log.debug( "S: %s", message_repr(v, Structure(response.tag, *response.fields))) elif isinstance(response, ExitCommand): self.stop() raise SystemExit(EXIT_OK) else: raise RuntimeError("Unknown response type %r" % (response, ))