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

Traits, basic documents, utility fields. #26

Merged
merged 106 commits into from
May 10, 2017
Merged

Traits, basic documents, utility fields. #26

merged 106 commits into from
May 10, 2017

Conversation

amcgregor
Copy link
Member

@amcgregor amcgregor commented Jan 3, 2017

Field Improvements

  • Optional case transformation on String assignment.
  • Optional character stripping transformation on String assignment.

Utilities

  • utcnow — generate a UTC timezone-aware datetime object representing now. (Saves on littering datetime and pytz imports all over the place; no need for pytz at all.)

New Fields

  • Markdown — string storage which self-renders under the __html__ method protocol.
  • PathPurePosixPath storage.

“Basic” Documents

  • VerifiedAddress — an e-mail address with addition and verification dates.
  • BaseLocation — representing an address or geophysical location.

Traits

  • Derived
    A Document sub-class which has its own sub-classes; track in-DB which to instantiate when deserializing. May apply to any Document sub-class utilized as a top-level record, Embed, or Reference target. Note: serialization/deserialization and complex types need to be generally aware of the __type_store__ document attribute.
    • Basic definition.
    • Automatic determination of entry point (short-form, portable) or fully-qualified dot-colon path (exact, more searchable, but more fragile) to store in cls attribute.
  • Expires
    Document self-destructs at a certain point in time. Note: this changes the behaviour of deserialization such that the value None may appear in place of records that have been loaded, but are expired. Pass expired=True to disable this check and load the record anyway, however, where not explicitly disabling the check be sure to validate the response and, if iterating a cursor, continue with the next record. Include a range comparison against the current time in UTC to exclude these from contention, however some may expire in the time it takes to iterate a cursor.
    • A TTL field named expires.
    • The requisite TTL index declaration.
    • A is_expired validation property.
    • Deserialization returns None if expired; optionally bypass-able behaviour.
  • Hierarchical
    Document is a member of an acyclic directed graph, or tree, with slugs and paths. Order preservation is not implied beyond parent/child and ancestor/descendant relationships. Moved to own issue: Hierarchical and/or taxonomy model structure or trait mix-in. #29
  • Identified
    A document utilizing this trait mix-in contains a MongoDB-side _id key accessible and queryable as the id ObjectId field attribute. Provides a read-only attribute to retrieve the record creation time from the id.
  • Localized
    Document contains localizable information.
    • Provide base embedded document class (Localized.Locale) containing sufficient field definitions to satisfy MongoDB full-text indexing requirements for language identification.
    • Array of embedded documents to store localized content.
  • Owned
    Document has the concept of a reference to an owner, and an index on such.
  • Published
    Document has explicit creation, modification, and optional publication and retraction times. Additionally, indexes to facilitate conditional range querying of publication and retraction. If mixing with Identified, ensure Published comes later; it overrides the meaning of creation.
  • Stateful
    Document maintains state described by a cyclic directed graph of allowable string tag-based state transitions. Moved to own issue: Stateful trait mix-in. #30

Here's an example model utilizing these:

"""Contentment Asset model."""

from marrow.mongo import Document, Index
from marrow.mongo.field import String, Embed, Reference, Array, Number, Markdown

from marrow.mongo.trait import Identified  # Easy access to the _id key.
from marrow.mongo.trait import Derived  # Provides cls references for subclassable Documents.
from marrow.mongo.trait import Localized  # Localized text storage.
from marrow.mongo.trait import Owned  # Track object that "owns" the document.
from marrow.mongo.trait import Published  # Track publication / retraction.
from marrow.mongo.trait import Heirarchical  # Directed acyclic graph, or tree.


class Asset(Identified, Derived, Owned, Published, Localized, Heirarchical, Document):
	__database__ = 'default'
	__collection__ = 'asset'
	
	class Locale(Localized.Locale):
		title = String()
		description = Markdown()
	
	acl = Array(Embed(), default=lambda: [], assign=True)  # Access control list.
	tags = Array(String(), default=lambda: [], assign=True)  # Free-form tags.
	properties = Embed(default=lambda: {}, assign=True)  # Free-form "data tags".
	handler = String(default='web.component.asset.controller:AssetController')


class Block(Identified, Derived, Published, Localized, Document):
	__database__ = 'default'
	__collection__ = 'block'
	
	class Locale(Localized.Locale):
		title = String()
	
	asset = Reference(Asset)  # Containing asset.
	order = Number(default=0)  # The sort order for this block on the page.
	tags = Array(String(), default=lambda: [], assign=True)  # Not so free-form.
	
	identifier = String()  # HTML identifier.
	styles = Array(String())  # CSS classes.
	
	_text = Index('$locale.title', '$locale.content')


class ContentBlock(Block):
	class Locale(Block.Locale):
		content = String()


class MarkdownBlock(ContentBlock):
	class Locale(Block.Locale):
		content = Markdown()


class Page(Asset):
	handler = String(default='web.component.page.controller:PageController')

@amcgregor amcgregor added the 2.enhancement New ideas or improvements. label Jan 3, 2017
@codecov-io
Copy link

codecov-io commented Jan 5, 2017

Codecov Report

Merging #26 into develop will decrease coverage by 0.5%.
The diff coverage is 98.4%.

Impacted file tree graph

@@            Coverage Diff             @@
##           develop     #26      +/-   ##
==========================================
- Coverage    99.91%   99.4%   -0.51%     
==========================================
  Files           21      30       +9     
  Lines         1174    1522     +348     
==========================================
+ Hits          1173    1513     +340     
- Misses           1       9       +8
Impacted Files Coverage Δ
marrow/mongo/core/field/base.py 100% <100%> (ø) ⬆️
marrow/mongo/core/trait/published.py 100% <100%> (ø)
marrow/mongo/core/trait/derived.py 100% <100%> (ø)
marrow/mongo/param/update.py 100% <100%> (ø) ⬆️
marrow/mongo/core/trait/expires.py 100% <100%> (ø)
marrow/mongo/query/query.py 100% <100%> (ø) ⬆️
marrow/mongo/core/trait/localized.py 100% <100%> (ø)
marrow/mongo/util/__init__.py 100% <100%> (ø) ⬆️
marrow/mongo/__init__.py 100% <100%> (ø) ⬆️
marrow/mongo/param/sort.py 100% <100%> (ø) ⬆️
... and 21 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2e230a7...815c07b. Read the comment docs.

@amcgregor amcgregor added this to the 1.1.1 Release milestone Jan 31, 2017
@amcgregor
Copy link
Member Author

amcgregor commented Feb 2, 2017

Additional ideas for traits:

  • Controlled
    An access control list, and mechanisms to verify it, allowing for dynamic custom actions (tag-based) as well as CRUD + field granular read/write.
  • Tracked
    Preserve an account of the history of changes to the document.

Down the rabbit hole.

@amcgregor amcgregor merged commit 28189bd into develop May 10, 2017
@amcgregor amcgregor deleted the feature/traits branch May 10, 2017 08:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.enhancement New ideas or improvements.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants