5 ms·
I don't see any real reason to rely on idempotence. They could simply store two names: One is provided by the user (verbatim), and the second is its reduction
by a-nikolaev 13y ago
I don't see any real reason to rely on idempotence.
They could simply store two names: One is provided by the user (verbatim), and the second is its reduction to lowercase letters and digits (canonical). For all internal logic, they could use only the canonical name, and use the verbatim name in the front-end to make the user happy.
> Lower casing has the key property of being idempotent, i.e., that applying it more than once has no effect: x.lower() == x.lower().lower(). So if a username gets passed from service to service and you want to make sure it is in canonical form you can safely apply .lower() and if it was already in canonical form there is no harm done, and it is easy to stay safe.
Apparently, they thought that it's ok to use verbatim and canonical names interchangeably, relying on idenpotence property of the XMPP function.
It looks like a huge design error.
- readme 13y ago>They could simply store two names Presumably you mean in the database? I don't see a reason to keep a copy of the lower() transformation of a string when it is incredibly cheap to transform a small string to lowercase. What exactly is the point of that? I would just call lower() as needed, personally.
- a-nikolaev 13y agoOh, my point was that two kinds of names should not be used interchangeably. To store or not the .lower() is a matter of taste.. (Personally, I would store both names, just to avoid wasting computing time)
- readme 13y agoI think the act of storing both names is bad, because you multiply the amount of data that could possibly become wrong by 2. With lower(), we can expect we'll get the right transformation of string A each time. If instead, we store string A, and then store string B as A.lower() and copy it... A.lower() will always be A.lower, but it's much easier for someone to come along, screw with the database, and change B.
- a-nikolaev 13y agoYeah, I see. I'm not a web developer, so maybe this is why I did not think about this way to break the data. Well, I still think that it is better to have two (hopefully) correct fields in the database, rather than only one. (Consistency of the two fields can be checked once in a while).
- timv 13y agoI'm not sure how they can avoid storing both. They need to store the verbatim username in order to know how to display the username in the UI. They need to store the canonical username in order to efficiently know whether a given canonical username is in use.
- brokenparser 13y agoNot necessarily, in PostgreSQL you could simply add a canonicalised index.
- timv 13y agoWell, in that case you're still storing it, you're just letting the the db store it for you. But - when the issue here is the question of the reliability of the implementation of the canonicalisation function, having it done once in python, and then again by PG is going to be a huge issue.
- gwright 13y agoIf you are testing for uniqueness of the canonical name you don't want to have to recompute the canonical name for all your existing records.
- willvarfar 13y agoCanocialisation functions are, by definition, idempotent. Their canocialisation function, which is a standard one, was broken by subtle changes in Python 2.5, but worked previously.
- a-nikolaev 13y agoYes, I agree that it sounds great. But, it does not mean that you really have to use this property. It was not necessary for the task, this is the point.. Well, in general, modular code should not make assumptions about other parts of the program (when possible). You know, if the function is idempotent by definiiton, it does not mean that its implementation is. Unicode is changing too, new symbols are added.