-
Notifications
You must be signed in to change notification settings - Fork 370
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[improvement] find_many returns an associative array #133
Conversation
…rm and Paris Added find_many return associative keys. Micro optimizations for Idiorm and Paris. set and set_expr returns the instance, to admit a fluent query
+1 |
On Paris, we can overload "_instances_with_key" instead "find_many". Using one loop less to fetch the query results. protected function _instances_with_key($rows){
$size = count($rows);
$instances = array();
for ($i = 0; $i < $size; $i++) {
$row = $this->_create_instance_from_row($rows[$i]);
$row = $this->_create_model_instance($row);
$key = (isset($row->{$this->_instance_id_column})) ? $row->{$this->_instance_id_column} : $i;
$instances[$key] = $row;
}
return $instances;
} |
It is possible to call the select method this way: ...->select('id,name,title')->...;
So my only real issue with this is that it is a backward compatibility break. I think at the minimum that this would need to be a configurable option. It would ship on, but you could disable it where required for compatibility with code bases that rely on sequential indexes in this array. |
What about including this feature on a new method? Something along the lines of |
Merged in commit 022d328 for Idiorm |
$columns = array_map('trim',explode(',',$column)); | ||
foreach($columns as $column){ | ||
$column = $this->_quote_identifier($column); | ||
$this->_add_result_column($column, $alias); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hummm... maybe it is no so simple. I think $alias parameter should be a list of aliases, shouln't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it looks like you have a point there. if the select is an array of columns then it should be in the form:
$columns = array(
'alias' => 'column_name',
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, on that particular commit I added the select to accepts comma separated values, but in that case you can't provide aliases, or it will fail. So you can use it as always, even using $alias
or you can call it like:
->select('id, name,title, content')
not using aliases.
There is no check if you are using the function on the right way so if you send a comma separated value and an alias you will have an unexpected behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unique use of that commit was to reduce the notation to take multiple fields. However select_many does it already. (using more , and ` but in the right way.
I stumbled upon this change after I updated from 1.3 to 1.4 and my application started blowing up in mysterious ways. Am I to understand that this is a known backwards incompatible change to an existing API, and was released under a minor point release? Do you follow the semantic versioning pattern at all? http://semver.org/ Would you please? |
@micmath don't know, but if your problem is related to the associative keys, it produces problems on
My original commit for this was changed in the official code in some ways and the results are not the ones you can expect.
|
Thanks for the technical details, @Surt. I eventually managed to fix my specific issue, but it involved a panicked late-night coding session, knowing my client expected to go live today. This might be why I'm a tiny bit cranky this morning, but my larger point is that I shouldn't have to worry about backwards incompatible changes to existing APIs on a minor point release. (see the suggested link to semantic versioning) |
@micmath Your petulance does nothing to resolve this situation or really make me all that sympathetic to be honest. The knock on effects were not anticipated when it was merged and I have been far too busy with client work to check and merge the subsequent patches. You can review them here #156 In the case of tables having no primary key: it is clearly documented that Idiorm assumes you have a primary key. if you implement differently then you're outside what is tested. If you implement something incorrectly then you can expect it to later be broken when something that assumes you have implemented it correctly is added to the code base. If you do this then it is important to check the changelog of any open source project to ensure that changes do not effect your non-conforming code. It has always been this way. |
Thanks for your reply, @treffynnon. I honestly didn't realise I was being "petulant." I tried to say please and thank you, and did make the caveat that I am not my usual happy-bunny self this morning. So I apologise if I sounded pissy, I didn't intend it that way. But, again, I wasn't asking about primary keys, or any detailed technical explanation for that matter. (for the record my table does have primary keys) I actually believe the problem was to do with some quirk of how Twig was iterating over the result set, and changing it from an array in 1.3 to an associative array in 1.4, in my specific case caused Twig to sometimes panic for a reason I haven't yet diagnosed. (I eventually quelled the issue by using |
Backwards incompatible changes are avoided in all merges. The knock on effects were not anticipated when this particular change was merged. Mea culpa - I was rushing. The release was also open for testing and I did put out a call for help testing before releasing, but no issues were raised.
The project has been since https://github.com/j4mie/idiorm/releases/tag/semver |
@micmath I would be interested to hear what the trouble with Twig is because I tested this release against a project of my own in addition to the unit tests. That project used Twig to iterate over |
I was planning to go through the issue with a fine-toothed comb when I have more time and caffeine. But if it helps in the short-run at all, I only saw the problem when there were NULL values in the result set returned from {% for row in rows %}
<tr>
{% for col in cols %}
<td>{{ attribute(row, col) }}</td>
{% endfor %}
</tr>
{% endfor %} where |
Hi @micmath did you tried this?
http://twig.sensiolabs.org/doc/api.html#environment-options I think that you can use this notation on the last foreach too {{ row[col] }} |
I also experienced some problems with Twig templates that were solved by using |
@micmath and @lrlopez could this be the same thing as @amerker is reporting on Paris? See j4mie/paris#75 (comment) It would be really helpful if anyone could include a regression test or some code I can use to replicate this error to take this issue forward. Unfortunately I am really busy with pre-Christmas client deadlines, a course and general family life at the moment so it is making it exceedingly difficult to work on Idiorm and Paris so any additional help is very welcome and gratefully received. |
@micmath , @lrlopez and @amerker please could you also try the proposed patch and let me know how it goes and whether it is good to merge or not. Please see: #156 (comment) and the pull request at #162 I would like to fix this regression ASAP as it is clearly affecting a significant proportion of Idiorm users. If the patch is not good enough then I am going to have consider rolling out a 1.4.1 release without the presence of the primary key as associative array key feature included. Please do let me know your thoughts as I would like to resolve this quickly and in a way you guys can use it/agree with. |
I've tested my current project with #162 and it seems to work well, although I haven't used any of the new methods but the default behavior. The only thing I miss in the PR are tests. About the problems with Twig templates, I suppose it is the same issue described by @amerker because no error was logged anywhere and a infinite recursion could explain that... |
Sadly, the problem persists for me with Surt's current regression.find_many_id_keys branch. DB (MySQL):
Model and Slim Route:
Twig:
This always throws an infinite recursion, which my Xdebug reacts to with:
Twig does not render the third output line (= data set) after that. This is using j4mie/paris 1.4.1, slim/slim 2.3.5, slim/views 0.1.0, twig/twig 1.14.2. |
Hi @amerker did you try setting the new variable in config: Anyway I don't think that bug is related to this patch, since the assignement to rows (where the null is assigned) is done prior to the primary keys assignement. |
Hi @Surt, you're right, my bug occurs no matter if the variable is true or false. I'm opening a new Paris issue, then. |
@amerker by the way, if you are using Paris, and my regression branch for Idiorm, be sure to make this changes to Paris. It affects to the assignement but again, I don't think the nullableField and regression problems are related to this. We must change in https://github.com/j4mie/paris/blob/master/paris.php#L128 /**
* Create instances of each row in the result and map
* them to an associative array with the primary IDs as
* the array keys.
* @param array $rows
* @return array
*/
protected function _instances_with_id_as_key($rows) {
$size = count($rows);
$instances = array();
for ($i = 0; $i < $size; $i++) {
$row = $this->_create_instance_from_row($rows[$i]);
$row = $this->_create_model_instance(row);
$key = (isset($row->{$this->_instance_id_column}) && $this->_associative_results) ? $row->{$this->_instance_id_column} : $i;
$instances[$key] = $row;
}
return $instances;
} And the last change, in Model, https://github.com/j4mie/paris/blob/master/paris.php#L388 ->where("{$join_table_name}.{$key_to_base_table}", $this->$base_table_id_column)
->non_associative(); Until this patchs, Paris is broken on has_many_through, returning just 1 instance of multiple objects with the same id (the objects are pushed on the same key) I can't make a fork of Paris since https://github.com/Surt/Granada and other forks are based on it and I'm so bad at git to make by my own :p |
@Surt, I changed the code manually, but it didn't help. So yes, I'm guessing it's not related. :) |
yep, maybe we can change it to be more concise. |
Pull based on #132
Added find_many return associative keys.
Micro optimizations for Idiorm and Paris.
set and set_expr returns the instance, to admit a fluent query