Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated date and unicode handling code. #142

Merged
merged 14 commits into from
Dec 9, 2015
Merged
15 changes: 12 additions & 3 deletions pyorient/ogm/commands.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
from ..utils import to_str


class CreateVertexCommand(object):
def __init__(self, command_text):
self.command_text = command_text

def __str__(self):
return '{}'.format(self.command_text)
return to_str(self.__unicode__())

def __unicode__(self):
return u'{}'.format(self.command_text)


class CreateEdgeCommand(object):
Expand All @@ -12,10 +18,13 @@ def __init__(self, command_text):
self.retries = None

def __str__(self):
return to_str(self.__unicode__())

def __unicode__(self):
if self.retries:
return '{} RETRY {}'.format(self.command_text, self.retries)
return u'{} RETRY {}'.format(self.command_text, self.retries)
else:
return '{}'.format(self.command_text)
return u'{}'.format(self.command_text)

def retry(self, retries):
self.retries = retries
Expand Down
27 changes: 14 additions & 13 deletions pyorient/ogm/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from .query import Query
from .batch import Batch
from .commands import CreateVertexCommand, CreateEdgeCommand
from ..utils import to_unicode

import pyorient
import json
from collections import namedtuple

ServerVersion = namedtuple('orientdb_version', ['major', 'minor', 'build'])
Expand Down Expand Up @@ -308,7 +308,8 @@ def drop_all(self, registry):

def create_vertex(self, vertex_cls, **kwargs):
result = self.client.command(
str(self.create_vertex_command(vertex_cls, **kwargs)))[0]
# to_unicode(str())
to_unicode(self.create_vertex_command(vertex_cls, **kwargs)))[0]

props = result.oRecordData
return vertex_cls.from_graph(self, result._rid,
Expand All @@ -319,18 +320,18 @@ def create_vertex_command(self, vertex_cls, **kwargs):

if kwargs:
db_props = self.props_to_db(vertex_cls, kwargs)
set_clause = ' SET {}'.format(
','.join('{}={}'.format(k,PropertyEncoder.encode(v))
set_clause = u' SET {}'.format(
u','.join(u'{}={}'.format(k,PropertyEncoder.encode(v))
for k,v in db_props.items()))
else:
set_clause = ''
set_clause = u''

return CreateVertexCommand(
'CREATE VERTEX {}{}'.format(class_name, set_clause))
u'CREATE VERTEX {}{}'.format(class_name, set_clause))

def create_edge(self, edge_cls, from_vertex, to_vertex, **kwargs):
result = self.client.command(
str(self.create_edge_command(edge_cls
to_unicode(self.create_edge_command(edge_cls
, from_vertex
, to_vertex
, **kwargs)))[0]
Expand All @@ -342,14 +343,14 @@ def create_edge_command(self, edge_cls, from_vertex, to_vertex, **kwargs):

if kwargs:
db_props = self.props_to_db(vertex_cls, kwargs)
set_clause = ' SET {}'.format(
','.join('{}={}'.format(k,PropertyEncoder.encode(v))
set_clause = u' SET {}'.format(
u','.join(u'{}={}'.format(k,PropertyEncoder.encode(v))
for k,v in db_props.items()))
else:
set_clause = ''

return CreateEdgeCommand(
'CREATE EDGE {} FROM {} TO {}{}'.format(
u'CREATE EDGE {} FROM {} TO {}{}'.format(
class_name, from_vertex._id, to_vertex._id, set_clause))


Expand All @@ -376,13 +377,13 @@ def save_element(self, element_class, props, elem_id):

if props:
db_props = self.props_to_db(element_class, props)
set_clause = ' SET {}'.format(
','.join('{}={}'.format(k,PropertyEncoder.encode(v))
set_clause = u' SET {}'.format(
u','.join(u'{}={}'.format(k,PropertyEncoder.encode(v))
for k,v in db_props.items()))
else:
set_clause = ''

result = self.client.command('UPDATE {}{}'.format(elem_id, set_clause))
result = self.client.command(u'UPDATE {}{}'.format(elem_id, set_clause))
return result and result[0] == b'1'

def query(self, first_entity, *entities):
Expand Down
16 changes: 11 additions & 5 deletions pyorient/ogm/property.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from .operators import Operand, ArithmeticMixin

import sys
import json
import decimal
from datetime import datetime
import datetime


class Property(Operand):
num_instances = 0 # Basis for ordering property instances
Expand Down Expand Up @@ -80,15 +80,21 @@ class PropertyEncoder:
def encode(value):
if isinstance(value, decimal.Decimal):
return repr(str(value))
elif isinstance(value, datetime):
return '"{}"'.format(value)
elif isinstance(value, datetime.datetime) or isinstance(value, datetime.date):
return u'"{}"'.format(value)
elif isinstance(value, str):
return repr(value)
elif sys.version_info[0] < 3 and isinstance(value, unicode):
return repr(value.encode('utf-8'))
return u'"{}"'.format(value.replace('"', '\\"'))
elif value is None:
return 'null'
elif isinstance(value, list) or isinstance(value, set):
return u'[{}]'.format(u','.join([PropertyEncoder.encode(v) for v in value]))
else:
# returning the same object will cause repr(value) to be used

# TODO: perhaps add more conversions, unclear if pyorient works for embedded maps

return value

class Boolean(Property):
Expand Down
40 changes: 20 additions & 20 deletions pyorient/ogm/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def __iter__(self):
g = self._graph
while True:
current_skip = params['skip']
where = 'WHERE {0}'.format(
' and '.join(
where = u'WHERE {0}'.format(
u' and '.join(
[self.rid_lower(current_skip)] + wheres))
select = self.build_select(props, [where] + optional_clauses)

Expand Down Expand Up @@ -144,7 +144,7 @@ def prepare(self, prop_names=None):
optional_clauses = self.build_optional_clauses(params, skip)

wheres = rid_clause + self.build_wheres(params)
where = ['WHERE {0}'.format(' and '.join(wheres))] if wheres else []
where = [u'WHERE {0}'.format(u' and '.join(wheres))] if wheres else []

return props, where, optional_clauses

Expand Down Expand Up @@ -283,60 +283,60 @@ def filter_string(self, expression_root):
if isinstance(left, Operand):
left_str = left.context_name() # Expecting a Property
elif isinstance(left, ArithmeticOperation):
left_str = '({})'.format(self.arithmetic_string(left))
left_str = u'({})'.format(self.arithmetic_string(left))
elif isinstance(left, FunctionWhat):
left_str = self.build_what(left)
else:
raise ValueError(
'Operator {} not supported as a filter'.format(op))

if op is Operator.Equal:
return '{0} = {1}'.format(
return u'{0} = {1}'.format(
left_str, ArgConverter.convert_to(ArgConverter.Value
, right, self))
elif op is Operator.GreaterEqual:
return '{0} >= {1}'.format(
return u'{0} >= {1}'.format(
left_str, ArgConverter.convert_to(ArgConverter.Value
, right, self))
elif op is Operator.Greater:
return '{0} > {1}'.format(
return u'{0} > {1}'.format(
left_str, ArgConverter.convert_to(ArgConverter.Value
, right, self))
elif op is Operator.LessEqual:
return '{0} <= {1}'.format(
return u'{0} <= {1}'.format(
left_str, ArgConverter.convert_to(ArgConverter.Value
, right, self))
elif op is Operator.Less:
return '{0} < {1}'.format(
return u'{0} < {1}'.format(
left_str, ArgConverter.convert_to(ArgConverter.Value
, right, self))
elif op is Operator.NotEqual:
return '{0} <> {1}'.format(
return u'{0} <> {1}'.format(
left_str, ArgConverter.convert_to(ArgConverter.Value
, right, self))
elif op is Operator.Between:
far_right = PropertyEncoder.encode(expression_root.operands[2])
return '{0} BETWEEN {1} and {2}'.format(
left_str, right, far_right)
elif op is Operator.Contains:
return '{0} contains({1})'.format(
return u'{0} contains({1})'.format(
left_str, self.filter_string(right))
elif op is Operator.EndsWith:
return '{0} like \'%{1}\''.format(left_str, right)
return u'{0} like \'%{1}\''.format(left_str, right)
elif op is Operator.Is:
if not right: # :)
return '{0} is null'.format(left_str)
elif op is Operator.Like:
return '{0} like \'{1}\''.format(
return u'{0} like \'{1}\''.format(
left_str, right)
elif op is Operator.Matches:
return '{0} matches \'{1}\''.format(
return u'{0} matches \'{1}\''.format(
left_str, right)
elif op is Operator.StartsWith:
return '{0} like \'{1}%\''.format(
return u'{0} like \'{1}%\''.format(
left_str, right)
else:
return '{0} {1} {2}'.format(
return u'{0} {1} {2}'.format(
self.filter_string(left)
, 'and' if op is Operator.And else 'or'
, self.filter_string(right))
Expand Down Expand Up @@ -406,7 +406,7 @@ def build_props(self, params, prop_names=None, for_iterator=False):

def build_wheres(self, params):
kw_filters = params.get('kw_filters')
kw_where = [' and '.join('{0}={1}'
kw_where = [u' and '.join(u'{0}={1}'
.format(k, PropertyEncoder.encode(v))
for k,v in kw_filters.items())] if kw_filters else []

Expand Down Expand Up @@ -595,16 +595,16 @@ def build_select(self, props, optional_clauses):
# This 'is not None' is important; don't want to implicitly call
# __len__ (which invokes count()) on subquery.
if self._subquery is not None:
src = '({})'.format(self._subquery)
src = u'({})'.format(self._subquery)
else:
src = self.source_name

optional_string = ' '.join(optional_clauses)
if props:
return 'SELECT {} FROM {} {}'.format(
return u'SELECT {} FROM {} {}'.format(
','.join(props), src, optional_string)
else:
return 'SELECT FROM {} {}'.format(src, optional_string)
return u'SELECT FROM {} {}'.format(src, optional_string)

class TempParams(object):
def __init__(self, params, **kwargs):
Expand Down
13 changes: 13 additions & 0 deletions pyorient/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,21 @@ def parse_cluster_position(_cluster_position):

if sys.version < '3':
import codecs

def u(x):
return codecs.unicode_escape_decode(x)[0]

def to_unicode(x):
return str(x).decode('utf-8')

def to_str(x):
return unicode(x).encode('utf-8')
else:
def u(x):
return x

def to_str(x):
return str(x)

def to_unicode(x):
return str(x)
Loading