<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://groups.drupal.org" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>Data Architecture Design Sprint</title>
 <link>http://groups.drupal.org/data-architecture-design-sprint</link>
 <description>The Data Architecture Design Sprint in Chicago, February 4-6, 2008</description>
 <language>en</language>
<item>
 <title>First fields in core issue + core</title>
 <link>http://groups.drupal.org/node/11935</link>
 <description>&lt;p&gt;Please see &lt;a href=&quot;http://drupal.org/node/265604&quot; title=&quot;http://drupal.org/node/265604&quot;&gt;http://drupal.org/node/265604&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/11935#comments</comments>
 <group domain="http://groups.drupal.org/content-construction-kit-cck">Content Construction Kit (CCK)</group>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Mon, 02 Jun 2008 14:21:50 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">11935 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Field API, field structure, and data migration</title>
 <link>http://groups.drupal.org/node/11487</link>
 <description>&lt;p&gt;Much has been said (&lt;a href=&quot;http://groups.drupal.org/node/9297&quot; title=&quot;http://groups.drupal.org/node/9297&quot;&gt;http://groups.drupal.org/node/9297&lt;/a&gt;) about how fields should be structured in D7 core, what aspects of fields can be changed, and how those changes are implemented.  It is (past) time to move forward on implementing fields in core and in this post I am proposing an answer.&lt;/p&gt;
&lt;p&gt;Disclaimer: I make a lot of declarative statements in this post.  Obviously I do not have unilateral authority; this is just a proposal.&lt;/p&gt;
&lt;h2&gt;Field storage&lt;/h2&gt;
&lt;p&gt;Contrary to what we &quot;decided&quot; at DADS, D7 will continue to support per-content-type and per-field storage as we already do.  I spelled out my reasons at &lt;a href=&quot;http://groups.drupal.org/node/9297#comment-37050&quot; title=&quot;http://groups.drupal.org/node/9297#comment-37050&quot;&gt;http://groups.drupal.org/node/9297#comment-37050&lt;/a&gt;.  The short summary is &quot;performance&quot;; until someone measures otherwise, we&#039;re assuming that fewer joins are more efficient than more joins.  Since we already have the code to support both storage methods, the implementation cost is low.&lt;/p&gt;
&lt;h2&gt;The Fields API&lt;/h2&gt;
&lt;p&gt;At DADS, we declared/clarified some basic concepts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A Field Type is a data type implemented by a module: text, nodereference, address, etc. The module defines semantics and functionality.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A Field is a specific configuration of a type.  Fields have settings that define the unique characteristics of that field.  All fields share some properties, such as: field type, name, cardinality (currently &quot;multiple&quot;), sharable.  A Field Type can define addititional properties; for example, a the Text field type defines the property &quot;formatted&quot; which can be FALSE (plain text) or TRUE (user chooses input format).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A Field Instance is the binding of a Field to a Content Type.  Field Instances have Settings that related to the association, such as: display name (label), weight, input widget, display format.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A field instance&#039;s settings do not affect the field&#039;s underlying data and can be changed without altering the field.  By contrast, a Field&#039;s settings cannot be changed because changing any of them constitutes fundamentally altering the field&#039;s identity.  However, a field can be &quot;migrated&quot; to a new field (of the same or different field type) to provide new functionality or semantics for the existing data.  More on this later.&lt;/p&gt;
&lt;p&gt;D6 CCK created the first version of the Fields API.  It is a big step forward but does not cleanly separate the concept of Field and Field Instance.  We currently have the function:&lt;/p&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;/p&gt;
&lt;p&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;content_field_instance_create&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;p&gt;The $field argument contains information defining both the Field and the Field Instance.  (Almost) Any property of a field or setting can be specified.  create() will both create the Field if it does not exist and then the Field Instance; if some Field Instance settings are not provided, they will be inherited from an existing Field Instance if one exists, the Field settings, and system-wide defaults.  If a non-shared Field Instance of the Field already exists, the Field is immediately converted from a non-shared field to a shared field, requiring a change in database schema.  And so forth.  content_field_instance_update() is similar.  A &lt;em&gt;lot&lt;/em&gt; happens inside these functions and I think their complexity is is keeping us in a straitjacket.&lt;/p&gt;
&lt;p&gt;In D7, the Field API will cleanly separate Fields from Field Instances.  We will have two create functions:&lt;/p&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;content_field_create_field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;content_field_create_instance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;p&gt;create_field()&#039;s $field will contain field name, field type, and can accept all global (e.g. field type, name, required, cardinality, sharable) and type-specifc (e.g. formatted) field settings.  create_field() will probably do nothing but store the information in the content_field table.&lt;/p&gt;
&lt;p&gt;create_instance()&#039;s $instance will contain the field name, the content type to bind to, and all global (e.g. label, weight) and type-specific (???) per-instance settings.  create_instance() &lt;em&gt;cannot&lt;/em&gt; change any Field settings (e.g. sharable, cardinality); those settings are simply meaningless in the $instance argument.  create_instance() also imposes the Field constraints; for example, if you try to create a second instance of a field created as non-sharable, create_instance() will fail.&lt;/p&gt;
&lt;p&gt;The Fields API will also have some fairly straightforward functions such as:&lt;/p&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;content_field_rename_field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$old_name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$new_name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;content_field_update_instance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;content_field_delete_instance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$instance&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;content_field_delete_field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;p&gt;Note content_field_update_instance() will be &quot;straightforward&quot; even though the current implementation is not because like create_instance() it enforces the constraints of the field; everything it does is pretty light-weight.  The heavy lifting is reserved for &quot;field migration.&quot;&lt;/p&gt;
&lt;h2&gt;Field migration&lt;/h2&gt;
&lt;p&gt;Conspicuously absent from the functions above is:&lt;/p&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;content_field_update_field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;p&gt;This is the magical function that can convert fields from shareable vs. not, from cardinality 1 vs. N vs. unlimited, from &quot;plain text&quot; to &quot;formatted text&quot;, and from &quot;text&quot; to &quot;nodereference&quot;.  Notice that these are all changes of Field settings, not Instance settings.&lt;/p&gt;
&lt;p&gt;As I said at &lt;a href=&quot;http://groups.drupal.org/node/9297#comment-37050&quot; title=&quot;http://groups.drupal.org/node/9297#comment-37050&quot;&gt;http://groups.drupal.org/node/9297#comment-37050&lt;/a&gt;, Drupal needs this functionality because humans cannot predict the future.  However, Drupal &lt;em&gt;core&lt;/em&gt; does not need this functionality.  Fields in core provide Drupal with capabilties not previously possible, but changes to fields in core is fundamentally a development-time operation that can perfectly well depend on contrib, as it does now.&lt;/p&gt;
&lt;p&gt;update_field() will handle three kinds of updates:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Changes to shareable and cardinality.  This is the code that moves columns between per-content-type and per-field storage and adds/removes the &#039;delta&#039; column.  It is the (&lt;em&gt;only&lt;/em&gt;) code that would be unnecessary if we declared all field tables to use per-field storage, and it is code that is already written.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Intra-field-type changes such as plain-text to formatted-text.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Inter-field-type changes such as &quot;text&quot; to &quot;nodereference&quot; (a.k.a &quot;the DabbleDB magic&quot;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It is important to recognize that #2 and #3 are actually the same thing and, despite what many think, CCK CANNOT CURRENTLY PERFORM EITHER ONE.  Yes, the one special case of plain-text to formatted-text works because it is a degenerate case of &quot;add or remove a single column, changing nothing else,&quot; and maybe there are some other similar cases.  But you can&#039;t convert an ISO Date field to a Unix Timestamp Date field because the CCK doesn&#039;t know how to do that with a simple assignment or typecast without any knowledge of the underlying field types.&lt;/p&gt;
&lt;p&gt;The core content_field_update_field() function will work by dispatching these operations to modules via hooks.  I am not yet 100% sure of the interface but it will look something like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Shareable and cardinality are &quot;core&quot; field properties and can be changed in a field-agnostic manner; the actual column types, names, and content always remain the same (though some content may be discarded), they just move from one table to another, possibly with/out a delta column.  This will be handled by a dedicated hook that is implemented by the CCK UI module.  An admin performing this operation will have to have the CCK UI module installed anyway; a module developer wanting to perform this via an update function will just have to depend on the CCK UI module (they do now anyway).&lt;/p&gt;
&lt;p&gt;If you try to update a shared field to be non-shareable, it will fail; explicitly delete all but one field instance first.  If you try to reduce a field&#039;s cardinality, I&#039;m not sure if it should fail or simply silently discard data (which is what it does now, I think).&lt;/p&gt;
&lt;p&gt;I can easily imagine this functionality, which is mostly already written, being moved into the core Fields API at some point when we resolve the PHP timeout and race condition issues.  If we ever want to change a &lt;em&gt;core&lt;/em&gt; field&#039;s shareability or cardinality, of course, we&#039;ll need the core in core then (as an example, this would be the case if we decided that nodes can only have one term and it lives in the node table).  For now, we do not need it in core.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Changes to field-type specific properties (e.g. &quot;formatted&quot;) or field-type changes will be implemented via a hook like:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&amp;nbsp; hook_content_field_update_field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$old_field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$new_field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;p&gt;The first module to return TRUE says the update is done; if all return FALSE, the update is not supported.  Fore example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If $old and $new are both of type &#039;text&#039;, presumably text.module will accept the update: change the formatted property by adding or removing the format column.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If $old is an ISO Date field and $new is a Unix Timestamp Date field, date.module will accept the update: create a new field, execute &quot;UPDATE new_field.value = TO_UNIXTIME(old_field.value)&quot;, delete the old field, and rename the new one into place.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If $old is any type and $new is type &#039;nodereference&#039;, presumably nodereference.module will accept the update: create a new node type, SELECT DISTINCT on the old field, create a new node for each value, call content_field_create_field() to add the new field, call content_field_create_instance() for each appropriate content type, UPDATE the _nid column of the new field based on a join of the old field columns to the node table for the new node type, call content_field_delete_field() on the old field, and cannot content_field_rename_field() to move the new field into place.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Or something like that.  :-)  CCK can&#039;t do this today so I do not feel too bad about not having ironed out all the details yet.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/11487#comments</comments>
 <group domain="http://groups.drupal.org/content-construction-kit-cck">Content Construction Kit (CCK)</group>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Wed, 14 May 2008 22:08:07 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">11487 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Remote Field Revision</title>
 <link>http://groups.drupal.org/node/9409</link>
 <description>&lt;p&gt;This discussion will revolve around issues of Remote Field Revisions.  This regards getting field population from single, multiple, and unknown sources.  Sending data to other sites and how they can use, modify, and potentially change that data from source.  Also regarding race state and origination of data sources and trusted sources for field revision.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/9409#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/680">field</category>
 <category domain="http://groups.drupal.org/taxonomy/term/4278">field vs node</category>
 <category domain="http://groups.drupal.org/taxonomy/term/4277">remote field revision</category>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Wed, 05 Mar 2008 17:14:56 +0000</pubDate>
 <dc:creator>neoliminal</dc:creator>
 <guid isPermaLink="false">9409 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Drupalcon: The Future of Fields</title>
 <link>http://groups.drupal.org/node/9375</link>
 <description>&lt;p&gt;Here are my notes from the Future of Fields presentation from this morning.&lt;/p&gt;
&lt;p&gt;[Begins showing a picture of the Data Architecture design Sprint including: chx, yched, bjaspan, crell, karens and nedjo]&lt;/p&gt;
&lt;p&gt;Drupalcon used to be a developer conference where they would meet and figure out what was going to happen for the next year, but in Barcelona they realized that it was harder to do that.&lt;/p&gt;
&lt;p&gt;So they asked about the who are the right people to be involved, and they all flew into Chicago and did a sprint.&lt;/p&gt;
&lt;p&gt;Barry would advocate this be a trend in future Drupal development, get together a targeted group to make some progress.&lt;/p&gt;
&lt;p&gt;The DADS (Data Architecture Design Sprint&lt;br /&gt;
Re-design of Drupal&#039;s core date architecture&lt;br /&gt;
* Data API&lt;br /&gt;
* Object modeling - node object is a dumping ground for stuff.  Some is in arrays, some are in classes, some are fake classes.&lt;br /&gt;
* Fields in core -- What does that mean?  CCK in core.  Once the node object is cleaned up, let&#039;s clean up how it&#039;s rendered.  Then realized that started getting really big, and started to focus on getting fields into core, and then things would go from there.&lt;br /&gt;
* Many related ideas&lt;/p&gt;
&lt;p&gt;Their goal was to propose a design at Drupalcon&lt;/p&gt;
&lt;p&gt;Our &quot;Grand Conclusions&quot;&lt;/p&gt;
&lt;p&gt;Some key thoughts:&lt;br /&gt;
What makes Drupal unique?&lt;br /&gt;
Drupal has the hook-based system&lt;br /&gt;
Drupal&#039;s architecture allows contributed modules to easily add value to content&lt;br /&gt;
Everything from fivestar to views -- and that there are so many of these modules, and that the fact there are so many of these modules is what makes Drupal unique.&lt;/p&gt;
&lt;p&gt;The Future&lt;br /&gt;
Web services -- sharing data from multiple sources&lt;br /&gt;
* Consuming - Need to import in Amazon data or RDF&lt;br /&gt;
* Providing access to our data -- no way at the moment to export data via JSON without custom coding.&lt;br /&gt;
* Enhancing -- Being able to do any Drupal action on fields that is currently limited to nodes&lt;/p&gt;
&lt;p&gt;Drupal is all about our contributed modules, we need to be able to provide our secret sauce throughout Drupal.  Otherwise we&#039;re just sucking and aggregating other people&#039;s data, and not leveraging Drupal&#039;s power and flexibility.&lt;/p&gt;
&lt;p&gt;So we want to add Drupal&#039;s value to the data sent out to web services. If we take photo from a Flickr, it shouldn&#039;t have to know it&#039;s a node to be able to vote on it.  And putting CCK into core, that&#039;s a big step towards that.&lt;/p&gt;
&lt;p&gt;[Showing KarenS flowchart]&lt;br /&gt;
Drupal takes in data, formats and saves data, and produces HTML (and XML, etc) -- The little triangle at the bottom are the Drupal hooks that holds Drupal together.&lt;/p&gt;
&lt;p&gt;If getting fields into Core is where we want to go, then Karen will talk more about it.&lt;/p&gt;
&lt;p&gt;KAREN STEVENSON:  We all know that getting fields into core is the big issue that we want to do for D7.&lt;br /&gt;
So why bother?  The way CCK handles fields is what we want to do, and it&#039;s a good way of looking at the issue.&lt;/p&gt;
&lt;p&gt;At the usability testing at UMN, people were confused that Title and Body were treated as fields -- even though they don&#039;t act the same way as fields.  The reason why they behave differently is that they&#039;re not in core.  One way to consistency is to get fields into core in order to have consistency.&lt;/p&gt;
&lt;p&gt;In a way, we have developed something better for users than developers.  Users can create fields on the fly, but developers need to be able to do that as well.  So that&#039;s also a motivation to get CCK fields into core.&lt;/p&gt;
&lt;p&gt;Hopefully people are familiar with CCK.&lt;br /&gt;
&quot;Field type&quot; is how is it stored, and what is unique about it.  A field type tells you how it is stored in the database.&lt;br /&gt;
The &quot;field&quot; is really the settings, how we set up the field, the length or what type of field.&lt;br /&gt;
&quot;Field instance&quot; is how bind a field to a content type.  The instance also have settings.&lt;/p&gt;
&lt;p&gt;It&#039;s confusing terminology, but that&#039;s the way CCK works now.&lt;/p&gt;
&lt;p&gt;Let&#039;s take a look at existing things in core to see what types of things could be fields.&lt;br /&gt;
Body: text area with a teaser splitter.  It&#039;s a two-field, teaser area and body area.&lt;br /&gt;
Created: date field&lt;br /&gt;
Upload: file field&lt;br /&gt;
User picture: image field&lt;br /&gt;
IDs: Number + optionwidgets&lt;br /&gt;
Taxonomy feels like a field -- but taxonomy has so much special processing, and will be a challenging thing&lt;br /&gt;
Comments? Fields? Or are they data?  They&#039;re not sure yet.&lt;/p&gt;
&lt;p&gt;Several of these things are not even in core CCK like date, file or image field.  So it&#039;s a double promotion from not existing in contrib to not existing in core.  And the reason why they&#039;re not in CCK is because they&#039;re not simple fields, and all of those things should make it in core CCK.&lt;/p&gt;
&lt;p&gt;When we do a split between -- no one is talking about taking ALL of CCK and putting into core. That&#039;s too much, and would be too much complication&lt;/p&gt;
&lt;p&gt;What is the Minimum Viable Possibility of how much should of CCK should go into core D7 and what should stay in contrib:&lt;/p&gt;
&lt;p&gt;Core&lt;br /&gt;
* Field API&lt;br /&gt;
* Field Storage Engine&lt;br /&gt;
* Node CRUD&lt;br /&gt;
* WIdgets&lt;br /&gt;
* Forms&lt;br /&gt;
* Formatters&lt;br /&gt;
* Multiple values -- handle them as a whole or as a separate things: like a GMAP&lt;br /&gt;
 -- &quot;Add more&quot; -- Core now has add more button&lt;br /&gt;
 -- Custom&lt;br /&gt;
* FIeld validation&lt;/p&gt;
&lt;p&gt;Contrib&lt;br /&gt;
* Field UI -- that&#039;ll have to stay in contrib, because it&#039;s messy and hard&lt;br /&gt;
 --  Add, manage, diplay tabs&lt;br /&gt;
* Fieldgroups&lt;br /&gt;
* Allowed &amp;amp; default values -- probably more complicated than we need to go&lt;br /&gt;
* Content Copy&lt;br /&gt;
* Module integration&lt;br /&gt;
 -- Views, token, pathauto&lt;/p&gt;
&lt;p&gt;The core module would be called &quot;field.module&quot; and we continue to have a contrib module.&lt;/p&gt;
&lt;p&gt;Field storage options&lt;br /&gt;
CCK does dynamic storage of fields, it is done in a per content type, and a multiple content is put into a &#039;per field&#039;&lt;br /&gt;
If you share a field between two content types, CCK has to create a new field.&lt;/p&gt;
&lt;p&gt;Any time you change parameters, you have to alter the schema, and move the data from one table to another one, and potentially loose some data&lt;/p&gt;
&lt;p&gt;Lots of places where it can go wrong and where data could get lost, and it&#039;s worse now because of CCK has a dynamically-defined schema.  Store the field information in a field table, and whenever there is a call to determine the schema&lt;br /&gt;
Ran into race conditions -- if you want to actually change the schema.&lt;br /&gt;
And the big concern is to get all of this into core without breaking everything and making it a maintaining nightmare.&lt;/p&gt;
&lt;p&gt;So fixed &#039;per tables&#039; tables with cached node array&lt;br /&gt;
* Simple structure and code&lt;br /&gt;
* Downside is that there is a performance hit from numerous sql JOINS&lt;/p&gt;
&lt;p&gt;One solution is to combine &#039;per field&#039; tables and intermediate tables better optimized for query&lt;br /&gt;
 * Duplication of data, yields a larger database&lt;/p&gt;
&lt;p&gt;They are doing a separate cache for the node object,so that they&#039;re not doing the joining as often -- which works fine for node_load, but we&#039;re back to lots of JOINS with views.  And currently Views is already doing the JOINS, but they&#039;ve been going around and round -- it&#039;s been a show stopper without figuring this out.&lt;/p&gt;
&lt;p&gt;Their preliminary conclusion os that simple fields seems to make sense.  It gives simple code that&#039;s predictable, and let&#039;s find out if these JOINS are an issue with performance tests.  They imagine coding it up and implementing it, and then seeing if there are killer performance issues.  If so, then scrap it and try another approach.&lt;/p&gt;
&lt;p&gt;The Field API&lt;br /&gt;
There is a basic API in CCK D6.&lt;br /&gt;
Having the ability to have modules to create fields creates some problems.&lt;br /&gt;
* Should the fields be locked down and not be able to be altered?&lt;br /&gt;
* Who is going to own the fields?&lt;br /&gt;
* Are they available in the UI?&lt;br /&gt;
* Should those fields be shared?&lt;/p&gt;
&lt;p&gt;A lot of these issues and more need to be worked through&lt;/p&gt;
&lt;p&gt;In CCK for D6, they are working on how to get some field-based permissions, and so it may also be a Phase II issue for getting these permissions fields into D7 after a big chunk of functionality has been committed in the Phase I.&lt;/p&gt;
&lt;p&gt;If they had permissions for fields, then modules could do more things with fields.  Jeff Eaton has been in discussion with KarenS, and they&#039;ve agreed that it&#039;s better to start with them as being locked down permissions-wise, and then gradually move towards allowing people to have permissions on them.&lt;/p&gt;
&lt;p&gt;Possible Roadmap&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can start the process as separating the API from the UI and create a new fields.module in D6 with the idea to move it into D7. &lt;/li&gt;
&lt;li&gt;It&#039;ll have to include the basic fields (text, number, optionwidgets)&lt;/li&gt;
&lt;li&gt;Rework existing core fields and transition them into fields.module -- they think it makes sense to start with the Body field.&lt;/li&gt;
&lt;li&gt;Determine what else needs to be done for date , image, file handling etc.&lt;/li&gt;
&lt;li&gt;If they can get something into D7 early in the process, and then possibly get some of the UI into core.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;QUESTION: Would Page and Story define in the CCK way instead of the way they are?&lt;/p&gt;
&lt;p&gt;Possibly.&lt;/p&gt;
&lt;p&gt;The revisions table could go away because the body would become the revisions table (and CCK currently handles revisions on the field level)&lt;/p&gt;
&lt;p&gt;QUESTION: If fields get into core, then instead of Webform would we now just use the core field.module?&lt;br /&gt;
Not sure, a lot of things could happen.&lt;/p&gt;
&lt;p&gt;QUESTION: What about the Image field -- Possibly grouping fields for the alt tags, etc. to have the same table? -- And a fourth option, not dynamically from the UI, but that there is a programatic way to have a hook that says that these fields will always stay together.  You could keep consistency in the schema API&lt;/p&gt;
&lt;p&gt;The API will be able to define how fields will be grouped together.&lt;/p&gt;
&lt;p&gt;LARRY GARFIELD gets up to talk about Local Fields on Remote Content&lt;/p&gt;
&lt;p&gt;One challenge: If you want Drupal to talk to foreign data, then it&#039;s really, really hard.&lt;/p&gt;
&lt;p&gt;What do we mean for data sources?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;local nodes&lt;/li&gt;
&lt;li&gt;Entire Amazon catalog&lt;/li&gt;
&lt;li&gt;Flickr photos&lt;/li&gt;
&lt;li&gt;legacy data -- accessible via SOAP, XML, etc.&lt;/li&gt;
&lt;li&gt;Other content from Drupal sites&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For any given piece of content you want to perform the any of the following operations:&lt;br /&gt;
* Display locally&lt;br /&gt;
* Comment&lt;br /&gt;
* Vote&lt;br /&gt;
* Search&lt;br /&gt;
* Views&lt;/p&gt;
&lt;p&gt;These operations don&#039;t work for non-local data.&lt;/p&gt;
&lt;p&gt;Importing ALL of that data can be really bad, because you have huge amounts of data -- and even if it was possible, then keeping it in sync could be really crazy.  Lazy node creation also isn&#039;t much better.&lt;/p&gt;
&lt;p&gt;But with everything we&#039;ve talked about so far -- we don&#039;t get anything new and exciting. So what would this enable that we could really get excited about?&lt;/p&gt;
&lt;p&gt;The Data Architecture Design Spring participants talked about &quot;Institute of Contempory Art&quot; as a case study -- coincidentally is very similar project to what Palatir was working on.&lt;br /&gt;
* Data in legacy database that was available via SOAP, and that they didn&#039;t want to import b/c needed access via another non-Drupal CMS.&lt;br /&gt;
* They had artwork (title, year, image ULR) artist (name birthplace, bio), resources (video, audio, etc)&lt;br /&gt;
* Had to figure out how to make all of this available to Drupal.&lt;br /&gt;
* The goal is to have the &lt;a href=&quot;http://example.com/artwork/abc&quot; title=&quot;http://example.com/artwork/abc&quot;&gt;http://example.com/artwork/abc&lt;/a&gt; -- and it&#039;s not a node in the database, but they want to be able to treat it as a node.&lt;/p&gt;
&lt;p&gt;So what does it mean to be a node?&lt;br /&gt;
It has a nid, and some simple properties like created, status, and simple metadata, and then they have the Fields, which are the meat of the content -- title body, comments, taxonomy, CCK fields, and other complex structured data attached on by other modules.&lt;/p&gt;
&lt;p&gt;So how can you provide a unified structure for the Node and the ICA: &quot;Thingy&quot;? [Thingy is a temporary name decided in Barelona that won&#039;t be called a thingy when it gets into core.]&lt;/p&gt;
&lt;p&gt;It has a unique ID: that has an opaque string that has properties (i.e. metadata), and it has fields -- which could be intrinsic to the title or body, as well as extrinsic fields that come from the Drupal database.&lt;br /&gt;
Anything else that is used that is pulled in doesn&#039;t need to be known where it&#039;s coming from remotely -- loading the object we shouldn&#039;t care where the external data is coming from.  They want to have a clear separation between the data source and the data interface.&lt;/p&gt;
&lt;p&gt;How do you add a field to a thingy so that you can add Fivestar.module and add some votes?  Instead of a single column for a nid, you have two columns, you have the the type of nid (node, artwork, artwork), id (12, abc [menu path on the file system], abc), Delta column (0,0,1) and then the Vote (2,5,4)&lt;/p&gt;
&lt;p&gt;The artwork &quot;abc&quot; does not exist anywhere exist anywhere else in SQL other than this vote column.&lt;/p&gt;
&lt;p&gt;The Delta column is a CCK-specific value that allows for multiple values for CCK fields.&lt;/p&gt;
&lt;p&gt;QUESTION: What if you have a combination of some images from Flickr and some locally&lt;br /&gt;
Having a given field with having some values come from some data sources would be helpful, but would be really difficult to implement.  The heavy lifting is on the field level.&lt;/p&gt;
&lt;p&gt;QUESTION: What if the remote data is deleted, how do you sync?&lt;br /&gt;
We don&#039;t know yet, that&#039;s yet to be determined, and part of the problem with dealing with external and stale data.&lt;/p&gt;
&lt;p&gt;The thingy called &quot;artwork&quot; is equivalent to what we currently call a &quot;node.&quot;  Artwork would be a class, and they we load the object with &quot;abc&quot; to pull it in from the remote system, and the only thing stored locally is the Drupal value-data like a fivestar vote.&lt;/p&gt;
&lt;p&gt;QUESTION: Works well from files or images, but what about text strings and caching?&lt;/p&gt;
&lt;p&gt;It would have to be exposed in some form that you can query.  But depends on your use case.&lt;/p&gt;
&lt;p&gt;This group left some of this discussion out of the presentation, and have more info in their group on &lt;a href=&quot;http://groups.drupal.org/data-architecture-design-sprint&quot;&gt;g.d.o.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What about searching these?&lt;/p&gt;
&lt;p&gt;Can&#039;t search local database AND remote SOAP within one SQL request -- possibly with SPARQL, but will probably still have to do a separate query for each data source and merge results.&lt;/p&gt;
&lt;p&gt;Views -- probably does not work as we understand it today because Views is tied to a local SQL database. We haven&#039;t figured it out yet -- possibly lazy load SQL. Will probably have to just implement it and see what works and what doesn&#039;t work.&lt;/p&gt;
&lt;p&gt;The Views query-builder will live on for local data, but the rest of views is unclear for how it will evolve or adapt for dealing with remote data.&lt;/p&gt;
&lt;p&gt;NEDJO ROGERS: Brief summary of these ideas and proposals, and we need to hear back and have follow-up discussions for how much this makes sense.  They will have to fundamentally rework how core works with data with nodes and users.&lt;/p&gt;
&lt;p&gt;We also have some assumptions in Drupal that are being challenged:&lt;br /&gt;
* All data is entered into the dB via forms for users&lt;br /&gt;
* Also anything can be extended at any time.&lt;br /&gt;
* All data resides in a local SQL database&lt;/p&gt;
&lt;p&gt;CCK knows what it&#039;s object looks like, we don&#039;t have to guess b/c it&#039;s aware of it&#039;s schema.  It&#039;s sort of representing the type of data API we&#039;re looking for.  Let&#039;s do it, but let&#039;s do it right.  By renewing our core Data API so that we can free our Data API from these assumptions.&lt;/p&gt;
&lt;p&gt;Some of these things can be taken care of now with CCK for Drupal 6.&lt;br /&gt;
Looking at a minimal implementation of CCK for Drupal 7, and where we take it is an open question.&lt;/p&gt;
&lt;p&gt;They&#039;d like to hear back any questions and comments, does it make sense to people?&lt;/p&gt;
&lt;p&gt;Does it ring true as a future direction for Drupal, and use the CCK fields as a broader goal for some of these things moving forward?&lt;/p&gt;
&lt;p&gt;None of this is going to happen unless someone takes ownership that is going to get involved and help make it happen.&lt;/p&gt;
&lt;p&gt;If you want to help, and don&#039;t know how, then write unit tests so that it will extend the development cycle.&lt;/p&gt;
&lt;p&gt;Much more info on Daily reports, Final Report, Proposed Content Models 1 and 2, and more ramblings:&lt;br /&gt;
&lt;a href=&quot;http://groups.drupal.org/data-architecture-design-sprint&quot; title=&quot;http://groups.drupal.org/data-architecture-design-sprint&quot;&gt;http://groups.drupal.org/data-architecture-design-sprint&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Replace the concept of nodes with objects that can be uniquely identified -- how we do it: whether it&#039;s something on top of the node vs. something else, then take a look at &lt;a href=&quot;http://groups.drupal.org/data-architecture-design-sprint&quot;&gt;Model 1 and 2.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;QUESTION: Will the data structure that is abstract and flexible enough to have a choice of fully normalized vs. de-normalized with no joins.&lt;/p&gt;
&lt;p&gt;We don&#039;t know yet.  So when we think about how can we attach a comment to an external Flickr photo, there is a choice between whether the field table knows what the actual data looks like or another option is something actively being discussed.&lt;/p&gt;
&lt;p&gt;They do have adding fields to fields in D6.&lt;/p&gt;
&lt;p&gt;QUESTION: Stale data problem, and data unavailable.&lt;/p&gt;
&lt;p&gt;Might be implementation specific: dependent on the field on whether it&#039;s a Flickr photo or for the museum.  But what you say generally is &quot;data unavailable&quot;&lt;/p&gt;
&lt;p&gt;QUESTION: How would node revisions work if KarenS is saying that using the field.module for the body would get rid of node revisions.  Do revisions go away?  What about the diff.module?&lt;/p&gt;
&lt;p&gt;Every CCK field keeps it&#039;s own revisions, and so she&#039;s is throwing that out, because CCK has something very similar already built in for each field.&lt;/p&gt;
&lt;p&gt;QUESTION: Also think about the possibility of storing the revisions as a diff, so that you have a whole version control system built in internally.&lt;/p&gt;
&lt;p&gt;QUESTION: Why not just use XML, and then think as thingies as &#039;entities&#039; and fields are &#039;attributes&#039;.&lt;/p&gt;
&lt;p&gt;It&#039;s good for some tasks, but it&#039;s not really a good mechanism to using it internally.  XML aren&#039;t multi-value.  You could easily map the thingy structure to XML if you want to export.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/9375#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/108">CCK</category>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Tue, 04 Mar 2008 18:32:40 +0000</pubDate>
 <dc:creator>kentbye</dc:creator>
 <guid isPermaLink="false">9375 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Field Structure</title>
 <link>http://groups.drupal.org/node/9297</link>
 <description>&lt;p&gt;The way that fields are structured in CCK now is that any field that is multiple or shared has its own separate &#039;per field&#039; table, and all other fields are grouped together in a &#039;per content type&#039; table. Querying this data to create a node can be expensive, so the serialized node is cached and the cached data is used during node_load().&lt;/p&gt;
&lt;p&gt;That structure requires a lot of complex data manipulation when fields are shared or unshared or changed from single to multiple or multiple to single. When those things happen, the schema must be altered and data must be migrated from one table to another. This makes the code quite complex and introduces the potential for data loss and other errors.&lt;/p&gt;
&lt;p&gt;Our conversations at the Design Sprint resulted in an initial idea of simplifying this so that all fields are stored in &#039;per field&#039; tables. This will greatly simplify the code, making it easier to get it into core. The hope was that the caching model would alleviate most of the performance problems that might result. But there is still a performance concern with this model.&lt;/p&gt;
&lt;p&gt;Another approach to this would be to go ahead and store the basic data in simple &#039;per field&#039; tables, as we discussed, but instead of storing a serialized array in the cache, create multiple tables at an intermediate level that can be queried and filtered easily without any need for joining data. Those intermediate tables will contain duplicates of the basic data stored in the &#039;per field&#039; tables, but the cost of keeping that data up to date is probably less than the cost of complex joined queries.&lt;/p&gt;
&lt;p&gt;If we did that we would no longer store the serialized data in the cache, so the cache_content table would not be needed. Once fields are moved to core, these intermediate tables would probably also eliminate the need for the revisions table.&lt;/p&gt;
&lt;p&gt;The new data structure might look like the following. The idea is that each node type would have a table with all its fields and each node might have multiple rows in the table to represent all the delta values of all its fields. Any field could potentially contain multiple values, so any node could potentially return multiple rows and node handling would need to take that into account. But these tables would be easily queriable for any of their values without any joins.&lt;/p&gt;
&lt;p&gt;Note that the idea of adding an intermediate level of tables is Dries&#039; idea, this implementation of this idea may or may not be anything like what he was thinking :)&lt;/p&gt;
&lt;h2&gt;INTERMEDIATE LEVEL&lt;/h2&gt;
&lt;h2&gt;table: node_page&lt;/h2&gt;
&lt;table border=&quot;1&quot;&gt;
&lt;tr&gt;
&lt;th&gt;nid&lt;/th&gt;
&lt;th&gt;vid&lt;/th&gt;
&lt;th&gt;delta&lt;/th&gt;
&lt;th&gt;uid&lt;/th&gt;
&lt;th&gt;body&lt;/th&gt;
&lt;th&gt;teaser&lt;/th&gt;
&lt;th&gt;field_phone_value&lt;/th&gt;
&lt;th&gt;field_file_fid&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt;xxx &lt;/td&gt;
&lt;td&gt;xxx  &lt;/td&gt;
&lt;td&gt; 555-5555&lt;/td&gt;
&lt;td&gt;34&lt;/p&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1 &lt;/td&gt;
&lt;td&gt; 1 &lt;/td&gt;
&lt;td&gt; NULL&lt;/td&gt;
&lt;td&gt; NULL &lt;/td&gt;
&lt;td&gt;NULL &lt;/td&gt;
&lt;td&gt;777-7777 &lt;/td&gt;
&lt;td&gt;NULL&lt;/p&gt;
&lt;tr&gt;
&lt;td&gt;2  &lt;/td&gt;
&lt;td&gt;2  &lt;/td&gt;
&lt;td&gt; 0 &lt;/td&gt;
&lt;td&gt;1  &lt;/td&gt;
&lt;td&gt; xxx&lt;/td&gt;
&lt;td&gt;xxx &lt;/td&gt;
&lt;td&gt;555-5555&lt;/td&gt;
&lt;td&gt;46&lt;br /&gt;
&lt;/table&gt;
&lt;h2&gt;table: node_story&lt;/h2&gt;
&lt;table border=&quot;1&quot;&gt;
&lt;tr&gt;
&lt;th&gt;nid&lt;/th&gt;
&lt;th&gt;vid&lt;/th&gt;
&lt;th&gt;delta&lt;/th&gt;
&lt;th&gt;uid&lt;/th&gt;
&lt;th&gt;body&lt;/th&gt;
&lt;th&gt;teaser&lt;/th&gt;
&lt;th&gt;field_name_value&lt;/th&gt;
&lt;th&gt;field_nodereference_nid&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt;xxx &lt;/td&gt;
&lt;td&gt;xxx  &lt;/td&gt;
&lt;td&gt; xxx&lt;/td&gt;
&lt;td&gt;34&lt;/p&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1 &lt;/td&gt;
&lt;td&gt; 1 &lt;/td&gt;
&lt;td&gt; NULL&lt;/td&gt;
&lt;td&gt; NULL &lt;/td&gt;
&lt;td&gt;NULL &lt;/td&gt;
&lt;td&gt;xxx &lt;/td&gt;
&lt;td&gt;NULL&lt;/p&gt;
&lt;tr&gt;
&lt;td&gt;2  &lt;/td&gt;
&lt;td&gt;2  &lt;/td&gt;
&lt;td&gt; 0 &lt;/td&gt;
&lt;td&gt;1  &lt;/td&gt;
&lt;td&gt; xxx&lt;/td&gt;
&lt;td&gt;xxx &lt;/td&gt;
&lt;td&gt;xxx&lt;/td&gt;
&lt;td&gt;46&lt;br /&gt;
&lt;/table&gt;
&lt;h2&gt;BASIC LEVEL&lt;/h2&gt;
&lt;h2&gt;table: field_name&lt;/h2&gt;
&lt;table border=&quot;1&quot;&gt;
&lt;tr&gt;
&lt;th&gt;nid&lt;/th&gt;
&lt;th&gt;vid&lt;/th&gt;
&lt;th&gt;delta&lt;/th&gt;
&lt;th&gt;field_name_value&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;xxx&lt;/td&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;xxx&lt;/td&gt;
&lt;/table&gt;
&lt;h2&gt;table: field_phone&lt;/h2&gt;
&lt;table border=&quot;1&quot;&gt;
&lt;tr&gt;
&lt;th&gt;nid&lt;/th&gt;
&lt;th&gt;vid&lt;/th&gt;
&lt;th&gt;delta&lt;/th&gt;
&lt;th&gt;field_phone_value&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;xxx&lt;/td&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;xxx&lt;/td&gt;
&lt;/table&gt;
&lt;h2&gt;table: field_city&lt;/h2&gt;
&lt;table border=&quot;1&quot;&gt;
&lt;tr&gt;
&lt;th&gt;nid&lt;/th&gt;
&lt;th&gt;vid&lt;/th&gt;
&lt;th&gt;delta&lt;/th&gt;
&lt;th&gt;field_city_value&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;xxx&lt;/td&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;xxx&lt;/td&gt;
&lt;/table&gt;
&lt;h2&gt;table: field_file&lt;/h2&gt;
&lt;table border=&quot;1&quot;&gt;
&lt;tr&gt;
&lt;th&gt;nid&lt;/th&gt;
&lt;th&gt;vid&lt;/th&gt;
&lt;th&gt;delta&lt;/th&gt;
&lt;th&gt;field_file_fid&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;/table&gt;
&lt;h2&gt;table: field_nodereference&lt;/h2&gt;
&lt;table border=&quot;1&quot;&gt;
&lt;tr&gt;
&lt;th&gt;nid&lt;/th&gt;
&lt;th&gt;vid&lt;/th&gt;
&lt;th&gt;delta&lt;/th&gt;
&lt;th&gt;field_nodereference_nid&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;tr&gt;
&lt;td&gt;1 &lt;/td&gt;
&lt;td&gt; 1  &lt;/td&gt;
&lt;td&gt; 0  &lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;/table&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/9297#comments</comments>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Sat, 01 Mar 2008 12:18:23 +0000</pubDate>
 <dc:creator>KarenS@drupal.org</dc:creator>
 <guid isPermaLink="false">9297 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Final Report</title>
 <link>http://groups.drupal.org/node/9221</link>
 <description>&lt;p&gt;OK, so, it took a lot longer than I expected or planned, but here is the final summary report from the design sprint.  I&#039;ve provided it in both OpenDoc and PDF format.  Hopefully there aren&#039;t too many spelling errors. :-)&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/9221#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/3319">Data API</category>
 <enclosure url="http://groups.drupal.org/files/DADS Final Report.pdf" length="332473" type="application/pdf" />
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Wed, 27 Feb 2008 07:54:33 +0000</pubDate>
 <dc:creator>Crell@drupal.org</dc:creator>
 <guid isPermaLink="false">9221 at http://groups.drupal.org</guid>
</item>
<item>
 <title>The Future of Fields, Drupalcon Boston 2008</title>
 <link>http://groups.drupal.org/node/9093</link>
 <description>&lt;p&gt;This wiki page is for the development of the Drupalcon session we&#039;ll be presenting in Boston.  We have 90 minutes on Tuesday morning; see &lt;a href=&quot;http://boston2008.drupalcon.org/sessiontutorial-schedule&quot;&gt;our session page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please edit this page only if you attended the Design Sprint and will be participating in the session.  Otherwise, please give us your feedback via comments.  Thanks!&lt;/p&gt;
&lt;h3&gt;Session outline&lt;/h3&gt;
&lt;p&gt;Each section to be a presentation with a pause for questions before moving on to next section.  The early sessions should be pretty quick because most of it is review of concepts already long-discussed within the community.&lt;/p&gt;
&lt;p&gt;Presenters are bjaspan, crell, karenS, nedjo.   I (bjaspan) have assigned specific presenters to each section; each presenter will create the slides for their own sections.  If anyone objects to my suggestions or does not have time to create the slides this week, just speak up.  Please create plain, unstyled slides.  I&#039;ll merge them all together for simplicity during the session (we don&#039;t want to have to switch computers, etc., mid-session).&lt;/p&gt;
&lt;h4&gt;Overview (bjaspan; 3 minutes)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Idea for and participants in design sprint&lt;/li&gt;
&lt;li&gt;Goals and outline of session
&lt;ul&gt;
&lt;li&gt;Goal: to present results of design sprint and get community feedback and collaboration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Need (bjaspan; 5 minutes: 3 minutes presentation, 2 minutes questions)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Our vision of Drupal&#039;s future
&lt;ul&gt;
&lt;li&gt;Web application development &lt;em&gt;platform&lt;/em&gt;; CMS is just one in-the-box app&lt;/li&gt;
&lt;li&gt;API driven, not form-driven&lt;/li&gt;
&lt;li&gt;Able to consume and provide web services&lt;/li&gt;
&lt;li&gt;Able to seamlessly leverage the power of contrib for local and web service data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Problems and challenges at present
&lt;ul&gt;
&lt;li&gt;Multiplicity of uneven APIs for object handling (user vs. node, etc.)&lt;/li&gt;
&lt;li&gt;Binding to user input (form) model &lt;/li&gt;
&lt;li&gt;Single assumed data store (local SQL DB)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Analysis (nedjo; 5 minutes: 3 minutes presentation, 2 minutes questions)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Some steps to achieve the vision
&lt;ul&gt;
&lt;li&gt;Data API: Consistent methods for using local and remote data&lt;/li&gt;
&lt;li&gt;Data rendering: Ability to output in many formats, not just HTML&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CCK fields as model
&lt;ul&gt;
&lt;li&gt;Already exemplifies much of what we are aiming for&lt;/li&gt;
&lt;li&gt;Consistent method for attaching data to nodes&lt;/li&gt;
&lt;li&gt;Escape the current garbage heap of $node&lt;/li&gt;
&lt;li&gt;Represents a shift from objects or entities (nodes, users) to their fields as the core focus&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Initial goal: minimal CCK-based fields in core (karenS; 15 minutes: 10 minutes presentation, 5 minutes questions)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;First step: Fields in core
&lt;ul&gt;
&lt;li&gt;Preliminary work in D6&lt;/li&gt;
&lt;li&gt;Separate directories&lt;/li&gt;
&lt;li&gt;Split out API from UI&lt;/li&gt;
&lt;li&gt;API in new Fields module, developed in contrib with aim of core&lt;/li&gt;
&lt;li&gt;UI remains in contrib&lt;/li&gt;
&lt;li&gt;Code-level methods for what is now UI-based&lt;/li&gt;
&lt;li&gt;Still limited to nodes&lt;/li&gt;
&lt;li&gt;A small number of sample fields converted&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Next steps
&lt;ul&gt;
&lt;li&gt;Further implementations (convert more core fields)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Further steps: entity models (bjaspan and crell; 15 minutes: 10 minutes presentation, 5 minutes questions)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Entity model, providing unified operations for all first-level objects (users, nodes, etc.). Two ideas of how this would work. Begin with what the two have in common, then review each for differences.
&lt;ul&gt;
&lt;li&gt;model 1&lt;/li&gt;
&lt;li&gt;model 2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Further steps: external data store support (nedjo; 5 minutes: 3 minutes presentation, 2 minutes questions)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Existing Services module. Adapt for core?&lt;/li&gt;
&lt;li&gt;Introduce a parallel Clients implementation?&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Concrete tasks and how to help (karenS; 5 minutes)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Contributing to CCK adaptation&lt;/li&gt;
&lt;li&gt;Work on Services and Clients&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Discussion (panel; 30 minutes)&lt;/h4&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/9093#comments</comments>
 <enclosure url="http://groups.drupal.org/files/The Future of Fields.ppt" length="35840" type="application/vnd.ms-powerpoint" />
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Fri, 22 Feb 2008 01:14:40 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">9093 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Proposed Web Service Clients module: Preparing the way for external fields</title>
 <link>http://groups.drupal.org/node/8867</link>
 <description>&lt;p&gt;At the recent &lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;, participants outlined a development path in which fields can be local or external. A given entity instance (node, user, etc.) can be fully local, fully external, or a combination of the two. For example, a node can have several fields stored and handled in a local SQL database and other fields both loaded from and written to an external SOAP service.&lt;/p&gt;
&lt;p&gt;As steps on this path, we outlined (a) short term changes to CCK, (b) a minimal patch to integrate CCK into core, and (c) some follow-up steps, like deciding on a consistent data structure for all entity types, to be followed by a unified set of methods for all entity types (e.g, &lt;code&gt;drupal_save($entity_type, $entity)&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Are there short term steps we can (should?) take now toward external data source support? Here is a rough, conceptual attempt to sketch out such steps in the form of a proposed contrib module, Web Service Clients, taking the existing Services module as a model to work from.&lt;/p&gt;
&lt;h2&gt;Services module: a model for external data source support&lt;/h2&gt;
&lt;p&gt;In D5 contrib, a services module was developed to enable standardized development of Drupal as a web services platform. Documentation: &lt;a href=&quot;http://drupal.org/node/109782&quot; title=&quot;http://drupal.org/node/109782&quot;&gt;http://drupal.org/node/109782&lt;/a&gt;, project: &lt;a href=&quot;http://drupal.org/project/services&quot; title=&quot;http://drupal.org/project/services&quot;&gt;http://drupal.org/project/services&lt;/a&gt;. Services implements a pluggable architecture in which various types of servers (XMLRPC, SOAP) can be implemented, drawing on a common set of services. Services here are sets of available methods, e.g., node load and user save. Through services, a Drupal site can respond to external requests, providing read/write access to locally stored data.&lt;/p&gt;
&lt;h2&gt;Clients module: web service clients modelled on Services&lt;/h2&gt;
&lt;p&gt;Services provides external read/write access to locally stored data. We need the parallel set of implementations: local read/write access to external data sources (via web services).&lt;/p&gt;
&lt;p&gt;Parallel to the Services module&#039;s pluggable server, we need a set of pluggable server types--but as clients rather than servers. In short, we need a Web Service Clients module (Clients for short).&lt;/p&gt;
&lt;p&gt;A minimal initial target spec for this module might be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using XMLRPC (the one server plugin bundled with Services module; there are others in contrib), implement a client such that a Drupal site running Clients can meet the following use cases:
&lt;ol&gt;
&lt;li&gt;User can create and update a node that has two fields from an external site running Services&#039; XMLRPC server. On create and update, those fields are not saved locally but instead are saved to the remote service. On load, fields are loaded from the remote service.&lt;/li&gt;
&lt;li&gt;Whenever a user record is updated locally, a call is sent to a remote service notifying of the update operation. This enables a remote service to store/track a user&#039;s ID and associated email address on the Drupal instance.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Solution components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generic handlers (in clients.module): shared methods&lt;/li&gt;
&lt;li&gt;Pluggable services: services supported, e.g., XMLRPC&lt;/li&gt;
&lt;li&gt;Pluggable methods: local methods for handling data operations&lt;/li&gt;
&lt;li&gt;Client instances: data unique to specific client instances&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Generic handlers&lt;/h3&gt;
&lt;p&gt;Generic handlers and methods, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connecting to external services.&lt;/li&gt;
&lt;li&gt;UI for admin-defined client instances.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Pluggable services&lt;/h3&gt;
&lt;p&gt;Example: generic SOAP support.&lt;/p&gt;
&lt;p&gt;Each service includes methods for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;authentication&lt;/li&gt;
&lt;li&gt;deriving schema information about external data sources&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Pluggable methods&lt;/h3&gt;
&lt;p&gt;Define in metadata form a common set of local methods and their expected data formats and return values. Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;entity_find: given an array of properties and values, return an array of matching entity IDs.&lt;/li&gt;
&lt;li&gt;entity_load: given an entity id, return an entity instance&lt;/li&gt;
&lt;li&gt;entity_save: given an entity instance, save to the remote service and return a result code&lt;/li&gt;
&lt;li&gt;field_load: given an entity id and a field name, return the value of that field for the given entity&lt;/li&gt;
&lt;li&gt;field_save: given an entity id, field name, and field value, save the field to that entity and return a result code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alternately, we could implement the same set of methods as are available in Services module (see the services plugins), but these may tend to be too specific to the Drupal environment and so to map poorly to external web services.&lt;/p&gt;
&lt;h3&gt;Client instances&lt;/h3&gt;
&lt;p&gt;Example: SOAP client to a particular SOAP service.&lt;/p&gt;
&lt;p&gt;A client instance may override generic methods for its service type.&lt;/p&gt;
&lt;p&gt;Each client instance includes handling and methods for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mapping available external request methods to the set of local methods. For example, fed a field_load call, translate this into a call to save data to a remote SOAP service. (Each client instance will implement only a subset of the available local methods.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Nodeapi and CCK integration&lt;/h3&gt;
&lt;p&gt;To locally present and edit data from external sources, we need the ability to represent and integrate those data locally.&lt;/p&gt;
&lt;p&gt;CCK provides our richest set of applicable tools, and is in any case our proposed long term solution. How therefore can we leverage CCK fields in 5.x or 6.x to provide handling for external fields?&lt;/p&gt;
&lt;h4&gt;Proposed implementation:&lt;/h4&gt;
&lt;p&gt;One-to-one mapping between external data fields and local CCK fields, with the CCK field handling overridden for CRUD operations.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For each external field, site admin defines a CCK field and attaches it to one or more content types.&lt;/li&gt;
&lt;li&gt;Clients module provides additional UI element in field definition to select external field to map this field to.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;hook_nodeapi()&lt;/code&gt; load op, Clients module overrides CCK field handling, inserting externally-derived data in place of local ones (which will be empty, as there are no locally stored data).&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;hook_nodeapi()&lt;/code&gt; insert, update, and delete ops, Clients module dispatches calls to external web service for fields it is responsible for.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Actions&lt;/h3&gt;
&lt;p&gt;As well as field-level handling, we need methods to invoke actions based on given state changes. In the above use case #2, this included responding to a user save operation by sending a notification to an external service.&lt;/p&gt;
&lt;p&gt;Here we can build off of Actions, particularly the hook operation support in D6.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Client method implementations (particular local methods, e.g., entity_save, that are implemented by a specific client, e.g., a Gazetteer SOAP service) may declare the &#039;hooks&#039; operations they support, using the same format as used for actions metadata.&lt;/li&gt;
&lt;li&gt;These methods are programmatically exposed as actions with associated hooks, to be called as appropriate, receiving in argument form the relevant data structure (e.g., a user object). &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;By developing genericized, fields-aware web service client support, we can both provide short term functionality for D5 and D6 and begin concretely to map out long term solutions for core.&lt;/p&gt;
&lt;p&gt;After getting our minimal CCK fields into core, we could turn to minimally bringing the Services module and (assuming some solid development by then) accompanying Clients module into core as well.&lt;/p&gt;
&lt;p&gt;Does this approach seem to make sense? What considerations are missing? Please comment on or edit up this Wiki page.&lt;/p&gt;
&lt;p&gt;[Note: I&#039;m hoping to be able to begin coding a draft Clients module within a week or two for an  upcoming client contract.--Nedjo]&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/services&quot;&gt;Services&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8867#comments</comments>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <group domain="http://groups.drupal.org/services">Services</group>
 <pubDate>Wed, 13 Feb 2008 20:02:05 +0000</pubDate>
 <dc:creator>nedjo</dc:creator>
 <guid isPermaLink="false">8867 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Proposed Content Model 2</title>
 <link>http://groups.drupal.org/node/8796</link>
 <description>&lt;p&gt;During the Data Architecture Design Sprint (or DADS, as I will henceforth call it), we discussed two general models for reaching our vision of &quot;data anywhere, value-add anything&quot;.  Those models became dubbed &quot;Model 1&quot; and &quot;Model 2&quot;, because that&#039;s the order in which we happened to write them down.&lt;/p&gt;
&lt;p&gt;Barry has already done a good job of explaining Model 1 in an earlier post.  Here, I am going to lay out the structure of Model 2.  I suspect that the final system, whever it looks like, will draw heavily from both models.&lt;/p&gt;
&lt;p&gt;As Barry described in Model 1 (and will probably be repeated in every summary we write for the next few months), Drupal&#039;s secret weapon is contrib.  Once a piece of data can be made into a node, it automatically gets hundreds of extra features by magic.  CCK and Views are the most common and most powerful magic, but by no means the only.  However, shoe-horning everything into nodes breaks very quickly when dealing with content that doesn&#039;t fit into the &quot;node&quot; model neatly.  In core, we have users.  In my day job, I frequently have museum artwork databases.  I have also considered ways to expose a DocBook tree to Drupal, such as the documentation Steven Peck has been writing for Drupal 6.  I will use all of these examples in the descriptions that follow.&lt;/p&gt;
&lt;h2&gt;The Institute of Contemporary Art&lt;/h2&gt;
&lt;p&gt;This fictional museum is based on the site that, by coincidence, we were launching during the DADS, the &lt;a href=&quot;http://www.artic.edu/aic/collections/&quot;&gt;Art Institute of Chicago&lt;/a&gt;.  There&#039;s much more going on with that site, but for now we&#039;ll focus on the data access.  (If you want to hear more, we&#039;ve proposed a &lt;a href=&quot;http://boston2008.drupalcon.org/session/drupal-museums&quot;&gt;session for DrupalCon Boston&lt;/a&gt;.  Go vote for it. :-) )  For consistency, though, I will continue to call it the ICA.&lt;/p&gt;
&lt;p&gt;The ICA has their entire archive in a legacy database system.  That system has a read-only SOAP interface, using RPC-style calls that return an array structure.  There are several types of &quot;thingies&quot; that the system exposes to us: Artworks, Resources, Artists, and Categories.  Each has its own integer key-space, in addition to between 2 and 30 single-value fields, ranging from an artwork title to the URL of the large-sized jpg of an artwork.  Resources also have a type, which is one of &quot;quicktime&quot;, &quot;full HTML&quot;, &quot;audio clip&quot;, &quot;jpg&quot;, etc.  Each Resource type needs somewhat different theming treatment.&lt;/p&gt;
&lt;p&gt;In Drupal 5/6, the only options for integrating such a 3rd party system are to lazy-create a stub node that wraps a 3rd party object (which can be a bit messy) or to create a completely parallel system that doesn&#039;t touch nodes (or all of their yummy value-add) at all.  Neither is a great solution.&lt;/p&gt;
&lt;h2&gt;Entities&lt;/h2&gt;
&lt;p&gt;In order to be able to value-add to non-local content, we need to be able to define content that is not nodes but still gets node-esque contrb-magic-connection-points.  Rather than make everything a node, we generalize those connection points to a higher-level concept formerly known as Thingie and now represented by the name &quot;Entity&quot; (or Prince, if you prefer).&lt;/p&gt;
&lt;p&gt;An Entity is a common interface that value-add modules can rely on.  Specifically, an Entity type has, and is defined by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A unique key-space.  Users, Nodes, Artworks, and Resource all have a separate key-space.  That is, their IDs are not mutually exclusive.  User 123, Node 123, Artwork 123, and Resource 123 can all co-exist peacefully.&lt;/li&gt;
&lt;li&gt;A set of properties.  We discussed &quot;properties&quot; on and off during the DADs, and didn&#039;t qutie nail down what they were.  The best definition we came up with was &quot;single-value data, and defined by the Entity type rather than the sub-type&quot;.&lt;/li&gt;
&lt;li&gt;Some set of behaviors.  An Entity type is able to define extra logic that applies to it, but doesn&#039;t apply to other Entity types.  For instance, the User entity type defines the logic relating to logging in a user, a concept that has no meaning for a Node or an Artist.&lt;/li&gt;
&lt;li&gt;One or more subtypes.  A subtype defines a set of field definitions that it will contain.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not all Entity types will have or need subtypes.  Nodes do now.  We discussed possible subtypes for Users, and came up with possible use-cases (users authenticated by different systems, such as local or LDAP) but nothing firm.  Artworks and Artists do not have subtypes, however, Resources do.  For simplicity, an Entity type that doesn&#039;t need subtypes simply has a single subtype, as &quot;1&quot; can always be treated as a special case of &quot;many&quot;.&lt;/p&gt;
&lt;p&gt;Absent from the Entity definition is whether its fields are local or remote; we established fairly early on that question to be a per-field question.  The keys-space of the Entity type, however, may be locally or remotely controlled.&lt;/p&gt;
&lt;p&gt;Contrib modules then value-add to an Entity by adding a field to one or more of the types of that Entity.  One could add, say, a fivestar field to the Artwork Entity&#039;s only subtype, the Resource Entity&#039;s &quot;quicktime&quot; subtype, and the &quot;story&quot; subtype of the Node entity.&lt;/p&gt;
&lt;h2&gt;Some examples&lt;/h2&gt;
&lt;p&gt;I had originally intended to have drupal_load() always take an integer ID, to normalize it across the board, but I realized while reading Barry&#039;s Model 1 description that won&#039;t work if the entity has yet to be locally linked from a remote service.  That gives an Entity two IDs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;id: The unique key in the entity&#039;s native system.  In the case of Nodes and Users, it is nid or vid.  For, say, a DocBook data source, it could be an XPath query string or the ID of a specific element.&lt;/li&gt;
&lt;li&gt;localId: This key, if present, is always an integer and is used by locally-stored fields to reference the Entity.  In some cases it will map 1:1 to the id (pretty much any case where the id is an integer, including nid and vid).  That is an implementation detail left to each Entity to determine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Perhaps some code will explain the structure better.&lt;/p&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;node_view&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$node &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;drupal_load&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;node&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;123&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;&amp;lt;h2&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$node&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() .&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;&amp;lt;/h2&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$node&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;body&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;drupal_load&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$entity_type&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp; return new &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$entity_type&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;class &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Node &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br /&gt;&amp;nbsp; protected &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; protected &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_properties&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; protected &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_fields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;__construct&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_id &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_properties &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;db_fetch_object&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;db_query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;SELECT * FROM {node} WHERE nid=%d&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_fields &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;get_fields_associated_with_type&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;Node&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;());&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;localId&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_properties&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_properties&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;fields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_fields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field_name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_fields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field_name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;];&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;fields &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;as &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;localId&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;p&gt;Things to note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Yes, it is OO.  OOP is very good at enforcing an interface and hiding implementation details, which is what we want to do here.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;title()&lt;/code&gt; is a method rather than a direct property.  Rendering a human-readable string to represent an Entity is a behavior, and therefore is Entity-type specific.&lt;/li&gt;
&lt;li&gt;All properties of the Node class are prefixed with a &lt;code&gt;_&lt;/code&gt; as well as made &lt;code&gt;protected&lt;/code&gt;.  That way, we can still arbitrarily add extra properties to the node without colliding with them to support older code, at least temporarily until we figure out how to make &quot;everything a field&quot;.&lt;/li&gt;
&lt;li&gt;Because we&#039;re behind an object interface, we can implement lazy-loading or not, or other optimizations, in the constructor, the &lt;code&gt;field()&lt;/code&gt; and &lt;code&gt;fields()&lt;/code&gt; methods, and in the yet-to-be-written &lt;code&gt;get_fields_associated_with_type()&lt;/code&gt; routine.  In some cases, lazy-loading makes a lot of sense.  In others, such as the Artwork example above, it&#039;s more efficient to pull the entire data object at once because the backend in this case supports it.  That&#039;s information that the caller (&lt;code&gt;node_view()&lt;/code&gt;) shouldn&#039;t have to care about.&lt;/li&gt;
&lt;li&gt;Somewhere in there it would be wise to implement at least static load caching, probably in &lt;code&gt;drupal_load()&lt;/code&gt;, but we&#039;ll deal with that later.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For comparison, the Artwork Entity might look like this, if we had to deal with non-integer ids:&lt;/p&gt;
&lt;div class=&quot;codeblock&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;class &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;Artwork &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;{&lt;br /&gt;&amp;nbsp; protected &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; protected &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_properties&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; protected &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_fields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; protected &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$_additionalFields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;__construct&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_id &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$data &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;SoapConnection&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;artwork&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_fields &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;parse_data_out_into_field_objects&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$data&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_additionalFields &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;get_fields_associated_with_type&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;Artwork&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;artwork&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;localId&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$localId&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (empty(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$localId&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$localId &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;db_result&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;db_query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;SELECT localId FROM {artwork} WHERE id=&#039;%s&#039;&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (empty(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$localId&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;db_query&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;INSERT INTO {artwork} (id) VALUES(&#039;%s&#039;)&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$localId &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;db_last_id&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$localId&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;artwork&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;title&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;();&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;fields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_fields &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;+ &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;additionalFields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field_name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;fields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field_name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;])) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_fields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field_name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_additionalFields&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field_name&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; function &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;_additionalFields &lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;as &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;localId&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;p&gt;Note here that the title is being generated differently, and we&#039;re internally classifying fields by where they came from.  Some are saveable, some are not.  If we try to save an artwork, a local ID will be created if necessary for our &quot;additional fields&quot; to use.  Again, the outside world doesn&#039;t care.  All it knows is that it asks for an Artwork of ID &#039;123.456/5&#039;, adds a fivestar rating to it, and saves the Artwork.  And until we call &lt;code&gt;save()&lt;/code&gt;, the local database is unaffected.&lt;/p&gt;
&lt;p&gt;Still an open question, of course, is what the interface for Field will look like.  We&#039;ve already said we want those to always be multi-value, but beyond that, I&#039;m not sure what they&#039;d look like.&lt;/p&gt;
&lt;p&gt;For those who like UML, here&#039;s what this model would look like, I think:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://groups.drupal.org/files/model2.png&quot; /&gt;&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8796#comments</comments>
 <category domain="http://groups.drupal.org/taxonomy/term/3319">Data API</category>
 <category domain="http://groups.drupal.org/taxonomy/term/3565">Object Oriented</category>
 <enclosure url="http://groups.drupal.org/files/model2.png" length="20947" type="image/png" />
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Sun, 10 Feb 2008 22:21:19 +0000</pubDate>
 <dc:creator>Crell@drupal.org</dc:creator>
 <guid isPermaLink="false">8796 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Taxonomy as a field</title>
 <link>http://groups.drupal.org/node/8793</link>
 <description>&lt;p&gt;It&#039;s useful to explore how existing core functionality can or cannot be implemented as a field.  Doing so may cause us to change how we decide to implement them.  In this post I&#039;m talking in terms of nodes but trying to avoid assuming that we are limited to nodes instead of Content objects and that all fields are stored locally in SQL.  I&#039;m also mostly just thinking as I go/type; I don&#039;t have a specific outcome in mind yet.&lt;/p&gt;
&lt;p&gt;Taxonomy is a &quot;multi-valued field&quot; assigned to node types currently via variable settings.  The term_node table is effectively a field table: (nid, tid) instead of (nid, delta, tid).  One note is that the tid assignments to a nid are unordered whereas field values are ordered.  Since the nid,tid order has never mattered before, arbitrarily assigning an order via delta should not matter.&lt;/p&gt;
&lt;p&gt;During load, term_node connects to term_data and vocabulary.  Observation: Although we wrote down that &quot;drupal_load(&#039;node&#039;, $nid) will SELECT FROM node + load all fields&quot;, drupal_load() probably will not actually load all the data itself directly; instead, it will have to call a taxonomy_field_load() hook.  For the specific taxonomy case, perhaps we could encode information in the Schema structure or the field definition that tells drupal_load() to join these other tables.  However, consider a field that access remote data (e.g. &quot;Amazon products related to this story&quot; field).  drupal_load() can&#039;t possibly load that data directly, so we need a field_load() hook, so taxonomy should probably just use it.&lt;/p&gt;
&lt;p&gt;term_data contains a term weight which determines the order of tids in the $node-&amp;gt;taxonomy array.  This is disjoint from the delta column in the term_node field table; the weight is a property of the term, not its assignment to a node.  Vocabularies have weights too.  taxonomy_field_load() will presumably return an array of field values to be merged into the node.  When the node is saved, the taxonomy field table  (term_node replacement) will be filled with (nid, delta, tid) but again the deltas will be &quot;arbitrary&quot;.&lt;/p&gt;
&lt;p&gt;So taxonomy_field_load() turns out to look almost exactly like taxonomy_nodeapi(&#039;load&#039;); well, we always knew nodeapi was a pretty powerful model.&lt;/p&gt;
&lt;p&gt;Today, $node-&amp;gt;taxonomy is filled in as an array mapping tid to an &quot;object&quot; of all the columns of term_data.  If taxonomy is a field, then $node-&amp;gt;taxonomyfieldname is a field array which means its keys are deltas (in this case, meaninglessly so).  $node-&amp;gt;taxfieldname[n] is a term_data &quot;object&quot; including the tid.  So code that assumes the indexes are tids will need to change to use the tid field directly.  Such code exists in taxonomy.module, elsewhere in core, and throughout contrib, probably.&lt;/p&gt;
&lt;p&gt;Hmmm.  I actually just glossed over something important.  If taxonomy is a field type, then multiple fields of type taxonomy can be added to a node.  This could be quite useful: &quot;user assigned terms&quot; and &quot;editor assigned terms&quot;.  However, fields are stored based on their name: $node-&amp;gt;usertaxterms, $node-&amp;gt;editortaxterms, or something like that.  Right now, a node only has one set of terms and it is &lt;em&gt;always&lt;/em&gt; available at $node-&amp;gt;taxonomy.  So if I have a node object I can ask, &quot;what are its terms?&quot; because I  know where they are stored.  With taxonomy as a field, I do not know where they are stored.&lt;/p&gt;
&lt;p&gt;This is not limited to taxonomy; comments are the same way, always at $node-&amp;gt;comments but if comments were a field they&#039;d be in $node-&amp;gt;commentfieldname.&lt;/p&gt;
&lt;p&gt;I think the ability to access $node-&amp;gt;taxonomy directly is an historical artifact.  Drupal was designed as a CMS and taxonomy, comments, and other CMSy features were built it in fixed ways.  Many sites use Drupal for events, and event nodes often have a venue, but we do not expect to be able to access $node-&amp;gt;venue to find out the venue for an event node.  We have to know the name of the venue field.&lt;/p&gt;
&lt;p&gt;What to do about this?  Random thoughts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The easy solution: At install time, when we create the &#039;page&#039; and &#039;story&#039; type, we create a field of type taxonomy named &#039;taxonomy&#039; and assign it to those node types.  If you create a new node type and want it to play with standard taxonomy functionality, assign the &#039;taxonomy&#039; field to it.  Otherwise, feel free to do whatever you want.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Perhaps we need to be able to ask a field type for all of the values on a node from that field type.  e.g. $taxonomy = taxonomy_field_all_values($node).  Or probably, since the core field registry knows what fields are assigned to each node type, it would be $taxonomy = field_all_values_of_field_type(&#039;taxonomy&#039;, $node).  That would give me all the terms for the node.  If I specifically wanted some subset (e.g. only one field&#039;s worth of terms), that implies I&#039;m writing new code in a post-taxonomy-as-field world and presumably I know which field I&#039;m looking for.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Perhaps what&#039;s going on here is that we&#039;re trying to turn Drupal into a more general web app development platform and we&#039;re discovering that it has aspects of the initial app built on the platform, the CMS app, integrated to deeply into core.  The CMS app defines that $node-&amp;gt;taxonomy and $node-&amp;gt;comment exist as those specific names and then uses them.  So perhaps we need to very clearly separate &quot;core Drupal functionality&quot; and &quot;the CMS app&quot; from each other.  They can still be shipped in the same tarbar but as clearly defined entities.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All that from &quot;let&#039;s think about taxonomy as a field&quot;!&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8793#comments</comments>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Sun, 10 Feb 2008 18:12:51 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">8793 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Summary of the Data Architecture Design Sprint</title>
 <link>http://groups.drupal.org/node/8786</link>
 <description>&lt;p&gt;Six Drupal developers met for three days in Feburary 2008 to work on and re-design Drupal&#039;s core data architecture.  We began with an overly broad list of topics and goals and spoke in very general terms about &quot;Drupal&#039;s overall mission&quot; and similarly vague concepts.  By the end of the design sprint, we devised a tangible vision for Drupal&#039;s future and an understandable method for getting there.&lt;/p&gt;
&lt;p&gt;We believe that the overall goal for the Drupal community should be to convert Drupal from a monolithic Content Management System into a web application development platform in which a powerful CMS is one built-in implementation.  We talked a lot about what that means and requires, including things like consistent and documented APIs for all parts of core, switching to an API-driven instead of form-driven architecture, and a data rendering architecture for producing output in many formats besides HTML.  None of these are new ideas within the community, of course, but discussing them in the context of our stated goal (making Drupal into a web app development platform) provided a useful organizing structure and new insights.&lt;/p&gt;
&lt;p&gt;One particular epiphany we had is the realization of how Drupal&#039;s existing architecture makes it an excellent tool for developing web applications in a web-services world.  Drupal receives a request from an external source (currently, from a web browser or XML-RPC client), converts it to a query against a data store (currently, an SQL database), and returns the result.  Before it returns the result, however, it exposes the data via Drupal&#039;s hook mechanism to an enormous variety of contributed modules that can add additional value to the data.  The fact that so many disparate people can write modules to enhance content value through Drupal&#039;s hook interface is Drupal&#039;s key feature.&lt;/p&gt;
&lt;p&gt;It became clear that, in a web services world, where Drupal needs to be able to both offer and consume web services, Drupal also needs to be able to provide its key feature---value-added data via contrib modules---to web services data.  Comments, votes, maps, social bookmarks, etc. etc. etc., should be just as appliable to a content object retrieved from Amazon as a node retrieved from SQL.&lt;/p&gt;
&lt;p&gt;We eventually decided, as we mostly knew we would, that moving CCK&#039;s field concept in Drupal core is important step forward.  Keeping our two days of discussion about &quot;the future of Drupal&quot; in mind, we worked to define how to put fields in core in a way that is consistent with our proposed future and makes it easier to get there.  We devised two &quot;Proposed Content Models&quot; for supporting what we called &quot;multi-source&quot; data with core fields though both need plenty more design work and exploration.&lt;/p&gt;
&lt;p&gt;A lot of work still needs to be done and, as always with Drupal, most of it is currently slated to be performed by volunteers.  It is our strong desire to at least have node-based fields in D7 core and, hopefully, have multi-source data support in D7 core as well.  We will have to see what is achievable.&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8786#comments</comments>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Sun, 10 Feb 2008 17:17:29 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">8786 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Structure of &quot;fields in core&quot; patch and of CCK project</title>
 <link>http://groups.drupal.org/node/8770</link>
 <description>&lt;p&gt;Following the design sprint, drawing on what we had discussed, Yves, Karen, and Nedjo tried to map out some of the structure of a core patch and the accompanying short and longer term changes to CCK fields.&lt;/p&gt;
&lt;p&gt;Specifically, we discussed the following approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the immediate term, make small changes as feasible to facilitate longer term changes, e.g., move CCK modules into their own  directories in CVS.&lt;/li&gt;
&lt;li&gt;Working in CCK HEAD or possibly a D6 branch, do as much as possible of the work of preparing the patch for core in the form of refactoring the CCK package. This should be possible because we are preparing a new set of APIs that will be isolated in their own files and won&#039;t immediately require large changes to existing Drupal core code. We avoid the work of rolling patch after patch.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Core patch structure&lt;/h2&gt;
&lt;p&gt;What concretely will a core patch look like?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New required core API module, Field. While initially implemented for nodes, it is abstracted to facilitate later application to other entity types.&lt;/li&gt;
&lt;li&gt;Field types
&lt;ul&gt;
&lt;li&gt;Could be implemented in a shared module, Field Types, with the various core field types in a single module. Alternately we stick with the current approach, one module per field type.&lt;/li&gt;
&lt;li&gt;Whether one or more modules, do they need to be required? Initial feeling is, many or most may need to be required.&lt;/li&gt;
&lt;li&gt;We could consider UI tweaks to the modules admin page to e.g. collect field type modules together.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Short term CCK steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Move all CCK modules to their own directories (except content?). Issue: &lt;a href=&quot;http://drupal.org/node/218973&quot; title=&quot;http://drupal.org/node/218973&quot;&gt;http://drupal.org/node/218973&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Branch 6.x&lt;/li&gt;
&lt;li&gt;Likely after branching, create new field module (in its own directory) and move field CRUD API from content module to field module. Content module eventually becomes a purely UI module.&lt;/li&gt;
&lt;li&gt;In Field module, implement &lt;code&gt;hook_nodeapi()&lt;/code&gt; as is currently done in CCK to implement fields CRUD. When we get to the point of a core patch, this hook implementation will be replaced by calls in &lt;code&gt;node_load()&lt;/code&gt;, &lt;code&gt;node_save()&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Sat, 09 Feb 2008 18:11:24 +0000</pubDate>
 <dc:creator>nedjo</dc:creator>
 <guid isPermaLink="false">8770 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Remote content as minimal viable functionality</title>
 <link>http://groups.drupal.org/node/8732</link>
 <description>&lt;p&gt;We talked a lot about minimum viable functionality (MVF) for D7 core.  We also talked briefly about what criteria to use to decide what should be in core vs. contrib.  I&#039;d like to revisit that.&lt;/p&gt;
&lt;p&gt;Question: Why bother putting fields in core at all?&lt;/p&gt;
&lt;p&gt;Being in core has many drawbacks.  Much slower development/release cycles, necessity to gain broad consensus for everything, requirement to operate in every possible environment that Drupal supports (e.g. low-memory hosting), etc.  We already have CCK and fields in contrib.  They work great.  Why are we going to incur all this extra pain?&lt;/p&gt;
&lt;p&gt;I think the answer to &quot;what should be in core&quot; is &quot;those things that provide substantial benefit and simply could not be done outside of core because they require fundamental architectural support or the like.&quot;&lt;/p&gt;
&lt;p&gt;CCK fields on nodes do not meet this requirement.  We already have a &#039;body&#039; field.  Just providing a new way to have a &#039;body&#039; field is not interesting or useful enough to incur the extra effort.&lt;/p&gt;
&lt;p&gt;Instead, I assert that the MVF for fields in core needs to include something that is just not possible with CCK in contrib.  Among the things we discussed in our sprint, the ability to add fields to remote content is that thing.  Fields on remote content will by itself make D7 a killer release, leaping Drupal past its competition.  I think it will make Jeff, Acquia&#039;s VP of marketing, drool.  I think this is the goal we need to strive for.&lt;/p&gt;
&lt;p&gt;I have a basic grasp of how to implement my proposed Content Model 1 and I do not think it will be a monster task; most node code and functionality will remain the same.  I still want to see Larry&#039;s writeup of Content Model 2.  Then I/we should get to serious work on nailing down the Content interface (or Fieldable as I&#039;ve suggested renaming it) or whatever Model 2 uses.&lt;/p&gt;
&lt;p&gt;Thoughts?&lt;/p&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8732#comments</comments>
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Thu, 07 Feb 2008 23:42:28 +0000</pubDate>
 <dc:creator>bjaspan</dc:creator>
 <guid isPermaLink="false">8732 at http://groups.drupal.org</guid>
</item>
<item>
 <title>Day 3</title>
 <link>http://groups.drupal.org/node/8714</link>
 <description>&lt;p&gt;Notes: Comments are now enabled on this page.&lt;/p&gt;
&lt;h2&gt;CCK simplifications for core&lt;/h2&gt;
&lt;p&gt;The day started with ways we can simplify current CCK functionality because there is a feeling that what we have is way to fragile and complex for core at this time.  Functionality slated for destruction includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Per-content type field storage, e.g. no more content_type_story tables with columns for multiple single-value fields.  All fields are stored in today&#039;s equivalent of content_field_fieldname tables.&lt;/li&gt;
&lt;li&gt;All field tables always have a delta column even if it is a single-value field.&lt;/li&gt;
&lt;li&gt;Field-level settings, which are defined as those that (at least) affect the schema, cannot be changed.  e.g. You cannot convert a text field from plain-text to formatted-text; instead, you must create a new field, copy the data, and drop the old one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The net effect of these changes is that field tables never need to change dynamically except during version upgrades.  No other part of core performs dynamic schema changes outside of update and it we felt it was much simpler to maintain this restriction.&lt;br /&gt;
bjaspan: I suppose there is an argument that if we are removing the ability to change field settings dynamically, allowing per-content-type storage and per-field storage does not imply/require the same level of complexity currently in CCK because if you can&#039;t change the field settings you can&#039;t change the storage method so we can still lose all the code that handles changing the storage method.&lt;/p&gt;
&lt;h2&gt;Field and Field Instance Definitions:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A field type is a set of functionality implemented by a module, e.g. text, nodereference, gmap.&lt;/li&gt;
&lt;li&gt;A field is a collection of settings of a field type: e.g.  a text field, max length 60, plain text (no input format option for the user).&lt;/li&gt;
&lt;li&gt;A field instance is the binding of a field to a content type with additional settings: e.g. the above text field assigned to the story node type with the label &quot;Five word summary.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The field settings contain aspects of the field that will be the same in all instances. They often include things that affect the database schema or storage and the way the field data will be stored. Because of this, they cannot vary from one instance to another or you would have a field with a different database schema. Examples of field settings are the size of the field and whether it can hold multiple values. (bjaspan: Since all field tables will always have a delta column, I&#039;m not clear on why single/multiple cannot be an instance setting UNLESS we continue to allow per-content-type storage as discussed above, though clearly changing a field from multiple to single will lose data).&lt;/p&gt;
&lt;p&gt;The field instance settings contain aspects of the field that can be different from one instance to another. They include things that do not affect the way the data is stored, only the way it is displayed. Examples of field instance settings include the label and weight of the field.&lt;/p&gt;
&lt;p&gt;The settings are stored in two tables, one for the field settings (one row for each field) and another for the field instances (one row for each instance).&lt;/p&gt;
&lt;h4&gt;Open questions&lt;/h4&gt;
&lt;p&gt;Is it necessary to have two separate tables or could all the data should be stored in the instance table, even if the instances have duplicate field information.  (bjaspan: That would be non-normal form and we&#039;d need a good reason for is; is there one?)&lt;/p&gt;
&lt;p&gt;Should field settings be locked, once created, so they cannot be changed? They impact the schema and it would greatly simplify core code if that is just not allowed. It would be OK to change instance settings like labels, but not field names, sizes, multiple, and other things that impact the database schema.&lt;/p&gt;
&lt;h2&gt;Multiple Values&lt;/h2&gt;
&lt;p&gt;We discussed whether core will need to handle multiple values and concluded that will certainly be necessary. So we examined the way that the D6 version of CCK handles multiple values to start thinking about what will need to be implemented in core.&lt;/p&gt;
&lt;p&gt;The D5 and earlier versions of CCK uses a separate formatter for each individual field value, one after the other. That does not always make sense. There should be a possibility to format all values for a field in a single formatter (like a field that contains multiple points on a map or a slideshow of images). This change has gone into the D6 version of the code.&lt;/p&gt;
&lt;p&gt;The D5 and earlier versions of CCK presume widgets will handle multiple value forms themselves and pass them back to the Content module. In D6 that is changed so that widgets create a single form value element and it is the Content module that combines them together into a single form element. Some widgets need to opt out of that behavior to handle all values in a single form element (like a select list or checkboxes). Now that the Content module handles multiple values, there is also a way for the widget to opt out of that and handle its own multiple values. The optionwidgets module does this.&lt;/p&gt;
&lt;h2&gt;API&lt;/h2&gt;
&lt;h3&gt;Example code&lt;/h3&gt;
&lt;p&gt;What will the API look like. An example of what a module developer might write:&lt;/p&gt;
&lt;p&gt;$info creates a content type called &#039;user_profile&#039;, it contains stuff like &#039;name&#039;, &#039;has_body&#039;, &#039;min_words&#039;, etc. (except that body probably won&#039;t be a built-in part of node types anymore, it will be a normal field).&lt;br /&gt;
node_type_save(&#039;user_profile&#039;, $info);&lt;/p&gt;
&lt;p&gt;$settings = array(&lt;br /&gt;
  &#039;name&#039; =&amp;gt; &#039;Eye Color&#039;,&lt;br /&gt;
  &#039;restricted values&#039; =&amp;gt; array(&lt;br /&gt;
    &#039;brown&#039;, &#039;green&#039;, &#039;blue&#039;));&lt;/p&gt;
&lt;p&gt;field_create_field(&#039;eyecolor&#039;, $settings);&lt;/p&gt;
&lt;p&gt;$settings = array(&lt;br /&gt;
  &#039;label&#039; =&amp;gt; &#039;User eye color&#039;);&lt;/p&gt;
&lt;p&gt;field_create_instance(&#039;user_profile&#039;, &#039;eyecolor&#039;, $settings);&lt;/p&gt;
&lt;p&gt;To add this field to another content type:&lt;/p&gt;
&lt;p&gt;$info creates a content type called &#039;admin_profile&#039;.&lt;br /&gt;
node_type_save(&#039;admin_profile&#039;, $info);&lt;/p&gt;
&lt;p&gt;$settings = array(&lt;br /&gt;
  &#039;label&#039; =&amp;gt; &#039;Administrator eye color&#039;);&lt;/p&gt;
&lt;p&gt;field_create_instance(&#039;admin_profile&#039;, &#039;eyecolor&#039;, $settings);&lt;/p&gt;
&lt;h3&gt;Needed Functionality&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Create node type / Delete node type&lt;/li&gt;
&lt;li&gt;Create field / Delete field&lt;/li&gt;
&lt;li&gt;Add field to node type / Delete field from node type&lt;/li&gt;
&lt;li&gt;Update field configuration (required, multiple, widgets/formatters, weight)&lt;/li&gt;
&lt;li&gt;Get table name for field&lt;/li&gt;
&lt;li&gt;Get types&lt;/li&gt;
&lt;li&gt;Get fields&lt;/li&gt;
&lt;li&gt;Get field instances for type&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Open questions :&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Current CCK field CRUD API operate only on &#039;field instances&#039;, and do not allow fields without instances. What sense does it have ? Is that even doable (both Karen and Eaton came to the conclusion that it might be a problem)?  Karen did not remember what the problem was; we are thinking that the simplifications we are planning will eliminate it.&lt;/li&gt;
&lt;li&gt;Other drupal CRUD APIs merge &#039;create&#039; and &#039;update&#039; into a &#039;save&#039; function...&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Approaches for letting modules define node types and their fields&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;imperative : sequence of direct field CRUD API calls at install time&lt;/li&gt;
&lt;li&gt;declarative : cf hook_node_info(), hook_schema()&lt;br /&gt;
-- modules provide returns an array &lt;em&gt;describing&lt;/em&gt; node types and their fields&lt;br /&gt;
-- this array gets processed and turned into a series of field CRUD API calls.&lt;br /&gt;
-- the hook_update_N() mechanism calls API functions for updates is used for version updates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We decided that we need to implement the API in either case so we&#039;re starting with that.  A declarative approach (hook_node_types() + hook_update_N() for changes) is more consistent with other parts of Drupal and can be added on later.&lt;/p&gt;
&lt;h3&gt;Workflow&lt;/h3&gt;
&lt;p&gt;Typical workflow for module authors (Just like what currently exists for Views) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adjust their fields setup using contrib CCK-UI&lt;/li&gt;
&lt;li&gt;&#039;Export&#039; types and fields in a PHP definition (new &#039;Content Copy&#039;)&lt;/li&gt;
&lt;li&gt;paste the PHP snippet into their hook_node_info (or whatever the actual hook)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Open questions :&lt;/h4&gt;
&lt;p&gt;UI-defined fields probably need to live in a different namespace (see below), so this workflow probably hits name issues.&lt;/p&gt;
&lt;h2&gt;Node structure :&lt;/h2&gt;
&lt;p&gt;$node-&amp;gt;fieldname[n][&#039;column&#039;]&lt;/p&gt;
&lt;p&gt;Field namespace :&lt;br /&gt;
It&#039;s the job of the modules not to create fields whose name clashes with other modules&#039; fields.&lt;br /&gt;
We need to ensure that module-defined fields don&#039;t clash with user-defined fields (with CCK UI in contrib)&lt;/p&gt;
&lt;p&gt;What happens when disabling the module that originated the field_create_field ?&lt;br /&gt;
- skip field&lt;br /&gt;
- raise exception&lt;/p&gt;
&lt;h2&gt;Compatibility with existing module&lt;/h2&gt;
&lt;p&gt;The &#039;core fields&#039; won&#039;t be able to co-exist with a D7 forward-port of current contrib CCK, if only because there can only be one &#039;text.module&#039;. Thus, we need to get &#039;fields in core&#039; right :-)&lt;/p&gt;
&lt;h2&gt;Node Load&lt;/h2&gt;
&lt;p&gt;Current node load operations (e.g. loading a poll node):&lt;br /&gt;
1) node_load: SELECT FROM node, node_revision&lt;br /&gt;
2) hook_load: SELECT FROM poll&lt;br /&gt;
3) hook_nodeapi op load: SELECT FROM comment&lt;/p&gt;
&lt;p&gt;New :&lt;br /&gt;
1) node_load: SELECT FROM node, node_revision &lt;em&gt;and&lt;/em&gt; load all fields.&lt;br /&gt;
2) hook_load: calls poll_load() so the poll module can do something if it wants but it does not need to load its field-based data&lt;br /&gt;
3) hook_nodeapi op load: SELECT FROM comment, for any modules that are not converted to fields (e.g. if comments are fields, SELECT FROM comment is handled automatically in step 1).&lt;/p&gt;
&lt;p&gt;If we go to a class Node, loading of all fields in step 1 can actually be lazy-loaded so unused fields are never actually loaded/processed.&lt;/p&gt;
&lt;h2&gt;Which CCK functions should go to core ?&lt;/h2&gt;
&lt;p&gt;Go to Core:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;field storage engine&lt;/li&gt;
&lt;li&gt;Field CRUD&lt;/li&gt;
&lt;li&gt;widgets / form gen.&lt;/li&gt;
&lt;li&gt;Node CRUD&lt;/li&gt;
&lt;li&gt;formatters&lt;/li&gt;
&lt;li&gt;add more / drag &#039;n drop re-ordering&lt;/li&gt;
&lt;li&gt;Field validation&lt;/li&gt;
&lt;li&gt;custom multiple value handling&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stay in contrib:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;field default value&lt;/li&gt;
&lt;li&gt;field allowed values&lt;/li&gt;
&lt;li&gt;Field CRUD UI (Manage Fields tab)&lt;/li&gt;
&lt;li&gt;Display UI (Display Fields tab)&lt;/li&gt;
&lt;li&gt;Fieldgroups&lt;/li&gt;
&lt;li&gt;Content Copy&lt;/li&gt;
&lt;li&gt;3rd party Drupal integration (Views, Pathauto, Token)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Which CCK fields should go to core?&lt;/h2&gt;
&lt;p&gt;The current CCK core fields:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;field types&lt;/li&gt;
&lt;li&gt;fieldgroup&lt;/li&gt;
&lt;li&gt;noderefence&lt;/li&gt;
&lt;li&gt;number&lt;/li&gt;
&lt;li&gt;userreference&lt;/li&gt;
&lt;li&gt;image&lt;/li&gt;
&lt;li&gt;file&lt;/li&gt;
&lt;li&gt;computed&lt;/li&gt;
&lt;li&gt;date&lt;/li&gt;
&lt;li&gt;text&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;widget&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;optionwidgets&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Things in core that might be fields :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;body: text field&lt;/li&gt;
&lt;li&gt;created: date&lt;/li&gt;
&lt;li&gt;upload: file&lt;/li&gt;
&lt;li&gt;user pic: image&lt;/li&gt;
&lt;li&gt;IDs: number+options&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Criteria for &#039;in core&#039; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wide applicability&lt;/li&gt;
&lt;li&gt;minimum useful functionality&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Action plan:&lt;br /&gt;
Start with text, number, optionwidgets, image, file. Leave nodereference and userreference in contrib until we need them in core so we can continue to easily add features and do other work on them. Once in core they will be hard to change. Getting a date field into core would be easier if improved date handling gets into core, which is a separate initiative. The complex date field would probably remain in contrib but a simpler date field could be created for core.&lt;/p&gt;
&lt;h2&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Beyond a minimal implementation of CCK fields in core, what will be the next steps?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;node as class?
&lt;ul&gt;
&lt;li&gt;To get a consistent set of methods for all first-class entity types (node, user, etc.), we need a consistent data format--array or class. If we use class, we may find it advantageous to use a custom rather than StdClass to have access to PHP 5 features such as lazy loading.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;gradual conversion of existing core &#039;fields&#039;
&lt;ul&gt;
&lt;li&gt;Having implemented a small number of new-style fields in core, we will need gradually to convert much (all?) of the remaining existing &#039;fields&#039; to the CCK-style system. Doing so will require new methods and functionality. For example, existing CCK cannot fully handle the current node taxonomy implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;field property can not be edited&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Lessons learned for future &#039;Design sprints&#039; :&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A facilitator was very useful. We benefited from having a process oriented faciliator who was a little removed from the issue (Nedjo).&lt;/li&gt;
&lt;li&gt;The initial scope too large. We did narrow it, but not in time, so we prepared for things that weren&#039;t directly relevant.&lt;/li&gt;
&lt;li&gt;Sometimes key contributors need financing to attend. In spite of the cost it would be a worthwhile investment output.&lt;/li&gt;
&lt;li&gt;Commercial community understands the value, but employee time is precious.&lt;/li&gt;
&lt;li&gt;The final number of six people was good size.&lt;/li&gt;
&lt;li&gt;Eight hours a day is good. It&#039;s tempting to go longer, but wouldn&#039;t have been a good idea.&lt;/li&gt;
&lt;li&gt;The nightly wiki summaries was a useful way for participants to analyze and review the results.&lt;/li&gt;
&lt;li&gt;Taking complete notes is critical, could it be done by someone else (e.g. a support role)? It would have to be someone who understands the discussion.&lt;/li&gt;
&lt;li&gt;Fun is good, eg. dinner out. There is a lot of pressure and intensity and providing some respite helps the process.&lt;/li&gt;
&lt;li&gt;Three days feels like an appropriate length of time.&lt;/li&gt;
&lt;li&gt;It is useful to have people on a similar skill/expertise level
&lt;ul&gt;
&lt;li&gt;invite key contributors for task on hand&lt;/li&gt;
&lt;li&gt;also useful to have a mix of the centrally involved with in this (some use CCK others not.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Getting everyone face to face in a small group really benefit the process.&lt;/li&gt;
&lt;li&gt;The facility needs
&lt;ul&gt;
&lt;li&gt;whiteboard&lt;/li&gt;
&lt;li&gt;wifi&lt;/li&gt;
&lt;li&gt;sufficient space&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A nice location (Hawaii) would be nice! :-)  Chicago in Feburary not so good.&lt;/li&gt;
&lt;li&gt;Put everyone up at the same hotel. It avoids wasting time and provides more chances for unscheduled interaction. Lots of good ideas came up while eating at Panera!&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;og_rss_groups&quot;&gt;&lt;a href=&quot;/data-architecture-design-sprint&quot;&gt;Data Architecture Design Sprint&lt;/a&gt;&lt;/div&gt;</description>
 <comments>http://groups.drupal.org/node/8714#comments</comments>
 <enclosure url="http://groups.drupal.org/files/plan.ods" length="13549" type="application/octet-stream" />
 <group domain="http://groups.drupal.org/data-architecture-design-sprint">Data Architecture Design Sprint</group>
 <pubDate>Thu, 07 Feb 2008 01:28:12 +0000</pubDate>
 <dc:creator>chx</dc:creator>
 <guid isPermaLink="false">8714 at http://groups.drupal.org</guid>
</item>
<item>
 <title>The new field settings array</title>
 <link>http://groups.drupal.org/node/8703</link>
 <description>&lt;p&gt;We&#039;re talking about having fields 