Skip to content

Commit

Permalink
[#981] Allow users to create a ckan resource and a datastore resource…
Browse files Browse the repository at this point in the history
… with one call
  • Loading branch information
domoritz committed Jun 12, 2013
1 parent e3456e9 commit 8d03df6
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 2 deletions.
29 changes: 29 additions & 0 deletions ckanext/datastore/logic/action.py
Expand Up @@ -6,6 +6,7 @@
import ckan.lib.navl.dictization_functions
import ckan.logic as logic
import ckan.plugins as p
import ckan.lib.helpers as h
import ckanext.datastore.db as db
import ckanext.datastore.logic.schema as dsschema

Expand All @@ -25,10 +26,16 @@ def datastore_create(context, data_dict):
times to initially insert more data, add fields, change the aliases or indexes
as well as the primary keys.
To create a datastore resource and a CKAN resource at the same time,
provide a valid ``package_id`` and omit the ``resource_id``.
See :ref:`fields` and :ref:`records` for details on how to lay out records.
:param resource_id: resource id that the data is going to be stored against.
:type resource_id: string
:param package_id: package in which a new resource will be crated.
use instead of ``resource_id``.
:type package_id: string
:param aliases: names for read only aliases of the resource.
:type aliases: list or comma separated string
:param fields: fields/columns and their extra metadata.
Expand Down Expand Up @@ -61,6 +68,28 @@ def datastore_create(context, data_dict):

p.toolkit.check_access('datastore_create', context, data_dict)

if 'package_id' in data_dict and 'resource_id' in data_dict:
raise p.toolkit.ValidationError({
'resource_id': ['package_id cannot be used with resource_id']
})

if not 'package_id' in data_dict and not 'resource_id' in data_dict:
raise p.toolkit.ValidationError({
'resource_id': ['resource_id or package_id required']
})

# create ckan resource if package_id was provided
if 'package_id' in data_dict:
res = p.toolkit.get_action('resource_create')(context, {
'package_id': data_dict['package_id'],
'url': '_tmp'
})
res['url'] = h.url_for(
controller='ckanext.datastore.controller:DatastoreController',
action='dump', resource_id=res['id'])
p.toolkit.get_action('resource_update')(context, res)
data_dict['resource_id'] = res['id']

data_dict['connection_url'] = pylons.config['ckan.datastore.write_url']

# validate aliases
Expand Down
4 changes: 3 additions & 1 deletion ckanext/datastore/logic/schema.py
Expand Up @@ -8,6 +8,7 @@
not_missing = get_validator('not_missing')
not_empty = get_validator('not_empty')
resource_id_exists = get_validator('resource_id_exists')
package_id_exists = get_validator('package_id_exists')
ignore_missing = get_validator('ignore_missing')
empty = get_validator('empty')
boolean_validator = get_validator('boolean_validator')
Expand Down Expand Up @@ -66,7 +67,8 @@ def json_validator(value, context):

def datastore_create_schema():
schema = {
'resource_id': [not_missing, unicode, resource_id_exists],
'resource_id': [ignore_missing, unicode, resource_id_exists],
'package_id': [ignore_missing, unicode, package_id_exists],
'id': [ignore_missing],
'aliases': [ignore_missing, list_of_strings_or_string],
'fields': {
Expand Down
1 change: 0 additions & 1 deletion ckanext/datastore/plugin.py
Expand Up @@ -248,7 +248,6 @@ def get_auth_functions(self):
'datastore_change_permissions': auth.datastore_change_permissions}

def before_map(self, m):
print "Load mapping"
m.connect('/datastore/dump/{resource_id}',
controller='ckanext.datastore.controller:DatastoreController',
action='dump')
Expand Down
33 changes: 33 additions & 0 deletions ckanext/datastore/tests/test_create.py
Expand Up @@ -525,6 +525,39 @@ def test_create_basic(self):

assert res_dict['success'] is True, res_dict

def test_create_ckan_resource_in_package(self):
package = model.Package.get('annakarenina')
data = {
'package_id': package.id
}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
res = self.app.post('/api/action/datastore_create', params=postparams,
extra_environ=auth, status=200)
res_dict = json.loads(res.body)

assert 'resource_id' in res_dict['result']
assert len(model.Package.get('annakarenina').resources) == 3

res = tests.call_action_api(
self.app, 'resource_show', id=res_dict['result']['resource_id'])
assert res['url'] == '/datastore/dump/' + res['id'], res

def test_cant_provide_resource_and_package_id(self):
package = model.Package.get('annakarenina')
resource = package.resources[0]
data = {
'resource_id': resource.id,
'package_id': package.id
}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
res = self.app.post('/api/action/datastore_create', params=postparams,
extra_environ=auth, status=409)
res_dict = json.loads(res.body)

assert res_dict['error']['__type'] == 'Validation Error'

def test_guess_types(self):
resource = model.Package.get('annakarenina').resources[1]

Expand Down

0 comments on commit 8d03df6

Please sign in to comment.