<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Infallible Logic</title>
	
	<link>http://infalliblelogic.com</link>
	<description />
	<lastBuildDate>Sat, 18 Feb 2012 11:11:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/InfallibleLogic" /><feedburner:info uri="infalliblelogic" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>cc1.exe: error: unrecognized command line option ‘-mno-cygwin’</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/GbFObRqz-Ks/</link>
		<comments>http://infalliblelogic.com/2012/02/18/cc1-exe-error-unrecognized-command-line-option-mno-cygwin/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 11:11:54 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[cygwin]]></category>
		<category><![CDATA[mingw]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=104</guid>
		<description><![CDATA[All I was really trying to do was install the hg-git extension, but somehow this led me to have to install: Python Cygwin MinGW I really hate doing development on Windows, which is why I usually avoid this crap, but I wanted to upload one of my projects to Github without having to remember how [...]]]></description>
			<content:encoded><![CDATA[<p>All I was really trying to do was install the hg-git extension, but somehow this led me to have to install:</p>
<ol>
<li>Python</li>
<li>Cygwin</li>
<li>MinGW</li>
</ol>

<p>I really hate doing development on Windows, which is why I usually avoid this crap, but I wanted to upload one of my projects to Github without having to remember how on Earth to install Git on Windows properly again. Maybe it would've been easier than this, but I digress.</p>

<p>The -mno-cygwin option doesn't actually exist anymore in the newer versions of gcc. But Windows Python 2.7's (I didn't try the others) distutils still tries to call it anyway if you actually need something compiled. After actually way more Googling than I probably should have needed, I finally stumbled upon <a href="http://stackoverflow.com/questions/8531983/easy-install-u-cython-fails-complaining-about-vcvarsall-bat-and-mno-cygwin">this Stack Overflow answer</a>.</p>

<p>Basically, you just need to edit <tt>[YourPythonInstallPath]\Lib\distutils\cygwinccompiler.py</tt> and remove all traces of <tt>-mno-cygwin</tt>, and try again and it'll probably work fine. Assuming you don't run into other errors (like say, actually trying to use 64-bit Python...).</p><img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/GbFObRqz-Ks" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2012/02/18/cc1-exe-error-unrecognized-command-line-option-mno-cygwin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2012/02/18/cc1-exe-error-unrecognized-command-line-option-mno-cygwin/</feedburner:origLink></item>
		<item>
		<title>[Javascript] Internet Explorer namespacing</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/woQqJie1gIw/</link>
		<comments>http://infalliblelogic.com/2011/01/31/javascript-internet-explorer-namespacing/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 19:52:31 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=98</guid>
		<description><![CDATA[We just ran into a ridiculous bug here that doesn't seem to be mentioned in many places. The best post I've seen about it is here: Basically there's a bug on how IE's JScript expands global variable names. If one does for(foo in {'a':'b', 'c':'d'}) { alert(foo); } One gets the expected alerts for 'a' [...]]]></description>
			<content:encoded><![CDATA[<p>We just ran into a ridiculous bug here that doesn't seem to be mentioned in many places. The best post I've seen about it is <a href="http://thedailyreviewer.com/windowsnet/view/jscript-bug-in-ie-6-7-8-104200632">here</a>:</p>
<blockquote>
<p>Basically there's a bug on how IE's JScript expands global variable names.</p>

<p>If one does<br/>
for(foo in {'a':'b', 'c':'d'}) { alert(foo); }<br/>
One gets the expected alerts for 'a' and 'c'.</p>

<p>However, if one chooses to use the variable name 'item', as such:<br/>
for(item in {'a':'b', 'c':'d'}) { alert(item); }</p>

<p>One gets an error, saying the 'object does not support this action'. Digging 
a bit deeper, this happens not only with the word 'item', but any property of 
the window object, or its prototype (any property to which it responds, like 
toString). It seems IE JScript is expanding 'item' to 'window.item', and what 
results is 'for(window.item in ...', which is wrong. </p>

<p>This does not happen if scoping with the 'var' keyword, since then the 
engine knows it's a local variable, not a property of the global object.</p>
</blockquote>

<p>So essentially, if you don't create a variable in a local scope with the 'var' keyword, and it's a variable that exists in the window object or its prototype, it will <strong>look for it in the window object</strong> instead of your local scope. So keep that in mind when creating loops and whatnot that may not necessarily require you to use the var keyword.</p><img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/woQqJie1gIw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2011/01/31/javascript-internet-explorer-namespacing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2011/01/31/javascript-internet-explorer-namespacing/</feedburner:origLink></item>
		<item>
		<title>[jQuery] Plugins putting developers in a bind</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/DzS-2gFGR58/</link>
		<comments>http://infalliblelogic.com/2011/01/23/jquery-plugins-putting-developers-in-a-bind/#comments</comments>
		<pubDate>Sun, 23 Jan 2011 10:19:57 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=85</guid>
		<description><![CDATA[So I've been working on a Chrome extension for a little while that utilizes jQuery. In the true spirit of being smart and lazy, and taking advantage of the huge community that jQuery has, I've naturally pulled in a number of plugins from other developers. Of course, I got a little lax on my quality [...]]]></description>
			<content:encoded><![CDATA[<p>So I've been working on a Chrome extension for a little while that utilizes jQuery. In the true spirit of being smart and lazy, and taking advantage of the huge community that jQuery has, I've naturally pulled in a number of plugins from other developers.</p>

<p>Of course, I got a little lax on my quality control. I wanted to implement some context menus on some of my elements, so I went to my go-to Chrome extension, <a href="https://github.com/cezarsa/chromed_bird/">Chromed Bird</a>, for inspiration. I like the way his context menus are implemented and wasn't too impressed with a few others that I had checked out. So I headed over to <a href="http://abeautifulsite.net/blog/2008/09/jquery-context-menu-plugin/">A Beautiful Site</a> to read up on their jQuery Context Menu plugin.</p>

<p>It's pretty decent. It installs quickly, has little configuration, and comes with a really nice default stylesheet that doesn't really need any changes (unless you don't want to use the included images). The first warning I should have noticed was that all of the CSS and JS HTML elements were referenced in uppercase (LI instead of li, A instead of a, etc). Ugh. What is this, 1994? Anyway, whatever.</p>

<p>So I set it up and it was quick and painless. I got to testing it out and it seemed to work like I had intended (I was using it in the same was Chromed Bird does, as a context menu for a tabbed interface). But something odd started to happen. I register click events on a number of anchor tags to spawn new tabs in the interface, and as soon as I would open up the context menu, none of the links would work anymore. Kind of a terrible side effect, when you think about it!</p>

<p>So I delved into the code, and this is what I discovered:</p>
<ul><li>It disables the standard context menu, which is fine and actually necessary.</li>
<li>When the jQuery context menu opens, it registers a click event on $(document) directly. This is so that you can 'remove' the context menu by clicking elsewhere on the page.</li>
<li>Once a menu item is clicked, or the document is clicked, it unregisters those click handlers on the document.</li>
</ul>
<p>Really straight-forward, when you get down to it. The problem was that he was using a global unbind call.</p>

<textarea name="code" class="xslt:nogutter">
$(document).unbind('click');
</textarea>

<p>This apparently has the nasty side-effect of removing ALL click elements that have been attached to any element on the page. jQuery does give you the option to pass either an event as the first option to use to unbind, or the function that was attached to the event to unbind from as the second parameter. However, because of the way the code was set up, this really just wasn't possible. I ended up having to do a very heavy rewrite to get it to work properly (and also to make it work a little more how I thought it should work).</p>

<p>The moral of the story is thus:</p>
<blockquote>If you're developing plugins that other people are going to use, you need to be as unobtrusive as possible with your code.</blockquote>
<p>It's entirely possible this is a bug or change in functionality that's happened over the past couple of years since the original release of the plugin, but it's still a design that could have easily been avoided with a slightly better design.</p>

<p>My updated code is below, though it does include a pretty large change in ideology over the original design. In mine, you create one context menu and attach elements to it that will use it, then remove them if they're not needed anymore. It's somewhat specialized for the way it works in my project, but should be generic enough. It does currently depend on <a href="http://ejohn.org/blog/simple-javascript-inheritance/">John Resig's Class.extend</a> inheritance model. I also removed anything that wasn't necessary for it to run in Chrome (there were a few IE/Firefox specific things), as well as the keypress functionality that had existed that I also didn't find super useful or necessary to have.</p>


<textarea name="code" class="xslt:nogutter">
/**
 * @author Chris Barmonde
 * @link http://infalliblelogic.com
 * 
 * This is a heavily modified version of the jQuery Context Menu
 * Plugin (v1.01) originally developed by Cory S.N. LaViska from
 * A Beautiful Site:
 * 
 * More info: http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/
 * 
 * The plugin is dual-licensed under the GNU General Public License
 *   and the MIT License.
 */

var ContextMenu = Class.extend({
	init: function(id, options) 
	{
		this.elements = {};
		
		$.extend(options, {
			inSpeed: 150,
			outSpeed: 75
		});
		
		// 0 needs to be -1 for expected results (no fade)
		if (options.inSpeed == 0) options.inSpeed = -1;
		if (options.outSpeed == 0) options.outSpeed = -1;
		
		this.options = options;
		this.events = {
			mousedown: this.mousedown.bind(this),
			mouseup: this.mouseup.bind(this),
			documentClick: this.documentClick.bind(this),
			menuClick: this.menuClick.bind(this)
		}		
		
		this.$menu = $(id);
		this.$menu.addClass('contextMenu');
		this.$menu.bind(
			'mousedown.disableTextSelect',
			function() { return false; }
		);
		
		this.$current_element = null;
	},
	
	attachTo: function(name, element) 
	{
		element = $(element);
		if (!element) return false;
		
		element.mousedown(this.events.mousedown);
		element.mouseup(this.events.mouseup);
		element.add(this.$menu).bind(
			'contextmenu',
			function() { return false; }
		);

		this.elements[name] = element;
	},
	
	removeFrom: function(name)
	{
		element = this.elements[name];
		if (!element) return;
		
		element.unbind('mousedown', this.events.mousedown);
		element.unbind('mouseup', this.events.mouseup);
		element.unbind('contextmenu');
		
		delete this.elements[name];
	},
	
	mousedown: function(e) 
	{
		e.stopPropagation();
	},
	
	mouseup: function(e) 
	{
		if (e.button != 2) return false;
		
		// Hide context menus that may be showing
		this.$menu.hide();

		var $element = $(e.currentTarget);
		if ($element.hasClass('disabled')) return false;
		
		this.$current_element = $element;
		
		// Detect mouse position
		var coords = this.getCoords(e);
		
		// Show the menu
		$(document).unbind('click', this.events.documentClick);
		this.$menu.css({ top: coords.y, left: coords.x })
			.fadeIn(this.options.inSpeed);
		
		// When items are selected
		this.$menu.find('a').unbind('click');
		this.$menu.find('li:not(.disabled) a')
			.click(this.events.menuClick);
		
		$(document).click(this.events.documentClick);
	},
	
	documentClick: function(e) {
		$(document).unbind('click', this.events.documentClick);
		this.$menu.fadeOut(this.options.outSpeed);
		this.$current_element = null;
		
		return false;
	},
	
	menuClick: function(e) {
		$(document).unbind('click', this.events.documentClick);
		this.$menu.hide();
		
		if ('callback' in this.options) 
		{
			var $element = $(e.target);
			var offset = $element.offset();
			var coords = this.getCoords(e);

			this.options.callback(
				$element.attr('href').substr(1),
				this.$current_element,
				{
					x: coords.x - offset.left,
					y: coords.y - offset.top,
					docX: coords.x,
					docY: coords.y
				}
			);
			
			this.$current_element = null;
		}
		
		return false;
	},
	
	getCoords: function(e) 
	{
		var d = {}, x, y;
		if (self.innerHeight)
		{
			d.pageYOffset = self.pageYOffset;
			d.pageXOffset = self.pageXOffset;
			d.innerHeight = self.innerHeight;
			d.innerWidth = self.innerWidth;
		}
		else if (document.documentElement
			&#038;& document.documentElement.clientHeight)
		{
			d.pageYOffset = document.documentElement.scrollTop;
			d.pageXOffset = document.documentElement.scrollLeft;
			d.innerHeight = document.documentElement.clientHeight;
			d.innerWidth = document.documentElement.clientWidth;
		}
		else if (document.body)
		{
			d.pageYOffset = document.body.scrollTop;
			d.pageXOffset = document.body.scrollLeft;
			d.innerHeight = document.body.clientHeight;
			d.innerWidth = document.body.clientWidth;
		}
		(e.pageX) ? x = e.pageX : x = e.clientX + d.scrollLeft;
		(e.pageY) ? y = e.pageY : y = e.clientY + d.scrollTop;
		
		return {d:d, x:x, y:y};
	}
});
</textarea>

<p><strong>[Edit]</strong> Oops, just realized it also uses a variation of Prototype's bind() method for binding the local space of function calls to objects:

<textarea name="code" class="xslt:nogutter">
Function.prototype.bind = function(context)
{
    if (arguments.length < 2 &#038;& typeof arguments[0] === "undefined") return this;
    var __method = this, args = Array.prototype.slice.call(arguments).slice(1);
    return function() {
        var a = args.concat(Array.prototype.slice.call(arguments));
        return __method.apply(context, a);
    }
}
</textarea><img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/DzS-2gFGR58" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2011/01/23/jquery-plugins-putting-developers-in-a-bind/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2011/01/23/jquery-plugins-putting-developers-in-a-bind/</feedburner:origLink></item>
		<item>
		<title>[OAuth] A Space-Escaping Gotcha</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/aalj1dAP4z0/</link>
		<comments>http://infalliblelogic.com/2010/12/03/oauth-a-space-escaping-gotcha/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 09:52:05 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=72</guid>
		<description><![CDATA[I just finished helping a third-party developer who is trying to integrate with Formspring's API, and it brought up a pretty common problem I've seen: Most standard URI escaping mechanisms will convert spaces to a '+' character. This works all well and fine in the browser, but OAuth is pretty finicky about its parameters. OAuth [...]]]></description>
			<content:encoded><![CDATA[<p>I just finished helping a third-party developer who is trying to integrate with Formspring's API, and it brought up a pretty common problem I've seen:</p>

<p>Most standard URI escaping mechanisms will convert spaces to a '+' character. This works all well and fine in the browser, but OAuth is pretty finicky about its parameters.</p>

<p><strong><a href="http://oauth.net/core/1.0a/#encoding_parameters">OAuth requires the space to be sent as %20.</a></strong></p>

<p>So in the case that your standard URI escaper converts to a '+', you'll need to add one additional step to convert the '+' to a '%20'. Otherwise, you'll likely find yourself getting Invalid Signature errors.</p><img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/aalj1dAP4z0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2010/12/03/oauth-a-space-escaping-gotcha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2010/12/03/oauth-a-space-escaping-gotcha/</feedburner:origLink></item>
		<item>
		<title>[PHP] More PEAR libraries that suck? Say it ain’t so, XML_RPC2!</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/f2jT37hRUyc/</link>
		<comments>http://infalliblelogic.com/2010/10/04/php-more-pear-libraries-that-suck-say-it-aint-so-xml_rpc2/#comments</comments>
		<pubDate>Tue, 05 Oct 2010 00:54:53 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=66</guid>
		<description><![CDATA[If you've paid attention, you'll know that I'm not particularly fond of most PEAR libraries. I appreciate the developers who spend their time maintaining them, and they generally save me some amount of potential time. But I don't think I've seen a single one with code that doesn't make me want to jump off the [...]]]></description>
			<content:encoded><![CDATA[<p>If you've paid attention, you'll know that I'm not particularly fond of most PEAR libraries. I appreciate the developers who spend their time maintaining them, and they <em>generally</em> save me some amount of potential time. But I don't think I've seen a single one with code that doesn't make me want to jump off the GGB.</p>

<p>If you recently upgraded to PHP5.3, and you just so happen to be using XML_RPC2, you may notice that... everything works fine. But conversely, you may notice that nothing works at all and your program dies with no error messages of any sort being logged anywhere, which is less awesome. If you were smart enough to actually track down the problem, and then conversely <strong>stupid</strong> enough to actually open up the XML_RPC2 code, you'd probably find your way to <tt>XML_RPC2_Backend</tt>.</p>

<p><tt>XML_RPC2_Backend</tt> is what is called when you use <tt>XML_RPC2_Client::create()</tt> to get your client object. It is a supposedly pluggable architecture so you could create your own backends to RPC2 or something, although it then has a hard-coded list of types it will actually allow, so it's not <em>really</em> pluggable at all, but uh.. yeah. Also, super LOLs to this snippet of useless clock cycles (what's the point of ucfirst???):</p>

<blockquote><pre>$backend = ucfirst(strtolower($backend));
        if (
            $backend != 'Php' &#038;&
            $backend != 'Xmlrpcext'
           )</pre></blockquote>

<p>Anyway, point is, it first checks for the existence of the <a href="http://php.net/xml_rpc">xml_rpc extension</a> in PHP, and does so by <strong>force-loading the extension if it can't find the functions from the library</strong>. Seriously?? Whatever. I guess it ultimately wouldn't be a huge problem, except for one small caveat from the <a href="http://php.net/dl">manual for the dl() function</a>:</p>

<blockquote>This function has been removed from some SAPI's in PHP 5.3.</blockquote>

<p>Apparently due to 'stability issues', PHP no longer includes the dl() function in most of their distributions. (Why they didn't remove it completely is a mystery, honestly.) They suggest people just update their php.ini's instead or something.</p>

<p><strong>THE POINT BEING:</strong> If your xml_rpc extension install either: 1) Doesn't exist because you don't want to include it, or 2) Isn't loaded by default, and you're running one of these SAPI's, XML_RPC2 will crash and burn gloriously by forging ahead and calling <tt>dl()</tt> <em>just in case</em>. I suggest just going directly into the <tt>XML_RPC2_Backend::getBackend()</tt> method and completely commenting out where it tries to load XMLRPCext. Seriously worthless.</p>

<img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/f2jT37hRUyc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2010/10/04/php-more-pear-libraries-that-suck-say-it-aint-so-xml_rpc2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2010/10/04/php-more-pear-libraries-that-suck-say-it-aint-so-xml_rpc2/</feedburner:origLink></item>
		<item>
		<title>[PHP] Still using MDB2? Getting a “no such table” error?</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/pmiJn-WLugw/</link>
		<comments>http://infalliblelogic.com/2010/08/31/php-still-using-mdb2-getting-a-no-such-table-error/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 07:16:43 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=61</guid>
		<description><![CDATA[So we're currently stuck using MDB2 at work. Like a vast majority of PEAR's repositories, it's just awful, awful code. I'm sure it served some kind of purpose before PDO came along (like what 5 or more years ago??), but now it's just a thorn in the side of any decent developer stuck dealing with [...]]]></description>
			<content:encoded><![CDATA[<p>So we're currently stuck using MDB2 at work. Like a vast majority of PEAR's repositories, it's just awful, awful code. I'm sure it served some kind of purpose before PDO came along (like what 5 or more years ago??), but now it's just a thorn in the side of any decent developer stuck dealing with it.</p>

<p>I recently came across a problem where I was accessing data across multiple database instances, and it was all well and good. Until you tried to use one of the first database connections again. Running anything against it would just result in a "no such table" error.</p>

<p>Buh? How can there not be a table there when I just queried from it not even a second before? Doing a dump of the MDB2 object itself even showed it was using the correct database information and it claimed to be using the correct database name.</p>

<p>Ultimately the problem turned out to be the fact that it still relies on the old mysql_* methods. This error occurred on our dev server, which is set up to model production, but isn't <em>quite</em> the same. On production, all our instances are actually on separate hosts. On dev, they're in separate databases, but the host and connecting information is all the same. If you look in the PHP docs for the <a href="http://php.net/mysql_connect">mysql_connect()</a> method's <tt>new_link</tt> parameter:</p>

<blockquote><big>If a second call is made to mysql_connect() with the same arguments, no new link will be established, but instead, the link identifier of the already opened link will be returned.</big></blockquote>

<p>Yay. So successive calls to <tt>mysql_connect()</tt> with the <em>same host, username, and password</em> will return the same connection. It's a good thing to have to prevent opening too many connections, but it also largely depends on your database framework being able to correctly give you separate connections if you really want them. (In fact, I might go so far as to say it SHOULD be the code that caches connections, not the underlying driver, but whatever. <tt>mysql_connect()</tt>'s <tt>new_link</tt> param <strong>does</strong> give back a new connection if set to true.) Unfortunately, MDB2 caches the database name and checks its own cached name to ensure the database hasn't been switched, so it never detects that the same connection was pulled and switched elsewhere.</p>

<p>The easy fix is just to call <tt>mysql_select_db()</tt> every time you're pulling a cached DB connection to ensure your DB is correct. I'm honestly not sure of the overhead of doing that, but assuming you're not making tens of thousands of those calls, I'm sure it's reasonably minuscule. I'd honestly just suggest switching to PDO and caching your own connections, anyway.</p><img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/pmiJn-WLugw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2010/08/31/php-still-using-mdb2-getting-a-no-such-table-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2010/08/31/php-still-using-mdb2-getting-a-no-such-table-error/</feedburner:origLink></item>
		<item>
		<title>More Zune Gotchas [Autoplaylists]</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/B-ERM6eCNIc/</link>
		<comments>http://infalliblelogic.com/2010/02/14/more-zune-gotchas-autoplaylists/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 02:12:50 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[windows 7]]></category>
		<category><![CDATA[zune]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=43</guid>
		<description><![CDATA[When setting up your Zune Software, one of the settings under Collection is for 'Zune Folders', where it will presumably store data when you rip CDs or download albums from the Marketplace. This is also where it will save any playlists you've created inside of the software. Now obviously when you uninstall the software, it [...]]]></description>
			<content:encoded><![CDATA[<p>When setting up your Zune Software, one of the settings under Collection is for 'Zune Folders', where it will presumably store data when you rip CDs or download albums from the Marketplace.  This is also where it will save any <strong>playlists</strong> you've created inside of the software.</p>

<p>Now obviously when you uninstall the software, it will keep this directory intact since it could potentially contain some of your music files. What it doesn't tell you is that <strong>it will automatically import any data it finds in your playlists</strong>! After running through the steps of my previous posts, it was still finding some of the albums from directories I was no longer including in monitoring and it was driving me crazy. I had kept my playlists because I had a decent number and didn't want to recreate them. Joke's on me because it just took all the tracks from those playlists and reimported every single one, including ones from when I was still using the 4.2 software!</p>

<p>So if you had any autoplaylists created, ensure you delete those (and really probably anything else inside that directory, to be safe) or else it will still import anything it finds in there.</p><img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/B-ERM6eCNIc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2010/02/14/more-zune-gotchas-autoplaylists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2010/02/14/more-zune-gotchas-autoplaylists/</feedburner:origLink></item>
		<item>
		<title>Zune 4.2 and Windows 7 Libraries [Rant]</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/Cjto4fPmCE8/</link>
		<comments>http://infalliblelogic.com/2010/02/04/zune-4-2-and-windows-7-libraries-rant/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 16:44:00 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[windows 7]]></category>
		<category><![CDATA[zune]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=39</guid>
		<description><![CDATA[As many people have discovered, the Zune 4.2 software brings a new 'feature' to Windows 7 users: It automatically uses your Libraries to discover new media. For many people, this will never be a problem, but it brings a number of issues along with it. First and foremost is that you can no longer keep [...]]]></description>
			<content:encoded><![CDATA[<p>As many people have discovered, the Zune 4.2 software brings a new 'feature' to Windows 7 users: It automatically uses your Libraries to discover new media. For many people, this will never be a problem, but it brings a number of issues along with it.</p>

<p>First and foremost is that you can no longer keep your Libraries and your Zune monitored folders separate. If you try to remove monitored folders in the Zune software, <em>it will remove them from your Libraries entirely</em>, which isn't even necessarily something you want to happen! So you are <strong>forced</strong> into putting all you media into Libraries, and even more than that, you're forced into keeping media <em>out</em> of your Libraries if you don't want them scanned!</p>

<p>In my scenario, I keep a separate folder for freshly-ripped or downloaded albums so that I can tag them and set them up in such a way that they can be integrated into the rest of my collection. I like to keep these separate because there's no way to guarantee how the source of the album has tagged it, or how they've set up their album art (I am fervently against putting art in tags since it's an unnecessary waste of space) or things of that nature.</p>

<p>At the same time, this folder <em>does</em> contain music, so I do like to keep it in my Music Library so I can easily access it with the rest of my music. But now I can no longer do that with the Zune 4.2 software update because it will scan it into my collection and try to sync it with the hardware, which I absolutely do not want it to do (the Zune software already has far too many troubles with tracking moved or renamed files).</p>

<p>I was fortunate enough to still have my installer for 4.0, and I would urge anyone who does not like this change to uninstall 4.2 and revert back. One thing to keep in mind, however, is that the software will attempt to auto-update when you run it, so you'll need to disable your internet connection during the install. After that, it will just prompt you when you open it and you can ignore it, if you'd like.</p>

<p>I just don't understand how it's so difficult for these guys (Microsoft and Apple) to get their software right. Why do we need it to be tied to some ridiculous piece of software? Why can't we allow syncing from anywhere? I understand that it gives them far more control over how you use your media, but it's ridiculous for the end-users to have to conform to that.</p>

<p>Back when zAlternator was actually functioning, I used MediaMonkey to sync and I found one thing out: The hardware has <em>far, far less</em> limitations than the software. The software requires you to rename all your album art to ZuneAlbumArt.jpg, where the hardware could read folder.jpg or cover.jpg just fine. The software will create a ridiculous database and throw all your files randomly onto the player where with MediaMonkey, I just synced my files over in the exact directory structure I have at home, and the player found and played it all fine.</p>

<p>The Zune is really a great piece of hardware, it's just such a shame to see such a terrible excuse for software holding it back.</p><img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/Cjto4fPmCE8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2010/02/04/zune-4-2-and-windows-7-libraries-rant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2010/02/04/zune-4-2-and-windows-7-libraries-rant/</feedburner:origLink></item>
		<item>
		<title>O’Reilly Has Released A Ton Of Books To The Android Market [Updated 12/30]</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/8GmG4NCWJs4/</link>
		<comments>http://infalliblelogic.com/2009/12/29/oreilly-has-released-a-ton-of-books-to-the-android-market/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 23:50:36 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[aldiko]]></category>
		<category><![CDATA[O'Reilly]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=16</guid>
		<description><![CDATA[I'm not quite sure when this happened, but O'Reilly (in partnership with Aldiko) has released quite a number of books to the Android market. Not only is there a pretty vast selection, but these books are priced extremely well, ranging from $2.99 to $5.99 for complete books. I picked up the Java Pocket Guide for [...]]]></description>
			<content:encoded><![CDATA[<p>I'm not quite sure when this happened, but O'Reilly (in partnership with <a href="http://www.aldiko.com/">Aldiko</a>) has released <a href="http://www.androlib.com/android.developer.reilly-media-EFA.aspx">quite a number of books to the Android market</a>. Not only is there a pretty vast selection, but these books are priced <em>extremely</em> well, ranging from $2.99 to $5.99 for complete books.</p>

<p>I picked up the <a href="http://www.androlib.com/android.application.com-aldiko-android-oreilly-javapocketguide-xBit.aspx">Java Pocket Guide</a> for three bucks and it was well worth the money. Near as I can tell, these are complete versions of the books at hand, and they're all running with the very slick Aldiko UI, which has many configuration options for font sizes and other reading preferences, as well as the ability to bookmark and view a table-of-contents and other things.</p>

<p>For those of you that have a debug or rooted phone (or the ability to pull APKs off your phone via ADB), you'll find that the files are also just split up via HTML, with an XML-based table-of-contents. I've created a quick XSLT file you can use to transform the TOC into a basic HTML file so you can browse the book on your computer if you want. You'll need to make one change to the toc.ncx file, right below the &lt;?xml?&gt; tag:</p>
<textarea name="code" class="xslt:nogutter"><?xml-stylesheet type="text/xsl" href="toc.xslt"?></textarea>

<p>Then put this file in the same directory and name it 'toc.xslt' (note that I haven't used XSLT or much Javascript in like 8 years, so this may suck). I've updated it to include some basic javascript for easier navigation between the pages!</p>
<textarea name="code" class="xslt:nogutter:collapse">
<?xml version="1.0"?>
<xsl:stylesheet
	version="2.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:ncx="http://www.daisy.org/z3986/2005/ncx/">
	<xsl:output method="html"/>

	<xsl:template match="/ncx:ncx">
		<html>
		<head>
			<style type="text/css">
				body { font:80% Verdana; }
				
				#_frame {
					width:60%;
					height:40em;
					border:0;
				}
				
				h1, #navigation {
					text-align:center;
					width:80%;
				}
				
				#navigation {
					list-style:none;
					padding:0;
					margin:1em 0;
				}
				
				#navigation li {
					display:inline;
					padding:0 2em;
				}
				
				ul#list {
					overflow:scroll;
					height:40em;
					width:20%;
					height:40em;
					margin:0 auto;
					float:left;
				}
				
				ul#list > li {
					font-size:.8em;
				}
				
				ul#list li {
					padding:.25em 0;
				}
				
				ul#list ul {
					padding:0;
					margin:0 0 0 1em;
					list-style-type:square;
				}
				
				ul#list ul ul {
					list-style-type:circle;
				}
				
				ul#list ul ul ul {
					list-style-type:disc;
				}
				
				ul#list ul ul ul ul {
					list-style-type:square;
				}
				
				.break {
					clear:both;
				}
			</style>
			
			<script type="text/javascript">
				var topIndex = 1;
				var currentIndex = null;
				
				var ToggleType = {
					"Prev": -1,
					"Top": 0,
					"Next": 1,
				}
				
				function toggleSection(id, type)
				{
					if (id &lt; topIndex || currentIndex == id) return;

					var currentEl = document.getElementById(currentIndex);

					if (type == null)
					{
						var el = document.getElementById(id);
						currentIndex = parseInt(id);
					}
					else
					{
						do 
						{
							var el = document.getElementById(id);
							if (!el) return;
							
							currentIndex = parseInt(id);
							id += type;
						}
						while (el.href.lastIndexOf('#') > -1);
					}
					
					document.getElementById('_frame').src = el.href;
					el.scrollIntoView(true);
					return false;
				}
				
				function toggleDirection(type)
				{
					var id = (type == ToggleType["Top"]) ? topIndex : currentIndex + type;
					toggleSection(id, type);
				}
			</script>
		</head>
		<body onload="toggleSection(topIndex);">
			<h1><xsl:value-of select="./ncx:docTitle/ncx:text"/></h1>
			<ul id="navigation">
				<li><a href="javascript:toggleDirection(ToggleType['Prev']);">&lt;--Prev</a></li>
				<li><a href="javascript:toggleDirection(ToggleType['Top']);">Top</a></li>
				<li><a href="javascript:toggleDirection(ToggleType['Next']);">Next--&gt;</a></li>
			</ul>
			<div class="break"> </div>
			<ul id="list">
				<xsl:call-template name="navPoint">
					<xsl:with-param name="nav" select="./ncx:navMap/ncx:navPoint"/>
				</xsl:call-template>
			</ul>
			<iframe name="_frame" id="_frame" />
		</body>
		</html>
	</xsl:template>
	
	<xsl:template name="navPoint">
		<xsl:param name="nav"/>
		<li>
			<a>
				<xsl:attribute name="href">
					<xsl:value-of select="$nav/ncx:content/@src"/>
				</xsl:attribute>
				<xsl:attribute name="id">
					<xsl:value-of select="$nav/@playOrder"/>
				</xsl:attribute>
				<xsl:attribute name="onclick">
					return toggleSection(this.id);
				</xsl:attribute>
				<xsl:value-of select="$nav/ncx:navLabel/ncx:text"/>
			</a>
			<xsl:if test="$nav/ncx:navPoint">
				<ul>
					<xsl:for-each select="$nav/ncx:navPoint">
						<xsl:call-template name="navPoint">
							<xsl:with-param name="nav" select="."/>
						</xsl:call-template>
					</xsl:for-each>
				</ul>
			</xsl:if>
		</li>
	</xsl:template>

</xsl:stylesheet>
</textarea>

<p>I've admittedly only tried this with one book, but I can't imagine the rest use a different format.</p>

<p>
<b>Aldiko Book Reader:</b><br />
<img src="http://chart.apis.google.com/chart?cht=qr&#038;chs=150x150&#038;chl=market://search?q=pname:com.aldiko.android" />
</p>

<p>
<b>Java Pocket Guide:</b><br />
<img src="http://chart.apis.google.com/chart?cht=qr&#038;chs=150x150&#038;chl=market://search?q=pname:com.aldiko.android.oreilly.javapocketguide" />
</p><img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/8GmG4NCWJs4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2009/12/29/oreilly-has-released-a-ton-of-books-to-the-android-market/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2009/12/29/oreilly-has-released-a-ton-of-books-to-the-android-market/</feedburner:origLink></item>
		<item>
		<title>[WHS] Backing Up To A Partitioned External Drive</title>
		<link>http://feedproxy.google.com/~r/InfallibleLogic/~3/LZLlMI0do44/</link>
		<comments>http://infalliblelogic.com/2009/12/28/whs-backing-up-to-a-partitioned-external-drive/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 00:23:57 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[WHS]]></category>
		<category><![CDATA[hard drive]]></category>
		<category><![CDATA[windows home server]]></category>

		<guid isPermaLink="false">http://infalliblelogic.com/?p=9</guid>
		<description><![CDATA[This past Christmas, I received a nice big external USB hard drive that I planned on using to store off-site backups of my Windows Home Server and PS3. The PS3's backups require a FAT32 partition, whereas the WHS will obviously work best with an NTFS file system, so I decided to partition the hard drive [...]]]></description>
			<content:encoded><![CDATA[<p>This past Christmas, I received a <a href="http://bit.ly/4zO4xL">nice big external USB hard drive</a> that I planned on using to store off-site backups of my Windows Home Server and PS3. The PS3's backups require a FAT32 partition, whereas the WHS will obviously work best with an NTFS file system, so I decided to partition the hard drive with two partitions for each of the systems. (For anyone who cares, I used <a href="http://gparted.sourceforge.net/">GParted</a> via a <a href="http://www.virtualbox.org/">VirtualBoxed</a> version of Ubuntu I use since the default Win7 partition manager won't create FAT32 partitions.)</p>

<p>The PS3 backup detected the correct partition and backed up like a charm. The WHS, however, didn't. Instead, it detected the PS3 partition I had created. It would correctly display the full size of the hard drive in the Server Storage tab, but when adding a new drive, it would only detect the PS3 partition (which was much, much smaller).</p>

<p>After some fiddling around (and accidentally reformatting the PS3 partition to NTFS, whoops!), it seems like the WHS will basically just take whichever drive has the <em>lowest drive letter</em> alphabetically. My PS3 partition had been set up with F:\ and the Backup partition was set up with G:\, so it was detecting the PS3 partition first. I swapped the drive letters and it detected the correct partition and everything worked swimmingly.</p>

<p>Kind of annoying, but I'm happy there's at least a workaround. I'm a little curious as to why WHS doesn't let you treat the individual partitions on an external drive separately, though.</p><img src="http://feeds.feedburner.com/~r/InfallibleLogic/~4/LZLlMI0do44" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://infalliblelogic.com/2009/12/28/whs-backing-up-to-a-partitioned-external-drive/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://infalliblelogic.com/2009/12/28/whs-backing-up-to-a-partitioned-external-drive/</feedburner:origLink></item>
	</channel>
</rss>

