Skip to content

Commit

Permalink
Load and merge aliases/tags/etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeboers committed Sep 22, 2015
1 parent f18e65a commit 86e703c
Show file tree
Hide file tree
Showing 6 changed files with 308 additions and 105 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/sandbox
79 changes: 34 additions & 45 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,5 @@


- every json file has the same structure, there top-level keys signify what
type of data it is, e.g. all raw data would be under a "raw_schema_read" field.
This allows us to merge a directory of cached data, and so that various
tools can have json files just about them on the SGSCHEMA_PATH, e.g.:

sgevents.json:

{
'entity_aliases': {
'sgevents:EventReceipt': 'CustomNonProjectEntity01'
},
'field_aliases': {
'CustomNonProjectEntity01': {
'type': 'sg_type'
}
},
'field_tags': {
'PublishEvent': {
'sg_type': ['sgcache:include']
}
}
}

{
'PublishEvent': {
'aliases': ['sgpublish:Publish', 'Publish'],
'fields': {
'sg_type': {
'aliases': ['sgpublish:type', 'type'],
'data_type': 'text',
'name': 'Type',
'tags': ['sgcache:include'],
}
}
}
}
- test the loading and resolution of aliases and tags

- caches of the raw schema; both public ones and the private one
- cache of the reduced schema
Expand All @@ -60,7 +24,7 @@
e.g.: EntityType.[sgcache.include==true]
PublishEvent.[sgpublish.is_core]

Tags: PublishEvent.$sgpublish:core -> {sg_code,sg_type,...}
Tags: PublishEvent.#sgsession:core -> {sg_code,sg_type,...}

- Automatic sg_ prefix detection:
Publish.type -> PublishEvent.sg_type
Expand All @@ -72,11 +36,36 @@
This is more in SGSession (or other consumers)


- Are tags/alises forward or backward declared?

schema.PublishEvent.aliases = ['Publish']
vs
schema.entity_aliases['Publish'] = 'PublishEvent'
- Public API:

schema.resolve_entity('$Publish') -> ['PublishEvent']
schema.resolve_field('PublishEvent', 'type') -> ['sg_type']

- Create a standard-ish set of tags and aliases:
$parent pointing to typical parent

- Include backrefs in reduced schema? Known as "inverse_association" in private
schema.























schema.PublishEvent.sg_type.aliases = ['type']
schema.field_aliases['PublishEvent']['type'] = 'sg_type'
79 changes: 79 additions & 0 deletions sgschema/entity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from .field import Field
from .utils import cached_property


class Entity(object):

def __init__(self, schema, name):

self.schema = schema
self.name = name

self.fields = {}

self._aliases = set()
self._tags = set()

self._field_aliases = {}
self._field_tags = {}

@cached_property
def field_aliases(self):
field_aliases = dict(self._field_aliases)
for field in self.fields.itervalues():
for alias in field._aliases:
field_aliases[alias] = field.name
return field_aliases

@cached_property
def field_tags(self):
field_tags = {k: set(v) for k, v in self._field_tags.iteritems()}
for field in self.fields.itervalues():
for tag in field._tags:
field_tags.setdefault(tag, set()).add(field.name)
return field_tags

@cached_property
def aliases(self):
aliases = set(self._aliases)
for k, v in self.schema._entity_aliases.iteritems():
if v == self.name:
aliases.add(k)
return aliases

@cached_property
def tags(self):
tags = set(self._tags)
for k, v in self.schema._entity_tags.iteritems():
if self.name in v:
tags.add(k)
return tags

def _get_or_make_field(self, name):
try:
return self.fields[name]
except KeyError:
return self.fields.setdefault(name, Field(self, name))

def _reduce_raw(self, schema, raw_entity):
pass

def _load(self, raw):
for name, value in raw.pop('fields', {}).iteritems():
self._get_or_make_field(name)._load(value)

self._field_aliases.update(raw.pop('field_aliases', {}))
self._field_tags.update(raw.pop('field_tags', {}))

self._aliases.update(raw.pop('aliases', ()))
self._tags.update(raw.pop('tags', ()))

if raw:
raise ValueError('unknown entity keys: %s' % ', '.join(sorted(raw)))

def _dump(self):
return {k: v for k, v in (
('fields', {field.name: field._dump() for field in self.fields.itervalues()}),
('tags', sorted(self.tags)),
('aliases', sorted(self.aliases)),
) if v}
60 changes: 60 additions & 0 deletions sgschema/field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from .utils import cached_property

class Field(dict):

def __init__(self, entity, name):

self.entity = entity
self.name = name

self.allowed_entity_types = set()
self.data_type = None

self._aliases = set()
self._tags = set()

@cached_property
def aliases(self):
aliases = set(self._aliases)
for k, v in self.entity._field_aliases.iteritems():
if v == self.name:
aliases.add(k)
return aliases

@cached_property
def tags(self):
tags = set(self._tags)
for k, v in self.entity._field_tags.iteritems():
if self.name in v:
tags.add(k)
return tags

def _reduce_raw(self, schema, raw_field):

self.data_type = raw_field['data_type']['value']

raw_private = schema._raw_private['entity_fields'][self.entity.name].get(self.name, {})

if raw_private.get('identifier_column'):
self._tags.add('identifier_column')

if self.data_type in ('entity', 'multi_entity'):
types_ = raw_private['allowed_entity_types'] or []
self.allowed_entity_types = set(types_[:])

def _load(self, raw):
self.allowed_entity_types.update(raw.pop('allowed_entity_types', ()))
self.data_type = raw.pop('data_type', self.data_type)
self._aliases.update(raw.pop('aliases', ()))
self._tags.update(raw.pop('tags', ()))
if raw:
raise ValueError('unknown field tags: %s' % ', '.join(sorted(raw)))

def _dump(self):
return {k: v for k, v in (
('aliases', sorted(self.aliases)),
('allowed_entity_types', sorted(self.allowed_entity_types)),
('data_type', self.data_type),
('tags', sorted(self.tags)),
) if v}

Loading

0 comments on commit 86e703c

Please sign in to comment.