R: Backend cleanup and query improvements

This commit is contained in:
Ivan 2024-07-31 21:09:42 +03:00
parent 2a30661355
commit 057850678a
7 changed files with 59 additions and 61 deletions

View File

@ -2,10 +2,8 @@
For more specific TODOs see comments in code
[Functionality - PROGRESS]
- Operational synthesis schema as LibraryItem ?
- Library organization, search and exploration. Consider new user experience
- Private projects and permissions. Consider cooperative editing
- Design first user experience
- Private projects. Consider cooperative editing
[Functionality - PENDING]

View File

@ -198,7 +198,7 @@ class OperationSchema:
# TODO: remove duplicates from diamond
for cst in receiver.constituents():
parent = parents.get(cst.id)
parent = parents.get(cst.pk)
assert parent is not None
Inheritance.objects.create(
child=cst,

View File

@ -91,24 +91,24 @@ class OperationUpdateSerializer(serializers.Serializer):
if 'substitutions' not in attrs:
return attrs
schemas = [arg.result.pk for arg in attrs['arguments'] if arg.result is not None]
schemas = [arg.result_id for arg in attrs['arguments'] if arg.result is not None]
substitutions = attrs['substitutions']
to_delete = {x['original'].pk for x in substitutions}
deleted = set()
for item in substitutions:
original_cst = cast(Constituenta, item['original'])
substitution_cst = cast(Constituenta, item['substitution'])
if original_cst.schema.pk not in schemas:
if original_cst.schema_id not in schemas:
raise serializers.ValidationError({
f'{original_cst.id}': msg.constituentaNotFromOperation()
f'{original_cst.pk}': msg.constituentaNotFromOperation()
})
if substitution_cst.schema.pk not in schemas:
if substitution_cst.schema_id not in schemas:
raise serializers.ValidationError({
f'{substitution_cst.id}': msg.constituentaNotFromOperation()
f'{substitution_cst.pk}': msg.constituentaNotFromOperation()
})
if original_cst.pk in deleted or substitution_cst.pk in to_delete:
raise serializers.ValidationError({
f'{original_cst.id}': msg.substituteDouble(original_cst.alias)
f'{original_cst.pk}': msg.substituteDouble(original_cst.alias)
})
if original_cst.schema == substitution_cst.schema:
raise serializers.ValidationError({

View File

@ -142,7 +142,7 @@ class RSForm:
result.definition_resolved = resolver.resolve(result.definition_raw)
result.save()
self.on_term_change([result.id])
self.on_term_change([result.pk])
result.refresh_from_db()
return result
@ -213,7 +213,7 @@ class RSForm:
count_bot = 0
size = len(listCst)
update_list = []
for cst in self.constituents().only('id', 'order').order_by('order'):
for cst in self.constituents().only('order').order_by('order'):
if cst not in listCst:
if count_top + 1 < target:
cst.order = count_top + 1
@ -248,7 +248,7 @@ class RSForm:
mapping = {original.alias: substitution.alias}
self.apply_mapping(mapping)
original.delete()
self.on_term_change([substitution.id])
self.on_term_change([substitution.pk])
def restore_order(self):
''' Restore order based on types and term graph. '''
@ -335,7 +335,7 @@ class RSForm:
definition_formal=text,
cst_type=cst_type
)
result.append(new_item.id)
result.append(new_item.pk)
free_index = free_index + 1
position = position + 1
@ -347,7 +347,7 @@ class RSForm:
return
update_list = \
Constituenta.objects \
.only('id', 'order', 'schema') \
.only('order') \
.filter(schema=self.model, order__gte=start)
for cst in update_list:
cst.order += shift
@ -372,7 +372,7 @@ class RSForm:
@transaction.atomic
def _reset_order(self):
order = 1
for cst in self.constituents().only('id', 'order').order_by('order'):
for cst in self.constituents().only('order').order_by('order'):
if cst.order != order:
cst.order = order
cst.save()
@ -383,15 +383,15 @@ class RSForm:
result: Graph[int] = Graph()
cst_list = \
self.constituents() \
.only('id', 'order', 'alias', 'definition_formal') \
.only('alias', 'definition_formal') \
.order_by('order')
for cst in cst_list:
result.add_node(cst.id)
result.add_node(cst.pk)
for cst in cst_list:
for alias in extract_globals(cst.definition_formal):
try:
child = cst_list.get(alias=alias)
result.add_edge(src=child.id, dest=cst.id)
result.add_edge(src=child.pk, dest=cst.pk)
except Constituenta.DoesNotExist:
pass
return result
@ -401,15 +401,15 @@ class RSForm:
result: Graph[int] = Graph()
cst_list = \
self.constituents() \
.only('id', 'order', 'alias', 'term_raw') \
.only('alias', 'term_raw') \
.order_by('order')
for cst in cst_list:
result.add_node(cst.id)
result.add_node(cst.pk)
for cst in cst_list:
for alias in extract_entities(cst.term_raw):
try:
child = cst_list.get(alias=alias)
result.add_edge(src=child.id, dest=cst.id)
result.add_edge(src=child.pk, dest=cst.pk)
except Constituenta.DoesNotExist:
pass
return result
@ -419,15 +419,15 @@ class RSForm:
result: Graph[int] = Graph()
cst_list = \
self.constituents() \
.only('id', 'order', 'alias', 'definition_raw') \
.only('alias', 'definition_raw') \
.order_by('order')
for cst in cst_list:
result.add_node(cst.id)
result.add_node(cst.pk)
for cst in cst_list:
for alias in extract_entities(cst.definition_raw):
try:
child = cst_list.get(alias=alias)
result.add_edge(src=child.id, dest=cst.id)
result.add_edge(src=child.pk, dest=cst.pk)
except Constituenta.DoesNotExist:
pass
return result
@ -440,16 +440,16 @@ class SemanticInfo:
self._graph = schema._graph_formal()
self._items = list(
schema.constituents()
.only('id', 'alias', 'cst_type', 'definition_formal')
.only('alias', 'cst_type', 'definition_formal')
.order_by('order')
)
self._cst_by_alias = {cst.alias: cst for cst in self._items}
self._cst_by_ID = {cst.id: cst for cst in self._items}
self._cst_by_ID = {cst.pk: cst for cst in self._items}
self.info = {
cst.id: {
cst.pk: {
'is_simple': False,
'is_template': False,
'parent': cst.id,
'parent': cst.pk,
'children': []
}
for cst in self._items
@ -491,7 +491,7 @@ class SemanticInfo:
if target.cst_type == CstType.STRUCTURED or is_base_set(target.cst_type):
return False
dependencies = self._graph.inputs[target.id]
dependencies = self._graph.inputs[target.pk]
has_complex_dependency = any(
self.is_template(cst_id) and
not self.is_simple_expression(cst_id) for cst_id in dependencies
@ -507,18 +507,18 @@ class SemanticInfo:
def _infer_parent(self, target: Constituenta) -> int:
sources = self._extract_sources(target)
if len(sources) != 1:
return target.id
return target.pk
parent_id = next(iter(sources))
parent = self._cst_by_ID[parent_id]
if is_base_set(parent.cst_type):
return target.id
return target.pk
return parent_id
def _extract_sources(self, target: Constituenta) -> set[int]:
sources: set[int] = set()
if not is_functional(target.cst_type):
for parent_id in self._graph.inputs[target.id]:
for parent_id in self._graph.inputs[target.pk]:
parent_info = self[parent_id]
if not parent_info['is_template'] or not parent_info['is_simple']:
sources.add(parent_info['parent'])
@ -531,7 +531,7 @@ class SemanticInfo:
if not parent:
continue
parent_info = self[parent.id]
parent_info = self[parent.pk]
if not parent_info['is_template'] or not parent_info['is_simple']:
sources.add(parent_info['parent'])
@ -542,7 +542,7 @@ class SemanticInfo:
if not parent:
continue
parent_info = self[parent.id]
parent_info = self[parent.pk]
if not is_base_set(parent.cst_type) and \
(not parent_info['is_template'] or not parent_info['is_simple']):
sources.add(parent_info['parent'])
@ -567,10 +567,10 @@ class _OrderManager:
self._graph = schema._graph_formal()
self._items = list(
schema.constituents()
.only('id', 'order', 'alias', 'cst_type', 'definition_formal')
.only('order', 'alias', 'cst_type', 'definition_formal')
.order_by('order')
)
self._cst_by_ID = {cst.id: cst for cst in self._items}
self._cst_by_ID = {cst.pk: cst for cst in self._items}
def restore_order(self) -> None:
''' Implement order restoration process. '''
@ -582,20 +582,20 @@ class _OrderManager:
self._save_order()
def _fix_topological(self) -> None:
sorted_ids = self._graph.sort_stable([cst.id for cst in self._items])
sorted_items = [next(cst for cst in self._items if cst.id == id) for id in sorted_ids]
sorted_ids = self._graph.sort_stable([cst.pk for cst in self._items])
sorted_items = [next(cst for cst in self._items if cst.pk == id) for id in sorted_ids]
self._items = sorted_items
def _fix_kernel(self) -> None:
result = [cst for cst in self._items if cst.cst_type == CstType.BASE]
result = result + [cst for cst in self._items if cst.cst_type == CstType.CONSTANT]
kernel = [
cst.id for cst in self._items if
cst.pk for cst in self._items if
cst.cst_type in [CstType.STRUCTURED, CstType.AXIOM] or
self._cst_by_ID[self._semantic.parent(cst.id)].cst_type == CstType.STRUCTURED
self._cst_by_ID[self._semantic.parent(cst.pk)].cst_type == CstType.STRUCTURED
]
kernel = kernel + self._graph.expand_inputs(kernel)
result = result + [cst for cst in self._items if result.count(cst) == 0 and cst.id in kernel]
result = result + [cst for cst in self._items if result.count(cst) == 0 and cst.pk in kernel]
result = result + [cst for cst in self._items if result.count(cst) == 0]
self._items = result
@ -606,11 +606,11 @@ class _OrderManager:
if cst in marked:
continue
result.append(cst)
children = self._semantic[cst.id]['children']
children = self._semantic[cst.pk]['children']
if len(children) == 0:
continue
for child in self._items:
if child.id in children:
if child.pk in children:
marked.add(child)
result.append(child)
self._items = result

View File

@ -48,7 +48,7 @@ class CstSerializer(serializers.ModelSerializer):
term_changed = data['term_resolved'] != instance.term_resolved
result: Constituenta = super().update(instance, data)
if term_changed:
schema.on_term_change([result.id])
schema.on_term_change([result.pk])
result.refresh_from_db()
schema.save()
return result
@ -212,11 +212,11 @@ class CstTargetSerializer(serializers.Serializer):
cst = cast(Constituenta, attrs['target'])
if schema and cst.schema != schema:
raise serializers.ValidationError({
f'{cst.id}': msg.constituentaNotInRSform(schema.title)
f'{cst.pk}': msg.constituentaNotInRSform(schema.title)
})
if cst.cst_type not in [CstType.FUNCTION, CstType.STRUCTURED, CstType.TERM]:
raise serializers.ValidationError({
f'{cst.id}': msg.constituentaNoStructure()
f'{cst.pk}': msg.constituentaNoStructure()
})
self.instance = cst
return attrs
@ -234,7 +234,7 @@ class CstRenameSerializer(serializers.Serializer):
cst = cast(Constituenta, attrs['target'])
if cst.schema != schema:
raise serializers.ValidationError({
f'{cst.id}': msg.constituentaNotInRSform(schema.title)
f'{cst.pk}': msg.constituentaNotInRSform(schema.title)
})
new_alias = self.initial_data['alias']
if cst.alias == new_alias:
@ -260,7 +260,7 @@ class CstListSerializer(serializers.Serializer):
for item in attrs['items']:
if item.schema != schema:
raise serializers.ValidationError({
f'{item.id}': msg.constituentaNotInRSform(schema.title)
f'{item.pk}': msg.constituentaNotInRSform(schema.title)
})
return attrs
@ -291,7 +291,7 @@ class CstSubstituteSerializer(serializers.Serializer):
substitution_cst = cast(Constituenta, item['substitution'])
if original_cst.pk in deleted:
raise serializers.ValidationError({
f'{original_cst.id}': msg.substituteDouble(original_cst.alias)
f'{original_cst.pk}': msg.substituteDouble(original_cst.alias)
})
if original_cst.alias == substitution_cst.alias:
raise serializers.ValidationError({
@ -325,13 +325,13 @@ class InlineSynthesisSerializer(serializers.Serializer):
if user.is_anonymous or (schema_out.owner != user and not user.is_staff):
raise PermissionDenied({
'message': msg.schemaForbidden(),
'object_id': schema_in.id
'object_id': schema_in.pk
})
constituents = cast(list[Constituenta], attrs['items'])
for cst in constituents:
if cst.schema != schema_in:
raise serializers.ValidationError({
f'{cst.id}': msg.constituentaNotInRSform(schema_in.title)
f'{cst.pk}': msg.constituentaNotInRSform(schema_in.title)
})
deleted = set()
for item in attrs['substitutions']:
@ -340,24 +340,24 @@ class InlineSynthesisSerializer(serializers.Serializer):
if original_cst.schema == schema_in:
if original_cst not in constituents:
raise serializers.ValidationError({
f'{original_cst.id}': msg.substitutionNotInList()
f'{original_cst.pk}': msg.substitutionNotInList()
})
if substitution_cst.schema != schema_out:
raise serializers.ValidationError({
f'{substitution_cst.id}': msg.constituentaNotInRSform(schema_out.title)
f'{substitution_cst.pk}': msg.constituentaNotInRSform(schema_out.title)
})
else:
if substitution_cst not in constituents:
raise serializers.ValidationError({
f'{substitution_cst.id}': msg.substitutionNotInList()
f'{substitution_cst.pk}': msg.substitutionNotInList()
})
if original_cst.schema != schema_out:
raise serializers.ValidationError({
f'{original_cst.id}': msg.constituentaNotInRSform(schema_out.title)
f'{original_cst.pk}': msg.constituentaNotInRSform(schema_out.title)
})
if original_cst.pk in deleted:
raise serializers.ValidationError({
f'{original_cst.id}': msg.substituteDouble(original_cst.alias)
f'{original_cst.pk}': msg.substituteDouble(original_cst.alias)
})
deleted.add(original_cst.pk)
return attrs

View File

@ -149,11 +149,11 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
cst = cast(m.Constituenta, serializer.validated_data['target'])
schema_details = s.RSFormParseSerializer(schema).data['items']
cst_parse = next(item for item in schema_details if item['id'] == cst.id)['parse']
cst_parse = next(item for item in schema_details if item['id'] == cst.pk)['parse']
if not cst_parse['typification']:
return Response(
status=c.HTTP_400_BAD_REQUEST,
data={f'{cst.id}': msg.constituentaNoStructure()}
data={f'{cst.pk}': msg.constituentaNoStructure()}
)
result = m.RSForm(schema).produce_structure(cst, cst_parse)

View File

@ -28,7 +28,7 @@ def _extract_item(obj: Any) -> LibraryItem:
return cast(LibraryItem, obj.item)
raise PermissionDenied({
'message': 'Invalid type error. Please contact developers',
'object_id': obj.id
'object_id': obj.pk
})