Cheap Tools 0

I often joke that since buying a house, my life has become short stints of work and sleep between trips to Home Depot. Between items on my todo list like painting our vaulted living room, building a wall to close in a loft, adding kitchen cabinets, and giving our bathroom a face-lift, I’ve had to buy quite a few different tools. Being pretty frugal (my wife would probably say obsessively so), I hate to spend more money on tools than I have to, especially when those tools probably won’t see a ton of use.

Enter the list of Harbor Freight Gems. If you’re unfamiliar with Harbor Freight, they sell a lot of off-brand tools at pretty good prices. Occasionally you get more than you pay for.

MSSQL JDBC Drivers and getSchemas 2

At work, we’re in the process of trying out some new development projects in Java. And I guess we’re just masochistic, since we decided to write this new project against MSSQL instead of our usual MySQL. Anyways, everything’s coming together for the most part, except that few of the GUI database tools seem to be able to find our schema. Instead, it just seems to list the database users. We noticed this in Netbeans, Eclipse, and SquirrelSQL.

Yesterday, I started tracking it all down. Turns out, Microsoft introduced the concept of an actual schema in SQL Server 2005. Prior to that, tables were segmented by their owner. Consequently, the available JDBC drivers (both jTDS and Microsoft’s) implementations of DatabaseMetaData.getSchemas() actually return the list of database users.

Since I can’t do anything about Microsoft’s driver, I downloaded the source for jTDS and started poking around. In net.sourceforge.jtds.jdbc.JtdsDatabaseMetaData, around line 1589, you’ll find the following query:

SELECT name AS TABLE_SCHEM, NULL as TABLE_CATALOG FROM dbo.sysusers

After digging up a copy of the 1.5 JDK, I changed this to a query based on the information schema and recompiled. Then I fired up SquirrelSQL, and, bam. All my schemas were listed. Feeling quite proud of myself, I then discovered that someone had already filed a bug and the issue was fixed in jTDS’ CVS repository. Oh well.

Anyways, if you’re having issues browsing your MSSQL schemas with SquirrelSQL or other JDBC database tools, try building jTDS from source.

Less is More 1

Canon just announced the G11, the latest in the G lineup of compact cameras that give you SLR-ish control and deliver great image quality. What immediately jumped out at me was that for the first time in the series, Canon actually reduced the resolution (10MP in the G11 compared to 14MP in the G10).

It’s no secret that higher resolution doesn’t necessarily mean a better picture, and I’d say this is undeniable proof that Canon is really shooting for the best image quality possible in the compact G cameras, regardless of how it might read on paper. Just makes me want one all the more.

Cruisecontrol Test Results with Maven 2

Today I finally figured out how to integrate the results of JUnit tests run via the Maven surefire plugin with the Test Results tab in CruiseControl. It was actually blindingly simple, however, I couldn’t seem to find a straight-forward explanation anywhere.

By default, the Surefire plugin dumps the JUnit XML logs into the target/surefire-reports directory. For the results to show on the Test Results tab, these log files simply need to be merged into the Cruisecontrol log. This is accomplished via a merge element in the log section of the Cruisecontrol config.xml file:

<log>
	<merge
		dir="projects/${project.name}/target/surefire-reports"
		pattern="TEST-*.xml"/>
</log>

Wonderfully funnily 2

Can this be real? I have a feeling that something’s being translated or rewritten with liberal use of a thesaurus. But I don’t get the point — there aren’t any ads that I can see, so it’s not just filler to bump up search rankings and get clicks. Weird.

I Have Cupcake 2

After saying it was coming, then delaying it, then people claiming to have gotten it, then those claims being debunked, then some people installing the UK version, TMobile has apparently finally begun shipping the Android 1.5 “Cupcake” update to US G1 owners.

This afternoon, I downloaded and installed the update by hand, a process that took maybe 5 minutes (tops). The instructions claim that there’s a risk of causing damage to your phone (bricking it, most likely); I followed them verbatim and didn’t have any issues.

So far, it’s really good. I doubt I could live without the hardware keyboard, but I was also really annoyed that I had to open the phone to be able to type even the simplest “ok”. The soft-keyboard completely solves that, and while I’m still in the process of calibrating my fingers, it’s worked well enough so far. The suggestions seemed accurate and have already saved me some pecking time.

Other than that, there seem to be a lot of spit and polish updates, and a few new features. The T-Mobile forums have a full list of changes. Since I have iPhone envy, I immediately turned on the screen transitions. I also played briefly with the video recorder, and also just made sure that I can play music through my Bluetooth headphones. I also turned on the auto-rotations, but I’m not sure I’ll keep them.

In short, if you have a G1, I’d say you check out the update now — don’t wait! (But, then, I’m impatient.)

When Objects Aren’t 0

When unserializing an object whose class definition is not present, PHP returns an instance of the special type, __PHP_Incomplete_Class, which issues notices if you attempt to call a method or access a property.

For example, this code produces the following:

andrew@fake:~$ php incomplete.php
object(__PHP_Incomplete_Class)#1 (2) {
  ["__PHP_Incomplete_Class_Name"]=>
  string(4) "test"
  ["name"]=>
  string(2) "hi"
}

Notice: main(): The script tried to execute a method or access a property of an
incomplete object. Please ensure that the class definition "test" of the object you
are trying to operate on was loaded _before_ unserialize() gets called or provide
a __autoload() function to load the class definition  in /home/andrew/test2.php
on line 7
NULL

Interestingly, the is_object method returns false when given an instance of __PHP_Incomplete_Class. This seems to be in contradiction with var_dump (as evidenced above), gettype, and get_class, all of which return values indicating that the incomplete class is a normal object.

This was reported as bug 19842 way back in 2002, but didn’t seem to be considered a problem. (The suggested solution was simply to have all class definitions present before unserializing that object.)

To be fair, this behavior of is_object is documented in the notes section of its manual page. It also appears to be intentional, judging from this section in ext/standard/type.c, determining whether a variable is an object:

   220                          if (!strcmp(ce->name, INCOMPLETE_CLASS)) {
   221                                  RETURN_FALSE;
   222                          }

That said, it’s a little confusing when you first run into it, and means that if you’re examining a session for which you don’t have all the class definitions (writing tools outside of your application, for instance), it’s just a little bit harder to determine which variables within the session are objects.

The workaround, of course, is easy, given that most other methods treat the object as an object: $is_object = (get_class($o) !== FALSE);.

Best PHP Bug Report 1

If this isn’t the best PHP bug report ever, it’s definitely in the running.

Every day 0

Here are two PHP functions (although one’s actually from an extension) that I didn’t know existed, but give you some good insight into your variables, especially when you’re mucking around with more complicated stuff: debug_zval_dump and xdebug_debug_zval.

Both give you more information about the underlying representation of your variables: in particular, what the refcount is for that particular value. Note, however, that while it’s literally called the “reference count”, a refcount greater than one doesn’t imply that the variable is actually a reference due to PHP’s “copy on write” semantics. XDebug’s version of the method wins here, because it also dumps is_ref, which does flag a reference.

(See Sara Golemon’s You’re being lied to or Derick Rethan’s References in PHP [PDF] for more.)

Instant Storage 1

Here’s one of my favorite PHP ‘hacks’: when I’m whipping up a quick script that needs a place to stash some persistent data, but don’t feel like coming up with a database structure, or doing anything remotely approaching a real solution, I instead stuff it into a “static” session. By static, I just mean that I set the session ID to a static value, so I’m always pulling the same session. Instant data store.

session_id('stash-stuff-here');
session_start();
$_SESSION['stuff'] = $w00tz;

(Another quick and dirty approach would be serializing an array into a local file… oh, wait, I just recreated the default PHP session handler. ;) )

Next Page »