Skip to content

Commit

Permalink
added example of implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
smotornyuk committed Mar 3, 2017
1 parent eef9925 commit 65c2bb6
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 1 deletion.
4 changes: 4 additions & 0 deletions ckanext/datastore/backend/__init__.py
Expand Up @@ -58,6 +58,10 @@ class InvalidDataError(Exception):
class DatastoreBackend:
"""Base class for all datastore backends.
Very simple example of implementation based on SQLite can be found in
`ckanext.datastore.backend.example`. In order to use it, set datastore.write_url
to 'example-sqlite:////tmp/database-name-on-your-choice'
:prop _backend: mapping(schema, class) of all registered backends
:type _backend: dictonary
:prop _active_backend: current active backend
Expand Down
118 changes: 118 additions & 0 deletions ckanext/datastore/backend/example.py
@@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-

import re
import logging
from sqlalchemy import create_engine

from ckanext.datastore.backend import DatastoreBackend

log = logging.getLogger(__name__)


class DatastoreExampleSqliteBackend(DatastoreBackend):

def __init__(self):
self._engine = None

def _get_engine(self):
if not self._engine:
self._engine = create_engine(self.write_url)
return self._engine

def _insert_records(self, table, records):
if len(records):
for record in records:
self._get_engine().execute(
'INSERT INTO "{0}"({1}) VALUES({2})'.format(
table,
', '.join(record.keys()),
', '.join(['?'] * len(record.keys()))
),
record.values()
)
pass


def configure(self, config):
self.write_url = config.get(
'ckan.datastore.write_url').replace('example-', '')

return config

def create(self, context, data_dict):
columns = str(', '.join(
map(lambda e: e['id'] + ' text', data_dict['fields'])))
engine = self._get_engine()
engine.execute(
' CREATE TABLE IF NOT EXISTS "{name}"({columns});'.format(
name=data_dict['resource_id'],
columns=columns
))
self._insert_records(data_dict['resource_id'], data_dict['records'])
return data_dict

def upsert(self, context, data_dict):
raise NotImplementedError()

def delete(self, context, data_dict):
engine = self._get_engine()
result = engine.execute('DROP TABLE IF EXISTS "{0}"'.format(
data_dict['resource_id']
))
return data_dict

def search(self, context, data_dict):
engine = self._get_engine()
result = engine.execute('SELECT * FROM "{0}" LIMIT {1}'.format(
data_dict['resource_id'],
data_dict.get('limit', 10)
))

data_dict['records'] = map(dict, result.fetchall())
data_dict['total'] = len(data_dict['records'])
data_dict['fields'] = self.resource_fields(data_dict['resource_id'])
return data_dict

def search_sql(self, context, data_dict):
raise NotImplementedError()

def make_private(self, context, data_dict):
pass

def make_public(self, context, data_dict):
pass

def resource_exists(self, id):
return self._get_engine().execute(
'''
select name from sqlite_master
where type = "table" and name = "{0}"'''.format(
id)
).fetchone()

def resource_fields(self, id):
result = []
engine = self._get_engine()
info = engine.execute('PRAGMA table_info("{0}")'.format(id)).fetchall()

for col in info:
result.append({
'type': col.type,
'id': col.name
})
return result

def resource_info(self, id):
raise NotImplementedError()

def resource_id_from_alias(self, alias):
if self.resource_exists(alias):
return True, alias
return False, alias

def get_all_ids(self):
return map(lambda t: t.name, self._get_engine().execute(
'''
select name from sqlite_master
where type = "table"'''
).fetchall())
4 changes: 3 additions & 1 deletion ckanext/datastore/plugin.py
Expand Up @@ -18,6 +18,7 @@
DatastoreBackend
)
from ckanext.datastore.backend.postgres import DatastorePostgresqlBackend
from ckanext.datastore.backend.example import DatastoreExampleSqliteBackend

log = logging.getLogger(__name__)
_get_or_bust = logic.get_or_bust
Expand Down Expand Up @@ -58,7 +59,8 @@ def __new__(cls, *args, **kwargs):

def register_backends(self):
return {
'postgresql': DatastorePostgresqlBackend
'postgresql': DatastorePostgresqlBackend,
'example-sqlite': DatastoreExampleSqliteBackend
}

# IConfigurer
Expand Down

0 comments on commit 65c2bb6

Please sign in to comment.