Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
 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()
Ejemplo n.º 4
0
 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
Ejemplo n.º 5
0
 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
Ejemplo n.º 6
0
 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
Ejemplo n.º 7
0
 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"]
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
    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, ))