Skip to content
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

Split binary to booleans #203

Merged
merged 11 commits into from
Aug 14, 2017
Merged

Conversation

danopz
Copy link
Contributor

@danopz danopz commented Jul 10, 2017

Since no one wrote on #191 I tried myself to map the status to boolean types. I already changed the code to use the new boolean fields instead of the status.
I don't really know what to do with StatusFlag::typeToStatus - if we should completely remove this one and somehow fix the code belongs to this, or move this to later and destruct this status in ItemMapper (see added comment). This would also change methods signatures for many methods.
I didn't find a way how we could add a data migraion from status to the new boolean fields, I just found asome docs in OC but it looks like in NC we don't have this feature - so how should we migrate?

I'm submitting this for the questions and also for a first review.

Todo

  • Drop unit tests ,write integration tests
  • Migration/Repair script
  • Completely remove status or map on some code parts?
  • Fix the integer/boolean stuff in the queries

@sonologic
Copy link
Collaborator

sonologic commented Jul 11, 2017 via email

@sonologic
Copy link
Collaborator

Looks like we basically did the same things, except I used true/false in sql where you used 1/0. I tend to prefer true/false.

Anyway, if you want to continue to work on it that would be very welcome!

I started to investigate 'repair-steps' (see http://nextcloudappstore.readthedocs.io/en/latest/developer.html#info-xml), which seems the way to go re migration.

As for the typeToStatus, I figure we should remove it and refactor code that is currently using it. It feels the typeToStatus method is a bit of a kludge..

Thanks for working on this! Let me know if you decide to drop it afterall. I will pause my work on this one for now in favour of some other bug(s).

@danopz
Copy link
Contributor Author

danopz commented Jul 11, 2017

Oh sry didn't see you assigned yourself.
Shure I could try to get this done, but also if you want you can still do it yourself, maybe you are more into the codebase.

Indeed True/False are the better option for this.

I will keep working on this until someone stops me from doing this :)

@BernhardPosselt
Copy link
Member

BTW since you are changing SQL statements it might make sense to throw away the unit tests and replace them with integration tests (examples available in the test folder)

@danopz
Copy link
Contributor Author

danopz commented Jul 18, 2017

I dropped the unit tests which belongs to the changed mappers and added integration tests.
Changed booleans in sql back to integers (0,1) as sqlite does not support true/false. But now it looks like postgres doesn't allow a boolean = integer check.. so we have to use prepared statements, am I right?

Also I added the repair step which checks for previous installed version. Currently I increased the version by a patch level, I think an increase in minor/major would be better?

@danopz danopz changed the title [WIP] Split binary to booleans Split binary to booleans Jul 20, 2017
@danopz
Copy link
Contributor Author

danopz commented Jul 20, 2017

For me it's ready for review.
I don't know why this is failing for MySQL with the message SQLSTATE[42S22]: Column not found: 1054 Unknown column 'items.unread' in 'where clause'" at? NC should have added the new fields?

Copy link
Member

@BernhardPosselt BernhardPosselt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work, everything looks like expected although I didn't have the power to make sure that the code still does the same thing in all places. I don't fully understand the bool casts however.

lib/Db/Item.php Outdated
$this->status |= StatusFlag::UNREAD;
public function setUnread($value = true) {
$this->markFieldUpdated('unread');
$this->unread = (bool)$value;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why we need bool casts?

@BernhardPosselt
Copy link
Member

I don't know why this is failing for MySQL with the message SQLSTATE[42S22]: Column not found: 1054 Unknown column 'items.unread' in 'where clause'" at? NC should have added the new fields?

I'd take a look at the MySql version on travis. Does it work for you locally on mysql?

@BernhardPosselt
Copy link
Member

I dropped the unit tests which belongs to the changed mappers and added integration tests.
Changed booleans in sql back to integers (0,1) as sqlite does not support true/false. But now it looks like postgres doesn't allow a boolean = integer check.. so we have to use prepared statements, am I right?

Yep. I'm unsure if the doctrince DAL handles the conversion for you or it could be solved via query builder. Worst case scenario is that we need to create a method that turns bools into whatever format your db currently expects. Check https://github.com/nextcloud/news/blob/master/lib/Db/MapperFactory.php#L23 for how to find out the db

@danopz
Copy link
Contributor Author

danopz commented Jul 23, 2017

  • Removed the bool casts, they they were there for no real reason
  • Shame on me for the MySQL error, this was just a copy-paste mistake
  • For the SQL queries this was already fixed by using the booleans as params, DBAL handles this for us

@BernhardPosselt
Copy link
Member

Can you take care of the tests?

@danopz
Copy link
Contributor Author

danopz commented Aug 2, 2017

Didn't notice the tests fail again, maybe this was the reason for bool casts. I'll have a look.

@danopz
Copy link
Contributor Author

danopz commented Aug 2, 2017

It's green 😁
I added empty checks to Item::is* methods which shouldn't be to expensive.

@BernhardPosselt
Copy link
Member

Cool, just a quick question: Can you set up a news install without the pull request, add some feeds and star them, then switch to your branch and ensure that everything still works as expected? Just trying to make sure that everything still works since the PR is quite big.

@BernhardPosselt
Copy link
Member

BernhardPosselt commented Aug 3, 2017

From a quick glance over the code the only thing that I don't really like is the usage of empty(). That "function" is pretty tricky and can lead to lots of bugs, see http://php.net/manual/en/function.empty.php

@danopz
Copy link
Contributor Author

danopz commented Aug 9, 2017

From a quick glance over the code the only thing that I don't really like is the usage of empty(). That "function" is pretty tricky and can lead to lots of bugs, see http://php.net/manual/en/function.empty.php

Do you have another idea how to have another way to force booleans? I have in mind that empty checks are faster than bool casts. And without such cast the one unit test was failing. Maybe the problem comes from another place but don't know right now.

@danopz
Copy link
Contributor Author

danopz commented Aug 9, 2017

There still is an issue in the migration where status 6 results in unread=false. I didn't find a proper solution yet..

@BernhardPosselt
Copy link
Member

BernhardPosselt commented Aug 12, 2017

Do you have another idea how to have another way to force booleans? I have in mind that empty checks are faster than bool casts. And without such cast the one unit test was failing. Maybe the problem comes from another place but don't know right now.

PHP is slow anyways so don't worry about speed of function calls but speed of algorithmic complexity ;) Also better to investigate the source of the issue

There still is an issue in the migration where status 6 results in unread=false. I didn't find a proper solution yet..

There still is an issue in the migration where status 6 results in unread=false. I didn't find a proper solution yet..

Are we sure that all three dbs treat this as truthy?

(status & 4)

I'd expect something like

WHERE (status & 4) = 4  -- starred
WHERE (status & 2) = 2  -- unread

@danopz
Copy link
Contributor Author

danopz commented Aug 13, 2017

Cool, just a quick question: Can you set up a news install without the pull request, add some feeds and star them, then switch to your branch and ensure that everything still works as expected? Just trying to make sure that everything still works since the PR is quite big.

Tested it on MySQL and SQLite - it was working for me.

I'd expect something like...

I dropped usage of the QueryBuilder in favor of a native SQL query in the migration step. Now I'm also using (status & 4) = 4.

PHP is slow anyways so don't worry about speed of function calls but speed of algorithmic complexity ;) Also better to investigate the source of the issue

I will have a deeper look.

@danopz
Copy link
Contributor Author

danopz commented Aug 13, 2017

@BernhardPosselt I changed something in my last commit to remove bool casts and empty checks.

@BernhardPosselt
Copy link
Member

Ok, reviewed it more closely and lets test it out, as in: merge this and check the effects on our own instances :D

@BernhardPosselt BernhardPosselt merged commit a97dd58 into nextcloud:master Aug 14, 2017
@BernhardPosselt
Copy link
Member

Seems to have worked fine on postgres, well done :) let's give this more testing before we create a release

@danopz danopz deleted the status-flags branch August 14, 2017 08:51
@danopz danopz restored the status-flags branch August 14, 2017 08:54
@danopz danopz deleted the status-flags branch March 5, 2018 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants