X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=daklib%2Fdbconn.py;h=1364539422961acf89e3a422e9cbf66a5f864e18;hb=2c76e10042115760eed33fce79a9917d006118bf;hp=30aa7aaa3743c1d85463ad91d1c1e53f9a9c1fe8;hpb=38843ebde0229ef2b4ec78280073e9f2393ba1a1;p=dak.git diff --git a/daklib/dbconn.py b/daklib/dbconn.py index 30aa7aaa..13645394 100755 --- a/daklib/dbconn.py +++ b/daklib/dbconn.py @@ -38,6 +38,14 @@ import re import psycopg2 import traceback import commands + +try: + # python >= 2.6 + import json +except: + # python <= 2.5 + import simplejson as json + from datetime import datetime, timedelta from errno import ENOENT from tempfile import mkstemp, mkdtemp @@ -156,7 +164,86 @@ __all__.append('session_wrapper') ################################################################################ -class Architecture(object): +class ORMObject(object): + """ + ORMObject is a base class for all ORM classes mapped by SQLalchemy. All + derived classes must implement the summary() method. + """ + + def properties(self): + ''' + This method should be implemented by all derived classes and returns a + list of the important properties. The properties 'created' and + 'modified' will be added automatically. A suffix '_count' should be + added to properties that are lists or query objects. The most important + property name should be returned as the first element in the list + because it is used by repr(). + ''' + return [] + + def json(self): + ''' + Returns a JSON representation of the object based on the properties + returned from the properties() method. + ''' + data = {} + # add created and modified + all_properties = self.properties() + ['created', 'modified'] + for property in all_properties: + # check for list or query + if property[-6:] == '_count': + value = getattr(self, property[:-6]) + if hasattr(value, '__len__'): + # list + value = len(value) + elif hasattr(value, 'count'): + # query + value = value.count() + else: + raise KeyError('Do not understand property %s.' % property) + else: + # plain object + value = getattr(self, property) + if value is None: + # skip None + pass + elif isinstance(value, ORMObject): + # use repr() for ORMObject types + value = repr(value) + else: + # we want a string for all other types because json cannot + # everything + value = str(value) + data[property] = value + return json.dumps(data) + + def classname(self): + ''' + Returns the name of the class. + ''' + return type(self).__name__ + + def __repr__(self): + ''' + Returns a short string representation of the object using the first + element from the properties() method. + ''' + primary_property = self.properties()[0] + value = getattr(self, primary_property) + return '<%s %s>' % (self.classname(), str(value)) + + def __str__(self): + ''' + Returns a human readable form of the object using the properties() + method. + ''' + return '<%s %s>' % (self.classname(), self.json()) + +__all__.append('ORMObject') + +################################################################################ + +class Architecture(ORMObject): def __init__(self, arch_string = None, description = None): self.arch_string = arch_string self.description = description @@ -173,8 +260,8 @@ class Architecture(object): # This signals to use the normal comparison operator return NotImplemented - def __repr__(self): - return '' % self.arch_string + def properties(self): + return ['arch_string', 'arch_id', 'suites_count'] __all__.append('Architecture') @@ -1069,7 +1156,7 @@ __all__.append('get_dscfiles') ################################################################################ -class PoolFile(object): +class PoolFile(ORMObject): def __init__(self, filename = None, location = None, filesize = -1, \ md5sum = None): self.filename = filename @@ -1077,9 +1164,6 @@ class PoolFile(object): self.filesize = filesize self.md5sum = md5sum - def __repr__(self): - return '' % self.filename - @property def fullpath(self): return os.path.join(self.location.path, self.filename) @@ -1087,6 +1171,10 @@ class PoolFile(object): def is_valid(self, filesize = -1, md5sum = None):\ return self.filesize == filesize and self.md5sum == md5sum + def properties(self): + return ['filename', 'file_id', 'filesize', 'md5sum', 'sha1sum', \ + 'sha256sum', 'location', 'source', 'last_used'] + __all__.append('PoolFile') @session_wrapper @@ -2501,8 +2589,7 @@ class Suite(object): @return: list of Architecture objects for the given name (may be empty) """ - q = object_session(self).query(Architecture). \ - filter(Architecture.suites.contains(self)) + q = object_session(self).query(Architecture).with_parent(self) if skipsrc: q = q.filter(Architecture.arch_string != 'source') if skipall: @@ -2525,7 +2612,7 @@ class Suite(object): session = object_session(self) return session.query(DBSource).filter_by(source = source). \ - filter(DBSource.suites.contains(self)) + with_parent(self) __all__.append('Suite')