<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Igor Partola</title>
	<atom:link href="http://igorpartola.com/feed" rel="self" type="application/rss+xml" />
	<link>http://igorpartola.com</link>
	<description>Square root of a piece of pie</description>
	<lastBuildDate>Sat, 21 Jan 2012 17:53:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Beware the Python generators</title>
		<link>http://igorpartola.com/programming/beware-the-python-generators</link>
		<comments>http://igorpartola.com/programming/beware-the-python-generators#comments</comments>
		<pubDate>Sat, 21 Jan 2012 17:41:07 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=172</guid>
		<description><![CDATA[Generators and list comprehension in Python are very closely related. After all, each gives you an iterable. However, I really wish that generators came with a &#8220;DANGER: Handle with care!&#8221; label. The problem is that while the syntax for creating a generator vs a list differs in exactly two characters, generators have side effects that [...]]]></description>
			<content:encoded><![CDATA[<p>Generators and list comprehension in Python are very closely related. After all, each gives you an iterable. However, I really wish that generators came with a &#8220;DANGER: Handle with care!&#8221; label. The problem is that while the syntax for creating a generator vs a list differs in exactly two characters, generators have side effects that are both subtle and easy to overlook. Let&#8217;s take a look at some code:<p>

<pre><code>items = get_items()

for x in items:
    print x

for x in items:
    print x
</code></pre>

<p>Does that code look reasonable to you? It does, until I tell you that get_items() returns a generator. You see, generators have an internal pointer to the index and cannot be reset. Thus the sequence of items will only be printed once. This can be solved by convention. Some libraries will prefix the function&#8217;s name with an &#8220;i&#8221; converting get_items to <code>iget_items()</code>. The built-in Python function <code>xrange()</code>, a generator version of range(), is another example of trying to solve this problem with convention.</p>

<p>Let&#8217;s look at another piece of code:<p>

<pre><code>
try:
    numbers = (int(x) for x in line.split(','))
except ValueError:
    numbers = [] # Handle the case where the input is invalid

for num in numbers:
   print num
</code></pre>

<p>That looks reasonably good, no? Well, generators are lazy, they have to be. Thus number = &#8230; line defines the generator, but not a single call to <code>int()</code> is made at that point. The calls to <code>int()</code> are made during the iteration, while the for loop is executing, which is outside of the try/except block. There are several solutions that exist here, ranging from using a list comprehension instead to placing the for loop inside the try/except block.</p>

<p>Another difference between lists/tuples/sets/other sequence types and generators is that generators have no length. Calling len(get_items()) would result in an error. This is by design: generators may be infinite, and thus it does not make sense to ask what their length is.</p>

<p>I love generators as much as the next guy. However, I think care must be taken when using them. My rules of thumb are:</p>

<p>First, if you are using a generator to optimize for speed: don&#8217;t. In casual observation they are indeed faster than lists, but lists are so flipping fast already that unless you are processing millions of items, it will make no difference. Exception to this rule is when you are in fact processing millions of items or you routinely need to create a lot of iterables in your hot loop and your profiler tells you that this is the bottleneck.</p>

<p>Second, if you are optimizing for memory usage, use generators only if you have a significant number of records. A list of 100 ints will make little difference. A list of ten million log entries is going to cost you some RAM.</p>

<p>Third, never return a generator from a library method, or any type of opaque object. Generators should mostly be used for intermediate iterables until a final result is obtained. Avoid the confusion of get_items() returning a generator.</p>

<p>Lastly, use generators if you must. They are the only way to create infinite iterables, and they do have small speed and large memory advantages over other iterables. If you use them, put in several safeguards: make sure to document the fact that a generator object is used in multiple places, create a convention for what these objects (and the corresponding functions) will be called and test, test, test. As I mentioned at the beginning of this post: generators should come with a warning to not surprise unsuspecting maintainers of your code.</p>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/programming/beware-the-python-generators/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A clever way to fight IE6</title>
		<link>http://igorpartola.com/web-development/a-clever-way-to-fight-ie6</link>
		<comments>http://igorpartola.com/web-development/a-clever-way-to-fight-ie6#comments</comments>
		<pubDate>Wed, 29 Sep 2010 11:33:44 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[IE6]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=159</guid>
		<description><![CDATA[A recent conversation with a web consultant I had got on the topic of browser support. I asked &#8220;What browsers do you support?&#8221;. He responded with the list of the usual &#8220;modern&#8221; ones: IE7+, Chrome, Firefox, Safari. &#8220;How about IE6?&#8221; I inquired. &#8220;Well, it is a hassle. What I usually do is add an extra [...]]]></description>
			<content:encoded><![CDATA[<p>A recent conversation with a web consultant I had got on the topic of browser support. I asked &#8220;What browsers do you support?&#8221;. He responded with the list of the usual &#8220;modern&#8221; ones: IE7+, Chrome, Firefox, Safari. &#8220;How about IE6?&#8221; I inquired. &#8220;Well, it is a hassle. What I usually do is add an extra charge for IE6 compatability. When the clients sees it, they usually drop that requirement. Normally, if you ask them whether it is important to support IE6, they say yes and then it&#8217;s your headache. But showing them the price tag seems to work well.&#8221;</p>

<p>This makes sense to me: making the cost of IE6 explicit is something that can hasten the departure from supporting this legacy browsers. People tend to be very careful with their money when they feel they are not getting the greatest return on it, and I have a feeling that a lot of clients would not want to spend extra on making sure their site works in the half-dead zombie that is IE6.</p>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/web-development/a-clever-way-to-fight-ie6/feed</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
		<item>
		<title>Introducing flint: an automated way to start and stop Django FastCGI processes on Debian/Ubuntu</title>
		<link>http://igorpartola.com/web-development/introducing-flint-an-automated-way-to-start-and-stop-django-fastcgi-processes-on-debianubuntu</link>
		<comments>http://igorpartola.com/web-development/introducing-flint-an-automated-way-to-start-and-stop-django-fastcgi-processes-on-debianubuntu#comments</comments>
		<pubDate>Wed, 08 Sep 2010 12:42:18 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=153</guid>
		<description><![CDATA[Flint is my way of running Django applications in production using FastCGI. It is built for Debian/Ubuntu but will work on many other systems. Read full description here.]]></description>
			<content:encoded><![CDATA[<p>Flint is my way of running Django applications in production using FastCGI. It is built for Debian/Ubuntu but will work on many other systems. Read full description <a href="/projects/flint">here</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/web-development/introducing-flint-an-automated-way-to-start-and-stop-django-fastcgi-processes-on-debianubuntu/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing Ping Brigade</title>
		<link>http://igorpartola.com/web-development/announcing-ping-brigade</link>
		<comments>http://igorpartola.com/web-development/announcing-ping-brigade#comments</comments>
		<pubDate>Sun, 01 Aug 2010 21:43:53 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[web apps]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=149</guid>
		<description><![CDATA[Ping Brigade is my latest project. It allows you to measure ping, web page load times and web server latency from multiple servers I run around the world. Give it a try!]]></description>
			<content:encoded><![CDATA[<p>Ping Brigade is my latest project. It allows you to measure ping, web page load times and web server latency from multiple servers I run around the world. <a title="Ping Brigade" href="http://www.pingbrigade.com/">Give it a try!</a></p>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/web-development/announcing-ping-brigade/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proper way to send e-mail from PHP</title>
		<link>http://igorpartola.com/web-development/proper-way-to-send-e-mail-from-php</link>
		<comments>http://igorpartola.com/web-development/proper-way-to-send-e-mail-from-php#comments</comments>
		<pubDate>Wed, 14 Apr 2010 14:47:18 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[web apps]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=137</guid>
		<description><![CDATA[Depending on your setup, PHP might not be sending properly encoded e-mails if you just use the mail() function. Specifically, headers might not be properly encoded, and this includes the subject, the To, and Reply-To, etc.  Just give it a try using some non-ASCII characters and see if it works. If it doesn&#8217;t, here&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p>Depending on your setup, PHP might not be sending properly encoded e-mails if you just use the mail() function. Specifically, headers might not be properly encoded, and this includes the subject, the To, and Reply-To, etc.  Just give it a try using some non-ASCII characters and see if it works. If it doesn&#8217;t, here&#8217;s a better way:</p>

<pre>// At the beginning of each page load, set internal encoding to UTF-8
mb_internal_encoding('UTF-8');

// ... rest of initialization code

// Headers are an associative array, unlike the original mail() function
function better_mail($email, $subject, $body, Array $headers = array(), $additional_parameter = NULL) {
    // Make sure we set Content-Type and charset
    if ( !isset( $headers['Content-Type'] ) ) {
        $headers['Content-Type'] = 'text/plain; charset=utf-8';
    }

    $headers_str = '';
    foreach( $headers as $key =&gt; $val ) {
        $headers_str .= sprintf( "%s: %s\r\n", $key, $val );
    }

    // Use mb_send_mail() function instead of mail() so that headers, including subject are properly encoded
    return mb_send_mail( $email, $subject, $body, $headers_str, $additional_parameters );
}

better_mail( 'example@example.com', 'Résumé with non-ASCII characters', 'Résumé content.', array( 'From' =&gt; 'noreply@example.com' ) );
</pre>

<p>For more information see:</p>

<ul>
	<li><a href="http://www.php.net/manual/en/function.mail.php">mail()</a></li>
	<li><a href="http://www.php.net/mb_send_mail">mb_send_mail()</a></li>
	<li><a href="http://www.php.net/mb_internal_encoding">mb_internal_encoding()</a></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/web-development/proper-way-to-send-e-mail-from-php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing LovelyCo.de</title>
		<link>http://igorpartola.com/pet-projects/introducing-lovelyco-de</link>
		<comments>http://igorpartola.com/pet-projects/introducing-lovelyco-de#comments</comments>
		<pubDate>Tue, 16 Mar 2010 11:47:53 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Pet Projects]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=118</guid>
		<description><![CDATA[LovelyCo.de is a social website for people to share code samples they find particularly elegant. My goal in creating it was to make the experience as smooth as possible. If you have a piece of code, in any language, that you think is worth, sharing, head on over!]]></description>
			<content:encoded><![CDATA[<p><a title="LovelyCo.de" href="http://lovelyco.de/">LovelyCo.de</a> is a social website for people to share code samples they find particularly elegant. My goal in creating it was to make the experience as smooth as possible. If you have a piece of code, in any language, that you think is worth, sharing, head on over!</p>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/pet-projects/introducing-lovelyco-de/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to set up nginx with PHP on Ubuntu</title>
		<link>http://igorpartola.com/web-development/how-to-set-up-nginx-with-php-on-ubuntu</link>
		<comments>http://igorpartola.com/web-development/how-to-set-up-nginx-with-php-on-ubuntu#comments</comments>
		<pubDate>Sun, 28 Feb 2010 15:38:21 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ubuntu php nginx fastcgi vps performance]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=109</guid>
		<description><![CDATA[In an environment where RAM is the major constraint, Apache might not be your best bet. Since I have moved all of my web projects over to an unmanaged VPS, I was looking for ways to either optimize or replace the LAMP stack with something less resource hungry. One of the ways I found to [...]]]></description>
			<content:encoded><![CDATA[<p>In an environment where RAM is the major constraint, Apache might not be your best bet. Since I have moved all of my web projects over to an unmanaged VPS, I was looking for ways to either optimize or replace the LAMP stack with something less resource hungry. One of the ways I found to decrease the RAM requirement of my web services was to replace Apache with an event driven web server called <a href="http://nginx.org/en/">nginx</a>. There are quite a few resources on setting it up but not many discuss how to marry nginx to PHP (to run a WordPress blog for example). The best guide I found so far is <a href="http://tomasz.sterna.tv/2009/04/php-fastcgi-with-nginx-on-ubuntu/">this one</a>. I built upon it to create the simplest nginx+FastCGI/PHP setup possible.</p>

<h4>Step 1: Installation</h4>
<pre>$ sudo apt-get install nginx php5-cgi</pre>

<p>Many of the <a href="http://www.howtoforge.com/nginx_php5_fast_cgi_xcache_ubuntu7.04">nginx/PHP guides</a> out there will tell you that you need to install spawn-fcgi, and most of them will have you compiling it from source. It turns out that php5-cgi package contains a FastCGI wrapper already, so the above two packages are all you need to get going.</p>

<h4>Step 2: Startup script for FastCGI</h4>

<p>We want to create a Startup script for FastCGI PHP processes to run on every boot up. Here is the script I use:</p>

<pre>!/bin/bash
BIND_DIR=/var/run/php-fastcgi
BIND="$BIND_DIR/php.sock"
USER=www-data
PHP_FCGI_CHILDREN=8
PHP_FCGI_MAX_REQUESTS=1000

PHP_CGI=/usr/bin/php-cgi
PHP_CGI_NAME=`basename $PHP_CGI`
PHP_CGI_ARGS="- USER=$USER PATH=/usr/bin PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND"
RETVAL=0

start() {
    echo -n "Starting PHP FastCGI: "
    mkdir $BIND_DIR
    chown -R $USER $BIND_DIR
    start-stop-daemon --quiet --start --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS
    RETVAL=$?
    echo "$PHP_CGI_NAME."
}
stop() {
    echo -n "Stopping PHP FastCGI: "
    killall -q -w -u $USER $PHP_CGI
    RETVAL=$?
    rm -rf $BIND_DIR
    echo "$PHP_CGI_NAME."
}

case "$1" in
    start)
        start
  ;;
    stop)
        stop
  ;;
    restart)
        stop
        start
  ;;
    *)
        echo "Usage: php-fastcgi {start|stop|restart}"
        exit 1
  ;;
esac
exit $RETVAL</pre>

<p>Put the text above into <em>/etc/init.d/fastcgi-php</em>. Then run:</p>

<pre>$ sudo chmod 755 /etc/init.d/fastcgi-php
$ sudo update-rc.d fastcgi-php defaults
$ sudo /etc/init.d/fastcgi-php start</pre>

<p>Note the variables at the top of the script and adjust to fit your available RAM. The the php-cgi processes will get bigger after a while so allot at least 16-20MB for each. This script is slightly different than most I&#8217;ve found, in that it uses a UNIX socket instead of a TCP one for communication. UNIX sockets are faster, and you never have to worry about your firewall setup.</p>

<h4>Step 3: Enable PHP processing</h4>

<p>Create a new file <em>/etc/nginx/fastcgi_php</em> with this content:</p>

<pre># pass the PHP scripts to FastCGI server listening on UNIX socket
location ~ \.php$ {
    fastcgi_pass   unix:/var/run/php-fastcgi/php.sock;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include /etc/nginx/fastcgi_params;
}
</pre>

<p>Now define you virtual servers. Here is a sample config:</p>

<pre>server {
    listen   80;
    server_name  example.com www.example.com;

    access_log  /var/log/nginx/example.com.access.log;

    root   /var/www/example.com;
    index  index.php index.html index.htm;
    autoindex off;

    error_page  404  /404.html;
    error_page   500 502 503 504  /50x.html;

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    location ~ /\.ht {
        deny  all;
    }
    # Enable PHP
    include /etc/nginx/fastcgi_php;
}</pre>

<p>Notice the next to last line of the file. You can include this line in all of your server definitions to enable PHP processing through FastCGI.</p>

<h4>Step 4: Enable the site:</h4>

<p>Enable the site and reload the configs:</p>

<pre>$ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
$ sudo /etc/init.d/nginx reload
</pre>
<h4>Optional tweaking</h4>

<p>There are several other things you might want to consider once this setup is in place. First of all, nginx does not process <em>htaccess</em> files since those are Apache specific. For the most part this means that mod_rewrite rules you&#8217;ve had in place won&#8217;t work. The good news is that nginx has its own <a href="http://wiki.nginx.org/NginxHttpRewriteModule">URL rewriting engine</a>, which is quite capable. The bad news is that you will have to translate your mod_rewrite rules to the syntax used by nginx.</p>

<h5>WordPress compatibility</h5>

<p>A &#8220;quick fix&#8221; exists for WordPress:</p>

<pre>server {
    # Your server definition
    # ...

    location / {
        # this serves static files that exist without running other rewrite tests
        if (-f $request_filename) {
            expires 30d;
            break;
        }

        # this sends all non-existing file or directory requests to index.php
        if (!-e $request_filename) {
            rewrite ^(.+)$ /index.php?q=$1 last;
        }
    }

    # End of server definition
}
</pre>

<p>Note that if you are using the above rules and <a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP Super Cache,</a> the cache will be used in only &#8220;half-on&#8221; mode, so you might want to at least consider translating the rewrite rules used by it to take full advantage of the caching.</p>

<h5>Security considerations</h5>

<p>Security of this setup can be increased if you define separate pools of PHP processes for each virtual server or even application, running as separate users. You can do so by running separate startup scripts. Just define each pool to use its own UNIX socket and instead of inlining the <em>/etc/nginx/fastcgi_php</em> file, write its contents with the customized socket name in each virtual server config.</p>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/web-development/how-to-set-up-nginx-with-php-on-ubuntu/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New server</title>
		<link>http://igorpartola.com/reflection/new-server</link>
		<comments>http://igorpartola.com/reflection/new-server#comments</comments>
		<pubDate>Thu, 25 Feb 2010 14:18:28 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Reflection]]></category>
		<category><![CDATA[disciddb]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=103</guid>
		<description><![CDATA[At the beginning of February I decided to move off my shared hosting and put all my projects to a small VPS. My old hosting provider, HostMonster, has been good to me, but my needs have grown beyond a simple shared plan. The new server is with BuildYourVPS, a TOCICI subsidiary. It is a new [...]]]></description>
			<content:encoded><![CDATA[<p>At the beginning of February I decided to move off my shared hosting and put all my projects to a small VPS. My old hosting provider, <a href="http://www.hostmonster.com/">HostMonster</a>, has been good to me, but my needs have grown beyond a simple shared plan. The new server is with <a href="http://buildyourvps.com/">BuildYourVPS</a>, a <a href="http://www.tocici.com/">TOCICI </a>subsidiary. It is a new and no frills company. There is little documentation and no control panel. On the other hand the support staff is quick to respond, friendly and efficient. With my favorite Debian-based distro, Ubuntu, I feel right at home so the lack of docs doesn&#8217;t bother me. The performance has been more than satisfactory and their prices are very decent.</p>

<p>The goal of this move has been to level out the performance of this blog and <a href="/projects/disciddb">Disc ID DB</a> and to allow more room for expansion. As I keep expanding capabilities of Disc ID DB, Server robustness will become more and more important, so this is a good long term move.</p>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/reflection/new-server/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disc ID DB now supports movies</title>
		<link>http://igorpartola.com/pet-projects/disc-id-db-now-supports-movies</link>
		<comments>http://igorpartola.com/pet-projects/disc-id-db-now-supports-movies#comments</comments>
		<pubDate>Tue, 09 Feb 2010 13:32:29 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Pet Projects]]></category>
		<category><![CDATA[disciddb]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=102</guid>
		<description><![CDATA[Thanks to the Movie DB, my pet project Disc ID DB now supports movies as well as TV shows. I have made several other improvements to the code which should help performance and reliability of the service: Now using prepared statements for database queries Returning more detailed errors Database backups available to the public Stats [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to <a href="http://www.themoviedb.org/">the Movie DB</a>, my pet project <a href="/projects/disciddb">Disc ID DB</a> now supports movies as well as TV shows. I have made several other improvements to the code which should help performance and reliability of the service:</p>

<ul>
	<li>Now using prepared statements for database queries</li>
	<li>Returning more detailed errors</li>
	<li>Database backups available to the public</li>
	<li>Stats page available to the public</li>
</ul>

<p>In addition I have been brewing a client for the database which will allow everyone and anyone to backup their DVD&#8217;s with all the metadata attached. More to come soon.</p>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/pet-projects/disc-id-db-now-supports-movies/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>This does not scale well</title>
		<link>http://igorpartola.com/web-development/this-does-not-scale-well</link>
		<comments>http://igorpartola.com/web-development/this-does-not-scale-well#comments</comments>
		<pubDate>Sun, 20 Dec 2009 04:26:55 +0000</pubDate>
		<dc:creator>Igor</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[daily wtf]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://igorpartola.com/?p=94</guid>
		<description><![CDATA[Here is a piece of code I just found: # new location # creates new record or seeks empty record marked by group_id = -2 if($CGI_DATA['new'] == 'New Location') { # look for empty - abandoned record $SQL = "SELECT * FROM location WHERE group_id = -2"; $result = mysql_query($SQL); if($row = mysql_fetch_array($result)) { $CGI_DATA['location_id'] [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a piece of code I just found:</p>

<pre>  # new location
  # creates new record or seeks empty record marked by group_id = -2
  if($CGI_DATA['new'] == 'New Location') {
    # look for empty - abandoned record
    $SQL  = "SELECT * FROM location WHERE group_id = -2";
    $result = mysql_query($SQL);
    if($row = mysql_fetch_array($result)) {
      $CGI_DATA['location_id'] = $row['location_id'];
    } else {
      $SQL  = "INSERT INTO location SET group_id = '-2',location_bname='New Location',location_roomnum='',
              location_capacity=0,location_address='',location_order=0,location_status='active'";
      $result = mysql_query($SQL);
      $CGI_DATA['location_id'] = mysql_insert_id();
    }
    $CGI_DATA['edit']='New';
  }
</pre>


<p>A little background: this application has a number of groups each of which can specify several locations. What the above code does is it inserts a location with an &#8220;invalid&#8221; (-2) group_id, and then allows you to &#8220;edit&#8221; that record on the next page load. I don&#8217;t know how they thought this was acceptable.</p>]]></content:encoded>
			<wfw:commentRss>http://igorpartola.com/web-development/this-does-not-scale-well/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

