Added Record superclass for models, handling __repr__ consistently.
[invirt/packages/invirt-database.git] / python / database / record.py
diff --git a/python/database/record.py b/python/database/record.py
new file mode 100755 (executable)
index 0000000..b1b46bb
--- /dev/null
@@ -0,0 +1,56 @@
+class Record(object):
+    _identity_field = None
+    def get(self, field):
+        try:
+            return self.__getattribute__(field)
+        except:
+            return None
+    def _formatField(self, field):
+        v = self.get(field)
+        if callable(v):
+            v = v()
+        if hasattr(v, '__iter__'):
+            if len(v) == 0:
+                return '[]'
+            else:
+                return '[%d x %s]'%(len(v), type(v[0]))
+        else:
+            return repr(v)
+    def _fields(self):
+        ignore = self._ignore()
+        keys = sorted(self.__class__.__dict__.keys())
+        return [(k,self._formatField(k)) for k in keys if k[0]!="_" and k not in ignore]
+    def __repr__(self):
+        classname = self.__class__.__name__
+
+        if self._identity_field:
+            identity = self.__dict__.get(self._identity_field)
+            identity = ' ' + (identity and repr(identity) or 'hash=%d'%hash(self))
+        else:
+            identity = ''
+
+        payload = " ".join(["%s=%s" % (k, v) for k,v in self._fields()])
+        if len(payload) > 0:
+            payload = ": "+payload
+
+        return "<%s%s%s>" % (classname, identity, payload)
+    def _ignore(self):
+        return [self._identity_field, 'c', 'query', 'get']
+
+class FormattableRecord(Record):
+    _format = {}
+    def _formatField(self, field):
+        func = self._format.get(field)
+        if func:
+            return func(self.get(field))
+        else:
+            return super(FormattableRecord, self)._formatField(field)
+
+class NullableRecord(FormattableRecord):
+    _default = {}
+    def get(self, field):
+        v = self.__dict__.get(field)
+        if v != None:
+            return v
+        else:
+            return self._default.get(field)