[ckan-changes] commit/ckan: 2 new changesets

Bitbucket commits-noreply at bitbucket.org
Tue May 24 21:31:09 UTC 2011


2 new changesets in ckan:

http://bitbucket.org/okfn/ckan/changeset/53370888fed4/
changeset:   r3105:53370888fed4
branch:      feature-1147-add-expired_id-to-revision-tables
user:        kindly
date:        2011-05-24 15:54:53
summary:     [revisioning] schema migration and field update
affected #:  11 files (4.2 KB)

--- a/ckan/model/core.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/core.py	Tue May 24 14:54:53 2011 +0100
@@ -1,4 +1,5 @@
-from meta import *
+from meta import metadata, mapper
+from sqlalchemy import Column, ForeignKey, DateTime, Text, orm
 import vdm.sqlalchemy
 
 from domain_object import DomainObject
@@ -26,5 +27,12 @@
 Revision = vdm.sqlalchemy.make_Revision(mapper, revision_table)
 
 
+def make_revisioned_table(table):
+    revision_table = vdm.sqlalchemy.make_revisioned_table(table)
+    revision_table.append_column(Column('expired_id', 
+                                 Text))
+    revision_table.append_column(Column('revision_timestamp', DateTime))
+    revision_table.append_column(Column('expired_timestamp', DateTime, 
+                                 default='9999-12-31'))
+    return revision_table
 
-


--- a/ckan/model/group.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/group.py	Tue May 24 14:54:53 2011 +0100
@@ -19,7 +19,7 @@
     )
     
 vdm.sqlalchemy.make_table_stateful(package_group_table)
-package_group_revision_table = vdm.sqlalchemy.make_revisioned_table(package_group_table)
+package_group_revision_table = make_revisioned_table(package_group_table)
 
 group_table = Table('group', metadata,
     Column('id', UnicodeText, primary_key=True, default=make_uuid),
@@ -30,7 +30,7 @@
     )
 
 vdm.sqlalchemy.make_table_stateful(group_table)
-group_revision_table = vdm.sqlalchemy.make_revisioned_table(group_table)
+group_revision_table = make_revisioned_table(group_table)
 
 
 class PackageGroup(vdm.sqlalchemy.RevisionedObjectMixin,


--- a/ckan/model/group_extra.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/group_extra.py	Tue May 24 14:54:53 2011 +0100
@@ -18,7 +18,7 @@
 )
 
 vdm.sqlalchemy.make_table_stateful(group_extra_table)
-group_extra_revision_table = vdm.sqlalchemy.make_revisioned_table(group_extra_table)
+group_extra_revision_table = make_revisioned_table(group_extra_table)
 
 
 class GroupExtra(vdm.sqlalchemy.RevisionedObjectMixin,


--- a/ckan/model/meta.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/meta.py	Tue May 24 14:54:53 2011 +0100
@@ -2,6 +2,7 @@
 from sqlalchemy import MetaData, __version__ as sqav
 from sqlalchemy.orm import scoped_session, sessionmaker
 import sqlalchemy.orm as orm
+from sqlalchemy.orm.session import SessionExtension
 
 # TODO: remove these imports from here and put them in client model modules
 from sqlalchemy import Column, MetaData, Table, types, ForeignKey
@@ -12,6 +13,59 @@
 
 from ckan.model import extension
 
+class CkanSessionExtension(SessionExtension):
+
+    def before_flush(self, session, flush_context, instances):
+        if not hasattr(session, '_object_cache'):
+            session._object_cache= {'new': set(),
+                                    'deleted': set(),
+                                    'changed': set()}
+
+        changed = [obj for obj in session.dirty if 
+            session.is_modified(obj, include_collections=False)]
+
+        session._object_cache['new'].update(session.new)
+        session._object_cache['deleted'].update(session.deleted)
+        session._object_cache['changed'].update(changed)
+
+    def before_commit(self, session):
+        session.flush()
+        try:
+            obj_cache = session._object_cache
+            revision = session.revision
+        except AttributeError:
+            return
+
+        new = obj_cache['new']
+        changed = obj_cache['changed']
+        deleted = obj_cache['deleted']
+
+        for obj in new | changed | deleted:
+            if not hasattr(obj, '__revision_class__'):
+                continue
+
+            revision_cls = obj.__revision_class__
+            q = session.query(revision_cls)
+            q = q.filter_by(expired_timestamp='9999-12-31', id=obj.id)
+            results = q.all()
+            assert len(results) <= 2
+
+            for rev_obj in results:
+                if rev_obj.revision_id == revision.id:
+                    rev_obj.revision_timestamp = revision.timestamp
+                else:
+                    rev_obj.expired_id = revision.id
+                    rev_obj.expired_timestamp = revision.timestamp
+                session.add(rev_obj)
+
+    def after_commit(self, session):
+        if hasattr(session, '_object_cache'):
+            del session._object_cache
+
+    def after_rollback(self, session):
+        if hasattr(session, '_object_cache'):
+            del session._object_cache
+
 # __all__ = ['Session', 'engine', 'metadata', 'mapper']
 
 # SQLAlchemy database engine. Updated by model.init_model()
@@ -22,14 +76,16 @@
     Session = scoped_session(sessionmaker(
         autoflush=False,
         transactional=True,
-        extension=extension.PluginSessionExtension(),
+        extension=[CkanSessionExtension(),
+                   extension.PluginSessionExtension()],
         ))
 else:
     Session = scoped_session(sessionmaker(
         autoflush=False,
         autocommit=False,
         expire_on_commit=False,
-        extension=extension.PluginSessionExtension(),
+        extension=[CkanSessionExtension(),
+                   extension.PluginSessionExtension()],
         ))
 
 #mapper = Session.mapper


--- a/ckan/model/modification.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/modification.py	Tue May 24 14:54:53 2011 +0100
@@ -26,20 +26,6 @@
     implements(ISession, inherit=True)
     observers = PluginImplementations(IDomainObjectModification)
 
-    def before_flush(self, session, flush_context, instances):
-
-        if not hasattr(session, '_object_cache'):
-            session._object_cache= {'new': set(),
-                                    'deleted': set(),
-                                    'changed': set()}
-
-        changed = [obj for obj in session.dirty if 
-            session.is_modified(obj, include_collections=False)]
-
-        session._object_cache['new'].update(session.new)
-        session._object_cache['deleted'].update(session.deleted)
-        session._object_cache['changed'].update(changed)
-
     def before_commit(self, session):
 
         session.flush()
@@ -69,7 +55,6 @@
 
         for obj in changed_pkgs:
             self.notify(obj, DomainObjectOperation.changed)
-        del session._object_cache
 
 
     def notify(self, entity, operation):


--- a/ckan/model/package.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/package.py	Tue May 24 14:54:53 2011 +0100
@@ -37,7 +37,7 @@
 
 
 vdm.sqlalchemy.make_table_stateful(package_table)
-package_revision_table = vdm.sqlalchemy.make_revisioned_table(package_table)
+package_revision_table = make_revisioned_table(package_table)
 
 ## -------------------
 ## Mapped classes


--- a/ckan/model/package_extra.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/package_extra.py	Tue May 24 14:54:53 2011 +0100
@@ -18,7 +18,7 @@
 )
 
 vdm.sqlalchemy.make_table_stateful(package_extra_table)
-extra_revision_table= vdm.sqlalchemy.make_revisioned_table(package_extra_table)
+extra_revision_table= make_revisioned_table(package_extra_table)
 
 class PackageExtra(vdm.sqlalchemy.RevisionedObjectMixin,
         vdm.sqlalchemy.StatefulObjectMixin,


--- a/ckan/model/package_relationship.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/package_relationship.py	Tue May 24 14:54:53 2011 +0100
@@ -24,7 +24,7 @@
      )
 
 vdm.sqlalchemy.make_table_stateful(package_relationship_table)
-package_relationship_revision_table = vdm.sqlalchemy.make_revisioned_table(package_relationship_table)
+package_relationship_revision_table = make_revisioned_table(package_relationship_table)
 
 class PackageRelationship(vdm.sqlalchemy.RevisionedObjectMixin,
                           vdm.sqlalchemy.StatefulObjectMixin,


--- a/ckan/model/resource.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/resource.py	Tue May 24 14:54:53 2011 +0100
@@ -39,10 +39,10 @@
     )
 
 vdm.sqlalchemy.make_table_stateful(resource_table)
-resource_revision_table = vdm.sqlalchemy.make_revisioned_table(resource_table)
+resource_revision_table = make_revisioned_table(resource_table)
 
 vdm.sqlalchemy.make_table_stateful(resource_group_table)
-resource_group_revision_table = vdm.sqlalchemy.make_revisioned_table(resource_group_table)
+resource_group_revision_table = make_revisioned_table(resource_group_table)
 
 class Resource(vdm.sqlalchemy.RevisionedObjectMixin,
                vdm.sqlalchemy.StatefulObjectMixin,


--- a/ckan/model/tag.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/model/tag.py	Tue May 24 14:54:53 2011 +0100
@@ -23,7 +23,7 @@
 
 vdm.sqlalchemy.make_table_stateful(package_tag_table)
 # TODO: this has a composite primary key ...
-package_tag_revision_table = vdm.sqlalchemy.make_revisioned_table(package_tag_table)
+package_tag_revision_table = make_revisioned_table(package_tag_table)
 
 class Tag(DomainObject):
     def __init__(self, name=''):


--- a/ckan/tests/models/test_package.py	Sat May 21 10:45:28 2011 +0100
+++ b/ckan/tests/models/test_package.py	Tue May 24 14:54:53 2011 +0100
@@ -37,14 +37,35 @@
         rev = model.repo.new_revision()
         package = model.Package(name=name)
         model.Session.add(package)
+        model.Session.flush()
+        revision_id = model.Session().revision.id
+        timestamp = model.Session().revision.timestamp
         model.repo.commit_and_remove()
 
+        package = model.Package.by_name(name)
+        assert len(package.all_revisions) == 1
+        assert package.all_revisions[0].revision_id == revision_id
+        assert package.all_revisions[0].revision_timestamp == timestamp
+        assert package.all_revisions[0].expired_id is None
+
         # change it
         rev = model.repo.new_revision()
         package = model.Package.by_name(name)
         package.title = "wobsnasm"
+        revision_id2 = model.Session().revision.id
+        timestamp2 = model.Session().revision.timestamp
         model.repo.commit_and_remove()
 
+        package = model.Package.by_name(name)
+        assert len(package.all_revisions) == 2
+        assert package.all_revisions[0].revision_id == revision_id2
+        assert package.all_revisions[0].revision_timestamp == timestamp2
+        assert package.all_revisions[0].expired_id is None
+
+        assert package.all_revisions[1].revision_id == revision_id
+        assert package.all_revisions[1].revision_timestamp == timestamp
+        assert package.all_revisions[1].expired_id == revision_id2
+
     def test_create_package(self):
         package = model.Package.by_name(self.name)
         assert package.name == self.name


http://bitbucket.org/okfn/ckan/changeset/a8b663accb57/
changeset:   r3106:a8b663accb57
branch:      feature-1141-moderated-edits-ajax
user:        kindly
date:        2011-05-24 23:17:14
summary:     [moderated edit] sample ajax calls added
affected #:  3 files (2.1 KB)

--- a/ckan/config/routing.py	Sun May 22 19:52:34 2011 +0100
+++ b/ckan/config/routing.py	Tue May 24 22:17:14 2011 +0100
@@ -179,11 +179,14 @@
             ]))
         )
     map.connect('/package', controller='package', action='index')
+    map.connect('/package/{action}/{id}/{revision}', controller='package', action='read_ajax')
     map.connect('/package/{action}/{id}', controller='package',
         requirements=dict(action='|'.join([
         'edit',
         'authz',
-        'history'
+        'history',
+        'read_ajax',
+        'history_ajax',
         ]))
         )
     map.connect('/package/{id}', controller='package', action='read')


--- a/ckan/controllers/package.py	Sun May 22 19:52:34 2011 +0100
+++ b/ckan/controllers/package.py	Tue May 24 22:17:14 2011 +0100
@@ -1,6 +1,7 @@
 import logging
 import urlparse
 from urllib import urlencode
+import json
 
 from sqlalchemy.orm import eagerload_all
 from sqlalchemy import or_
@@ -21,8 +22,9 @@
 from ckan.lib.package_saver import PackageSaver, ValidationException
 from ckan.lib.navl.dictization_functions import DataError, unflatten, validate
 from ckan.logic import NotFound, NotAuthorized, ValidationError
-from ckan.logic import tuplize_dict, clean_dict, parse_params
+from ckan.logic import tuplize_dict, clean_dict, parse_params, flatten_to_string_key
 from ckan.plugins import PluginImplementations, IPackageController
+from ckan.lib.dictization import table_dictize
 import ckan.forms
 import ckan.authz
 import ckan.rating
@@ -347,6 +349,49 @@
         c.form = render(self.package_form, extra_vars=vars)
         return render('package/edit.html')
 
+    def read_ajax(self, id, revision=None):
+        context = {'model': model, 'session': model.Session,
+                   'user': c.user or c.author,
+                   'id': id, 'extras_as_string': True,
+                   'schema': self._form_to_db_schema()}
+
+        try:
+            data = get.package_show(context)
+            schema = self._db_to_form_schema()
+            if schema:
+                data, errors = validate(data, schema)
+        except NotAuthorized:
+            abort(401, _('Unauthorized to read package %s') % '')
+
+        ## hack as db_to_form schema should have this
+        data['tag_string'] = ' '.join([tag['name'] for tag in data.get('tags', [])])
+        data.pop('tags')
+        data = flatten_to_string_key(data)
+        
+        if revision:
+            revision = model.Session.query(model.PackageRevision).filter_by(
+                revision_id=revision, id=data['id']).one()
+            data.update(table_dictize(revision, context))
+
+        response.headers['Content-Type'] = 'application/json;charset=utf-8'
+        return json.dumps(data)
+
+    def history_ajax(self, id):
+
+        context = {'model': model, 'session': model.Session,
+                   'user': c.user or c.author,
+                   'id': id, 'extras_as_string': True}
+        pkg = model.Package.get(id)
+        data = []
+        for num, (revision, revision_obj) in enumerate(pkg.all_related_revisions):
+            data.append({'revision_id': revision.id,
+                         'message': revision.message,
+                         'timestamp': revision.timestamp.isoformat(),
+                         'current_approved': True if num == 0 else False})
+
+        response.headers['Content-Type'] = 'application/json;charset=utf-8'
+        return json.dumps(data)
+
     def _save_new(self, context):
         try:
             data_dict = clean_dict(unflatten(


--- a/ckan/logic/__init__.py	Sun May 22 19:52:34 2011 +0100
+++ b/ckan/logic/__init__.py	Tue May 24 22:17:14 2011 +0100
@@ -1,5 +1,6 @@
 import logging
 import ckan.authz
+from ckan.lib.navl.dictization_functions import flatten_dict
 
 class ActionError(Exception):
     def __init__(self, extra_msg=None):
@@ -65,6 +66,11 @@
         data_dict[new_key] = value
     return data_dict
 
+def flatten_to_string_key(dict):
+
+    flattented = flatten_dict(dict)
+    return untuplize_dict(flattented)
+
 def check_access(entity, action, context):
     model = context["model"]
     user = context.get("user")

Repository URL: https://bitbucket.org/okfn/ckan/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.




More information about the ckan-changes mailing list