[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