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.
]]>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.
]]>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.
]]>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>
]]>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.)
]]>__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);.
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.)
]]>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. ;))
]]>