RSS
 

Archive for the ‘Coding’ Category

Let me drive

12 Mar

One odd quirk that I have noticed about myself as I have been building a reputation as an SQL guru at Grooveshark, and therefore being regularly pulled aside to look at queries, is that I have a hard time thinking about an SQL query when I’m just looking at it over someone’s shoulder. It’s even harder for me to think about how I would change the query.

For some reason, I need to be in the proverbial driver’s seat. Let me sit down in front of the screen, give me a gui text editor that I can use easily (vim does not qualify), and my brain is prepared to evaluate the problem. I may not even need to type anything out in the process of solving the problem, but the brain juice just won’t even start to flow if I don’t have that.

I seem to have that problem much less when looking at PHP (although I prefer to look at the code in my IDE of choice), and I’m not entirely sure why that is. The only thing I can think of is that maybe SQL requires a higher level of abstract thought than PHP does most of the time, so I am more dependent on having the right set up before I can get into the right mode?

Do any other coders out there have this problem?

‡ ‘an’ is the correct usage here because I expect you to read that as S Q L, not Sequel.

 
1 Comment

Posted in Coding

 

OhHai->I->HasA(UPDAET)

04 Feb

As an update to my previous lolcode post, we are fixing the GetGenre()->GetGenre() issue by calling them names. GetGenre()->GetName()

There is talk of adding __toString() functions to classes like Genres and Tags but I tend to not be a fan of automagic functions. __toString() would enable us to just call GetGenre() and if we treat the resulting object as a string, it will call GetName() behind the scenes, and if we treat it like an object it will still be an object. That is a “neat” language feature, but I believe it leads to obscurity and inconsistent behavior in certain cases.

For example, if the object is not directly treated as a string even though it needs to be a string, it __toString() will not be called, and problems will ensue. Confusing problems, because the object acts like a string, sometimes.

sloppy example code:

class notAString
{
    public $what;
    public function __construct($val)
    {
        $this->what = $val;
    }
    public function __toString()
    {
        return $this->what;
    }
}
$whatIsIt = new notAString("a string");
$isAString = is_string($whatIsIt);
$isAnObject = is_object($whatIsIt);
var_dump(array('isAString' => $isAString, 'isAnObject' => $isAnObject));
echo $whatIsIt;

Output:array
'isAString' => boolean false
'isAnObject' => boolean true
a string

It fails the is_string check, so if you pass the object to a function that expects a string, and the function is smart enough to check for a string before doing anything with it, your call is going to fail and you’re going to be scratching your head wondering why.

Now imagine how confusing this would be if you were trying to debug a piece of code that you had no hand in writing, you see this object being used as a string, only you don’t know it’s an object because it’s being used as a string and that part of the cod works. “It should be declared right there, just look and you’ll see it’s an object.” Sure, or it could be passed in from another function and you haven’t looked that far up the ladder yet.

Worse, you finally figure out that it’s an object, and now you can’t figure out why it’s successfully being treated as a string elsewhere. You look at the class and you don’t see a __toString() function. You look at the parent class, no __toString() there either. Ah well, a red herring, time to move on right? Or did you give up before looking at the parent class’s parent? Was there a __toString() there? How much time was wasted trying to find that, compared to how much time the automagic __toString() function might save you as a developer?

I’d wager it’s not worth the lost time, and the added frustration.

 
No Comments

Posted in Coding

 

OhHai->IHasASong()->ICanHasGenre()

03 Feb

Sometimes naming conventions can have weird side effects.

Consider this example:
Our tables and fields are named in CamelCase (or StudleyCaps, or StudleyCamels as we like to call them), this is not my preferred way of naming tables/fields, but it’s what we’ve got so we work with it. We* decided that Genres are entities so the Genres table contains a Genre field which is a VARCHAR.
In PHP we are using our own flavor of ORM that avoids the pitfalls of most ORM systems while keeping the benefits. Our database objects all have Get methods for each object property (which may or may not be a field in the table that the object represents). If you want a song’s Genre, you call Song->GetGenre(), which gives you a Genre object. If you then want the text-representation of the Genre, you have to call…GetGenre(). So if you want, from the Song object, the text representation of the Song’s Genre, you call: Song->GetGenre()->GetGenre()
We might as well have made it say Song->GetGenre()->PrettyPlease() or ->NoSeriously()

At least we aren’t writing our code lolcats style (see: lolcode) or it might look more like the title:
OhHai->I->HasASong()->CanHasGenre()->CanHasGenreNoowwwwwwws()

*actually someone else decided before I ever started working here

Kthxbye.

 
3 Comments

Posted in Coding

 

Auto-query-generator

02 Feb

They say that Computer Scientists aren’t satisfied with putting other people out of jobs; they want to put themselves out of a job as well. In that vein I am writing a function that, given basic information about our database tables and their relationships, can build efficient queries automatically based on a complex filter consisting of:

  • The information requested
  • Any combination of IDs to filter the results based on

For example, you can tell it that you want the names and IDs of Playlists belonging to a user with a certain artist and my function will build the SQL on the fly based on what it knows.
This is extremely useful because I am working on a super secret project* with Katy and her app has no knowledge of hte database but needs to be able to ask for some extremely specific sets of data depending on user behavior. Instead of manually writing N! queries to handle every possible combination of requests, my function does all of the heavy lifting for me.

The code isn’t quite done yet but the code that figures out the join sequence and which key to join on is done, and surprisingly it only takes about 10 lines of code. I still need to add code to handle special cases, and I need to write the code that takes that sequence and turns it into real live SQL so it will surely grow, but that is still far less than I imagined would be required to get this far.

*not actually a secret project, but I haven’t written about it yet and it’s beyond the scope of this post.

 
1 Comment

Posted in Coding, SQL

 

The Importance of Being Earnest

27 Jan

One of the facts of life you have to work with when working at a startup is that your code will always be changing. New features are added, old code gets re-factored, the database layer gets overhauled, etc. That, coupled with the fact that there is always more that needs to be done than time to do it, add up to having almost no documentation for anything.

This is why it is critically important to have self-documenting code. If your code is not self-documenting, and I need to interface with it, then I have to wait for you to have time to answer my questions, or spend a lot of time digging through your code trying to figure out what is actually going on.

There is actually something worse than non-self-documenting code, however, and that’s self-documenting code that is incorrect. If you do not have real documentation and the names you use imply one thing but do another, you are going to cause serious problems.

Of course, I have examples of both problems. In the first, we have two entities that I needed to extrapolate information from: Duration and Bitrate. Do you see the problem? No? What if I ask you for the file size of a song given the following: Bitrate: 190000, Duration: 211749000. Can you tell me at a glance what math would be required in order to get the file size? You can’t, because the units are missing.

For the second example we have something that actually caused a major bug in Grooveshark that is just now in the process of being fixed. We have a field called isOnline. Do you think that isOnline tells whether a file is online? It doesn’t. Well, not always. If isOnline is 0, the file is definitely offline. But if isOnline is 1, it might still be offline, because what is really being tracked by this field is whether the file has been removed from a user’s library (or rather, the inverse of that). With a name like isOnline, it’s quite tempting to assume that that is how you check whether a file is online, and so that is what happened. Which is why often times when you click play on a song in Grooveshark, you get a peer offline error. The file isn’t online because the peer isn’t online, but isOnline is set to 1 because the user has not removed the file.

 
1 Comment

Posted in Coding, SQL