Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug model edge language #1789

Merged
merged 4 commits into from
Jul 3, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions synapse/lib/storm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1496,12 +1496,14 @@ def help(self, mesg=None):
for names, argdef in options:
self._print_optarg(names, argdef)

self._printf('')
self._printf('Arguments:')
self._printf('')
if self.posargs:

for name, argdef in self.posargs:
self._print_posarg(name, argdef)
self._printf('')
self._printf('Arguments:')
self._printf('')

for name, argdef in self.posargs:
self._print_posarg(name, argdef)

if mesg is not None:
self._printf('')
Expand Down
101 changes: 56 additions & 45 deletions synapse/lib/stormlib/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,64 @@
stormcmds = [
{
'name': 'model.edge.set',
'descr': 'Set a global extended property for an edge verb that exists in the current view.',
'descr': 'Set an key value for an edge verb that exists in the current view.',
vEpiphyte marked this conversation as resolved.
Show resolved Hide resolved
'cmdargs': (
('verb', {'help': 'The edge verb to add an extended property to.'}),
('prop', {'help': 'The extended property name (e.g. doc).'}),
('valu', {'help': 'The extended property string value to set.'}),
('verb', {'help': 'The edge verb to add a key to.'}),
('key', {'help': 'The key name (e.g. doc).'}),
('valu', {'help': 'The string value to set.'}),
),
'storm': '''
$verb = $cmdopts.verb
$prop = $cmdopts.prop
$lib.model.edge.set($verb, $prop, $cmdopts.valu)
$lib.print('Set edge extended prop: verb={verb} prop={prop}', verb=$verb, prop=$prop)
$key = $cmdopts.key
$lib.model.edge.set($verb, $key, $cmdopts.valu)
$lib.print('Set edge key: verb={verb} key={key}', verb=$verb, key=$key)
''',
},
{
'name': 'model.edge.get',
'descr': 'Retrieve global extended properties for an edge verb in the current view.',
'descr': 'Retrieve key-value pairs an edge verb in the current view.',
'cmdargs': (
('verb', {'help': 'The edge verb to retrieve.'}),
),
'storm': '''
$verb = $cmdopts.verb
$props = $lib.model.edge.get($verb)
$doc = $props.doc
if ($doc=$lib.null) { $doc = '' }
$lib.print('\nverb={verb}\ndoc="{doc}"\n', verb=$verb, doc=$doc)
$kvpairs = $lib.model.edge.get($verb)
if $kvpairs {
$lib.print('verb = {verb}', verb=$verb)
for ($key, $valu) in $kvpairs {
$lib.print(' {key} = {valu}', key=$key, valu=$valu)
}
} else {
$lib.print('verb={verb} contains no key-value pairs.', verb=$verb)
}
''',
},
{
'name': 'model.edge.del',
'descr': 'Delete a global extended property for an edge verb in the current view.',
'descr': 'Delete a global key-value pair for an edge verb in the current view.',
'cmdargs': (
('verb', {'help': 'The edge verb to delete documentation for.'}),
('prop', {'help': 'The extended property name (e.g. doc).'}),
('key', {'help': 'The key name (e.g. doc).'}),
),
'storm': '''
$verb = $cmdopts.verb
$prop = $cmdopts.prop
$lib.model.edge.del($verb, $prop)
$lib.print('Deleted edge extended property: verb={verb} prop={prop}', verb=$verb, prop=$prop)
$key = $cmdopts.key
$lib.model.edge.del($verb, $key)
$lib.print('Deleted edge key: verb={verb} key={key}', verb=$verb, key=$key)
''',
},
{
'name': 'model.edge.list',
'descr': 'List all edge verbs in the current view and their extended properties.',
'descr': 'List all edge verbs in the current view and their doc key (if set).',
'storm': '''
$edgelist = $lib.model.edge.list()
if $edgelist {
$lib.print('\nname doc')
$lib.print('---- ---')
for ($verb, $props) in $edgelist {
for ($verb, $kvdict) in $edgelist {
$verb = $verb.ljust(10)

$doc = $props.doc
$doc = $kvdict.doc
if ($doc=$lib.null) { $doc = '' }

$lib.print('{verb} {doc}', verb=$verb, doc=$doc)
Expand Down Expand Up @@ -171,8 +176,17 @@ async def _methNorm(self, valu):

class ModelEdge(s_stormtypes.Prim):
'''
Inspect edges and manipulate extended attributes
Inspect light edges and manipulate key-value attributes.
'''
# Note: The use of extprops in hive paths in this class is an artifact of the
# original implementation which used extended property language which had a
# very bad cognitive overload with the cortex extended properties, but we
# dont' want to change underlying data. epiphyte 20200703

# restrict list of keys which we allow to be set/del through this API.
validedgekeys = (
'doc',
)

def __init__(self, runt):

Expand All @@ -182,11 +196,6 @@ def __init__(self, runt):

self.hivepath = ('cortex', 'model', 'edges')

# restrict list of extended props that can be set
self.extpropnames = (
'doc',
)

self.locls.update({
'get': self._methEdgeGet,
'set': self._methEdgeSet,
Expand All @@ -201,9 +210,10 @@ async def _chkEdgeVerbInView(self, verb):

raise s_exc.NoSuchName(mesg=f'No such edge verb in the current view', name=verb)

async def _chkExtPropName(self, prop):
if prop not in self.extpropnames:
raise s_exc.NoSuchProp(mesg=f'No such edge extended property name', name=prop)
async def _chkKeyName(self, key):
if key not in self.validedgekeys:
raise s_exc.NoSuchProp(mesg=f'The requested key is not valid for light edge metadata.',
name=key)

async def _methEdgeGet(self, verb):
verb = await s_stormtypes.tostr(verb)
Expand All @@ -212,42 +222,43 @@ async def _methEdgeGet(self, verb):
path = self.hivepath + (verb, 'extprops')
return await self.runt.snap.core.getHiveKey(path) or {}

async def _methEdgeSet(self, verb, prop, valu):
async def _methEdgeSet(self, verb, key, valu):
verb = await s_stormtypes.tostr(verb)
await self._chkEdgeVerbInView(verb)

prop = await s_stormtypes.tostr(prop)
await self._chkExtPropName(prop)
key = await s_stormtypes.tostr(key)
await self._chkKeyName(key)

valu = await s_stormtypes.tostr(valu)

path = self.hivepath + (verb, 'extprops')
extprops = await self.runt.snap.core.getHiveKey(path) or {}
kvdict = await self.runt.snap.core.getHiveKey(path) or {}

extprops[prop] = valu
await self.runt.snap.core.setHiveKey(path, extprops)
kvdict[key] = valu
await self.runt.snap.core.setHiveKey(path, kvdict)

async def _methEdgeDel(self, verb, prop):
async def _methEdgeDel(self, verb, key):
verb = await s_stormtypes.tostr(verb)
await self._chkEdgeVerbInView(verb)

prop = await s_stormtypes.tostr(prop)
await self._chkExtPropName(prop)
key = await s_stormtypes.tostr(key)
await self._chkKeyName(key)

path = self.hivepath + (verb, 'extprops')
extprops = await self.runt.snap.core.getHiveKey(path) or {}
kvdict = await self.runt.snap.core.getHiveKey(path) or {}

oldv = extprops.pop(prop, None)
if not oldv:
raise s_exc.NoSuchProp(mesg=f'Extended property does not exist for this edge verb', name=prop)
oldv = kvdict.pop(key, None)
if oldv is None:
raise s_exc.NoSuchProp(mesg=f'Key is not set for this edge verb',
verb=verb, name=key)

await self.runt.snap.core.setHiveKey(path, extprops)
await self.runt.snap.core.setHiveKey(path, kvdict)

async def _methEdgeList(self):
retn = []
async for verb in self.runt.snap.view.getEdgeVerbs():
path = self.hivepath + (verb, 'extprops')
extprops = await self.runt.snap.core.getHiveKey(path) or {}
retn.append((verb, extprops))
kvdict = await self.runt.snap.core.getHiveKey(path) or {}
retn.append((verb, kvdict))

return retn
8 changes: 4 additions & 4 deletions synapse/tests/test_lib_stormlib_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ async def test_stormlib_model_edge(self):
self.stormIsInPrint('refs', mesgs)

mesgs = await core.stormlist('model.edge.set refs doc "foobar"', opts=asuser)
self.stormIsInPrint('Set edge extended prop: verb=refs prop=doc', mesgs)
self.stormIsInPrint('Set edge key: verb=refs key=doc', mesgs)

mesgs = await core.stormlist('model.edge.list', opts=asuser)
self.stormIsInPrint('foobar', mesgs)
Expand Down Expand Up @@ -82,7 +82,7 @@ async def test_stormlib_model_edge(self):

# Delete entry
mesgs = await core.stormlist('model.edge.del refs doc', opts=asuser)
self.stormIsInPrint('Deleted edge extended property: verb=refs prop=doc', mesgs)
self.stormIsInPrint('Deleted edge key: verb=refs key=doc', mesgs)

elist = await core.callStorm('return($lib.model.edge.list())')
self.isin('refs', [e[0] for e in elist])
Expand Down Expand Up @@ -114,7 +114,7 @@ async def test_stormlib_model_edge(self):

# Error conditions - set
mesgs = await core.stormlist('model.edge.set missing')
self.stormIsInPrint('The argument <prop> is required', mesgs)
self.stormIsInPrint('The argument <key> is required', mesgs)

with self.raises(s_exc.NoSuchProp):
await core.nodes('model.edge.set refs newp foo')
Expand All @@ -134,7 +134,7 @@ async def test_stormlib_model_edge(self):

# Error conditions - del
mesgs = await core.stormlist('model.edge.del missing')
self.stormIsInPrint('The argument <prop> is required', mesgs)
self.stormIsInPrint('The argument <key> is required', mesgs)

with self.raises(s_exc.NoSuchProp):
await core.nodes('model.edge.del refs newp')
Expand Down