Hi there,

On 10/28/07, mmstud <[EMAIL PROTECTED]> wrote:
> Next design problem for me is version table. I have Document model
> with DocumentVersion model, but i dont know how to:
>
> - get the latest version of document
> - set creator and updator, automatic behavior for this
> - update version number
> - fetch thru Document(s) and DocumentVersion(s)

I didn't read your code thoroughly, but I have a model with some
similarities. Perhaps it will provide some insight. Basically, I'm
dealing with "Pages" and "PageVersions". "PageVersions" refers to it's
parent "Page", but "Page" also keeps the version number of the latest
version.

Arnar


# encoding: utf-8

import os
from datetime import datetime

from sqlalchemy import *

from softproof import utils
from softproof.json import jsonify_saobject

__meta__ = metadata

def constructor(fun):
    def decorated(self, *args, **kw):
        assert hasattr(self, 'c')
        for key,value in kw.items():
            if hasattr(self.c, key):
                setattr(self, key, value)
                del kw[key]
        fun(self, *args, **kw)
    return decorated


jobs = Table("jobs", __meta__,
                Column("jobno", Unicode(15), primary_key=True),
                Column("created", DateTime, nullable=False,
default=datetime.now),
                Column("deleted", Boolean, nullable=False, default=False))

class Job(object):

    @constructor
    def __init__(self, jobno=None):
        if jobno:
            self.jobno = jobno

    def sortedpages(self):
        listcopy = self.pages[:]
        listcopy.sort(key=Page.sort_key)
        return listcopy

    def get_page_by_name(self, pagename):
        """Finnur síðu með nafnið pagename og skilar henni. Skilar
None ef engin síða hefur
        viðkomandi nafn.
        Ef pagename er _firstpage_ er skilað viðeigandi síðu (t.d.
kápu ef hún er til)"""
        if len(self.pages) == 0:
            return None

        if '_firstpage_' == pagename:
            for p in self.pages:
                if 'KAP' in p.pagename:
                    return p
            return self.pages[0]

        for p in self.pages:
            if p.pagename == pagename:
                return p
        return None

    def create_page(self, pagename, *args, **kwargs):
        p = Page(job=self, pagename=pagename, *args, **kwargs)
        return p

    def get_path(self):
        if self.jobno.startswith('P'):
            pg1, pg2, pg3 = self.jobno.split('.')
            return os.path.join(pg1, pg1+'.'+pg2, self.jobno)
        else:
            return os.path.join(self.jobno[:-3]+'000',
self.jobno[:-2]+'00', self.jobno)

mapper(Job, jobs)


pageversions = Table("pageversions", __meta__,
                Column("jobno", Unicode(15),
ForeignKey("pages.jobno"),  primary_key=True),
                Column("pagename", Unicode(30),
ForeignKey("pages.pagename"), primary_key=True),
                Column("version", Integer, primary_key=True, default=1),
                Column("created", DateTime, nullable=False,
default=datetime.now),
                Column("md5sum", String(32)),
                Column("width", Integer, nullable=False, default=0),
                Column("height", Integer, nullable=False, default=0),
                ForeignKeyConstraint(["jobno",
"pagename"],["pages.jobno", "pages.pagename"]))

class PageVersion(object):

    @constructor
    def __init__(self, page=None, version=None):
        if page:
            self.page = page
        if version:
            self.version = version

    @property
    def filename(self):
        if self.version == 1:
            return self.page.pagename + '.jpg'
        else:
            return "%s.v%02d.jpg" % (self.page.pagename, self.version)

mapper(PageVersion, pageversions)


PageStates = utils.Enum('new', 'approved', 'rejected')

pages = Table("pages", __meta__,
                Column("jobno", Unicode(15), ForeignKey("jobs.jobno"),
primary_key=True),
                Column("pagename", Unicode(30), primary_key=True),
                Column("created", DateTime, nullable=False,
default=datetime.now),
                Column("deleted", Boolean, nullable=False, default=False),
                Column("current_version", Integer),
                Column("status", PageStates, nullable=False,
default=PageStates.new))

class Page(object):

    @constructor
    def __init__(self, job=None, pagename=None):
        if job:
            self.job = job
        if pagename:
            self.pagename = pagename
        self.currentversion = PageVersion(self, 1)
        self.status = PageStates.new

    def add_version(self):
        self.currentversion = PageVersion(self, self.currentversion.version+1)
        self.status = PageStates.new
        comment = self.add_comment()
        comment.closeable = False
        comment.content = u'Ný útgáfa rippuð'
        return self.currentversion

    def get_version(self, versionno):
        return self.versions[versionno-1]

    def _get_status(self):
        return self._status

    def _set_status(self, newstatus):
        if self._status is None:
            self._status = newstatus
            return
        if self._status == newstatus:
            return
        if self._status == PageStates.new and newstatus == PageStates.approved:
            opencomment = False
            for c in self.comments:
                if not c.closeable:
                    continue
                opencomment = opencomment or c.closed is None
            if opencomment:
                raise ValueError('Cant set job state to approved if it
has open comments.')
        self._status = newstatus

    status = property(_get_status, _set_status)

    def changeStatus(self, newstatus, user_name=None):
        self.status = newstatus
        comment = self.add_comment(user_name)
        comment.closeable = False
        if newstatus == PageStates.new:
            comment.content = u"Merkt sem ný"
        elif newstatus == PageStates.approved:
            comment.content = u"Samþykkt"
        elif newstatus == PageStates.rejected:
            comment.content = u"Hafnað"

    def get_next_page(self):
        myindex = self.job.pages.index(self)
        if myindex < len(self.job.pages)-1:
            return self.job.pages[myindex+1]
        else:
            return None

    def get_previous_page(self):
        myindex = self.job.pages.index(self)
        if myindex > 0:
            return self.job.pages[myindex-1]
        else:
            return None

    SORT_VALUES = {
        "ali":  0 - 1000,
        "kap":  1 - 1000,
        "ik":   2 - 1000,
        "ib":   3 - 1000,
        "bak":  4 - 1000,
        "aud":  5 - 1000,
        "r":    6 - 1000,
        # Tölur koma hér
        "lakk": 1 + 100000,
        "__default__": 2 + 100000,
    }

    def sort_key(self):
        t = []
        pn = self.pagename
        if pn.endswith("-P1"):
            pn = pn[:-3]
        if pn.startswith(self.job.jobno + "."):
            pn = pn[len(self.job.jobno)+1:]
        for part in pn.split("."):
            if part.lower().strip() in Page.SORT_VALUES:
                t.append(Page.SORT_VALUES[part.lower().strip()])
            else:
                try:
                    t.append(int(part))
                except ValueError:
                    t.append(part)
        return tuple(t)

    def __jsonextra__(self, props):
        props['status'] = self.status

mapper(Page, pages, properties={
    '_status': pages.c.status,
    'job': relation(Job, backref=backref('pages', cascade="all,
delete-orphan", order_by=pages.c.pagename)),
    'currentversion': relation(PageVersion,
                    foreignkey=pages.c.current_version,
                    primaryjoin=and_(pages.c.jobno==pageversions.c.jobno,
                                     pages.c.pagename==pageversions.c.pagename,

pages.c.current_version==pageversions.c.version),
                    post_update=True),
    'versions': relation(PageVersion, cascade="all, delete-orphan",
                    primaryjoin=and_(pages.c.jobno==pageversions.c.jobno,
                                     pages.c.pagename==pageversions.c.pagename),
                    order_by=pageversions.c.version,
                    backref=backref('page',

primaryjoin=and_(pages.c.jobno==pageversions.c.jobno,

pages.c.pagename==pageversions.c.pagename)))
    # '_status': pages.c.status,
    # 'status': synonym('_status')
})

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to