| 1 | from .manager import Manager |
| 2 | from .fields import Field, IntField |
| 3 | from .exceptions import * |
| 4 | |
| 5 | |
| 6 | class Parser: |
| 7 | id = IntField() |
| 8 | objects = Manager() |
| 9 | |
| 10 | class Meta: |
| 11 | unique_together = [] |
| 12 | |
| 13 | def __init__(self, **kwargs): |
| 14 | self.unique_fields = [] |
| 15 | for key, val in self.field_items(): |
| 16 | if val.unique: |
| 17 | self.unique_fields.append(key) |
| 18 | if val.null: |
| 19 | kwargs[key] = kwargs.get(key) |
| 20 | if val.default: |
| 21 | if type(val.default) != val.type: |
| 22 | raise TypeError( |
| 23 | f'{key} default should be of type {val.type}') |
| 24 | if not kwargs.get(key): |
| 25 | kwargs[key] = val.default |
| 26 | self.objects.set_cls(type(self)) |
| 27 | missing_fields = set(self.fields())-set(kwargs) |
| 28 | if 'id' not in missing_fields: |
| 29 | raise CreateWithIdParseError(self) |
| 30 | missing_fields = missing_fields-{'id'} |
| 31 | if missing_fields: |
| 32 | raise MissingFieldsParseError(self, missing_fields) |
| 33 | extra_fields = set(kwargs)-set(self.fields()) |
| 34 | if extra_fields: |
| 35 | raise ExtraFieldsParseError(self, extra_fields) |
| 36 | kwargs['id'] = self.objects.count() |
| 37 | for name, field in self.field_items(): |
| 38 | val = kwargs[name] |
| 39 | if type(val) == str: |
| 40 | setattr(self, name, field.convert(val)) |
| 41 | else: |
| 42 | setattr(self, name, val) |
| 43 | |
| 44 | def save(self): |
| 45 | self.objects.raise_unique_constraints(self) |
| 46 | self.objects.append(self) |
| 47 | |
| 48 | def fields(self): |
| 49 | |
| 50 | fields = {} |
| 51 | for attr in dir(self): |
| 52 | item = getattr(self, attr) |
| 53 | if issubclass(type(item), Field): |
| 54 | fields[attr] = item |
| 55 | return fields |
| 56 | |
| 57 | def field_items(self): |
| 58 | |
| 59 | return self.fields().items() |
| 60 | |
| 61 | def __eq__(self, obj): |
| 62 | matched = {key: False for key in set(self.__dict__)-{'id'}} |
| 63 | for key in matched: |
| 64 | if self.__dict__[key] == obj.__dict__[key]: |
| 65 | return True |
| 66 | return False not in matched.values() |