Add template value compilation

This commit is contained in:
Yuriy Taraday 2016-01-19 17:14:23 +03:00
parent f737ac7bf5
commit f78785950e
3 changed files with 103 additions and 0 deletions

2
TODO
View File

@ -3,3 +3,5 @@
allowed on both collection and element which leads to bad error codes)
* add cascade deletes or smth like it
* verify that schema/template is actually related to environment
* add component priorities
* add versioning of all data

View File

@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import collections
import functools
import itertools
import flask
@ -227,6 +229,47 @@ class EnvironmentSchemaValues(flask_restful.Resource):
return None, 204
@api.resource(
'/environments/<int:environment_id>' +
'/templates/<int:template_id>/<levels:levels>values')
class EnvironmentTemplateValues(flask_restful.Resource):
def get(self, environment_id, template_id, levels):
environment = db.Environment.query.get_or_404(environment_id)
template = db.Template.query.get_or_404(template_id)
level_values = list(iter_environment_level_values(environment, levels))
query = (
db.db.session.query(db.EnvironmentSchemaValues, db.Namespace)
.join(db.Schema)
.join(db.Namespace)
.filter(db.EnvironmentSchemaValues.level_value_id.in_(
[lv.id for lv in level_values]))
)
namespaces_schemas = query.all()
namespaces_levels = collections.defaultdict(
functools.partial(collections.defaultdict, dict))
# Merge data on every level
for esv, namespace in namespaces_schemas:
nl = namespaces_levels[namespace.name][esv.level_value]
nl.update(esv.values)
# Merge data across levels
namespaces_data = {}
for ns_name, ns_levels in namespaces_levels.items():
ns_data = {}
for level_value in level_values:
try:
values = ns_levels[level_value]
except KeyError:
pass
else:
ns_data.update(values)
namespaces_data[ns_name] = ns_data
result = {}
for key, value_tmpl in template.content.items():
ns_name, ns_key = value_tmpl.split('.')
result[key] = namespaces_data[ns_name][ns_key]
return result
def build_app():
app = flask.Flask(__name__)
app.url_map.converters['levels'] = LevelsConverter

View File

@ -342,6 +342,64 @@ class TestApp(base.TestCase):
{"message": "Unexpected level name 'lvlx'. Expected 'lvl1'."},
)
def test_get_etv(self):
self._fixture()
res = self.client.put('/environments/9/schema/5/values',
data={'key': 'value'})
self.assertEqual(res.status_code, 204)
self.assertEqual(res.data, b'')
res = self.client.get('/environments/9/templates/5/lvl1/1/values')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.json, {'my_key': 'value'})
def test_get_etv_level_override(self):
self._fixture()
res = self.client.put('/environments/9/schema/5/values',
data={'key': 'value'})
res = self.client.put('/environments/9/schema/5/lvl1/1/values',
data={'key': 'value1'})
res = self.client.put('/environments/9/schema/5/lvl1/2/values',
data={'key': 'value2'})
self.assertEqual(res.status_code, 204)
self.assertEqual(res.data, b'')
res = self.client.get('/environments/9/templates/5/lvl1/1/values')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.json, {'my_key': 'value1'})
def test_get_etv_two_namespaces(self):
self._fixture()
with self.app.app_context():
schema = db.Schema(
namespace=db.Namespace(name='other_ns'),
content={'key1': 'description'},
)
template = db.Template(
content={'mkey1': 'nsname.key', 'mkey2': 'other_ns.key1'},
)
component = db.Component(
name='testcomp',
schemas=[schema],
templates=[template],
)
db.db.session.add(component)
db.db.session.commit()
db.db.session.refresh(schema)
db.db.session.refresh(template)
res = self.client.put('/environments/9/schema/5/values',
data={'key': 'value'})
res = self.client.put(
'/environments/9/schema/{}/lvl1/1/values'.format(schema.id),
data={'key1': 'value1'},
)
self.assertEqual(res.status_code, 204)
self.assertEqual(res.data, b'')
res = self.client.get(
'/environments/9/templates/{}/lvl1/1/values'.format(template.id),
)
self.assertEqual(res.status_code, 200)
self.assertEqual(res.json, {'mkey1': 'value', 'mkey2': 'value1'})
class TestLevelsConverter(base.TestCase):
def setUp(self):