Added basic implentation for where
This commit is contained in:
@@ -45,7 +45,7 @@ class SheerkaCreateNewConcept:
|
||||
|
||||
# add the BNF if known
|
||||
if concept.bnf:
|
||||
concepts_definitions = self.sheerka.get_concept_definition()
|
||||
concepts_definitions = self.sheerka.get_concepts_definitions(context)
|
||||
concepts_definitions[concept] = concept.bnf
|
||||
|
||||
# check if it's a valid BNF or whether it breaks the known rules
|
||||
@@ -61,22 +61,26 @@ class SheerkaCreateNewConcept:
|
||||
# save the new concept in sdp
|
||||
try:
|
||||
# TODO : needs to make these calls atomic (or at least one single call)
|
||||
# save the new concept
|
||||
self.sheerka.sdp.add(
|
||||
context.event.get_digest(),
|
||||
self.sheerka.CONCEPTS_ENTRY,
|
||||
concept,
|
||||
use_ref=True)
|
||||
# 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)
|
||||
# update the definition table
|
||||
if concepts_definitions is not None:
|
||||
self.sheerka.sdp.set(
|
||||
context.event.get_digest(),
|
||||
self.sheerka.CONCEPTS_DEFINITIONS_ENTRY,
|
||||
concepts_definitions,
|
||||
concept_lexer_parser.encode_grammar(init_ret_value.body),
|
||||
use_ref=True)
|
||||
self.sheerka.concepts_definitions_cache = None # invalidate cache
|
||||
except SheerkaDataProviderDuplicateKeyError as error:
|
||||
context.log_error(logger, "Failed to create a new concept.", who=self.logger_name)
|
||||
return self.sheerka.ret(
|
||||
@@ -94,6 +98,3 @@ class SheerkaCreateNewConcept:
|
||||
# process the return in needed
|
||||
ret = self.sheerka.ret(self.logger_name, True, self.sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProvider
|
||||
import pprint
|
||||
import os
|
||||
|
||||
|
||||
def get_pp():
|
||||
rows, columns = os.popen('stty size', 'r').read().split()
|
||||
pp = pprint.PrettyPrinter(width=columns, compact=True)
|
||||
return pp
|
||||
|
||||
|
||||
class SheerkaDump:
|
||||
@@ -71,3 +80,8 @@ class SheerkaDump:
|
||||
break
|
||||
|
||||
page_count += 1
|
||||
|
||||
def dump_state(self):
|
||||
snapshot = self.sheerka.sdp.get_snapshot(SheerkaDataProvider.HeadFile)
|
||||
state = self.sheerka.sdp.load_state(snapshot)
|
||||
self.sheerka.log.info(get_pp().pformat(state.data))
|
||||
|
||||
@@ -147,9 +147,6 @@ class SheerkaEvaluateConcept:
|
||||
if concept.metadata.is_evaluated:
|
||||
return concept
|
||||
|
||||
# WHERE condition should already be validated by the parser.
|
||||
# It's a mandatory condition for the concept before it can be recognized
|
||||
|
||||
#
|
||||
# TODO : Validate the PRE condition
|
||||
#
|
||||
@@ -157,8 +154,8 @@ class SheerkaEvaluateConcept:
|
||||
self.initialize_concept_asts(context, concept, logger)
|
||||
|
||||
# to make sure of the order, it don't use ConceptParts.get_parts()
|
||||
# props must be evaluated first
|
||||
all_metadata_to_eval = ["props", "where", "pre", "post", "body"]
|
||||
# props must be evaluated first, body must be evaluated before where
|
||||
all_metadata_to_eval = ["pre", "post", "props", "body", "where"]
|
||||
|
||||
for metadata_to_eval in all_metadata_to_eval:
|
||||
if metadata_to_eval == "props":
|
||||
@@ -186,6 +183,12 @@ class SheerkaEvaluateConcept:
|
||||
else:
|
||||
concept.values[part_key] = resolved
|
||||
|
||||
# validate where clause
|
||||
if concept.metadata.where is not None:
|
||||
where_value = concept.values[ConceptParts.WHERE]
|
||||
if not (where_value is None or self.sheerka.value(where_value) is True):
|
||||
return self.sheerka.new(BuiltinConcepts.WHERE_CLAUSE_FAILED, body=concept)
|
||||
|
||||
#
|
||||
# TODO : Validate the POST condition
|
||||
#
|
||||
|
||||
@@ -19,7 +19,7 @@ class History:
|
||||
return msg
|
||||
|
||||
def __repr__(self):
|
||||
return f"event={self.event!r}, status={self.status}, result={self.result}"
|
||||
return f"History(event={self.event!r}, status={self.status}, result={self.result})"
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
|
||||
@@ -38,6 +38,21 @@ class SheerkaSetsManager:
|
||||
context.log_error(logger, "Failed to add to set.", who=self.logger_name)
|
||||
return self.sheerka.ret(self.logger_name, False, ErrorConcept(error), error.args[0])
|
||||
|
||||
def add_concepts_to_set(self, context, concepts, concept_set, logger=None):
|
||||
"""Adding multiple concepts at the same time"""
|
||||
logger = logger or self.sheerka.log
|
||||
|
||||
context.log(logger, f"Adding concepts {concepts} to set {concept_set}", who=self.logger_name)
|
||||
previous = self.sheerka.sdp.get_safe(GROUP_PREFIX + concept_set.id)
|
||||
|
||||
new_ids = [c.id for c in concepts] if previous is None else previous + [c.id for c in concepts]
|
||||
try:
|
||||
self.sheerka.sdp.set(context.event.get_digest(), GROUP_PREFIX + concept_set.id, new_ids)
|
||||
return self.sheerka.ret(self.logger_name, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
|
||||
except Exception as error:
|
||||
context.log_error(logger, "Failed to add to set.", who=self.logger_name)
|
||||
return self.sheerka.ret(self.logger_name, False, ErrorConcept(error), error.args[0])
|
||||
|
||||
def get_set_elements(self, concept):
|
||||
"""
|
||||
Concept is supposed to be a set
|
||||
|
||||
@@ -22,6 +22,7 @@ import logging
|
||||
# BuiltinConcepts.AFTER_EVALUATION]
|
||||
|
||||
CONCEPT_LEXER_PARSER_CLASS = "parsers.ConceptLexerParser.ConceptLexerParser"
|
||||
BNF_PARSER_CLASS = "parsers.BnfParser.BnfParser"
|
||||
CONCEPTS_FILE = "_concepts.txt"
|
||||
|
||||
|
||||
@@ -52,7 +53,7 @@ class Sheerka(Concept):
|
||||
|
||||
# cache for concept definitions,
|
||||
# Primarily used for unit test that does not have access to sdp
|
||||
self.concepts_definition_cache = {}
|
||||
self.concepts_definitions_cache = {}
|
||||
|
||||
#
|
||||
# cache for concepts grammars
|
||||
@@ -187,7 +188,8 @@ class Sheerka(Concept):
|
||||
|
||||
def initialize_concepts_definitions(self, execution_context):
|
||||
self.init_log.debug("Initializing concepts definitions")
|
||||
definitions = self.sdp.get_safe(self.CONCEPTS_DEFINITIONS_ENTRY, load_origin=False)
|
||||
# definitions = self.sdp.get_safe(self.CONCEPTS_DEFINITIONS_ENTRY, load_origin=False)
|
||||
definitions = self.get_concepts_definitions(execution_context)
|
||||
|
||||
if definitions is None:
|
||||
self.init_log.debug("No BNF defined")
|
||||
@@ -389,14 +391,26 @@ class Sheerka(Concept):
|
||||
|
||||
return result or self._get_unknown(('id', concept_id))
|
||||
|
||||
def get_concept_definition(self):
|
||||
if self.concepts_definition_cache:
|
||||
return self.concepts_definition_cache
|
||||
def get_concepts_definitions(self, context):
|
||||
if self.concepts_definitions_cache:
|
||||
return self.concepts_definitions_cache
|
||||
|
||||
self.concepts_definition_cache = self.sdp.get_safe(
|
||||
encoded = self.sdp.get_safe(
|
||||
self.CONCEPTS_DEFINITIONS_ENTRY,
|
||||
load_origin=False) or {}
|
||||
return self.concepts_definition_cache
|
||||
|
||||
self.concepts_definitions_cache = {}
|
||||
bnf_parser = self.parsers[BNF_PARSER_CLASS]()
|
||||
for k, v in encoded.items():
|
||||
key, id_ = core.utils.unstr_concept(k)
|
||||
concept = self.new((key, id_))
|
||||
rule_result = bnf_parser.parse(context, v)
|
||||
if rule_result.status:
|
||||
self.concepts_definitions_cache[concept] = rule_result.value.value
|
||||
else:
|
||||
self.log.error(f"Failed to load bnf rule for concept {key}")
|
||||
|
||||
return self.concepts_definitions_cache
|
||||
|
||||
def new(self, concept_key, **kwargs):
|
||||
"""
|
||||
@@ -411,7 +425,7 @@ class Sheerka(Concept):
|
||||
else:
|
||||
concept_id = None
|
||||
|
||||
template = self.get(concept_key, concept_id)
|
||||
template = self.get_by_id(concept_id) if not concept_key else self.get(concept_key, concept_id)
|
||||
|
||||
# manage concept not found
|
||||
if self.isinstance(template, BuiltinConcepts.UNKNOWN_CONCEPT) and \
|
||||
@@ -579,7 +593,10 @@ class Sheerka(Concept):
|
||||
self.during_restore = True
|
||||
with open(CONCEPTS_FILE, "r") as f:
|
||||
for line in f.readlines():
|
||||
self.log.info(line.strip())
|
||||
line = line.strip()
|
||||
if line == "" or line.startswith("#"):
|
||||
continue
|
||||
self.log.info(line)
|
||||
self.evaluate_user_input(line)
|
||||
self.during_restore = False
|
||||
except IOError:
|
||||
|
||||
Reference in New Issue
Block a user