Commit c46b3c82 authored by JonBob's avatar JonBob

Okay, here goes nothin'.

This commit changes the storage mechanism for hopefully the final time. As
was discussed a while back, now data is stored in tables for each content
type unless it cannot be. It may require per-field storage for two reasons:
- The field is present in more than one content type.
- The field allows multiple values.
parent a2e3b335
......@@ -22,6 +22,7 @@ function content_install() {
global_settings mediumtext NOT NULL,
required int NOT NULL default '0',
multiple int NOT NULL default '0',
db_storage int NOT NULL default '0',
PRIMARY KEY (field_name)
) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;");
db_query("CREATE TABLE {node_field_instance} (
......@@ -51,6 +52,7 @@ function content_install() {
global_settings text NOT NULL,
required integer NOT NULL default '0',
multiple integer NOT NULL default '0',
db_storage integer NOT NULL default '0',
PRIMARY KEY (field_name)
)");
db_query("CREATE TABLE {node_field_instance} (
......@@ -87,3 +89,91 @@ function content_update_2() {
return $ret;
}
/**
* Add information about where data is stored.
*/
function content_update_3() {
$ret = array();
switch ($GLOBALS['db_type']) {
case 'pgsql':
db_add_column($ret, 'node_field', 'db_storage', 'integer', array('not null' => TRUE, 'default' => '0'));
break;
case 'mysql':
case 'mysqli':
$ret[] = update_sql("ALTER TABLE {node_field} ADD COLUMN db_storage int NOT NULL default 0");
break;
}
return $ret;
}
/**
* Add tables for content types to store their data.
*/
function content_update_4() {
$ret = array();
$result = db_query("SELECT type_name FROM {node_type}");
while ($type = db_fetch_object($result)) {
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$ret[] = update_sql("CREATE TABLE {node_". strtr($type->type_name, '-', '_') ."} (
vid int unsigned NOT NULL default '0',
nid int unsigned NOT NULL default '0',
PRIMARY KEY (vid)
) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;");
break;
case 'pgsql':
$ret[] = update_sql("CREATE TABLE {node_". strtr($type->type_name, '-', '_') ."} (
vid integer unsigned NOT NULL default '0',
nid integer unsigned NOT NULL default '0',
PRIMARY KEY (vid)
)");
break;
}
}
return $ret;
}
/**
* Move data from per-field storage to per-content-type storage where possible.
*/
function content_update_5() {
$ret = array();
include_once(drupal_get_path('module', 'content') .'/content.module');
include_once(drupal_get_path('module', 'content') .'/content_admin.inc');
$result = db_query('SELECT nf.field_name FROM {node_field} nf LEFT JOIN {node_field_instance} nfi ON nfi.field_name = nf.field_name WHERE nf.multiple = 0 AND nf.db_storage = 0 GROUP BY nfi.field_name HAVING COUNT(*) = 1');
if (db_num_rows($result)) {
// Multi-part update
if (!isset($_SESSION['content_update_5'])) {
$_SESSION['content_update_5'] = 0;
$_SESSION['content_update_5_max'] = db_num_rows($result);
}
$field = db_fetch_array($result);
$fields = _content_fields();
$field = $fields[$field['field_name']];
$field_types = _content_field_types();
$field_type = $field_types[$field['type']];
$columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $field);
$ret[] = update_sql("UPDATE {node_field} SET db_storage = ". CONTENT_DB_STORAGE_PER_CONTENT_TYPE ." WHERE field_name = '". $field['field_name'] ."'");
if (is_array($columns) && count($columns)) {
$new_field = $field;
$new_field['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
content_alter_db_field($field, $columns, $new_field, $columns);
}
$_SESSION['content_update_5']++;
$ret['#finished'] = $_SESSION['content_update_5'] / $_SESSION['content_update_5_max'];
return $ret;
}
}
......@@ -6,6 +6,9 @@
* Allows administrators to define new content types.
*/
define(CONTENT_DB_STORAGE_PER_FIELD, 0);
define(CONTENT_DB_STORAGE_PER_CONTENT_TYPE, 1);
/**
* Implementation of hook_help().
*/
......@@ -358,7 +361,7 @@ function content_field($op, &$node, $field, &$node_field, $teaser, $page) {
break;
default:
$column_placeholders[] = "'%s'";
$column_assignments[] = $attributes['column'] .' = %s';
$column_assignments[] = $attributes['column'] ." = '%s'";
}
$data[] = $item[$column];
}
......@@ -395,13 +398,21 @@ function content_field($op, &$node, $field, &$node_field, $teaser, $page) {
$column_assignments = array();
foreach ($db_info['columns'] as $column => $attributes) {
$column_names[] = $attributes['column'];
if (in_array($attributes['type'], array('int', 'mediumint', 'tinyint', 'bigint', 'float'))) {
$column_placeholders[] = '%d';
$column_assignments[] = $attributes['column'] .' = %d';
}
else {
$column_placeholders[] = "'%s'";
$column_assignments[] = $attributes['column'] .' = %s';
switch ($attributes['type']) {
case 'int':
case 'mediumint':
case 'tinyint':
case 'bigint':
$column_placeholders[] = '%d';
$column_assignments[] = $attributes['column'] .' = %d';
break;
case 'float':
$column_placeholders[] = '%f';
$column_assignments[] = $attributes['column'] .' = %f';
break;
default:
$column_placeholders[] = "'%s'";
$column_assignments[] = $attributes['column'] ." = '%s'";
}
$data[] = $item[$column];
}
......@@ -531,7 +542,7 @@ function _content_types($reset = FALSE) {
$type_result = db_query('SELECT * FROM {node_type} nt ORDER BY nt.type_name ASC');
while ($type = db_fetch_object($type_result)) {
$type->fields = array();
$field_result = db_query("SELECT nfi.field_name, nfi.weight, nfi.label, nfi.widget_type, nfi.widget_settings, nfi.description, nf.type, nf.global_settings, nf.required, nf.multiple FROM {node_field_instance} nfi LEFT JOIN {node_field} nf ON nfi.field_name = nf.field_name WHERE nfi.type_name = '%s' ORDER BY nfi.weight ASC, nfi.label ASC", $type->type_name);
$field_result = db_query("SELECT nfi.field_name, nfi.weight, nfi.label, nfi.widget_type, nfi.widget_settings, nfi.description, nf.type, nf.global_settings, nf.required, nf.multiple, nf.db_storage FROM {node_field_instance} nfi LEFT JOIN {node_field} nf ON nfi.field_name = nf.field_name WHERE nfi.type_name = '%s' ORDER BY nfi.weight ASC, nfi.label ASC", $type->type_name);
while ($field = db_fetch_array($field_result)) {
$field_settings = $field['global_settings'] ? unserialize($field['global_settings']) : array();
$widget_settings = $field['widget_settings'] ? unserialize($field['widget_settings']) : array();
......@@ -547,6 +558,7 @@ function _content_types($reset = FALSE) {
unset($field['label']);
$field['widget']['description'] = $field['description'];
unset($field['description']);
$field['type_name'] = $type->type_name;
$type->fields[$field['field_name']] = $field;
}
......@@ -576,7 +588,9 @@ function _content_fields($reset = FALSE) {
$global_settings = $field['global_settings'] ? unserialize($field['global_settings']) : array();
unset($field['global_settings']);
$field = array_merge($field, $global_settings);
$field['widget']['label'] = db_result(db_query("SELECT label FROM {node_field_instance} WHERE field_name = '%s'", $field['field_name']));
$instance_info = db_fetch_array(db_query("SELECT type_name, label FROM {node_field_instance} WHERE field_name = '%s'", $field['field_name']));
$field['widget']['label'] = $instance_info['label'];
$field['type_name'] = $instance_info['type_name'];
$fields[$field['field_name']] = $field;
}
}
......@@ -671,7 +685,12 @@ function content_database_info($field) {
$db_info = array();
$db_info['table'] = 'node_data_'. $field['field_name'];
if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_FIELD) {
$db_info['table'] = 'node_data_'. $field['field_name'];
}
else {
$db_info['table'] = 'node_'. strtr($field['type_name'], '-', '_');
}
if (is_array($columns) && count($columns)) {
$db_info['columns'] = $columns;
......@@ -779,7 +798,10 @@ function content_views_tables() {
);
}
$tables[$db_info['table']] = $table;
// We don't use $db_info['table'] for the key, since that may change during
// the lifetime of the field and we don't want to require users to redefine
// their views.
$tables['node_data_'. $field['field_name']] = $table;
}
}
return $tables;
......@@ -789,7 +811,7 @@ function content_views_field_handler($field_info, $field_data, $value, $data) {
$field = $field_info['content_field'];
$node_field_item = array();
foreach ($field_info['content_db_info']['columns'] as $column => $attributes) {
$view_column_name = $field_info['content_db_info']['table'] .'_'. $attributes['column'];
$view_column_name = 'node_data_'. $field['field_name'] .'_'. $attributes['column'];
$node_field_item[$column] = $data->$view_column_name;
}
$function = $field_info['content_field_module'] .'_field_view_item';
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment