Skip to content

Commit

Permalink
Embedded Bolt driver package
Browse files Browse the repository at this point in the history
  • Loading branch information
technige committed Dec 31, 2015
1 parent 888b8e3 commit 5fc910d
Show file tree
Hide file tree
Showing 13 changed files with 2,582 additions and 10 deletions.
2 changes: 1 addition & 1 deletion bau
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ LATEST_2_0_VERSION="2.0.4"
LATEST_2_1_VERSION="2.1.5"
LATEST_2_2_VERSION="2.2.7"
LATEST_2_3_VERSION="2.3.1"
LATEST_3_0_VERSION="3.0.0-M01"
LATEST_3_0_VERSION="3.0.0-M02"
LATEST_VERSION=$LATEST_3_0_VERSION

SELF=$0
Expand Down
38 changes: 29 additions & 9 deletions py2neo/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
# limitations under the License.


from io import StringIO
from itertools import chain
from warnings import warn
import webbrowser

from py2neo.compat import integer, string, ustr, xstr, ReprIO
from py2neo import PRODUCT
from py2neo.compat import integer, string, ustr, ReprIO
from py2neo.env import NEO4J_AUTH, NEO4J_URI
from py2neo.http import authenticate, Resource
from py2neo.packages.httpstream.packages.urimagic import URI
from py2neo.packages.neo4j.v1.connection import connect
from py2neo.data import PropertyContainer, coerce_property
from py2neo.util import is_collection, round_robin, version_tuple, \
ThreadLocalWeakValueDictionary, deprecated, relationship_case, snake_case, base62
Expand Down Expand Up @@ -149,17 +150,36 @@ class Graph(object):
__node_labels = None
__relationship_types = None

def __new__(cls, uri=None):
if uri is None:
uri = DBMS().graph.uri.string
if not uri.endswith("/"):
uri += "/"
key = (cls, uri)
resource = None
connection = None

def __new__(cls, *uris):
# Gather all URIs
uri_dict = {"http": [], "bolt": []}
for uri in uris:
uri = URI(uri)
uri_dict.setdefault(uri.scheme, []).append(uri.string)
# Ensure there is at least one HTTP URI available
if not uri_dict["http"]:
uri_dict["http"].append(DBMS().graph.uri.string)
http_uri = uri_dict["http"][0]
# Add a trailing slash if required
if not http_uri.endswith("/"):
http_uri += "/"
# Construct a new instance
key = (cls, http_uri)
try:
inst = cls.__instances[key]
except KeyError:
inst = super(Graph, cls).__new__(cls)
inst.resource = Resource(uri)
inst.uris = uri_dict
inst.resource = Resource(http_uri)
if inst.neo4j_version >= (3,):
if not uri_dict["bolt"]:
uri_dict["bolt"].append("bolt://%s" % inst.resource.uri.host)
bolt_uri = URI(uri_dict["bolt"][0])
inst.connection = connect(bolt_uri.host, bolt_uri.port,
user_agent="/".join(PRODUCT))
cls.__instances[key] = inst
return inst

Expand Down
22 changes: 22 additions & 0 deletions py2neo/packages/neo4j/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

# Copyright (c) 2002-2015 "Neo Technology,"
# Network Engine for Objects in Lund AB [http://neotechnology.com]
#
# This file is part of Neo4j.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from .meta import version as __version__
132 changes: 132 additions & 0 deletions py2neo/packages/neo4j/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

# Copyright (c) 2002-2015 "Neo Technology,"
# Network Engine for Objects in Lund AB [http://neotechnology.com]
#
# This file is part of Neo4j.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from __future__ import unicode_literals

import logging
from argparse import ArgumentParser
from json import loads as json_loads
from sys import stdout, stderr

from .v1.session import GraphDatabase, CypherError


class ColourFormatter(logging.Formatter):
""" Colour formatter for pretty log output.
"""

def format(self, record):
s = super(ColourFormatter, self).format(record)
if record.levelno == logging.CRITICAL:
return "\x1b[31;1m%s\x1b[0m" % s # bright red
elif record.levelno == logging.ERROR:
return "\x1b[33;1m%s\x1b[0m" % s # bright yellow
elif record.levelno == logging.WARNING:
return "\x1b[33m%s\x1b[0m" % s # yellow
elif record.levelno == logging.INFO:
return "\x1b[36m%s\x1b[0m" % s # cyan
elif record.levelno == logging.DEBUG:
return "\x1b[34m%s\x1b[0m" % s # blue
else:
return s


class Watcher(object):
""" Log watcher for debug output.
"""

handlers = {}

def __init__(self, logger_name):
super(Watcher, self).__init__()
self.logger_name = logger_name
self.logger = logging.getLogger(self.logger_name)
self.formatter = ColourFormatter("%(asctime)s %(message)s")

def watch(self, level=logging.INFO, out=stdout):
try:
self.logger.removeHandler(self.handlers[self.logger_name])
except KeyError:
pass
handler = logging.StreamHandler(out)
handler.setFormatter(self.formatter)
self.handlers[self.logger_name] = handler
self.logger.addHandler(handler)
self.logger.setLevel(level)


def main():
parser = ArgumentParser(description="Execute one or more Cypher statements using Bolt.")
parser.add_argument("statement", nargs="+")
parser.add_argument("-u", "--url", default="bolt://localhost", metavar="CONNECTION_URL")
parser.add_argument("-p", "--parameter", action="append", metavar="NAME=VALUE")
parser.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("-s", "--secure", action="store_true")
parser.add_argument("-v", "--verbose", action="count")
parser.add_argument("-x", "--times", type=int, default=1)
parser.add_argument("-z", "--summarize", action="store_true")
args = parser.parse_args()

if args.verbose:
level = logging.INFO if args.verbose == 1 else logging.DEBUG
Watcher("neo4j").watch(level, stderr)

parameters = {}
for parameter in args.parameter or []:
name, _, value = parameter.partition("=")
if value == "" and name in parameters:
del parameters[name]
else:
try:
parameters[name] = json_loads(value)
except ValueError:
parameters[name] = value

driver = GraphDatabase.driver(args.url, secure=args.secure)
session = driver.session()
for _ in range(args.times):
for statement in args.statement:
try:
result = session.run(statement, parameters)
except CypherError as error:
stderr.write("%s: %s\r\n" % (error.code, error.message))
else:
if not args.quiet:
has_results = False
for i, record in enumerate(result):
has_results = True
if i == 0:
stdout.write("%s\r\n" % "\t".join(record.__keys__))
stdout.write("%s\r\n" % "\t".join(map(repr, record)))
if has_results:
stdout.write("\r\n")
if args.summarize:
summary = result.summarize()
stdout.write("Statement : %r\r\n" % summary.statement)
stdout.write("Parameters : %r\r\n" % summary.parameters)
stdout.write("Statement Type : %r\r\n" % summary.statement_type)
stdout.write("Statistics : %r\r\n" % summary.statistics)
stdout.write("\r\n")
session.close()


if __name__ == "__main__":
main()
22 changes: 22 additions & 0 deletions py2neo/packages/neo4j/meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

# Copyright (c) 2002-2015 "Neo Technology,"
# Network Engine for Objects in Lund AB [http://neotechnology.com]
#
# This file is part of Neo4j.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


version = "1.0.0b2"
22 changes: 22 additions & 0 deletions py2neo/packages/neo4j/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

# Copyright (c) 2002-2015 "Neo Technology,"
# Network Engine for Objects in Lund AB [http://neotechnology.com]
#
# This file is part of Neo4j.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from .session import *
from .typesystem import *
Loading

0 comments on commit 5fc910d

Please sign in to comment.