March 2008


Howto and PHP26 Mar 2008 05:08 am

When attempting to debug my program, zend studio for eclipse wasn’t recognizing that I had my mysql extension installed. I found a small work around.

Go to
[install_path]\plugins\org.zend.php.debug.debugger.win32.x86_5.2.12.v20071210\resources\php5

In there, you will see your php.exe’s and your php.ini that the debugger uses. I just copied my php.ini there for it to work.

Opinion21 Mar 2008 12:22 am

Public methods should be deceptively named to foil would-be hackers.

Development and PHP19 Mar 2008 10:00 pm

After a few weeks of downtime, and helpful input and comments from my readers, I have finally submitted my Zend_Framework CLA and authored a Zend_Pdf_Cell proposal! Please feel free to read it and comment on any of the functionality! I really hope that this can get integrated within the Zend Framework, as I have put a lot of time into this and hope that the community can gain as much as possible from it.

I want to give everyone a great big thanks for the valuable feedback and excellent encouragement!

Development and EPICS and Howto and Ideas and Opinion19 Mar 2008 09:45 am

As the Active Record class has become increasingly popular due to it’s wild success in Ruby on Rails, it seems as though every framework has an implementation of it. It is no surprise that inside the covers of the MyEPICS framework lives an active record class that I had created. This class has evolved and changed over time, which I am going to share my experiences writing it. It is far from finished, but it has been quite a great learning experience along the way.

2.0 Implementation

The MyEPICS 2.0 implementation contained one master database class (ME_DB) which contained generic CRUD functions, and each table contained its own class which would implement the specific CRUD functions for each table (ME_DBO). A sample way to read users with the name ‘bob’ would be the following:

$user=new ME_DBO_User();
$user->read(array('name'=>'bob'));

And to update a person’s last name to “foobar”, you would do the following:

$user->lastname="foobar";
$user->update();

About 90% of each of the ME_DBO classes were the same code, and there was even a script to create a DBO class given a SQL create statement. A major problem with this approach is that for every new table created, you needed to make sure you created a new ME_DBO file, and that the file really only contained such things as which columns were in the table and their default values. We would have about 2k lines of code between 30 files, of which only about 50 lines were different… YUCK! Over Christmas break, I decided that this was a major, major issue that needed to be worked out before MyEPICS 2.1.

MyEPICS 2.1 Implementation

With the 2.1 implementation, I took a step back and attempted to create two classes which would fix the pitfalls of the 2.0 implementation. What I ended up doing was using MBD2′s reverse engineering module in order to find out which fields were available and what their default values were. This reduced the need for a separate file for each table and removed about 1500 lines of code from the Active Record implementation. Now, instead of

$user=new ME_DBO_User();

You would do this instead

$user=ME_Db::factory('User');

This has the main database create a Dbo object with just the right properties that you need.

The only major gripe I have with the current implementation is that I don’t implement anything for relationships. If you need information from a relationship, then you have three options.

  1. Cry
  2. Write Manual SQL
  3. Write many lines of code which does a lot of extra sql queries and is inefficient and crappy

I mainly want to create something so that the relationship table is transparent. A lot of the time, your relationship table doesn’t have anything of value in it, and it only exists for a many to many relationship.

SQL Command Functions

About

One such feature that I see in a lot of Active Record implementations is the ability to use functions named after SQL commands, such as:

$db=new Some_Active_Record_Class();
$db->select('firstname')->from('User')->where('id=5');

Mostly, I had disregarded this need in my Active Record implementation because it seemed like it was a lot of work for very little gain. Why would you need to allow such functionality when creating a simple sql statement would do?

Well, I think I had just stumbled upon the reason for its need.

The Problem

I have a class for a user and contains information pertaining to the user such as first name, last name, e-mail address etc… It has some very useful functions such as getUserWithRole($role) and getPriviliges($user). What I need to be able to do, is extend this information through one of the MyEPICS modules. Such an example is in my Roommate Finder application, which extends the user to give them traits. The user module does not know about the Roommate Finder application, nor should it have to. Now, here’s the problem. What I need to be able to do, is return a result set of all the users’ traits, where the user has a certain role. I already have the code to return all users with a certain role in the Users module, now I just need to attach the trait information to the output of it.

I have come up with a few different solutions that would plug this hole, but not fix the problem, with most of them being some variation of typing up a single sql statement to get me the information. What I don’t want to do, is getUsersWithRole(), then iterate through all of theses picking out the traits for each individual user. This would result in at least one sql statement per user, which is highly innefficient.

I want to be able to execute this functionality in one sql query, without having to tightly couple the User module with the Roommate Finder module, and without duplicating functionality already existing in the User module.

A Solution?

What I have been thinking about that would solve this problem would end up having me creating something like the database command functions. Then, what the getUserWithRoel() function would do, is instead of returning the results, it would return a Dbo object with the sql already added. So that if getUsersWithRole() would normally result in some query like “select role from roles where role=?”, then it would now return an object that represents this statement. What this would allow me to do is chain these functions together, then only execute the query at the end. For example:

//fetch results in an array
$dbo=$userModule->withRole('Tenant')->join('Traits')->fetchArray();

This has several features which I haven’t implemented. Easy relationships, chaining of functions, and the sql commands.

Is it bad that I am never satisfied with what I already have, and always want to refactor to make it better?

Opinion19 Mar 2008 03:53 am

Just now, I was about to download OpenOffice.org on my home computer to help with a bug report I made, and realized that I downloaded a 120MB file in about 70 seconds. Yes, I downloaded this puppy at nearly 2 megabytes per second!! Damn my connection is fast when my neighborhood is asleep!

Not only did I get a lot of work done tonight on my Roommate Finder application, but I also have managed to do a lot more in the past four hours.

Ideas17 Mar 2008 12:03 pm

Currently, I have at least 7 e-mail accounts, of which, I regularly use three. There are plenty of desktop e-mail clients that will allow me to use IMAP to combine all of these applications into a single e-mail inbox, but why isn’t there a service that allows me to have all of this “in the cloud”. I hate it when I am at a different computer other than my own and have to install my mail software and set up 7 different e-mail accounts, or visit 7 different pages in order to get my e-mail. Why isn’t there a web 2.0 e-mail client? I would even pay a small monthly fee in order to use this service!

Development and Howto02 Mar 2008 03:25 pm

I have been a big supporter of Subversion for a long time. I have used it off and on for about 3 years now and have never really had very many troubles while using it. It has always suited my needs and actually allowed me to really learn what version control is, why it’s useful and how to use it. Until recently, I have been very satisfied with its capabilities.

A Distributed Problem

When I created the MyEPICS 2.0 application, I had a vision to make a general framework which can be used outside the context of a service learning management program. Well, fast forward about two years later and I feel I have a stellar framework. I have one tiny problem though, which is that I need to make modifications inside the framework’s directory structure, without changing the main subversion repository. In other words, I have a project that I want to base upon the MyEPICS Framework, but I don’t want to use the main Subversion repository for its version control because not everything I do is going to back into the framework.

An example directory structure is below:

/
-/ME
--Core.php
--...
-/Modules
--/<--- Here is where I want to change things

Purely Subversion Option

If I were to want to do something like this, I would have to check out each Module directory individually from my own repository, and manually do each svn command in each module directory to get up to speed. Not to mention, if I want to update it server side, I must update each directory individually.

On the other hand, I could just set up a new repository for my own work, and any changes outside of the Modules directory I could manually generate a diff, and apply it to the main repository and commit, and vice versa for getting changes from the main repository. It's tedious, but can work.

Mercurial managed

With using a mercurial managed repository, I can check out the repository to some directory, and make a mercurial repository on top of that. From there, I can hg clone the repository to do any of my own work. I can play around with the modules directory, do all of my own changes, without effecting the main Subversion repository. Any time I have a change to add to the main Subversion repository, I just svn commit them. If I have a change to pull from the main Subversion repository, I just
svn update
hg commit

And I have an updated repository! The only downside is that for some reason, any clone of my main mercurial repository doesn't allow me to do my Subversion commands, such as updating and committing. There are a few directories that Mercurial doesn't see in the .svn directory, which I will have to find out why at a later date.

Making the Switch

No Central Repository

Probably the biggest difference is that there is no "central" repository to work with. This means, that any changes you create can be isolated to your environment. You can totally fork an entire project and set up your own version control, and sync up with it whenever you want w/o them really knowing. In fact, that's the entire problem that I've had working with Subversion... I couldn't find a way to do this. Now, trying to argue that there isn't a "main" repository and you'll just be wasting energy. In every project, there has to be some "official" repository which contains the "official" code. In the Linux kernel, that's Linus' repository. For other projects, they may have an "official" repository which is delegated by a select group of people.

Ignoring Files

Mercurial uses a file named .hgignore to tell it to ignore files, as opposed to Subversion using a property on the file, namely svn:ignore. In this file, you can either add single files, or regular expressions. The man page on hgignore is helpful in this case.

Meta Repositories, Tagging, and Branching OH MY!

In the case of Subversion, it is recommended that each repository contain all the tags and branches in it's repository layout, and even allows for multiple repositories contained within one large repository, thus making a meta-repository.

In Mercurial, there is no repository layout. Your repository is just your project itself, so there is no trunk, branches or tag directory. In subversion, if you wanted to branch or tag, you just copy a directory in the repository to the branches or tags and work from there. In Mercurial if you wish to make a branch, you simply hg clone hg branch (thanks luke!) it. When you want your changes to be seen, you push it back or wait for someone to pull from you. If you want to tag something, it's accomplished via hg tag.

Helpful Hint

While I was reading the mercurial red-bean book, I came across such an excellent note, I'm going to repeat it verbatim:

Note: If you’re new to Mercurial, you should keep in mind a common “error”, which is to use the “hg pull” command without any options. By default, the “hg pull” command does not update the working directory, so you’ll bring new changesets into your repository, but the working directory will stay synced at the same changeset as before the pull. If you make some changes and commit afterwards, you’ll thus create a new head, because your working directory isn’t synced to whatever the current tip is.

I put the word “error” in quotes because all that you need to do to rectify this situation is “hg merge”, then “hg commit”. In other words, this almost never has negative consequences; it just surprises people. I’ll discuss other ways to avoid this behaviour, and why Mercurial behaves in this initially surprising way, later on.

Conclusion

After working with Mercurial for a few weeks, I have a little bit better of an understanding of how it works, and enjoy using much better than I did when working on the Rubix Cube project. For now, this will allow me to have my own version control while keeping in sync with the main Subversion repository.