Skip to content

Commit bf91500

Browse files
author
Jeroen van der Heijden
committed
small improvements and handle mod_enum actions
1 parent 75b7a2b commit bf91500

File tree

6 files changed

+113
-36
lines changed

6 files changed

+113
-36
lines changed

README.md

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -657,19 +657,9 @@ When adding a new brick, for example using the following code:
657657
color value: #f00
658658
```
659659

660-
If you do not care about having defined the `Color` class, then you can drop this class and change the
661-
color specification to the plain string `"Enum"`. For example:
660+
If you do not care about the whole `Color` class, then you can just create an empty class like this:
662661

663662
```python
664-
class Brick(Thing):
665-
color = 'Enum'
666-
667-
def on_init(self, *args, **kwars):
668-
super().on_init(*args, **kwars)
669-
print(f'''
670-
Init Brick:
671-
id: {self.id()}
672-
color name: {self.color.name}
673-
color value: {self.color.value}
674-
''')
663+
class Color(Enum):
664+
pass
675665
```

thingsdb/model/collection.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .eventhandler import EventHandler
77
from .thing import Thing
88
from .enum import Enum
9+
from .prop import Prop
910

1011

1112
class Collection(Thing):
@@ -24,6 +25,9 @@ def __init__(self, name=None):
2425
self._id = None
2526
self._types = {} # mapping where keys are type_id
2627
self._enums = {} # mapping where keys are enum_id
28+
self._conv_any = Prop.get_conv('any', klass=Thing, collection=self)
29+
self._conv_thing = Prop.get_conv('thing', klass=Thing, collection=self)
30+
2731
for p in self._props.values():
2832
p.unpack(self)
2933

@@ -138,16 +142,42 @@ def _set_procedure(self, data):
138142
def _update_type(self, data):
139143
self._types[data['type_id']] = tuple(k[0] for k in data['fields'])
140144

141-
def _update_type_add(self, data):
145+
def _upd_type_add(self, data):
142146
self._types[data['type_id']] += data['name'],
143147

144-
def _update_type_del(self, data):
148+
def _upd_type_del(self, data):
145149
type_id, name = data['type_id'], data['name']
146150
t = self._types[type_id]
147-
self._types[type_id] = tuple(p for p in t if p != name)
151+
idx = t.index(name)
152+
t = list(t)
153+
try:
154+
t[idx] = t.pop() # swap remove
155+
except IndexError:
156+
pass
157+
self._types[type_id] = tuple(t)
158+
159+
def _upd_type_ren(self, data):
160+
type_id, name, to = data['type_id'], data['name'], data['to']
161+
t = self._types[type_id]
162+
idx = t.index(name)
163+
t = list(t)
164+
t[idx] = to
165+
self._types[type_id] = tuple(t)
148166

149167
def _update_enum(self, data):
150-
Enum._update_enum(self._enums, data)
168+
Enum._update_enum(self._enums, data, convert=self._conv_any)
169+
170+
def _upd_enum_add(self, data):
171+
Enum._upd_enum_add(self._enums, data, convert=self._conv_any)
172+
173+
def _upd_enum_del(self, data):
174+
Enum._upd_enum_del(self._enums, data)
175+
176+
def _upd_enum_mod(self, data):
177+
Enum._upd_enum_mod(self._enums, data, convert=self._conv_any)
178+
179+
def _upd_enum_ren(self, data):
180+
Enum._upd_enum_ren(self._enums, data)
151181

152182
def _get_enum_member(self, enum_id, idx):
153183
enum = self._enums[enum_id]

thingsdb/model/enum.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ def __init_subclass__(cls, **kwargs):
2020
_enums_lookup[cls._name] = cls
2121

2222
@staticmethod
23-
def _update_enum(enums, data):
23+
def _update_enum(enums, data, convert):
2424
name = data['name']
25-
members = tuple(Member(name, k, v) for k, v in data['members'])
25+
members = [Member(name, k, convert(v)) for k, v in data['members']]
2626

2727
enum = _enums_lookup.get(name)
2828
if enum is not None:
@@ -32,6 +32,53 @@ def _update_enum(enums, data):
3232

3333
enums[data['enum_id']] = members
3434

35+
@staticmethod
36+
def _upd_enum_add(enums, data, convert):
37+
members = enums[data['enum_id']]
38+
name = members[0]._enum_name
39+
member = Member(name, data['name'], convert(data['value']))
40+
members.append(member)
41+
42+
enum = _enums_lookup.get(name)
43+
if enum is not None:
44+
setattr(enum, member.name, member)
45+
46+
@staticmethod
47+
def _upd_enum_del(enums, data):
48+
members = enums[data['enum_id']]
49+
name = members[0]._enum_name
50+
51+
enum = _enums_lookup.get(name)
52+
if enum is not None:
53+
member = members[data['index']]
54+
delattr(enum, member.name)
55+
56+
try:
57+
# swap remove the index
58+
members[data['index']] = members.pop()
59+
except IndexError:
60+
pass
61+
62+
@staticmethod
63+
def _upd_enum_mod(enums, data, convert):
64+
members = enums[data['enum_id']]
65+
name = members[0]._enum_name
66+
member = members[data['index']]
67+
member._value = convert(data['value'])
68+
69+
@staticmethod
70+
def _upd_enum_ren(enums, data):
71+
members = enums[data['enum_id']]
72+
name = members[0]._enum_name
73+
member = members[data['index']]
74+
75+
enum = _enums_lookup.get(name)
76+
if enum is not None:
77+
delattr(enum, member.name)
78+
setattr(enum, data['name'], member)
79+
80+
member._name = data['name']
81+
3582
@classmethod
3683
async def _new_type(cls, client, collection):
3784
if cls._visited > 0:

thingsdb/model/prop.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,9 @@ def unpack(self, collection):
7272
if spec == 'Thing' and cb_type is None:
7373
spec, kwargs['watch'] = 'thing', True
7474

75-
if spec == 'Enum' and cb_type is None:
76-
self.vconv = self.get_conv('enum', collection=collection)
77-
else:
78-
self.vconv = self.get_conv(
79-
spec, is_nillable, **kwargs
80-
if spec == 'any' or spec == 'thing' else {})
75+
self.vconv = self.get_conv(
76+
spec, is_nillable, **kwargs
77+
if spec == 'any' or spec == 'thing' else {})
8178

8279
if self.vconv is None:
8380
assert callable(cb_type), \

thingsdb/model/thing.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,13 @@ class Thing(ThingHash):
4444
__AS_TYPE__ = True
4545

4646
_props = dict()
47-
_any = None
48-
_thing = None
4947
_type_name = None # Only set when __AS_TYPE__ is True
5048
_visited = 0 # For build, 0=not visited, 1=new_type, 2=set_type, 3=build
5149

5250
def __init__(self, collection, id: int):
5351
super().__init__(id)
54-
cls = self.__class__
5552
self._event_id = 0
5653
self._collection = collection
57-
cls._any = Prop.get_conv('any', klass=Thing, collection=collection)
58-
cls._thing = Prop.get_conv('thing', klass=Thing, collection=collection)
5954
collection._register(self)
6055

6156
def __init_subclass__(cls):
@@ -134,7 +129,7 @@ def _job_add(self, pair):
134129
f'while the property is of type `{type(set_)}`')
135130
return
136131

137-
convert = prop.nconv if prop else cls._thing
132+
convert = prop.nconv if prop else self.collection._conv_thing
138133
try:
139134
set_.update((convert(item) for item in v))
140135
except Exception as e:
@@ -177,14 +172,16 @@ def _job_remove(self, pair):
177172

178173
def _job_set(self, pairs):
179174
cls = self.__class__
175+
180176
for k, v in pairs.items():
181177
prop = cls._props.get(k)
182178
if prop:
183179
convert = prop.vconv
184180
elif cls.__STRICT__:
185181
continue
186182
else:
187-
convert = cls._any(v)
183+
convert = self.collection._conv_any
184+
188185
try:
189186
v = convert(v)
190187
except Exception as e:
@@ -219,7 +216,7 @@ def _job_splice(self, pair):
219216
return
220217

221218
index, count, *items = v
222-
convert = prop.nconv if prop else cls._any
219+
convert = prop.nconv if prop else self.collection._conv_any
223220
try:
224221
arr[index:index+count] = (convert(item) for item in items)
225222
except (TypeError, ValueError) as e:
@@ -235,15 +232,27 @@ def _job_del_type(self, data):
235232
pass
236233

237234
def _job_mod_type_add(self, data):
238-
self._collection._update_type_add(data)
235+
self._collection._upd_type_add(data)
239236

240237
def _job_mod_type_del(self, data):
241-
self._collection._update_type_del(data)
238+
self._collection._upd_type_del(data)
242239

243240
def _job_mod_type_mod(self, data):
244241
# we do not care about the specification so simply ignore this event
245242
pass
246243

244+
def _job_mod_enum_add(self, data):
245+
self._collection._upd_enum_add(data)
246+
247+
def _job_mod_enum_del(self, data):
248+
self._collection._upd_enum_del(data)
249+
250+
def _job_mod_enum_mod(self, data):
251+
self._collection._upd_enum_mod(data)
252+
253+
def _job_mod_enum_ren(self, data):
254+
self._collection._upd_enum_ren(data)
255+
247256
def _job_new_procedure(self, data):
248257
self._collection._set_procedure(data)
249258

@@ -268,6 +277,10 @@ def _job_set_type(self, data):
268277
'mod_type_add': _job_mod_type_add,
269278
'mod_type_del': _job_mod_type_del,
270279
'mod_type_mod': _job_mod_type_mod,
280+
'mod_enum_add': _job_mod_enum_add,
281+
'mod_enum_del': _job_mod_enum_del,
282+
'mod_enum_mod': _job_mod_enum_mod,
283+
'mod_enum_ren': _job_mod_enum_ren,
271284
'new_procedure': _job_new_procedure,
272285
'new_type': _job_new_type,
273286
'set_type': _job_set_type,

thingsdb/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.6.0'
1+
__version__ = '0.6.1'

0 commit comments

Comments
 (0)