forked from APrioriInvestments/typed_python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathobject.py
More file actions
151 lines (105 loc) · 4.64 KB
/
Copy pathobject.py
File metadata and controls
151 lines (105 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# Copyright 2018 Braxton Mckee
#
# 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 object_database.view import _cur_view, coerce_value
from typed_python.hash import sha_hash
from typed_python import NamedTuple
_base = NamedTuple(_identity=str)
class DatabaseObject(_base):
__types__ = None
__schema__ = None
def __ne__(self, other):
return not (self == other)
def __eq__(self, other):
if not isinstance(other, DatabaseObject):
return False
if not type(self) is type(other):
return False
return self._identity == other._identity
def __hash__(self):
return hash(self._identity)
@classmethod
def fromIdentity(cls, identity):
assert isinstance(identity, str), type(identity)
cls.__schema__.freeze()
return _base.__new__(cls, _identity=identity)
def __new__(cls, *args, **kwds):
if args and len(args) == 1 and isinstance(args[0], cls):
return args[0]
if not hasattr(_cur_view, "view"):
raise Exception("Please create new objects from within a transaction.")
if args:
raise Exception("%s cannot be created with positional arguments." % cls)
return _cur_view.view._new(cls, kwds)
def __repr__(self):
return type(self).__qualname__ + "(" + self._identity[:8] + ")"
@classmethod
def lookupOne(cls, **kwargs):
if not hasattr(_cur_view, "view"):
raise Exception("Please lookup in indices from within a transaction.")
return _cur_view.view.indexLookupOne(cls, **kwargs or {" exists": True})
@classmethod
def lookupAll(cls, **kwargs):
if not hasattr(_cur_view, "view"):
raise Exception("Please lookup in indices from within a transaction.")
return _cur_view.view.indexLookup(cls, **kwargs or {" exists": True})
@classmethod
def lookupAny(cls, **kwargs):
if not hasattr(_cur_view, "view"):
raise Exception("Please lookup in indices from within a transaction.")
return _cur_view.view.indexLookupAny(cls, **kwargs or {" exists": True})
def exists(self):
if not hasattr(_cur_view, "view"):
raise Exception("Please access properties from within a view or transaction.")
return _cur_view.view._exists(self, self._identity)
def __getattr__(self, name):
return self.get_field(name)
def get_field(self, name):
if name not in self.__types__:
raise AttributeError("Object of type %s has no field '%s'" % (type(self).__qualname__, name))
if not hasattr(_cur_view, "view"):
raise Exception("Please access properties from within a view or transaction.")
return _cur_view.view._get(self, self._identity, name, self.__types__[name])
def __setattr__(self, name, val):
if name not in self.__types__:
raise AttributeError("Database object of type %s has no attribute %s" % (type(self).__qualname__, name))
if not hasattr(_cur_view, "view"):
raise Exception("Please access properties from within a view or transaction.")
coerced_val = coerce_value(val, self.__types__[name])
_cur_view.view._set(self, self._identity, name, self.__types__[name], coerced_val)
def delete(self):
_cur_view.view._delete(self, self._identity, self.__types__.keys())
@classmethod
def _define(cls, **types):
assert cls.__types__ is None, "'{}' already defined".format(cls)
assert isinstance(types, dict)
cls.__types__ = types
return cls
@classmethod
def to_json(cls, obj):
return obj.__dict__['_identity']
@classmethod
def from_json(cls, obj):
assert isinstance(obj, str), obj
return cls.fromIdentity(obj)
def __sha_hash__(self):
return sha_hash(self._identity) + sha_hash(type(self).__qualname__)
class Indexed:
def __init__(self, obj):
assert isinstance(obj, type)
self.obj = obj
class Index:
def __init__(self, *names):
self.names = names
def __call__(self, instance):
return tuple(getattr(instance, x) for x in self.names)