-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add basic datastore extension skeleton with create logic/auth functio…
…ns and tests.
- Loading branch information
1 parent
1a5712d
commit a62293a
Showing
12 changed files
with
179 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
|
||
def create(resource_id, fields, rows): | ||
''' | ||
The first row will be used to guess types not in the fields and the | ||
guessed types will be added to the headers permanently. | ||
Consecutive rows have to conform to the field definitions. | ||
rows can be empty so that you can just set the fields. | ||
fields are optional but needed if you want to do type hinting or | ||
add extra information for certain columns or to explicitly | ||
define ordering. | ||
eg [{"id": "dob", "label": ""Date of Birth", | ||
"type": "timestamp" ,"concept": "day"}, | ||
{"name": "some_stuff": ..]. | ||
A header items values can not be changed after it has been defined | ||
nor can the ordering of them be changed. They can be extended though. | ||
Any error results in total failure! For now pass back the actual error. | ||
Should be transactional. | ||
''' | ||
pass |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import logging | ||
import ckan.logic as logic | ||
import ckan.logic.action | ||
import ckan.lib.dictization | ||
import ckan.plugins as p | ||
import ckanext.datastore.logic.schema | ||
import ckanext.datastore.db as db | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
_validate = ckan.lib.navl.dictization_functions.validate | ||
_check_access = logic.check_access | ||
_get_or_bust = logic.get_or_bust | ||
|
||
|
||
def datastore_create(context, data_dict): | ||
'''Adds a new table to the datastore. | ||
:param resource_id: resource id that the data is going to be stored under. | ||
:type resource_id: string | ||
:param fields: fields/columns and their extra metadata. | ||
:type fields: list of dictionaries | ||
:param records: the data, eg: [{"dob": "2005", "some_stuff": ['a', b']}] | ||
:type records: list of dictionaries | ||
:returns: the newly created data object. | ||
:rtype: dictionary | ||
''' | ||
model = _get_or_bust(context, 'model') | ||
resource_id = _get_or_bust(data_dict, 'resource_id') | ||
fields = data_dict.get('fields') | ||
records = _get_or_bust(data_dict, 'records') | ||
|
||
_check_access('datastore_create', context, data_dict) | ||
|
||
schema = ckanext.datastore.logic.schema.default_datastore_create_schema() | ||
data, errors = _validate(data_dict, schema, context) | ||
if errors: | ||
model.Session.rollback() | ||
raise p.toolkit.ValidationError(errors) | ||
|
||
return db.create(resource_id, fields, records) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import ckan.plugins as p | ||
|
||
|
||
def datastore_create(context, data_dict): | ||
model = context['model'] | ||
user = context['user'] | ||
userobj = model.User.get(user) | ||
|
||
if userobj: | ||
return {'success': True} | ||
return {'success': False, | ||
'msg': p.toolkit._('You must be logged in to use the datastore.')} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from ckan.lib.navl.validators import (not_empty, | ||
not_missing, | ||
empty, | ||
ignore_missing, | ||
ignore) | ||
|
||
|
||
def default_fields_schema(): | ||
return { | ||
'id': [not_missing, not_empty, unicode], | ||
'type': [not_missing, not_empty, unicode], | ||
'label': [ignore_missing, unicode], | ||
} | ||
|
||
|
||
def default_datastore_create_schema(): | ||
return { | ||
'resource_id': [not_missing, not_empty, unicode], | ||
'fields': default_fields_schema(), | ||
'records': [ignore], | ||
'__extras': [empty], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import ckan.plugins as p | ||
import ckanext.datastore.logic.action.create as action_create | ||
import ckanext.datastore.logic.auth.create as auth_create | ||
|
||
|
||
class DatastorePlugin(p.SingletonPlugin): | ||
''' | ||
Datastore plugin. | ||
''' | ||
p.implements(p.IActions) | ||
p.implements(p.IAuthFunctions) | ||
|
||
def get_actions(self): | ||
return {'datastore_create': action_create.datastore_create} | ||
|
||
def get_auth_functions(self): | ||
return {'datastore_create': auth_create.datastore_create} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import json | ||
import ckan.plugins as p | ||
import ckan.lib.create_test_data as ctd | ||
import ckan.model as model | ||
import ckan.tests as tests | ||
|
||
|
||
class TestDatastore(tests.WsgiAppCase): | ||
sysadmin_user = None | ||
normal_user = None | ||
|
||
@classmethod | ||
def setup_class(cls): | ||
p.load('datastore') | ||
ctd.CreateTestData.create() | ||
cls.sysadmin_user = model.User.get('testsysadmin') | ||
cls.normal_user = model.User.get('annafan') | ||
|
||
@classmethod | ||
def teardown_class(cls): | ||
model.repo.rebuild_db() | ||
|
||
def test_create_empty_fails(self): | ||
postparams = '%s=1' % json.dumps({}) | ||
res = self.app.post('/api/action/datastore_create', params=postparams, | ||
status=409) | ||
res_dict = json.loads(res.body) | ||
assert res_dict['success'] is False | ||
|
||
def test_create_requires_auth(self): | ||
resource = model.Package.get('annakarenina').resources[0] | ||
data = { | ||
'resource_id': resource.id | ||
} | ||
postparams = '%s=1' % json.dumps(data) | ||
res = self.app.post('/api/action/datastore_create', params=postparams, | ||
status=403) | ||
res_dict = json.loads(res.body) | ||
assert res_dict['success'] is False | ||
|
||
def test_create_basic(self): | ||
resource = model.Package.get('annakarenina').resources[0] | ||
data = { | ||
'resource_id': resource.id, | ||
'fields': [{'id': 'book', 'label': 'Name', 'type': 'text'}, | ||
{'id': 'author', 'label': 'Author ', 'type': 'text'}], | ||
'records': [{'book': 'annakarenina', 'author': 'tolstoy'}, | ||
{'book': 'warandpeace', 'author': 'tolstoy'}] | ||
} | ||
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) | ||
res_dict = json.loads(res.body) | ||
|
||
assert res_dict['success'] is True | ||
assert res_dict['result']['resource_id'] == data['resource_id'] | ||
assert res_dict['result']['fields'] == data['fields'] | ||
assert res_dict['result']['records'] == data['records'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters