Ticket #339 (closed Enhancement: fixed)

Opened 8 years ago

Last modified 7 years ago

Attach CompositeValue to the database

Reported by: jri Owned by: jri
Priority: Major Milestone: Release 4.1
Component: DeepaMehta Standard Distribution Version: 4.0.12
Keywords: Cc: dgf, Malte
Complexity: 8 Area:
Module: deepamehta-core

Description (last modified by jri) (diff)

CompositeValue? is a mere model class currently. CompositeValue? is the only Core object where the model-interface-implementation trinity is not realized. It should.

In particular, Core API calls that return a CompositeValue? should return an object which is attached to the database (like all other Core objects).

This would be more comfortable and less confusing for plugin developers.

Furthermore it would speed up composite update operations.
(All involved application objects would be loaded once and then stored in the attached CompositeValue?. Currently the involved topics, including its childs!, are re-fetched multiple times.)

Change History

comment:1 Changed 8 years ago by jri

  • Status changed from new to accepted

comment:2 Changed 7 years ago by Jörg Richter

comment:3 Changed 7 years ago by Jörg Richter

Core: refactor fetching composite values (#339).

The model, including its composite values, is fully fetched *before* the (attached) application object is created from it.

Storage API has 2 new methods:

  • fetchRelatedTopics(long id, ...
  • fetchRelatedAssociations(long id, ...

id is a topic ID or association ID

In preparation to "Attach CompositeValue? to the database".
See ticket 339.

comment:4 Changed 7 years ago by jri

  • Description modified (diff)

comment:5 Changed 7 years ago by Jörg Richter

Core: build attached composite values (#339).

Not yet usable.

Core API:

de.deepamehta.core.ChildTopics? is new interface (still empty).

ChildTopicsModel?:

Object get(String key) is new method -- Returns the TopicModel? or List<TopicModel?> for the given child type URI.

BREAKING CHANGES

ChildTopicsModel?:

Object get(String key) -- Convenience method for accessing the *simple* value of a single-valued child.

is renamed to

Object getObject(String key)

IMPORTANT: if your plugin makes use compValue.get("..") to access a simple value the call MUST be renamed to getObject() (see above). A get(..) method with the same signature still exists but has changed semantics (as described above). So, the need for method renaming can not be detected by the compiler.

See ticket 339.

comment:6 Changed 7 years ago by Jörg Richter

Core: replace getCompositeValue() (#339).

getCompositeValue() is replaced by 2 different methods.

BREAKING CHANGES

DeepaMehtaObject?:

CompositeValue? getCompositeValue() -> ChildTopics? getChildTopics()
# changed semantics!
# ChildTopics? is attached to the DB!

DeepaMehtaObjectModel?:

CompositeValue? getCompositeValue() -> ChildTopicsModel? getChildTopicsModel()
# just a renaming

Note: in 4.0.14 both getCompositeValue() methods returned a model, the same model. Now they have different semantics:

  • getChildTopics() returns an application object that is attached to the DB.
  • getChildTopicsModel() returns just a model, like before.

So, also the child topics (formerly: "composite values") follow the very pattern that is applied to all the other core objects (topic, association, ...).

When your plugin makes use of getCompositeValue() it must be adapted. 2 cases:

1) dmObject.getCompositeValue() -> dmObject.getModel().getChildTopicsModel()
2) dmModel.getCompositeValue() -> dmModel.getChildTopicsModel()

With these 2 transformations your 4.0.14 code will have exactly the same semantics as before.

On the other hand, to take benefit from the fact child topics are now attached to the DB, you would write

dmObject.getChildTopics()...

However, for the moment the ChildTopics? object is not yet fully functional.

Generally: in the near future, to perform update operations on child topics you will use the (attached) ChildTopics? object. This is convenient (and in accordance with the rest of the DM core API) as DM keeps the model (memory) and DB in-sync automatically. Only in rare occasions you might want to manipulate the model directly while leaving the DB untouched (resp. update it later).

One more note: conceptually both expressions have exactly the same semantics:

1) dmObject.getModel().getChildTopicsModel()
2) dmObject.getChildTopics().getModel()

However, there is a bug in DM that prevents expression 2) from working. So, for the moment you must use expression 1).

This branch ("attach-comp-value") is fully functional.
All plugins of the standard distro are already adapted.

Please try out this branch and adapt your plugins soon.

See ticket 339.

comment:7 Changed 7 years ago by Jörg Richter

Core: refactor value storage (#339).

Storing an object model's simple or composite value is segregated from the (attached) application object. An application object no longer stores its value itself. Instead the value is stored *before* the application object is created. The storage responsibility is located in a new class: ValueStorage? (analogous to TypeStorage?).

In preparation to "Attach CompositeValue? to the database".

DeepaMehtaObjectModel?:

  • createRoleModel() is new method

See ticket 339.

comment:8 Changed 7 years ago by Jörg Richter

Core: refactor label storage (#339).

The simple value of a composite object (as used as the label) is calculated and stored outside the (attached) application object. Furthermore, optimization: calculating the label involves no DB access anymore.

Together with the recent commit (and the TypeStorage? as recently introduced) the following invariant is valid for the first time:

=> An attached application object is in-sync with the DB *at any time*, in particular when creating or retrieving a DB object.

This provides for more flexibility and more clean code.
And this provides the basis for "Attach CompositeValue? to the database" (#339).

Furthermore the bug described in 18fda563 (4 Feb) is fixed.
Both expressions now have exactly the same semantics:

  • dmObject.getModel().getChildTopicsModel()
  • dmObject.getChildTopics().getModel()

See ticket 339.

comment:9 Changed 7 years ago by Jörg Richter

Core: restore "CompositeValue?" wording (#339).

The "ChildTopics?" wording is revoked.

de.deepamehta.core.CompositeValue? # Interface (represents an attached Object)
de.deepamehta.core.model.CompositeValueModel? # Model class (CompositeValue? in DM 4.0.14)

DeepaMehtaObject?:

DeepaMehtaObjectModel?:

CompositeValue?:

See ticket 339.

comment:10 Changed 7 years ago by Jörg Richter

Core: lazy composite value laading (#339, #411).

Before an update operation is performed on an object its composite value is loaded lazily. Applies to facet updating as well.
Pending for a "get child topic" operation.
See ticket 411.

Update optimization: updating a "composition one" child topic involves no further DB read operation.
Pending for:

  • composition many
  • aggregation one
  • aggregation many

See ticket 339.

comment:11 Changed 7 years ago by Jörg Richter

Fix access control for types (#339).

Editing a type topic works.
Was broken since some days.

See ticket 339.

comment:12 Changed 7 years ago by Jörg Richter

Core: optimize "composition many" update (#339).

Update optimization: updating a "composition many" child topics involves no further DB read operation.
Pending for:

  • aggregation one
  • aggregation many

See ticket 339.

comment:13 Changed 7 years ago by Jörg Richter

Core: optimize "aggregation one" update (#339).

Update optimization: updating a "aggregation one" child topics involves no further DB read operation.
Pending for:

  • aggregation many

See ticket 339.

comment:14 Changed 7 years ago by Jörg Richter

Core: optimize "aggregation many" update (#339).

Update optimization: updating "aggregation many" child topics involves no multiple DB read operation on the target topic.

Optimization phase is complete now.
Update requests ("submitting a form") with complex composite structures perform more efficiently.

The actual attached composite value operations follow.

See ticket 339.

comment:15 Changed 7 years ago by Jörg Richter

Core: drop [get|set]ChildTopicValue?() (#339, #411)

BREAKING CHANGES

DeepaMehtaObject? (interface):

  • SimpleValue? getChildTopicValue() is dropped
  • void setChildTopicValue() is dropped

CompositeValue? (interface):

To adapt your plugins, replace

    object.getChildTopicValue("child.type.uri")

with

    object.getCompositeValue().getTopic("child.type.uri").getSimpleValue()

Replace

    object.setChildTopicValue("child.type.uri", new SimpleValue(val))

with

    object.getCompositeValue().set("child.type.uri", new SimpleValue(val), clientState, directives)

Furthermore: CompositeValue?'s getTopic() and getTopics() methods do fetch the respective child topics lazily.

See ticket 339.
See ticket 411.

comment:16 Changed 7 years ago by Jörg Richter

Core: add accessors to attached comp value (#339).

CompositeValue? (interface) has new accessor methods:

  • getString(String childTypeUri)
  • getInt(String childTypeUri)
  • getLong(String childTypeUri)
  • getDouble(String childTypeUri)
  • getBoolean(String childTypeUri)
  • getObject(String childTypeUri)
  • getComposite(String childTypeUri)

The respective child topic is loaded lazily.

See ticket 339.
See ticket 411.

comment:17 Changed 7 years ago by Jörg Richter

Core: add more accessors to attached comp (#339).

CompositeValue? (interface) has 3 new accessor methods:

  • Object get(String childTypeUri)
  • Iterable<String> childTypeUris()
  • int size()

Note: under some circumstances the underlying CompositeValueModel? differs from the attached CompositeValue?.
The 3 new accessors (as well as the existing has() method) operate on the attached values.

See ticket 339.

comment:18 Changed 7 years ago by Jörg Richter

Core: attached composite manipulators (#339).

CompositeValue? (interface) has 5 new manipulator methods:

  • set(String childTypeUri, TopicModel? value, ..) # Sets a child topic
  • set(String childTypeUri, Object value, ..) # Convenience to set child topic with simple value
  • set(String childTypeUri, CompositeValueModel? value, ..) # Convenience to set child topic with composite value
  • setRef(String childTypeUri, long refTopicId, ..) # Sets topic reference via ID
  • setRef(String childTypeUri, String refTopicUri, ..) # Sets topic reference via URI

The attached composite manipulator methods are complete now.

Every manipulation done before via composite model is now available as a DB-attached operation. So, in most cases the developer must not care about model updates vs. DB-updates. With the new attched CompositeValue? object the underlying model and the DB is always in-sync automatically.

Note: unlike the CompositeValueModel? methods the attached CompositeValue? object needs no differentiation between put() and add() for single-value and multiple-value childs respectively. It's just set(). set() can be used for both, single-value and multiple-value childs.

The set() method introduced yesterday is slightly changed. It takes an Object now. So, the caller is not required to construct a SimpleValue? object but can pass the value directly.

Remember, there is still DeepaMehtaObject?'s setCompositeValue() method. This one performs an attached update operation on the object's composite value itself (instead of on one of its childs like the methods above).

See ticket 339.

comment:19 Changed 7 years ago by Jörg Richter

Core: fix label recalculation (#339).

The CompositeValue?'s setXX() methods trigger a label recalculation.

See ticket 339.

comment:20 Changed 7 years ago by Jörg Richter

Core: add remove() to attached comp value (#339).

AttachedCompositeValue?:

  • remove(String childTypeUri, long topicId, ..) is new method

It removes a child topic from multiple-value childs.
(Analogue to remove() in CompositeValueModel?).

Can be used for both:

  • Composition: the child topic is deleted.
  • Aggregation: only the assignment (association) is deleted.

See ticket 339.

comment:21 Changed 7 years ago by Jörg Richter

comment:22 Changed 7 years ago by Jörg Richter

Core: refactor fetching composite values (#339).

The model, including its composite values, is fully fetched *before* the (attached) application object is created from it.

Storage API has 2 new methods:

  • fetchRelatedTopics(long id, ...
  • fetchRelatedAssociations(long id, ...

id is a topic ID or association ID

In preparation to "Attach CompositeValue? to the database".
See ticket 339.

comment:23 Changed 7 years ago by Jörg Richter

Core: build attached composite values (#339).

Not yet usable.

Core API:

de.deepamehta.core.ChildTopics? is new interface (still empty).

ChildTopicsModel?:

Object get(String key) is new method -- Returns the TopicModel? or List<TopicModel?> for the given child type URI.

BREAKING CHANGES

ChildTopicsModel?:

Object get(String key) -- Convenience method for accessing the *simple* value of a single-valued child.

is renamed to

Object getObject(String key)

IMPORTANT: if your plugin makes use compValue.get("..") to access a simple value the call MUST be renamed to getObject() (see above). A get(..) method with the same signature still exists but has changed semantics (as described above). So, the need for method renaming can not be detected by the compiler.

See ticket 339.

comment:24 Changed 7 years ago by Jörg Richter

Core: replace getCompositeValue() (#339).

getCompositeValue() is replaced by 2 different methods.

BREAKING CHANGES

DeepaMehtaObject?:

CompositeValue? getCompositeValue() -> ChildTopics? getChildTopics()
# changed semantics!
# ChildTopics? is attached to the DB!

DeepaMehtaObjectModel?:

CompositeValue? getCompositeValue() -> ChildTopicsModel? getChildTopicsModel()
# just a renaming

Note: in 4.0.14 both getCompositeValue() methods returned a model, the same model. Now they have different semantics:

  • getChildTopics() returns an application object that is attached to the DB.
  • getChildTopicsModel() returns just a model, like before.

So, also the child topics (formerly: "composite values") follow the very pattern that is applied to all the other core objects (topic, association, ...).

When your plugin makes use of getCompositeValue() it must be adapted. 2 cases:

1) dmObject.getCompositeValue() -> dmObject.getModel().getChildTopicsModel()
2) dmModel.getCompositeValue() -> dmModel.getChildTopicsModel()

With these 2 transformations your 4.0.14 code will have exactly the same semantics as before.

On the other hand, to take benefit from the fact child topics are now attached to the DB, you would write

dmObject.getChildTopics()...

However, for the moment the ChildTopics? object is not yet fully functional.

Generally: in the near future, to perform update operations on child topics you will use the (attached) ChildTopics? object. This is convenient (and in accordance with the rest of the DM core API) as DM keeps the model (memory) and DB in-sync automatically. Only in rare occasions you might want to manipulate the model directly while leaving the DB untouched (resp. update it later).

One more note: conceptually both expressions have exactly the same semantics:

1) dmObject.getModel().getChildTopicsModel()
2) dmObject.getChildTopics().getModel()

However, there is a bug in DM that prevents expression 2) from working. So, for the moment you must use expression 1).

This branch ("attach-comp-value") is fully functional.
All plugins of the standard distro are already adapted.

Please try out this branch and adapt your plugins soon.

See ticket 339.

comment:25 Changed 7 years ago by Jörg Richter

Core: refactor value storage (#339).

Storing an object model's simple or composite value is segregated from the (attached) application object. An application object no longer stores its value itself. Instead the value is stored *before* the application object is created. The storage responsibility is located in a new class: ValueStorage? (analogous to TypeStorage?).

In preparation to "Attach CompositeValue? to the database".

DeepaMehtaObjectModel?:

  • createRoleModel() is new method

See ticket 339.

comment:26 Changed 7 years ago by Jörg Richter

Core: refactor label storage (#339).

The simple value of a composite object (as used as the label) is calculated and stored outside the (attached) application object. Furthermore, optimization: calculating the label involves no DB access anymore.

Together with the recent commit (and the TypeStorage? as recently introduced) the following invariant is valid for the first time:

=> An attached application object is in-sync with the DB *at any time*, in particular when creating or retrieving a DB object.

This provides for more flexibility and more clean code.
And this provides the basis for "Attach CompositeValue? to the database" (#339).

Furthermore the bug described in 18fda563 (4 Feb) is fixed.
Both expressions now have exactly the same semantics:

  • dmObject.getModel().getChildTopicsModel()
  • dmObject.getChildTopics().getModel()

See ticket 339.

comment:27 Changed 7 years ago by Jörg Richter

Core: restore "CompositeValue?" wording (#339).

The "ChildTopics?" wording is revoked.

de.deepamehta.core.CompositeValue? # Interface (represents an attached Object)
de.deepamehta.core.model.CompositeValueModel? # Model class (CompositeValue? in DM 4.0.14)

DeepaMehtaObject?:

DeepaMehtaObjectModel?:

CompositeValue?:

See ticket 339.

comment:28 Changed 7 years ago by Jörg Richter

Core: lazy composite value laading (#339, #411).

Before an update operation is performed on an object its composite value is loaded lazily. Applies to facet updating as well.
Pending for a "get child topic" operation.
See ticket 411.

Update optimization: updating a "composition one" child topic involves no further DB read operation.
Pending for:

  • composition many
  • aggregation one
  • aggregation many

See ticket 339.

comment:29 Changed 7 years ago by Jörg Richter

Fix access control for types (#339).

Editing a type topic works.
Was broken since some days.

See ticket 339.

comment:30 Changed 7 years ago by Jörg Richter

Core: optimize "composition many" update (#339).

Update optimization: updating a "composition many" child topics involves no further DB read operation.
Pending for:

  • aggregation one
  • aggregation many

See ticket 339.

comment:31 Changed 7 years ago by Jörg Richter

Core: optimize "aggregation one" update (#339).

Update optimization: updating a "aggregation one" child topics involves no further DB read operation.
Pending for:

  • aggregation many

See ticket 339.

comment:32 Changed 7 years ago by Jörg Richter

Core: optimize "aggregation many" update (#339).

Update optimization: updating "aggregation many" child topics involves no multiple DB read operation on the target topic.

Optimization phase is complete now.
Update requests ("submitting a form") with complex composite structures perform more efficiently.

The actual attached composite value operations follow.

See ticket 339.

comment:33 Changed 7 years ago by Jörg Richter

Core: drop [get|set]ChildTopicValue?() (#339, #411)

BREAKING CHANGES

DeepaMehtaObject? (interface):

  • SimpleValue? getChildTopicValue() is dropped
  • void setChildTopicValue() is dropped

CompositeValue? (interface):

To adapt your plugins, replace

    object.getChildTopicValue("child.type.uri")

with

    object.getCompositeValue().getTopic("child.type.uri").getSimpleValue()

Replace

    object.setChildTopicValue("child.type.uri", new SimpleValue(val))

with

    object.getCompositeValue().set("child.type.uri", new SimpleValue(val), clientState, directives)

Furthermore: CompositeValue?'s getTopic() and getTopics() methods do fetch the respective child topics lazily.

See ticket 339.
See ticket 411.

comment:34 Changed 7 years ago by Jörg Richter

Core: add accessors to attached comp value (#339).

CompositeValue? (interface) has new accessor methods:

  • getString(String childTypeUri)
  • getInt(String childTypeUri)
  • getLong(String childTypeUri)
  • getDouble(String childTypeUri)
  • getBoolean(String childTypeUri)
  • getObject(String childTypeUri)
  • getComposite(String childTypeUri)

The respective child topic is loaded lazily.

See ticket 339.
See ticket 411.

comment:35 Changed 7 years ago by Jörg Richter

Core: add more accessors to attached comp (#339).

CompositeValue? (interface) has 3 new accessor methods:

  • Object get(String childTypeUri)
  • Iterable<String> childTypeUris()
  • int size()

Note: under some circumstances the underlying CompositeValueModel? differs from the attached CompositeValue?.
The 3 new accessors (as well as the existing has() method) operate on the attached values.

See ticket 339.

comment:36 Changed 7 years ago by Jörg Richter

Core: attached composite manipulators (#339).

CompositeValue? (interface) has 5 new manipulator methods:

  • set(String childTypeUri, TopicModel? value, ..) # Sets a child topic
  • set(String childTypeUri, Object value, ..) # Convenience to set child topic with simple value
  • set(String childTypeUri, CompositeValueModel? value, ..) # Convenience to set child topic with composite value
  • setRef(String childTypeUri, long refTopicId, ..) # Sets topic reference via ID
  • setRef(String childTypeUri, String refTopicUri, ..) # Sets topic reference via URI

The attached composite manipulator methods are complete now.

Every manipulation done before via composite model is now available as a DB-attached operation. So, in most cases the developer must not care about model updates vs. DB-updates. With the new attched CompositeValue? object the underlying model and the DB is always in-sync automatically.

Note: unlike the CompositeValueModel? methods the attached CompositeValue? object needs no differentiation between put() and add() for single-value and multiple-value childs respectively. It's just set(). set() can be used for both, single-value and multiple-value childs.

The set() method introduced yesterday is slightly changed. It takes an Object now. So, the caller is not required to construct a SimpleValue? object but can pass the value directly.

Remember, there is still DeepaMehtaObject?'s setCompositeValue() method. This one performs an attached update operation on the object's composite value itself (instead of on one of its childs like the methods above).

See ticket 339.

comment:37 Changed 7 years ago by Jörg Richter

Core: fix label recalculation (#339).

The CompositeValue?'s setXX() methods trigger a label recalculation.

See ticket 339.

comment:38 Changed 7 years ago by Jörg Richter

Core: add remove() to attached comp value (#339).

AttachedCompositeValue?:

  • remove(String childTypeUri, long topicId, ..) is new method

It removes a child topic from multiple-value childs.
(Analogue to remove() in CompositeValueModel?).

Can be used for both:

  • Composition: the child topic is deleted.
  • Aggregation: only the assignment (association) is deleted.

See ticket 339.

comment:39 Changed 7 years ago by jri

  • Status changed from accepted to closed
  • Resolution set to fixed

comment:40 Changed 7 years ago by Jörg Richter

Core: fix attached composite values (#339).

Thank you dgf for reporting!

Close ticket 339.

comment:41 Changed 7 years ago by Jörg Richter

Core: fix attached composite values (#339).

Thank you dgf for reporting!

Close ticket 339.

comment:42 Changed 7 years ago by Jörg Richter

Core fix: no doublettes in comp val model (#339).

BREAKING CHANGE

CompositeValueModel? public API:

semantics of add() method has slightly changed:
If the topic is already added (based on ID-equality) nothing is performed.

This change is required in conjunction with plugins which enrich a topic model in response to a PRE_SEND event, e.g. by fetching multi-facets. For an update request the facets might be fetched already and would be added again through PRE_SEND yielding to doublettes in the model (and eventually to double renderings in the webclient). This happened e.g. with the Kiezatlas plugin.

This Kiezatlas error does not occur anymore: multi-facet values are rendered twice after form submission.

Your plugins are probably *not* required to be updated.

See ticket 339.

comment:43 Changed 7 years ago by Jörg Richter

Core: fix composite value model again (#339).

BREAKING CHANGE

Again, semantics of add() method has slightly changed: if the topic is already added nothing is performed unless its ID is -1.

This allows adding a couple of new child topics at once e.g. in a webclient form by pressing the "Add" button serveral times. (was broken by recent commit)

Your plugins are probably *not* required to be updated.

See ticket 339.

Note: See TracTickets for help on using tickets.