Skip to content

Commit

Permalink
[1407] WIP - Remove resourcegroups.
Browse files Browse the repository at this point in the history
Contains a migration to remove the resourcegroups and have the resource
have a reference direct to it's package, this removes a lot of joins.
  • Loading branch information
rossjones committed Jan 22, 2014
1 parent c9d05af commit 7afc50a
Show file tree
Hide file tree
Showing 20 changed files with 117 additions and 264 deletions.
11 changes: 1 addition & 10 deletions ckan/controllers/revision.py
Expand Up @@ -62,8 +62,6 @@ def list(self):
package_indications = []
revision_changes = model.repo.list_changes(revision)
resource_revisions = revision_changes[model.Resource]
resource_group_revisions = \
revision_changes[model.ResourceGroup]
package_extra_revisions = revision_changes[model.PackageExtra]
for package in revision.packages:
if not package:
Expand All @@ -89,16 +87,9 @@ def list(self):
else:
transition = 'updated'
for resource_revision in resource_revisions:
if resource_revision.continuity.resource_group.\
package_id == package.id:
if resource_revision.package_id == package.id:
transition += ':resources'
break
for resource_group_revision in \
resource_group_revisions:
if resource_group_revision.package_id == \
package.id:
transition += ':resource_group'
break
for package_extra_revision in package_extra_revisions:
if package_extra_revision.package_id == \
package.id:
Expand Down
4 changes: 2 additions & 2 deletions ckan/lib/create_test_data.py
Expand Up @@ -440,8 +440,8 @@ def create(cls, auth_profile="", package_type=None):
)
model.Session.add(pr1)
model.Session.add(pr2)
pkg1.resource_groups_all[0].resources_all.append(pr1)
pkg1.resource_groups_all[0].resources_all.append(pr2)
pkg1.resources_all.append(pr1)
pkg1.resources_all.append(pr2)
pkg1.notes = u'''Some test notes
### A 3rd level heading
Expand Down
14 changes: 3 additions & 11 deletions ckan/lib/dictization/model_dictize.py
Expand Up @@ -146,7 +146,6 @@ def _unified_resource_format(format_):
def resource_dictize(res, context):
model = context['model']
resource = d.table_dictize(res, context)
resource_group_id = resource['resource_group_id']
extras = resource.pop("extras", None)
if extras:
resource.update(extras)
Expand All @@ -156,13 +155,11 @@ def resource_dictize(res, context):
## for_edit is only called at the times when the dataset is to be edited
## in the frontend. Without for_edit the whole qualified url is returned.
if resource.get('url_type') == 'upload' and not context.get('for_edit'):
resource_group = model.Session.query(
model.ResourceGroup).get(resource_group_id)
last_part = url.split('/')[-1]
cleaned_name = munge.munge_filename(last_part)
resource['url'] = h.url_for(controller='package',
action='resource_download',
id=resource_group.package_id,
id=resource['package_id'],
resource_id=res.id,
filename=cleaned_name,
qualified=True)
Expand Down Expand Up @@ -240,13 +237,8 @@ def package_dictize(pkg, context):
result_dict['title'] = result_dict['title'].strip()
#resources
res_rev = model.resource_revision_table
resource_group = model.resource_group_table
q = select([res_rev], from_obj = res_rev.join(resource_group,
resource_group.c.id == res_rev.c.resource_group_id))
q = q.where(resource_group.c.package_id == pkg.id)
result = _execute_with_revision(q, res_rev, context)
result_dict["resources"] = resource_list_dictize(result, context)
result_dict['num_resources'] = len(result_dict.get('resources', []))

result_dict["resources"] = resource_list_dictize(pkg.resources_all,context)

#tags
tag_rev = model.package_tag_revision_table
Expand Down
4 changes: 2 additions & 2 deletions ckan/lib/dictization/model_save.py
Expand Up @@ -71,8 +71,8 @@ def package_resource_list_save(res_dicts, package, context):

pending = context.get('pending')

resource_list = package.resource_groups_all[0].resources_all
old_list = package.resource_groups_all[0].resources_all[:]
resource_list = package.resources_all
old_list = package.resources_all[:]

obj_list = []
for res_dict in res_dicts or []:
Expand Down
2 changes: 1 addition & 1 deletion ckan/logic/action/get.py
Expand Up @@ -1676,7 +1676,7 @@ def resource_search(context, data_dict):
offset = data_dict.get('offset')
limit = data_dict.get('limit')

q = model.Session.query(model.Resource).join(model.ResourceGroup).join(model.Package)
q = model.Session.query(model.Resource).join(model.Package)
q = q.filter(model.Package.state == 'active')
q = q.filter(model.Package.private == False)
q = q.filter(model.Resource.state == 'active')
Expand Down
8 changes: 4 additions & 4 deletions ckan/logic/action/update.py
Expand Up @@ -90,7 +90,7 @@ def make_latest_pending_package_active(context, data_dict):
_make_latest_rev_active(context, q)

#resources
for resource in pkg.resource_groups_all[0].resources_all:
for resource in pkg.resources_all:
q = session.query(model.ResourceRevision).filter_by(id=resource.id)
_make_latest_rev_active(context, q)

Expand Down Expand Up @@ -214,7 +214,7 @@ def resource_update(context, data_dict):
_check_access('resource_update', context, data_dict)
del context["resource"]

package_id = resource.resource_group.package.id
package_id = resource.package.id
pkg_dict = _get_action('package_show')(context, {'id': package_id})

for n, p in enumerate(pkg_dict['resources']):
Expand Down Expand Up @@ -247,7 +247,7 @@ def package_update(context, data_dict):
You must be authorized to edit the dataset and the groups that it belongs
to.
It is recommended to call
:py:func:`ckan.logic.action.get.package_show`, make the desired changes to
the result, and then call ``package_update()`` with it.
Expand Down Expand Up @@ -735,7 +735,7 @@ def task_status_update_many(context, data_dict):
'''Update many task statuses at once.
:param data: the task_status dictionaries to update, for the format of task
status dictionaries see
status dictionaries see
:py:func:`~task_status_update`
:type data: list of dictionaries
Expand Down
6 changes: 1 addition & 5 deletions ckan/logic/auth/delete.py
Expand Up @@ -26,11 +26,7 @@ def resource_delete(context, data_dict):
resource = get_resource_object(context, data_dict)

# check authentication against package
query = model.Session.query(model.Package)\
.join(model.ResourceGroup)\
.join(model.Resource)\
.filter(model.ResourceGroup.id == resource.resource_group_id)
pkg = query.first()
query = model.Package.get(resource.package_id)
if not pkg:
raise logic.NotFound(_('No package found for this resource, cannot check auth.'))

Expand Down
6 changes: 1 addition & 5 deletions ckan/logic/auth/get.py
Expand Up @@ -126,11 +126,7 @@ def resource_show(context, data_dict):
resource = get_resource_object(context, data_dict)

# check authentication against package
query = model.Session.query(model.Package)\
.join(model.ResourceGroup)\
.join(model.Resource)\
.filter(model.ResourceGroup.id == resource.resource_group_id)
pkg = query.first()
pkg = model.Package.get(resource.package_id)
if not pkg:
raise logic.NotFound(_('No package found for this resource, cannot check auth.'))

Expand Down
6 changes: 1 addition & 5 deletions ckan/logic/auth/update.py
Expand Up @@ -51,11 +51,7 @@ def resource_update(context, data_dict):
resource = logic_auth.get_resource_object(context, data_dict)

# check authentication against package
query = model.Session.query(model.Package)\
.join(model.ResourceGroup)\
.join(model.Resource)\
.filter(model.ResourceGroup.id == resource.resource_group_id)
pkg = query.first()
pkg = model.Package.get(resource.package_id)
if not pkg:
raise logic.NotFound(
_('No package found for this resource, cannot check auth.')
Expand Down
2 changes: 0 additions & 2 deletions ckan/logic/schema.py
Expand Up @@ -67,7 +67,6 @@ def default_resource_schema():
schema = {
'id': [ignore_empty, unicode],
'revision_id': [ignore_missing, unicode],
'resource_group_id': [ignore],
'package_id': [ignore],
'url': [not_empty, unicode],#, URL(add_http=False)],
'description': [ignore_missing, unicode],
Expand Down Expand Up @@ -204,7 +203,6 @@ def default_show_package_schema():
'cache_last_updated': [ckan.lib.navl.validators.ignore_missing],
'webstore_last_updated': [ckan.lib.navl.validators.ignore_missing],
'revision_timestamp': [],
'resource_group_id': [],
'cache_last_updated': [],
'webstore_last_updated': [],
'size': [],
Expand Down
27 changes: 27 additions & 0 deletions ckan/migration/versions/072-remove-resource-groups.py
@@ -0,0 +1,27 @@
import ckan.model


def upgrade(migrate_engine):
migrate_engine.execute(
'''
ALTER TABLE "resource" ADD COLUMN "package_id" text NOT NULL DEFAULT '';
UPDATE "resource" AS R
SET package_id = G.package_id
FROM "resource_group" AS G
WHERE R.resource_group_id = G.id;
ALTER TABLE "resource_revision" ADD COLUMN "package_id" text NOT NULL DEFAULT '';
UPDATE "resource_revision" AS R
SET package_id = G.package_id
FROM "resource_group_revision" AS G
WHERE R.resource_group_id = G.id;
ALTER TABLE resource DROP CONSTRAINT resource_resource_group_id_fkey;
ALTER TABLE resource_revision DROP CONSTRAINT resource_revision_resource_group_id_fkey;
DROP TABLE "resource_group";
DROP TABLE "resource_group_revision";
'''
)


6 changes: 1 addition & 5 deletions ckan/model/__init__.py
Expand Up @@ -89,14 +89,10 @@
)
from resource import (
Resource,
ResourceGroup,
ResourceRevision,
DictProxy,
resource_group_table,
resource_table,
resource_revision_table,
ResourceGroupRevision,
resource_group_revision_table,
)
from tracking import (
tracking_summary_table,
Expand Down Expand Up @@ -408,7 +404,7 @@ def purge_revision(self, revision, leave_record=False):

repo = Repository(meta.metadata, meta.Session,
versioned_objects=[Package, PackageTag, Resource,
ResourceGroup, PackageExtra, Member,
PackageExtra, Member,
Group]
)

Expand Down
46 changes: 13 additions & 33 deletions ckan/model/package.py
Expand Up @@ -65,8 +65,6 @@ class Package(vdm.sqlalchemy.RevisionedObjectMixin,
def __init__(self, **kw):
from ckan import model
super(Package, self).__init__(**kw)
resource_group = model.ResourceGroup(label="default")
self.resource_groups_all.append(resource_group)

@classmethod
def search_by_name(cls, text_query):
Expand All @@ -85,21 +83,17 @@ def get(cls, reference):

@property
def resources(self):
if len(self.resource_groups_all) == 0:
return []

assert len(self.resource_groups_all) == 1, "can only use resources on packages if there is only one resource_group"
return [resource for resource in
self.resource_groups_all[0].resources_all
return [resource for resource in
self.resources_all
if resource.state <> 'deleted']

def related_packages(self):
return [self]

def add_resource(self, url, format=u'', description=u'', hash=u'', **kw):
import resource
self.resource_groups_all[0].resources_all.append(resource.Resource(
resource_group_id=self.resource_groups_all[0].id,
self.resources_all.append(resource.Resource(
package_id=self.id,
url=url,
format=format,
description=description,
Expand Down Expand Up @@ -377,22 +371,17 @@ def all_related_revisions(self):
Ordered by most recent first.
'''
from tag import PackageTag
from resource import ResourceGroup, Resource
from resource import Resource
from package_extra import PackageExtra

results = {} # revision:[PackageRevision1, PackageTagRevision1, etc.]
for pkg_rev in self.all_revisions:
if not results.has_key(pkg_rev.revision):
results[pkg_rev.revision] = []
results[pkg_rev.revision].append(pkg_rev)
for class_ in [ResourceGroup, Resource, PackageExtra, PackageTag]:
for class_ in [Resource, PackageExtra, PackageTag]:
rev_class = class_.__revision_class__
if class_ == Resource:
q = meta.Session.query(rev_class).join('continuity',
'resource_group')
obj_revisions = q.filter(ResourceGroup.package_id == self.id).all()
else:
obj_revisions = meta.Session.query(rev_class).filter_by(package_id=self.id).all()
obj_revisions = meta.Session.query(rev_class).filter_by(package_id=self.id).all()
for obj_rev in obj_revisions:
if not results.has_key(obj_rev.revision):
results[obj_rev.revision] = []
Expand All @@ -413,32 +402,23 @@ def diff(self, to_revision=None, from_revision=None):
'''Overrides the diff in vdm, so that related obj revisions are
diffed as well as PackageRevisions'''
from tag import PackageTag
from resource import ResourceGroup, Resource
from resource import Resource
from package_extra import PackageExtra

results = {} # field_name:diffs
results.update(super(Package, self).diff(to_revision, from_revision))
# Iterate over PackageTag, PackageExtra, Resources etc.
for obj_class in [ResourceGroup, Resource, PackageExtra, PackageTag]:
for obj_class in [Resource, PackageExtra, PackageTag]:
obj_rev_class = obj_class.__revision_class__
# Query for object revisions related to this package
if obj_class == Resource:
obj_rev_query = meta.Session.query(obj_rev_class).\
join('continuity', 'resource_group').\
join('revision').\
filter(ResourceGroup.package_id == self.id).\
order_by(core.Revision.timestamp.desc())
else:
obj_rev_query = meta.Session.query(obj_rev_class).\
filter_by(package_id=self.id).\
join('revision').\
order_by(core.Revision.timestamp.desc())
obj_rev_query = meta.Session.query(obj_rev_class).\
filter_by(package_id=self.id).\
join('revision').\
order_by(core.Revision.timestamp.desc())
# Columns to include in the diff
cols_to_diff = obj_class.revisioned_fields()
cols_to_diff.remove('id')
if obj_class is Resource:
cols_to_diff.remove('resource_group_id')
else:
cols_to_diff.remove('package_id')
# Particular object types are better known by an invariant field
if obj_class is PackageTag:
Expand Down

0 comments on commit 7afc50a

Please sign in to comment.