Posted by beppause on May 22, 2006 at 9:51pm
| Project: | Flexinode |
| Version: | master |
| Component: | flexinode.module (core) |
| Category: | feature request |
| Priority: | normal |
| Assigned: | beppause |
| Status: | needs review |
Issue Summary
Patch for the flexinode_load function that make the component scalable, when the number of fields grows.
/**
* Implementation of hook_load().
*/
function flexinode_load($node) {
$ctype = flexinode_load_content_type(substr($node->type, 10));
/**
* Original code
* n-Join
*/
/*
// build the query
$fields_to_select = array();
$table_joins = array();
foreach ($ctype->fields as $field) {
$fieldname = 'flexinode_'. $field->field_id;
$fields_to_select[] = flexinode_invoke('db_select', $field, $field);
$table_joins[] = 'LEFT JOIN {flexinode_data} '. $fieldname .' ON n.nid = '. $fieldname .'.nid AND '. $fieldname .'.field_id = ' . $field->field_id;
}
if (count($fields_to_select) > 0) {
// make the query
$flexinode = db_fetch_object(db_query('SELECT '. implode(', ', $fields_to_select) .' FROM {node} n '. implode(' ', $table_joins) .' WHERE n.nid = %d', $node->nid));
// unserialize necessary fields
foreach ($ctype->fields as $field) {
$fieldname = 'flexinode_'. $field->field_id;
$field_data = flexinode_invoke('load', $field, $flexinode);
if ($field_data) {
$flexinode->$fieldname = $field_data;
}
}
}
/**
* End original code
*/
/**
* My code:
* without any join
*/
$flexinode_arr_data = array();
$flexinode_fields_data = db_query('SELECT * FROM {flexinode_data} fd WHERE fd.nid = %d', $node->nid);
$flexinode_arr = array();
while ($field_data = db_fetch_object($flexinode_fields_data)) {
$fieldname = 'flexinode_'. $field_data->field_id;
$flexinode_arr_data[$fieldname] = $field_data;
}
foreach ($ctype->fields as $field) {
$fieldname = 'flexinode_'. $field->field_id;
/**
* ex. flexinode_1.textual_data as flexinode_1, flexinode_1.numeric_data as flexinode_1_format
*/
$fields_to_select = strtolower(flexinode_invoke('db_select', $field, $field));
$field_arr1 = explode(',',$fields_to_select); // [[flexinode_1.textual_data as flexinode_1][flexinode_1.numeric_data as flexinode_1_format]]
foreach ($field_arr1 as $field_tmp) {
$field_arr2 = explode(' as ', trim($field_tmp)); //[[flexinode_1.textual_data][flexinode_1]]
$field_arr3 = explode('.', trim($field_arr2[0])); //[[flexinode_1][textual_data]]
$flexinode_arr[trim($field_arr2[1])] = $flexinode_arr_data[trim($field_arr3[0])]->{trim($field_arr3[1])};
}
}
$flexinode =(object)$flexinode_arr;
foreach ($ctype->fields as $field) {
$fieldname = 'flexinode_'. $field->field_id;
$field_data = flexinode_invoke('load', $field, $flexinode);
if ($field_data) {
$flexinode->$fieldname = $field_data;
}
}
/**
* End modify without any join
*/
$flexinode->ctype_id = $ctype->ctype_id;
return $flexinode;
}
Comments
#1
Greetings,
And what will this patch give ? Do you think it will really save the time ? If so, I think it is good for large database. What will be decision about applying this patch to the existing code ?
#2
I'm unable to commit my change on function flexinode_load:
I receive the errror:
flexinode: cvs commit: Pre-commit check failed
This is what I would commit
/**
* Implementation of hook_load().
*/
function flexinode_load($node) {
$ctype = flexinode_load_content_type(substr($node->type, 10));
$flexinode_arr_data = array();
$flexinode_fields_data = db_query('SELECT * FROM {flexinode_data} fd WHERE fd.nid = %d', $node->nid);
$flexinode_arr = array();
while ($field_data = db_fetch_object($flexinode_fields_data)) {
$fieldname = 'flexinode_'. $field_data->field_id;
$flexinode_arr_data[$fieldname] = $field_data;
}
foreach ($ctype->fields as $field) {
$fieldname = 'flexinode_'. $field->field_id;
//example: flexinode_1.textual_data as flexinode_1, flexinode_1.numeric_data as flexinode_1_format
$fields_to_select = strtolower(flexinode_invoke('db_select', $field, $field));
// [[flexinode_1.textual_data as flexinode_1][flexinode_1.numeric_data as flexinode_1_format]]
$field_arr1 = explode(',', $fields_to_select);
foreach ($field_arr1 as $field_tmp) {
//[[flexinode_1.textual_data][flexinode_1]]
$field_arr2 = explode(' as ', trim($field_tmp));
//[[flexinode_1][textual_data]]
$field_arr3 = explode('.', trim($field_arr2[0]));
$flexinode_arr[trim($field_arr2[1])] = $flexinode_arr_data[trim($field_arr3[0])]->{trim($field_arr3[1])};
}
}
$flexinode = (object)$flexinode_arr;
foreach ($ctype->fields as $field) {
$fieldname = 'flexinode_'. $field->field_id;
$field_data = flexinode_invoke('load', $field, $flexinode);
if ($field_data) {
$flexinode->$fieldname = $field_data;
}
}
$flexinode->ctype_id = $ctype->ctype_id;
return $flexinode;
}
#3
two things:
provide normal patches, else people cannot review the code: http://drupal.org/diffandpatch tells you why and how.
Please explain better what the feature is that you wnat to introduce and why it is needed. If it involves UI or visual changes, provide screenshots too, they often explain best what it is you want to achieve.
#4
Sorry but my english is not very good ...
I try to explain better the problem:
In the function
flexinode_load($node)you make aLEFT JOIN {flexinode_data}for each flexinode fieldIt isn't required for the field loading because you can make a single select on flexinode_data that load all the fields.
This way is faster, and the limit on the max number of fields for flexinode is removed.
About diffandpatch ...
--actual function load_flexinode
++my posted function load_flexinode
Best Regards
Giuseppe Rizzo
#5
Patch
#6
Thanks for the work. I like the concept, and think we can go much further then this.
One of my future plans is to normalize the tables for flexinode more. Therefore, I think this patch is a first step in that direction.
What do you think about changing the return value of
flexinode_invoke('db_select', $field), so that yuo don't need to do explode()s and implodes(), but that the data/strings returned by that hook are erady to be used in the single SELECT?My primary aim, now, however, is to get flexinode released and stable for 4.7 and then for 5.x. Allthough I would love to add new features, this will have to wait, else we will probably never have a release. So this will have to wait a bit more. Sorry for that. And agai thanks for the work.