diff options
author | Stanislav Ochotnicky <sochotnicky@gmail.com> | 2009-07-09 19:13:47 +0200 |
---|---|---|
committer | Stanislav Ochotnicky <sochotnicky@gmail.com> | 2009-07-09 20:25:30 +0200 |
commit | e5ca34ab98e44a4c4897fd4c2450a9842a55779f (patch) | |
tree | 6f7f57754c3a20229a095a2154e8afb84f8b043d /src | |
parent | Fix errors in ddl (diff) | |
download | collagen-e5ca34ab98e44a4c4897fd4c2450a9842a55779f.tar.gz collagen-e5ca34ab98e44a4c4897fd4c2450a9842a55779f.tar.bz2 collagen-e5ca34ab98e44a4c4897fd4c2450a9842a55779f.zip |
Added implementation of basic db functions
Using Django backend for ORM mapping. Django ORM may not be best, but we
can reuse it later in web application
Diffstat (limited to 'src')
-rw-r--r-- | src/matchbox/db/__init__.py | 166 | ||||
-rw-r--r-- | src/matchbox/db/main/__init__.py | 0 | ||||
-rw-r--r-- | src/matchbox/db/main/initial_data.json | 23 | ||||
-rw-r--r-- | src/matchbox/db/main/models.py | 50 | ||||
-rw-r--r-- | src/matchbox/db/manage.py | 11 | ||||
-rw-r--r-- | src/matchbox/db/settings.py | 8 |
6 files changed, 244 insertions, 14 deletions
diff --git a/src/matchbox/db/__init__.py b/src/matchbox/db/__init__.py index acd8323..dc2171c 100644 --- a/src/matchbox/db/__init__.py +++ b/src/matchbox/db/__init__.py @@ -1,10 +1,14 @@ -try: - import psycopg2 as dbapi -except ImportError: - print "Error importing psycopg package. Check your dependencies!!" - sys.exit(1) +import sys +import os +import settings as config +from django.conf import settings +os.environ["DJANGO_SETTINGS_MODULE"]="matchbox.db.settings" + +from main.models import * +from django.db import reset_queries, close_connection, _rollback_on_exception + class DbIface(object): """ Class representing interface to database for Matchbox @@ -142,14 +146,148 @@ class DbIface(object): """ @param packageproperties_id: id of row in packageproperties table @type packageproperties_id: integer - @param contents: dict of files in packageproperties (path is key, ) - @param path: path to add to database - @type path: string - @param type: type of file to add as returned from dblink.getcontents() (e.g. 'dir', 'obj' or 'sym') - @type type: string - @param size: size of file or 0 if not regular file - @type size: integer - @param hash: hash of file or None if not regular file - @type hash: 32 character string + @param contents: dict of files in packageproperties (path is key, value is list of information about path) + see dblink.getcontents() for more info + @type contents: dict """ pass + +class DjangoDB(object): + + def dbquery(f): + def newfunc(*args, **kwargs): + reset_queries() + try: + return f(*args, **kwargs) + except Exception, e: + _rollback_on_exception() + raise e + return newfunc + + @dbquery + def add_package(self, name): + p = Package.objects.filter(name=name) + if len(p) > 0: + return p[0].id + p = Package(name=name) + p.save() + return p.id + + + @dbquery + def add_category(self, name): + c = PackageCategory.objects.filter(name=name) + if len(c) > 0: + return c[0].id + c = PackageCategory(name=name) + c.save() + return c.id + + @dbquery + def add_package_version(self, package_id, category_id, version): + p = Package.objects.get(pk=package_id) + c = PackageCategory.objects.get(pk=category_id) + + v = PackageVersion.objects.filter(version=version, category=c, package=p) + if len(v) > 0: + return v[0].id + v = PackageVersion(version=version, package=p, category=c) + v.save() + return v.id + + @dbquery + def add_dependency(self, packageversion_id, dependency_id): + p = Package.objects.get(pk=packageversion_id) + dep = Package.objects.get(pk=dependency_id) + p.dependencies.add(dep) + + @dbquery + def add_tinderbox(self, ip): + t = Tinderbox.objects.filter(ip=ip) + if len(t) > 0: + return t[0].id + + t = Tinderbox(ip=ip) + t.save() + return t.id + + @dbquery + def add_attachment(self, packageproperties_id, name, content, mimetype): + pp = PackageProperties.objects.get(pk=packageproperties_id) + + attachments = Attachment.objects.filter(packageproperties=pp, name=name) + if len(attachments) > 0: + return attachments[0].id + + a = Attachment(packageproperties=pp, name=name, content=content, mimetype=mimetype) + a.save() + return a.id + + @dbquery + def add_portage_profile(self, name): + pp = PortageProfile.objects.filter(name=name) + if len(pp) > 0: + return pp[0].id + pp = PortageProfile(name=name) + pp.save() + return pp.id + + @dbquery + def add_useflag(self, name): + u = Useflag.objects.filter(name=name) + if len(u) > 0: + return u[0].id + u = Useflag(name=name) + u.save() + return u.id + + @dbquery + def add_packageproperties(self, packageversion_id, profile_id, tinderbox_id, error_code): + pv = PackageVersion.objects.get(pk=packageversion_id) + profile = PortageProfile.objects.get(pk=profile_id) + tinderbox = Tinderbox.objects.get(pk=tinderbox_id) + + pp = PackageProperties(packageversion=pv, + profile=profile, + tinderbox=tinderbox, + error_code=error_code) + pp.save() + + @dbquery + def add_useflags_to_packageproperies(self, packageproperties_id, useflag_ids): + pp = PackageProperties.objects.get(pk=packageproperties_id) + + for id in useflag_ids: + useflag = Useflag.objects.get(pk=id) + pp.useflags.add(useflag) + + @dbquery + def add_contents_to_packageproperties(self, packageproperties_id, contents): + pp = PackageProperties.objects.get(pk=packageproperties_id) + + for path in contents.keys(): + type = contents[path][0] + file = File.objects.filter(path=path) + if len(file) == 0: + file = File(path=path) + file.save() + else: + file = file[0] + + filetype = FileType.objects.filter(name=type) + if len(filetype) == 0: + raise DatabaseError ("Database not initialized from fixtures!!\nFile type loading failed (for type %s)" % type) + filetype = filetype[0] + hash = None + size = None + if type == 'obj': + hash = contents[path][1] + size = contents[path][2] + + ppf = PackageProperties_File(file=file, + filetype=filetype, + packageproperties=pp, + hash=hash, + size=size) + ppf.save() + diff --git a/src/matchbox/db/main/__init__.py b/src/matchbox/db/main/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/matchbox/db/main/__init__.py diff --git a/src/matchbox/db/main/initial_data.json b/src/matchbox/db/main/initial_data.json new file mode 100644 index 0000000..613b7a5 --- /dev/null +++ b/src/matchbox/db/main/initial_data.json @@ -0,0 +1,23 @@ +[ + { + "model": "main.FileType", + "pk": 1, + "fields": { + "name": "obj" + } + }, + { + "model": "main.FileType", + "pk": 2, + "fields": { + "name": "sym" + } + }, + { + "model": "main.FileType", + "pk": 3, + "fields": { + "name": "dir" + } + } +] diff --git a/src/matchbox/db/main/models.py b/src/matchbox/db/main/models.py new file mode 100644 index 0000000..5448269 --- /dev/null +++ b/src/matchbox/db/main/models.py @@ -0,0 +1,50 @@ +from django.db import models + +# Create your models here. +class Package(models.Model): + name = models.CharField(max_length=255,unique=True) + +class PackageVersion(models.Model): + version = models.CharField(max_length=255) + package = models.ForeignKey('Package') + category = models.ForeignKey('PackageCategory') + dependencies = models.ManyToManyField('self', symmetrical=False) + +class PackageCategory(models.Model): + name = models.CharField(max_length=255,unique=True) + +class PortageProfile(models.Model): + name = models.CharField(max_length=255,unique=True) + +class Tinderbox(models.Model): + ip = models.IPAddressField() + +class PackageProperties(models.Model): + packageversion = models.ForeignKey('PackageVersion') + profile = models.ForeignKey('PortageProfile') + tinderbox = models.ForeignKey('Tinderbox') + error_code = models.IntegerField() + contents = models.ManyToManyField('File',through='PackageProperties_File') + useflags = models.ManyToManyField('Useflag') + +class Attachment(models.Model): + packageproperties = models.ForeignKey('PackageProperties') + name = models.CharField(max_length=255) + mimetype = models.CharField(max_length=255) + content = models.TextField() + +class Useflag(models.Model): + name = models.CharField(max_length=255, unique=True) + +class File(models.Model): + path = models.CharField(max_length=65535, unique=True) + +class FileType(models.Model): + name = models.CharField(max_length=20, unique=True) + +class PackageProperties_File(models.Model): + file = models.ForeignKey('File') + filetype = models.ForeignKey('FileType') + packageproperties = models.ForeignKey('PackageProperties') + hash = models.CharField(max_length=32,blank=True) + size = models.IntegerField(blank=True) diff --git a/src/matchbox/db/manage.py b/src/matchbox/db/manage.py new file mode 100644 index 0000000..5e78ea9 --- /dev/null +++ b/src/matchbox/db/manage.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +from django.core.management import execute_manager +try: + import settings # Assumed to be in the same directory. +except ImportError: + import sys + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) + sys.exit(1) + +if __name__ == "__main__": + execute_manager(settings) diff --git a/src/matchbox/db/settings.py b/src/matchbox/db/settings.py new file mode 100644 index 0000000..bd20bac --- /dev/null +++ b/src/matchbox/db/settings.py @@ -0,0 +1,8 @@ + +DATABASE_ENGINE = 'postgresql_psycopg2' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. +DATABASE_NAME = 'collagen' # Or path to database file if using sqlite3. +DATABASE_USER = 'username' # Not used with sqlite3. +DATABASE_PASSWORD = 'password' # Not used with sqlite3. +DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. +DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. +INSTALLED_APPS = ('db.main') |