Source code for goblin.gremlin.table

from __future__ import unicode_literals
from goblin._compat import integer_types, float_types, string_types, iteritems
from goblin.tools import LazyImportClass
from goblin.exceptions import GoblinException

# avoid circular import
element = LazyImportClass('goblin.models.element.Element')
numeric_types = (integer_types + float_types)


[docs]class Row(object): """ Row A row represent a table row, from which it's columns can be accessed like a tuple or dict. Rows are read-only and accept elements or dicts with as initializers as a result of a GremlinTable query. Also the . getattr notation can be used to access elements Example: row = Row({'person': Friend.create(....), 'myval': 3}) print "{}:{} - {}".format(row.friend_edge.nickname, row.person.name, row.myval) """ __ready = False __okay_setattr = '_Row__' def __init__(self, data): # this class is cached, so no performance hit here. if isinstance(data, element.klass): data = data.as_dict() elif not isinstance(data, dict): raise GoblinException("Result data is not tabular!") self.__data = data for k, v in data.items(): if isinstance(k, string_types): setattr(self, k, v) self.__position = 0 self.__ready = True def __getslice__(self, i, j): return list(self.__data.values())[i:j] def __setslice__(self, i, j, sequence): raise GoblinException("Row is not editable") def __delslice__(self, i, j): raise GoblinException("Row is not editable") def __getitem__(self, item): if isinstance(item, numeric_types) or isinstance(item, slice): return list(self.__data.values())[item] return self.__data[item] def __setitem__(self, key, value): raise GoblinException("Row is not editable") def __delitem__(self, key): raise GoblinException("Row is not editable") def __setattr__(self, key, value): # only allow 'private' fields to be set if not self.__ready or key.startswith(self.__okay_setattr): super(Row, self).__setattr__(key, value) else: raise GoblinException("Row is not editable") def __delattr__(self, item): raise GoblinException("Row is not editable") def __iter__(self): return self def __next__(self): return self.next()
[docs] def keys(self): return self.__data.keys()
[docs] def values(self): return self.__data.values()
[docs] def items(self): return self.__data.items()
[docs] def iteritems(self): for k, v in self.__data.items(): yield k, v
[docs] def next(self): if self.__position == len(self.__data): self.__position = 0 raise StopIteration() tmp = list(self.__data.values())[self.__position] self.__position += 1 return tmp
def __len__(self): return len(self.__data) def __repr__(self): result = "{}(".format(self.__class__.__name__) for k, v in iteritems(self.__data): result += "{}={}, ".format(k, v) result = result.rstrip(", ") result += ")" return result def __eq__(self, other): if not isinstance(other, self.__class__): return False else: return self.__data == other._Row__data
[docs]class Table(object): """ Table A table accepts the results of a GremlinTable in it's constructor. It can be iterated over like a normal list, but within the rows the dictionaries are accessible via .notation For example: # returns a table of people & my friend edge to them # the edge contains my nickname for that person friends = goblin.gremlin.GremlinTable() def get_friends_and_my_nickname(self): result = self.friends() for i in result: print "{}:{}".format(i.friend_edge.nickname, i.person.name) """ def __init__(self, gremlin_result): if gremlin_result == [[]]: gremlin_result = [] self.__gremlin_result = gremlin_result self.__position = 0 def __getitem__(self, item): """ Returns an enhanced dictionary """ return Row(self.__gremlin_result[item]) def __setitem__(self, key, value): raise GoblinException("Cannot edit Table result") def __delitem__(self, key): raise GoblinException("Cannot edit Table result") def __getslice__(self, i, j): return [Row(r) for r in self.__gremlin_result[i:j]] def __setslice__(self, i, j, sequence): raise GoblinException("Cannot edit Table result") def __delslice__(self, i, j): raise GoblinException("Cannot edit Table result") def __iter__(self): return self def __next__(self): return self.next()
[docs] def next(self): if self.__position == len(self.__gremlin_result): self.__position = 0 raise StopIteration() tmp = self.__gremlin_result[self.__position] self.__position += 1 return Row(tmp)
def __len__(self): return len(self.__gremlin_result) def __repr__(self): return '{}(rows={})'.format( self.__class__.__name__, len(self.__gremlin_result))
__all__ = ['Table', 'Row']