Hi Conny,
I have elaborated a bit further; not yet formal, but showing the intention.
“Cornelius Weiss” c.weiss@metaways.de schrieb:
Hi Sven,
great Comments! Tnx a lot for your time!
I’m not shure if i got all your points right. So here is a summary of
what I got:
- I trashed my concept as linking and relations are different topic
- relations (parent/child/sibling) are properties of entries as e.g.
defined in ical
Concerning application data this is exactly what I meant. The
parent/child/sibling “properties” depend on the user imposed on a specific
relation and there may even be more than one relation per link instance
(shown below).
A link table would be as follows:
+link_id
+table1: foreign key into the names column of meta table of tables
+item1_id: foreign key into the ids column of table1
+table2: like ~1
+item2_id: like ~1~
+deleted: boolean (necessary only to indicate existence of a history log)
+owner: as needed by the acl scheme?
+remark: free text field for unspecific manual links
+rel_type_list: a text, listing rel_type_ids in the form "(>|<|x)+ ,-
, … ", explained below.
There is zero or one record per link.
obviously denotes a relation_type; the substrings “+ nnn,” and “-
nnn,” are put into the string by the event listeners of item(col1) and
item(col2), respectively while establishing the relation. For asymmetrical
relations “>” indicates a relation from col1 to col2 to be named (see
further down), “<” indicates a relation from col1 to col2 to be named
. A leading “x” is for symmetrical relations (text1=text2). The last
(maybe only) char in the list always is a space. This way an UI can be
prepared to list any relation, when showing any item. Even relations not
yet invented.
Using the form shown, there is no need for regexps to analyze the
rel_type_list for the most important questions concerning a certain rel:
- is rel of type nnn in list? -> search for " nnn,"
- is a rel of type mm established completely? -> search for “+ mm,- mm,”; if
found -> complete
- if not, which part is done, which lacks? -> search for " mm," and, if
found, look at the last char prior to location
- if complete, what direction has rel k? -> search for “+ k,- k,” and look
at the last char prior to location
Using simple regexes, the sanity checks can be formulated abstractly for any
rel type. ("[x<>]-" shows incomplete links,
"+ \d*,[x<> ]" too.
All numbers are preceded by a space and followed by a comma; the second
listener has to make sure “+” comes first; the first listener has to note
the direction [><x].
The relations on a link are listed if the user has read rights for both
items. I don’t know the concept behind the owner of a link. The owner is
listed only because the current eGW links have one. Only a “manual” relation
over the link may be modified/deleted directly by a general UI element,
change rights for both items provided.
relation_types table
+rel_type_id
+text1: text to describe link type as seen from parent side
(“uses”,“requests”,“consists of”,…)
+text2: text to describe link type from the child side (“is used”,“is
requested”,“is part of”,…)
text1 and text2 are identical for bidi relations (“may replace”, …) any
equiv relation.
Physical deletion of a link record is only appropriate after successful
archival, or in case of repairing a damaged set of records.
This enables to describe more than one relation over one link, possibly with
different asymetrical meanings without the colum number of the link table
implying any further meaning. Links are always bi-directional:
(SELECT link_id1 AS ID, 1 AS column
FROM JOIN links ON .ID=link_id1
WHERE .ID= AND link_app1=’’)
UNION
(SELECT link_id2 AS ID, 2 AS column
FROM JOIN links ON .ID=link_id2
WHERE .ID= AND link_app2=’’)
gives a list of all links an with is involved in. So now we
know there’s some relation between and other <Items[n]>. What else?
Semantics:
The links produced manually via standard UI are not elaborated further. They
get a symmetric link type of “manual” and can be managed by any user having
change rights for both sides of the link or maybe by some acl scheme
depending on ownership.
There are two special, meta link types: “deleted” and “archived”. Both look
symetrical but aren’t as they don’t describe the state of the link but the
state of the items respectively. (the texts both read “archived” as it can
be seen from one side only, the one not yet archived).
This opens possibilities for housekeeping. Links having “x +,-
” may be archived along with their history log. Link records with
just one side “” will usually not be shown to the regular user. How
to interpret this observation will depend on the design of the
linking/unlinking mechanism. If done right link/unlink processes stuck half
way can be completed or reverted consistently.
“archived” may also be a state of either side of the link. If both sides are
marked “archived” the link itself may be archived along with its history
log. As long as one side isn’t archived the link should exist in the live
DB. Transfer from/to archive storage (serial, archive DB, offline, …) can
be general tasks not needing any knowledge of items or relations, aside from
the DB meta schema. They act upon the link.
A controller would have to select relations relevant to his job by
extracting links with tags known to him and treat all others non existant.
"… WHERE rel_type_list = “%+ nnn,- nnn,%” selects all links carrying rel
nnn in MySQL jargon.
- This implies, that each of those relations is defined twice ( in
both ends of a link)
- Such, a link is just redundand information, but very usefull for
performance ishues. In princible one can calculate all ‘links’ by the
related properties of all entries.
- for the archiving and viewing in time, we have allmost the same
ideas. That was my intention only to break up links, but never to
delete them. Viewing in time, you can see when a relation was broken up.
- But this leadas to a new problem. If a link don’t know about its
properties, how helpfull is an archived link, as the properties of an
record could not be viewed in time (ok there is the history
logging, … this is getting complicated )
What i don’t understand is the point about custom link properties and
the example with resource <-> task. The properties of the links (and
the actions) are defined by the relation properties of the entries
itself (and the event listeners).
I hope custom link tags are a bit clearer now. An UI can be prepared to show
a text for any relation between any two items of equal or different kind;
automata may need hints about the semantics of links; the two step process
of link creation is documented step by step and can be sanity checked with
simple text operations.
A better example for multiple relations over one link in the user data area
would be the following setup:
A person represented by a contact (e.g. because this person isn’t inhouse)
is assigned the task to put up a text and distribute it to a bunch of
people, again represented by contacts. The inhouse owner of the task is just
supervising this. Now this bunch of people happens to be a workgroup the
person to carry out the task is part of:
task -> “is executed by” -> contact A
task -> “needs” -> contact A
task -> “needs” -> contact B
.
.
.
With a manual setup this is just written down in the remark of the link. But
while representing real world workflows it is possible to stumble over such
a situation too. So custom controllers extending the standard behaviour of
eGW items must have a means to specify semantics for the links they use,
independently of any other standard or custom behaviour. And the UI only
needs a record in the taglist to be able to list the relation without any
need for modification.
I also don’t understand the link-tagging approach, if links are just
redundant information.
hope this is clearer now. Of cause “deleted(1|2)” and “archived(1|2)” may be
4 simple bools, mainly because they are needed for all links anyway. So
handling will be faster. But they fit in the scheme.
Cu
Sven
would be great to hear from you!
cu
Conny
Hi Conny,
it’s a lot of text, I know. But please give it a try.
“Cornelius Weiss” c.weiss@metaways.de schrieb:
Hi devs,
in the last days I struggeld with link problems.
Here is my problem:
I have a contact, a (crm) project related to this contact, and a set
of tasks related to the (crm) project.
- If a (crm) project gets deleted, I want to ask the user if also the
related tasks should be deleted. But how do I know, what is is
parent,
what is child? All I see are the links I have, and they are all
unidirectional.
As I recall from some doc I’m unable to point at right now the
semantics of
eGW links is _bi_directional and which item goes place one or two in
the
record is merely a matter of the creation UI. If both items exist,
you can
attach a project to a task (from project UI) or the other way
around. This
doesn’t mean the project gets part of the task or so. The task keeps
record
about an action taken related to a given project (but also to the
person
carrying out the task or maybe ressources needed or whatever).
- Lets asume I use some kind of convention (like link_id1,app1 is
allways parent) and moreover I choose not to delete the tasks. So I
have a set of dangeling tasks and the user might have no idea where
this tasks came from.
The assumption is not correct: Tasks and projects are conceptually
stand
alone. The tasks are not “dangling” if you delete the project. The
semantics
of the links are not imposed by the link system! Or put otherwise:
If you
want to have tasks only valid in project context, go ahead! But it
has to be
a property of the task, not the link! Single tasks may even belong
to more
than one project! And it is great that eGW can handle this quite
naturally
just because it imposes so little link semantics.
- An other case: What happens if I add a new contact from my (crm)
projects view. I would assume that this is a sub object of the (crm)
project, so if the project gets deleted, also the new address should
be deleted. How to archive this?
This also is a misconception: A contact is a contact is a contact (A
human
being mostly, known by a human being in your org and addressable via
this
contact record in various ways). If you take away information from
it (like
here by deleting the crm context it has been created in), you might
ask a
follow up delete question if e.g. the contact has no other
association, be
it knowledge base, project, task, wiki page, the address bokk it is
kept in,
contact (org) and the user is entitled to delete such a bit of
info …
- At some point I might want to make the new address parent and the
(crm) project child (power user feature)
This is not a power user feature but just one possible aspect of the
contact <-> project relation. And in the course of a longer lasting
project
a contact may wander between different orgs connected to the project
- If I made an attachment to the (crm) project and I choose to delte
the project, but not the children, what has to be done with the
attachment?
That is quite clear: It depends on the nature of the attachment. If
it is a
file within filemanager’s reach it just stays that (maybe you check
for
other links to the att and if there are none the file may be
tagged (or
put into a special folder) or the user might be entitled to kill the
file
too.
Any other kind of attachment: The housekeeping depends on the nature
of the
att. A ressource will most likely not been deleted even if it then
has no
other links. A KB or WIKI entry also: It keeps knowledge possibly
valuable
beyond the context described by the link itself.
My result of all this thoughts is, that we have to extend the current
link system:
- have a clean structure for parent and child object,
- seperate the attachments stuff out in a different class
- have handling for orphaned childs (yes, this might happen )
I think it is totally sufficient to notify both sides of the link if a
connection is to be broken up (like it is the case right now AFAIK)
so both
can take appropriate action. In general it is not a good idea to mix
the
delete action for an item with breaking up the links (which has to
be done
explicitly and beforehand, one by one while the item_to_be_deleted
still
exists). It is the responsibility of the application causing the
link to
break to impose the correct semantics for that breakup, not of an
abstract
demon behind the scenes.
This is mainly because the follow up consequences of a link breakup
depend
on dynamic conditions imo beyond abstraction by a rel mech. This
abstraction
would be so general that it wouldn’t achieve anything or it would
impose
limitations on link semantics.
IMHO the right way to go is to have a posibility to select _un_linked
objects per link class and additional properties and possibly decide
upon
these one by one.
Use cases may introduce restrictions upon certain link
transitions. So it
could be valuable to think about a mechanism to describe what may or
may not
happen while linking or unlinking certain objects in certain states
and
contexts (including suppression of some link relations), as some
kind of
configuration management.
Getting concrete on the proposal: The Parent/Child/Sibling thinggy
is not a
static property of a link but an emanation of a collection of
properties of
both parties and possibly even other items linked. “Orphaned” also
isn’t an
explicit property of an item linked to. This gets you directly back
into the
conceptional hell a lot of other GWs are facing. Lots of "anomalies"
originating solely from the misconception of explicit and static
dependency
and hierarchy. Both come from certain “real” and use-case-dependent
properties of the items linked and may change in lifetime of an item.
You even have to be careful with the semantics intended by breaking
a link.
“No more relation whatsoever”? A GW handles information in time.
There has
been a relation some time, so basically a link may only be broken
-
if it was wrong in the first place. Consequences depend upon how
many
decisions have been taken assuming existence of the link.
-
if one of the parties go out of scope. This opens the discussion
of how to
consistently archive (and cut) past journals. This has to be put
aside for
now.
I’d vote for some kind of link tagging. Links can have properties
too. This
way custom extensions of controllers may act differently upon
different
kinds of relations between certain items. An example would be
ressource <->
task. This is not clear: A ressource could be used to accomplish a
task or a
task could be executed upon a ressource (like maintenance or
transport or
sth). This clearly is a property of the link. But the task isn’t
orphaned if
transport leads to the junk yard: The ressource will be gone but the
task
will be billed or fill a persons time table or whatever.
All in all: There is no such thing as an unidirectional link. Links
may have
one or aribtrary meanings, governing what to do when one of the
sides fade
or even the link goes out of time or organizational scope.
Attributing links instead of breaking them is imo demanded by the
archiving
effort anyway:
Archiving an item should not lead to deleting the links to the
archived item
or archiving the items linked-to (other than a possibly necessary
"snaphot"
of the item to keep the items propeties at the time of archival).
Archiving
schould mark the link as an archive link for items staying within
scope. All
items should have an ID consistent between archived and ready state.
So
anything can be archived with its links in place. They stay valid.
Unarchiving an element means putting it back into place, updating
the state
of each link because the archived state of a link may have changed
while in
coffin and deciding if the snapshots or the current items of the
links from
there should be used.
There we enter movement in time while viewing an eGW data base which
again
is a totally different case.
Jm2c
Sven
Here is my proposal for a relations class. What I realy don’t know at
the moment is, if there should be a relation “buddy” (same hirachy),
or if this is stuff for categories/tags.
If you wonder why there is no Egwbase_Relations::__construct with an
active record pattern, this is cause we want a consistant flow over
all actions, an the active record pattern does not fit for backends
like LDAP or file (ical).
The basic idea of the class is to be a simple relations housekeeper.
If Important changes to the relataions are made, the class fires
events and notifies the related objects. This way each application
could decide how to handle the situation.
E.g a task which becomes orphaned by the action, could save a
toString() of it’s original parent. Other listeners might commit
sucide or whatever
Please drop me a note, what you think, I’ll start to write the unit-
tests for it in the next days.
cu
conny
Cornelius Weiss
Metaways Infosystems GmbH
Pickhuben 2 - 4
20457 Hamburg
Germany
E-Mail: c.weiss@metaways.de
Web: http://www.metaways.de
http://www.tine20.org
Jabber: nelius@jabber.tine20.org
Metaways Infosystems GmbH - Sitz: D-22967 Tremsbüttel
Handelsregister: Amtsgericht Ahrensburg HRB 4508
Geschäftsführung: Hermann Thaele, Lüder-H.Thaele
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft® Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
eGroupWare-developers mailing list
eGroupWare-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/egroupware-developers