In order to be able to explain possible impact of bindapi on node creation and behaviour let's look at it as a state machine. A rather general state machine. The bindapi is a proposed api, probably implemented as a module. It is intended to facilitate the creating of dynamic nodes, as in nodes extended with new data fields or behaviour, 0 changing the other nodes of the same type. It is a node extension as opposed to type extension.
react_on_signal(X): foreach(action) { if guards(X) then { action(X) } guards(X): foreach(guard) { $result &&= guard(X,action) }
A state is a bag full of things, a set. It can be identified only by the things contained in it. The state machine on the other hand adds to the mix the possible actions defined for that state. The actions can happen only if allowed by the appropriate guards - some condition checkers. A pseudo-code for this general state machine algorithm is outlined in the inlay. Let's follow it through. The world issues a signal, let's say 'view'. The SM checks for each action if it is allowed in this state, for this signal and possibly executes it.
In theory, such state machines should be able to compute any computable tasks. Turing complete for the CS types and the theoreticians. If somebody is interested in the theory - have a search for Abstract State Machines and or Gurevich evolving algebras. In practice using this model is a bit unsavoury. It can quickly become a mess. We need some extra syntactic sugar, to sweeten this up and simplify the usage. We need some practical means to make all of this UI friendly as well.
If we generalise the state - the things should know how to react to external events and labels for those things, then we come to a new, but equivalent, model.
react_on_signal(X): foreach(thing) { foreach(action) { if guards(X) then { action(X) } } } guards(X): foreach(guard) { $result &&= guard(X) }
The state stores things, which consist of some data and guarded actions. When an event reaches the state machine the appropriate actions are fired. Execution result wise nothing really changes. It's the internal structure that differs. We use micro management - to reduce the number of things we take into account, when defining a state.
So what is a thing and what can we do with it? A thing is the state from take 1, at least the way it was described until now. It knows, what is in it. It knows how to react to events. It is akin to a class in OO terminology. We can take a thing from 'the great outside' and add it to the state. We can /ove a thing from a state and throw it to the 'the great outside' or the big bucket in the sky. A thing on its own is immutable - as a structure it can't be changed from anything else.
If you make a comparison between drupal nodes and the take two state machine, you will notice similarities. Both of them contain things - drupal calls them fields. Both react to events. Both guard their actions. OK, to be precise the drupal node types are quite tightly coded, so such clear separation may not be possible, but the bird-eye view should be correct. Node api is equivalent to 'add from the outside' type of action, as described earlier. Drupal's node collection as a whole can be viewed as a mother state machine, containing things - nodes.
This kind of abstraction is helpful, at least for me, when trying to uncover how to use and what are the consequences of implementing metadata Drupal.
What is metadata? What do we want to do with it? How can we do that? What is the impact on speed? What are the benefits for the users?
Metadata. Data about data. In different situations within drupal it can mean different things. Firstly it is knowledge about the underlying structure of things. In this case metadata programming will involve smart manipulation of the things structures. Or move to and from the outside actions as described above.
In the case of associating program semantics to taxonomy terms, i guess it is dependent on the taxonomy domain. Generally this would mean having some kind of template structures that implement that meaning. Adding association of this type means adding a set of things from the great outside according to the template. This kinds of operations are good, since they implement an ontology - a classification with rules to react to the outside world, which definitely will make Drupal even more useful as a Content Management Platform. It will make Drupal smarter.
Benefits? Flexible content creation. Smarter content organisation, cross referencing. Easier adaptation to their needs. All this can come from having combination of a visual language to adapt drupal to one's needs, a set of simple consistent apis to define data and behaviour.
The biggest contributor to slow speed Drupal is the database storage. So the main impact on speed should come from the implementation of how are things stored. It can be helpful if we look at this problem as engineering the optimal Virtual Machine. Components:
SELECT n.nid, n.title f1.name, f2.name, f3.name FROM node AS n JOIN f1 field1 on n.nid = f1.nid JOIN f2 field2 on n.nid = f2.nid JOIN f3 field3 on n.nid = f3.nid WHERE n.nid like 12;
SELECT n.nid, n.title f1.name, f1_1.name, f3.name FROM node AS n JOIN f1 field1 on n.nid = f1.nid JOIN f1_1 field1 on n.nid = f1_1.nid JOIN f3 field3 on n.nid = f3.nid WHERE n.nid like 12 AND f1.label = 'label1' AND f1_1.label = 'label2';
All non-volatile data is reflected into a DB. What types of operations can appear using the above abstractions? Select a field, Update a field, add field to node, remove field from node.
attempt for schema description 1: Store fields by field type. For selects this leads to a query joining X+1 tables, where X is the number of fields in the node. The complication is if we have several fields from one and the same node-type. This will require to perform multiple joins on on and the same table. Depending on database implementation, this can be penalised. The 'add field' operation is an update to the node schema, and initialisation of the field. Remove field is similar,but delete a field instead. The node schema is either stored explicitly, or derived from the storage. When stored explicitly we can form a faster query, the second method will require to do more complicated queries.
attempt 2: To avoid penalties on single table joins, field pools can be used. By field pool I mean several tables for a single field. This will solve the above problem, but introduce complexity from the pool management. I'm not going to discuss that in depth, but selects, updates, add, remove for fields will get complicated. It is not obvious that there will be benefits, and if there are, that they will outweigh the losses from complexity.
SELECT n.nid, n.title, f1.name, f2.name FROM node AS n JOIN f1 nodetype1_fone on n.nid = f1.nid JOIN f2 nodetype1_ftwo on n.nid = f2.nid WHERE n.nid like 12;
attempt 3: Predefined templates, no add or remove outside node type definition. This is similar to rigid types. This scenario can benefit from named field types, so if a node should have two different fields of one and the same type, they are placed in different explicitly named database tables. This approach benefits from the fact that there won't be any joins on single tables. We loose the flexibility of the 'run-time' as opposed to 'definition-time' structure definition. We gain the predefined type semantics. This is how standard drupal types, including flexinode work.
attempt 4: What if we adopt both 1 and 3? We will end up with two different subsystems, interacting with each other, and enriching each other. They are complimentary. The user (designer) should be able to make an informed decision, which approach is better in a particular context. The beauty of this approach is that there is a possibility for cross-fertilisation - 'type 3' can be used with very little glue logic as a field type. Remember, the drupal nodes are state machines very similar to fields as described above. While 'type 1' by definition extends normal (including 'type 3') nodes.
For the fluid nodes, predefined templates can be employed to create a mass field add to and remove from semantics. They don't change the behaviour of the nodes - if a node has one and the same collection of fields, then it behaves the same way in an identical context.
Prepackaged ontologies. By this I mean predefined relations between a taxonomy and a set of node operations. This can be implemented as a 'special' field, which can add to, or remove from a node. Additionally on install time the taxonomy is initialised.
Drupal node-types as fields adaptors. Special fields, which package nodes from an existing drupal type to a field.
I will try and produce a more detailed discussion on the different ways, and different traps for the SQL side, I can notice at a later stage. I hope this will benefit someone, and not only my ego.