Added ModifyConcept function, and fixed 'isa' not working

This commit is contained in:
2020-02-20 11:30:53 +01:00
parent 87f232b527
commit 7cd94e888f
17 changed files with 750 additions and 228 deletions
+27 -2
View File
@@ -1,6 +1,6 @@
import hashlib
from collections import namedtuple
from dataclasses import dataclass, field
from dataclasses import dataclass
from enum import Enum
from core.sheerka_logger import get_logger
@@ -15,6 +15,7 @@ PROPERTIES_FOR_DIGEST = ("name", "key",
PROPERTIES_TO_SERIALIZE = PROPERTIES_FOR_DIGEST + tuple(["id"])
PROPERTIES_FOR_NEW = ("where", "pre", "post", "body", "desc")
VARIABLE_PREFIX = "__var__"
ORIGIN = "##origin##" # same as Serializer.ORIGIN but I don't want to include the reference
class ConceptParts(Enum):
@@ -97,6 +98,7 @@ class Concept:
self.bnf = None
self.log = get_logger("core." + self.__class__.__name__)
self.init_log = get_logger("init.core." + self.__class__.__name__)
self.original_definition_hash = None
def __repr__(self):
return f"({self.metadata.id}){self.metadata.name}"
@@ -243,7 +245,19 @@ class Concept:
def body(self):
return self.values[ConceptParts.BODY] if ConceptParts.BODY in self.values else None
def get_digest(self):
def get_origin(self):
"""
Return the digest used to save the concept if it exists
:return:
"""
if hasattr(self, ORIGIN):
return getattr(self, ORIGIN)
return None
def set_origin(self, origin):
setattr(self, ORIGIN, origin)
def get_definition_hash(self):
"""
Returns the digest of the event
:return: hexa form of the sha256
@@ -301,6 +315,11 @@ class Concept:
for k, v in other.props.items():
self.set_prop(k, v.value)
# origin
from sdp.sheerkaSerializer import Serializer
if hasattr(other, Serializer.ORIGIN):
setattr(self, Serializer.ORIGIN, getattr(other, Serializer.ORIGIN))
return self
def set_prop(self, prop_name, prop_value):
@@ -362,6 +381,12 @@ class Concept:
self.metadata.is_evaluated = True
return self
def freeze_definition_hash(self):
self.original_definition_hash = self.get_definition_hash()
def get_original_definition_hash(self):
return self.original_definition_hash
class Property:
"""
@@ -1,6 +1,6 @@
from core.builtin_concepts import BuiltinConcepts, ErrorConcept
from core.concept import Concept
from sdp.sheerkaDataProvider import SheerkaDataProviderDuplicateKeyError
from sdp.sheerkaDataProvider import SheerkaDataProviderDuplicateKeyError, SheerkaDataProviderRef
CONCEPT_LEXER_PARSER_CLASS = "parsers.ConceptLexerParser.ConceptLexerParser"
@@ -30,7 +30,7 @@ class SheerkaCreateNewConcept:
# checks for duplicate concepts
# TODO checks if it exists in cache first
if self.sheerka.sdp.exists(self.sheerka.CONCEPTS_ENTRY, concept.key, concept.get_digest()):
if self.sheerka.sdp.exists(self.sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash()):
error = SheerkaDataProviderDuplicateKeyError(self.sheerka.CONCEPTS_ENTRY + "." + concept.key, concept)
return self.sheerka.ret(
self.logger_name,
@@ -55,22 +55,35 @@ class SheerkaCreateNewConcept:
if not init_ret_value.status:
return self.sheerka.ret(self.logger_name, False, ErrorConcept(init_ret_value.value))
concept.freeze_definition_hash()
# save the new concept in sdp
concept.metadata.full_serialization = True
try:
# TODO : needs to make these calls atomic (or at least one single call)
# save the new concept
self.sheerka.sdp.add(
concept.metadata.full_serialization = True
result = self.sheerka.sdp.add(
context.event.get_digest(),
self.sheerka.CONCEPTS_ENTRY,
concept,
use_ref=True)
concept.metadata.full_serialization = False
# update the concept (I hope that it's enough)
concept.set_origin(result.digest)
# save it by id
self.sheerka.sdp.add(
context.event.get_digest(),
self.sheerka.CONCEPTS_BY_ID_ENTRY,
{concept.id: concept.get_digest()},
is_ref=True)
SheerkaDataProviderRef(concept.id, result.digest))
# records the hash
self.sheerka.sdp.add(
context.event.get_digest(),
self.sheerka.CONCEPTS_BY_HASH_ENTRY,
SheerkaDataProviderRef(concept.get_definition_hash(), result.digest))
# update the definition table
if concepts_definitions is not None:
self.sheerka.sdp.set(
@@ -88,7 +101,7 @@ class SheerkaCreateNewConcept:
error.args[0])
# Updates the caches
concept.metadata.full_serialization = False
self.sheerka.cache_by_key[concept.key] = self.sheerka.sdp.get_safe(self.sheerka.CONCEPTS_ENTRY, concept.key)
self.sheerka.cache_by_id[concept.id] = concept
if init_ret_value is not None and init_ret_value.status:
+1 -1
View File
@@ -63,7 +63,7 @@ class SheerkaDump:
else:
self.sheerka.log.info("No property")
self.sheerka.log.info(f"digest : {c.get_digest()}")
self.sheerka.log.info(f"digest : {c.get_origin()}")
if self.sheerka.isaset(context, c):
items = self.sheerka.get_set_elements(context, c)
@@ -1,4 +1,5 @@
from core.builtin_concepts import BuiltinConcepts
from sdp.sheerkaDataProvider import SheerkaDataProviderRef
class SheerkaModifyConcept:
@@ -8,7 +9,41 @@ class SheerkaModifyConcept:
def modify_concept(self, context, concept):
self.sheerka.sdp.modify(context.event.get_digest(), self.sheerka.CONCEPTS_ENTRY, concept.key, concept)
try:
# modify the entry
concept.metadata.full_serialization = True
result = self.sheerka.sdp.modify(
context.event.get_digest(),
self.sheerka.CONCEPTS_ENTRY,
concept.key,
concept)
concept.metadata.full_serialization = False
# update its reference
self.sheerka.sdp.modify(
context.event.get_digest(),
self.sheerka.CONCEPTS_BY_ID_ENTRY,
concept.id,
SheerkaDataProviderRef(concept.id, result.digest, concept.get_origin()))
# update the hash entry
self.sheerka.sdp.modify(
context.event.get_digest(),
self.sheerka.CONCEPTS_BY_HASH_ENTRY,
concept.get_original_definition_hash(),
SheerkaDataProviderRef(concept.get_definition_hash(), result.digest, concept.get_origin()))
except IndexError as error:
context.log_error(f"Failed to update concept '{concept}'.", who=self.logger_name)
return self.sheerka.ret(
self.logger_name,
False,
self.sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body=concept),
error.args[0])
# update cache
self.sheerka.cache_by_key[concept.key] = self.sheerka.sdp.get_safe(self.sheerka.CONCEPTS_ENTRY, concept.key)
self.sheerka.cache_by_id[concept.id] = concept
ret = self.sheerka.ret(self.logger_name, True, self.sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
return ret
@@ -48,8 +48,8 @@ class SheerkaSetsManager:
assert concept_set.id
try:
ret = self.sheerka.sdp.add_unique(context.event.get_digest(), GROUP_PREFIX + concept_set.id, concept.id)
if ret == (None, None): # concept already in set
result = self.sheerka.sdp.add_unique(context.event.get_digest(), GROUP_PREFIX + concept_set.id, concept.id)
if result.already_exists: # concept already in set
return self.sheerka.ret(
self.logger_name,
False,
+2
View File
@@ -34,6 +34,7 @@ class Sheerka(Concept):
CONCEPTS_ENTRY = "All_Concepts" # to store all the concepts
CONCEPTS_BY_ID_ENTRY = "Concepts_By_ID"
CONCEPTS_BY_HASH_ENTRY = "Concepts_By_Hash" # store hash of concepts definitions (not values)
CONCEPTS_DEFINITIONS_ENTRY = "Concepts_Definitions" # to store definitions (bnf) of concepts
BUILTIN_CONCEPTS_KEYS = "Builtins_Concepts" # sequential key for builtin concepts
USER_CONCEPTS_KEYS = "User_Concepts" # sequential key for user defined concepts
@@ -482,6 +483,7 @@ class Sheerka(Concept):
# otherwise, create another instance
concept = self.builtin_cache[key]() if key in self.builtin_cache else Concept()
concept.update_from(template)
concept.freeze_definition_hash()
if len(kwargs) == 0:
return concept