<?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>Robert Roland&#039;s Blog</title>
	<atom:link href="http://robertroland.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://robertroland.org</link>
	<description>code, cooking, cars, cycling...</description>
	<lastBuildDate>Sat, 02 Jul 2011 00:19:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Musings on mobile app development</title>
		<link>http://robertroland.org/2011/07/01/musings-on-mobile-app-development/</link>
		<comments>http://robertroland.org/2011/07/01/musings-on-mobile-app-development/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 00:12:12 +0000</pubDate>
		<dc:creator>Robert Roland</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://robertroland.org/?p=45</guid>
		<description><![CDATA[In May, I submitted my first application to the Apple App Store. It was a really simple application &#8211; it presents a user with a list of silly sound effects and allows you to play them. It has two views &#8211; the sound list, and a browser component to display an &#8220;About&#8221; page. The code [...]]]></description>
			<content:encoded><![CDATA[<p>In May, I submitted my first application to the Apple App Store.  It was a really simple application &#8211; it presents a user with a list of silly sound effects and allows you to play them.  It has two views &#8211; the sound list, and a browser component to display an &#8220;About&#8221; page.  The code for the application was relatively painless to create, once I got the hang of release / retain in Objective-C.  The pain came later &#8211; figuring out which parts of the API I used that did not work on iOS 3.x, development and deployment certificates, submitting updates and the waiting.  All told, this took me about four days of development and testing.</p>
<p>Today, I submitted a &#8220;port&#8221; of the same application to the Windows Phone 7 Marketplace.  I hesitate to use the term &#8220;port&#8221; for this though &#8211; it was a rewrite of the application.  The only thing that remained common was the sound effect files themselves.  The development here only took me about 4 hours.  Contrast that to four days with the iOS version.  To be fair, I spent a few hours finding the audio files the first time around, so the comparison really is the 3 1/2 days of development on the iOS version.</p>
<p>Comparing and contrasting both development environments:</p>
<p><strong><span style="line-height: normal;">iOS / Xcode 4</span></strong></p>
<p><span style="line-height: normal;">Pros:</span></p>
<ul>
<li><span style="line-height: normal;">Large, established developer community.  Lots and lots of examples on the Internet.</span></li>
<li><span style="line-height: normal;">More users = larger potential market.  This has a negative side too &#8211; see the cons below.</span></li>
<li><span style="line-height: normal;">UNIX tools at your disposal, built into the OS.  There are some command line tools that are just invaluable. (sed, awk, grep anyone?)</span></li>
<li><span style="line-height: normal;">Full memory management at your disposal.  If you&#8217;re trying to do something that you want to track memory usage explicitly, those tools are there.  This is a double-edged sword, though.</span></li>
</ul>
<p><span style="line-height: normal;">Cons:</span></p>
<ul>
<li><span style="line-height: normal;">Xcode 4 is just odd.  It uses a &#8220;browser&#8221; metaphor to code editing.  I kept closing the entire project instead of the source file I was editing.  Tabbed editing is there, but doesn&#8217;t work like you&#8217;d expect a text editor to work.  This made switching files complicated and mouse-heavy.</span></li>
<li><span style="line-height: normal;">Harder to get noticed in the App Store.  There are so many applications that marketing is even more important.</span></li>
<li><span style="line-height: normal;">It took a few days to get approved as a developer to even submit my app.</span></li>
<li><span style="line-height: normal;">Trying to remember when to [release] or [retain] an object was tricky and led to strange errors in the app.  Widgets would display but not function, the application would crash, etc.</span></li>
<li><span style="line-height: normal;">I crashed Xcode several times when I refactored parts of the application.  Lesson 1: do NOT rename your project within Xcode!</span></li>
<li><span style="line-height: normal;">Random mixing of C/C++ calling conventions and Objective-C message passing.  Not everything is an object.  Some will also argue that this is a feature.</span></li>
</ul>
<p><strong>Windows Phone 7 / Visual Studio 2010 SP1</strong></p>
<p>Pros:</p>
<ul>
<li>More traditional IDE.  Visual Studio has editor tabs and seems more keyboard-friendly.  This just mostly just an Apple / Microsoft difference in ideology though.</li>
<li>Visual Studio&#8217;s debugger is phenomenal.</li>
<li>Less applications = easier to get noticed in the Marketplace.</li>
<li>MSDN is an awesome resource.  I&#8217;ve done a lot of Microsoft development over the years, so I&#8217;m just used to navigating it and finding documentation there.  (Others will dispute this point, I&#8217;m sure.  This is just a preference of mine.)</li>
<li>Project layout tracks the file system well.  Folders within your solution are truly folders on the file system as opposed to pointers in the project file.</li>
<li>Approval to the Marketplace and developer program took about an hour.</li>
<li>C#&#8217;s memory model.  If you&#8217;ve been working in garbage collected languages for a long time, it just feels natural to you.</li>
<li>XAML is just cool.  It&#8217;s nice to see your UI in one view, with design data bound to it, and the code that generates it side-by-side.  This lets you get into the advanced parts of the UI design easily.  I&#8217;m sure Expression Blend will be handy if I ever try to get creative with the UI.</li>
</ul>
<p>Cons:</p>
<ul>
<li>Less users.  The potential market for your application is simply smaller.</li>
<li>Using Zune software to connect your phone.  This made the MediaElement component of my application not work while connected via USB.  Zune would lock the media library, so the sound files could not be found.  Had to disconnect the USB cable to test audio playback.  This meant I couldn&#8217;t use the amazing debugger during that testing.</li>
<li>Windows Phone is a little more limited than iOS (multitasking, database support) &#8211; this reduces what your application can do.  To be fair, this has been resolved in the SDK, and in a few months, users will get these benefits in the Mango update.</li>
</ul>
<p>Ultimately, both environments are good and bad.  It&#8217;s unfortunate that the only real reusable parts of an application are the resources (images, icons, sounds.)  This makes sense in some ways &#8211; Apple users expect a certain look and feel towards the application to fit in the rest of the ecosystem, and Microsoft users are no different.</p>
<p>I will probably continue to do development in both environments &#8211; after all, the point here is to have users want to buy your applications, regardless of the device.</p>
]]></content:encoded>
			<wfw:commentRss>http://robertroland.org/2011/07/01/musings-on-mobile-app-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Active Directory support in Django</title>
		<link>http://robertroland.org/2011/04/26/active-directory-support-in-django/</link>
		<comments>http://robertroland.org/2011/04/26/active-directory-support-in-django/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 17:47:37 +0000</pubDate>
		<dc:creator>Robert Roland</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[active directory]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[ldap]]></category>

		<guid isPermaLink="false">http://robertroland.org/?p=27</guid>
		<description><![CDATA[As part of an app I&#8217;m working on now, we need to authenticate our users against the corporate Active Directory LDAP server. This was pretty painless in Django, with the help of django-auth-ldap Make sure you install the dependencies &#8211; in my case, I did this: 12easy_install python-ldap==2.3.13 easy_install django-auth-ldap==1.0.9 Next up, modify your settings.py [...]]]></description>
			<content:encoded><![CDATA[<p>As part of an app I&#8217;m working on now, we need to authenticate our users against the corporate Active Directory LDAP server.  This was pretty painless in Django, with the help of <a href="http://pypi.python.org/pypi/django-auth-ldap/">django-auth-ldap</a></p>
<p>Make sure you install the dependencies &#8211; in my case, I did this:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">easy_install python-ldap==2.3.13<br />
easy_install django-auth-ldap==1.0.9</div></td></tr></tbody></table></div>
<p>Next up, modify your settings.py accordingly:</p>
<div class="codecolorer-container python blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> ldap<br />
<span style="color: #ff7700;font-weight:bold;">from</span> django_auth_ldap.<span style="color: black;">config</span> <span style="color: #ff7700;font-weight:bold;">import</span> LDAPSearch<br />
<br />
<span style="color: #808080; font-style: italic;"># makes sure this works in Active Directory</span><br />
ldap.<span style="color: black;">set_option</span><span style="color: black;">&#40;</span>ldap.<span style="color: black;">OPT_REFERRALS</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><br />
<br />
AUTH_LDAP_SERVER_URI <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'ldap://yourLdapServerHere:389/'</span><br />
AUTH_LDAP_BIND_DN <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'yourLogin'</span><br />
AUTH_LDAP_BIND_PASSWORD <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'yourPassword'</span><br />
AUTH_LDAP_USER_SEARCH <span style="color: #66cc66;">=</span> LDAPSearch<span style="color: black;">&#40;</span><span style="color: #483d8b;">'dc=yourdomain,dc=com'</span><span style="color: #66cc66;">,</span> ldap.<span style="color: black;">SCOPE_SUBTREE</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'(SAMAccountName=%(user)s)'</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Populate the Django user from the LDAP directory.</span><br />
AUTH_LDAP_USER_ATTR_MAP <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;first_name&quot;</span>: <span style="color: #483d8b;">&quot;givenName&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;last_name&quot;</span>: <span style="color: #483d8b;">&quot;sn&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;email&quot;</span>: <span style="color: #483d8b;">&quot;mail&quot;</span><br />
<span style="color: black;">&#125;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># This is the default, but I like to be explicit.</span><br />
AUTH_LDAP_ALWAYS_UPDATE_USER <span style="color: #66cc66;">=</span> <span style="color: #008000;">True</span><br />
<br />
AUTHENTICATION_BACKENDS <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'django_auth_ldap.backend.LDAPBackend'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'django.contrib.auth.backends.ModelBackend'</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>I highly recommend you use SSL though, which changes your connect string to ldaps.</p>
<p>You still need to create a &#8220;superuser&#8221; when you do your syncdb.  In my case, the username was the same as my Active Directory login and password.  On your first login, it will fill in your first name, last name and email address in the database properly.</p>
<p>Initially, I had some trouble getting this to work because I was using &#8216;(uid=%(user)s)&#8217; as my filter.  In Active Directory, the user&#8217;s login field is called SAMAccountName.  Turning on django-auth-ldap logging was very useful here.</p>
<div class="codecolorer-container python blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">LOGGING <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'version'</span>: <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'disable_existing_loggers'</span>: <span style="color: #008000;">False</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'formatters'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'verbose'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'format'</span>: <span style="color: #483d8b;">'%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'simple'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'format'</span>: <span style="color: #483d8b;">'%(levelname)s %(message)s'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'handlers'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'null'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'level'</span>:<span style="color: #483d8b;">'DEBUG'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'class'</span>:<span style="color: #483d8b;">'django.utils.log.NullHandler'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'console'</span>:<span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'level'</span>:<span style="color: #483d8b;">'DEBUG'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'class'</span>:<span style="color: #483d8b;">'logging.StreamHandler'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'formatter'</span>: <span style="color: #483d8b;">'verbose'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'mail_admins'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'level'</span>: <span style="color: #483d8b;">'ERROR'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'class'</span>: <span style="color: #483d8b;">'django.utils.log.AdminEmailHandler'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: #483d8b;">'loggers'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'django_auth_ldap'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'handlers'</span>:<span style="color: black;">&#91;</span><span style="color: #483d8b;">'console'</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'propagate'</span>: <span style="color: #008000;">True</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'level'</span>:<span style="color: #483d8b;">'DEBUG'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'django'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'handlers'</span>:<span style="color: black;">&#91;</span><span style="color: #483d8b;">'console'</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'propagate'</span>: <span style="color: #008000;">True</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'level'</span>:<span style="color: #483d8b;">'INFO'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'django.request'</span>: <span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'handlers'</span>: <span style="color: black;">&#91;</span><span style="color: #483d8b;">'mail_admins'</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'level'</span>: <span style="color: #483d8b;">'ERROR'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'propagate'</span>: <span style="color: #008000;">True</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: black;">&#125;</span><br />
<span style="color: black;">&#125;</span></div></td></tr></tbody></table></div>
<p>Look for more details as we further integrate authentication / authorization into our app.</p>
]]></content:encoded>
			<wfw:commentRss>http://robertroland.org/2011/04/26/active-directory-support-in-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using a sequence without a trigger in Django</title>
		<link>http://robertroland.org/2011/04/14/using-a-sequence-without-a-trigger-in-django/</link>
		<comments>http://robertroland.org/2011/04/14/using-a-sequence-without-a-trigger-in-django/#comments</comments>
		<pubDate>Fri, 15 Apr 2011 01:13:15 +0000</pubDate>
		<dc:creator>Robert Roland</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[sequence]]></category>

		<guid isPermaLink="false">http://robertroland.org/?p=20</guid>
		<description><![CDATA[I ran into an issue today where I was attempting to use a sequence for the primary key on a table, but the DBA team preferred that we didn&#8217;t use a trigger to retrieve the value set. This happened to be in Oracle 10g, but it doesn&#8217;t stop you from using this technique in another [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into an issue today where I was attempting to use a sequence for the primary key on a table, but the DBA team preferred that we didn&#8217;t use a trigger to retrieve the value set.  This happened to be in Oracle 10g, but it doesn&#8217;t stop you from using this technique in another database that uses sequences.</p>
<p>We stumbled upon <a title="Fetch Oracle Sequence when Saving Django Model" href="http://drumcoder.co.uk/blog/2010/aug/24/fetch-oracle-sequence-when-saving-django-model/" target="_blank">this helpful link</a>, but it seemed out of date and had some hardcoded values that didn&#8217;t mesh well with our schema.</p>
<p>The modified version now looks like this:</p>
<div class="codecolorer-container python blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># utility helpers for Oracle so we don't need to </span><br />
<span style="color: #808080; font-style: italic;"># use a trigger when a sequence is used</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span> <span style="color: #ff7700;font-weight:bold;">import</span> connections<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> populate_serial_if_blank<span style="color: black;">&#40;</span>model_object<span style="color: #66cc66;">,</span> sequence_name<span style="color: #66cc66;">,</span> id_attr<span style="color: #66cc66;">,</span> database_name<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;&quot;&quot;<br />
&nbsp; &nbsp; Look to see if this object has a valid id.&nbsp; If it does not, select from the sequence<br />
&nbsp; &nbsp; to get the next value, then populate the id field.<br />
&nbsp; &nbsp; &quot;&quot;&quot;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>model_object<span style="color: #66cc66;">,</span> id_attr<span style="color: black;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #008000;">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; cursor <span style="color: #66cc66;">=</span> connections<span style="color: black;">&#91;</span>database_name<span style="color: black;">&#93;</span>.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; sql <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;SELECT %s.nextval FROM dual&quot;</span> % sequence_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>sql<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; rows <span style="color: #66cc66;">=</span> cursor.<span style="color: black;">fetchall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span>model_object<span style="color: #66cc66;">,</span> id_attr<span style="color: #66cc66;">,</span> rows<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cursor.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Within my model class, I override the save() method to use this:</p>
<div class="codecolorer-container python blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">class</span> MyModel<span style="color: black;">&#40;</span>models.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; model_id <span style="color: #66cc66;">=</span> models.<span style="color: black;">AutoField</span><span style="color: black;">&#40;</span>primary_key<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; foo <span style="color: #66cc66;">=</span> models.<span style="color: black;">CharField</span><span style="color: black;">&#40;</span>max_length<span style="color: #66cc66;">=</span><span style="color: #ff4500;">100</span><span style="color: #66cc66;">,</span> null<span style="color: #66cc66;">=</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">class</span> Meta:<br />
&nbsp; &nbsp; &nbsp; &nbsp; db_table <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'my_table'</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__unicode__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">foo</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> save<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&quot;&quot;&quot;Get next value from the database sequence&quot;&quot;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; populate_serial_if_blank<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> sequence_name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'seq_my_table'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;database_name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'my_database'</span><span style="color: #66cc66;">,</span> id_attr<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'model_id'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>MyModel<span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">save</span><span style="color: black;">&#40;</span>*args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>You can use &#8216;default&#8217; as your database_name parameter if you are not using multiple databases in your Django project.</p>
]]></content:encoded>
			<wfw:commentRss>http://robertroland.org/2011/04/14/using-a-sequence-without-a-trigger-in-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I&#8217;m switching to Django&#8230;</title>
		<link>http://robertroland.org/2011/04/09/why-im-switching-to-django/</link>
		<comments>http://robertroland.org/2011/04/09/why-im-switching-to-django/#comments</comments>
		<pubDate>Sat, 09 Apr 2011 20:57:24 +0000</pubDate>
		<dc:creator>Robert Roland</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://robertroland.org/?p=14</guid>
		<description><![CDATA[A few years ago, I gave a talk at work aimed at standardizing our internal tool platform on Python. This talk was mostly well received, but there was some debate on the web framework to use. Everyone at my employer is definitely capable of using any framework, from low-level to high-level frameworks. Most of our [...]]]></description>
			<content:encoded><![CDATA[<p>A few years ago, I gave a talk at work aimed at standardizing our  internal tool platform on Python. This talk was mostly well received,  but there was some debate on the web framework to use. Everyone at my  employer is definitely capable of using any framework, from low-level to  high-level frameworks. Most of our development now is in Java, using  Spring MVC and a Java implementation of Zope Page Templates for a  templating engine.</p>
<p>While researching Python web frameworks, I briefly looked at Django,  TurboGears and Pylons. I ruled out Django and TurboGears because I made a  false assumption that high-level frameworks would be too limiting for  our needs. Turns out I had greatly overestimated our “needs.” I reasoned  that a lower-level framework like Pylons would be better suited for how  we were used to developing web-based applications. I noticed that, over  time, we spent an inordinate amount of time reinventing the wheel. How  many authentication and authorization frameworks do you really need? The  first time you write one, it can be considered interesting. By the 5th  time, you’re wondering why you keep doing this.</p>
<p>Last year, I started a small hobby project at home. It’s never gotten  very far, because I kept experimenting with different languages and  frameworks. I even signed up for a VPS at GoDaddy, which I’m not even  using. While this was a fun learning experience, here I am, a year  later, no closer to complete with the project than I started.</p>
<p>Back to the drawing board, I decided to take another look at Django. IDE and tooling support has really changed. (Side note, <a title="PyCharm" href="http://www.jetbrains.com/pycharm/">PyCharm</a> is really a great IDE.) Django’s documentation really is top-notch,  it’s development and user community is active and thriving, and it’s  simply a wonderful framework. In a short amount of time, I feel like  I’ve actually made progress on my project. I’m using the Django-nonrel  branch with the goal of deploying against Google App Engine by the end  of the summer.</p>
<p>Now, at my day job, we’re making a custom content management system  for powering one of our sites. There was a lot of talk about using an  off-the-shelf product, but by the time we customize it and build modules  to meet our needs, we’re no better off than writing an entirely custom  solution. We also wouldn’t be serving content directly out of the CMS,  so the “buy vs. build” decision was even easier. As soon as I mentioned  using Django for development here, several other developers in the room  got even more excited about starting this project.</p>
]]></content:encoded>
			<wfw:commentRss>http://robertroland.org/2011/04/09/why-im-switching-to-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bacon and Onion Frittata</title>
		<link>http://robertroland.org/2010/11/28/bacon-and-onion-frittata/</link>
		<comments>http://robertroland.org/2010/11/28/bacon-and-onion-frittata/#comments</comments>
		<pubDate>Sun, 28 Nov 2010 19:21:31 +0000</pubDate>
		<dc:creator>Robert Roland</dc:creator>
				<category><![CDATA[cooking]]></category>
		<category><![CDATA[bacon]]></category>
		<category><![CDATA[cheese]]></category>
		<category><![CDATA[eggs]]></category>
		<category><![CDATA[frittata]]></category>
		<category><![CDATA[onion]]></category>

		<guid isPermaLink="false">http://robertroland.org/2010/11/28/bacon-and-onion-frittata/</guid>
		<description><![CDATA[6 eggs 1/2 cup half-and-half 1/2 onion, diced 4 strips of good, smoked bacon, cut into lardon shapes 1/2 cup of shredded cheese salt and pepper to taste Preheat the oven to 400 degrees.&#160; Heat a medium sized, oven-safe skillet over medium-high heat.&#160; Cook the bacon, but you don’t want it too crispy.&#160; Remove the [...]]]></description>
			<content:encoded><![CDATA[<p>6 eggs   <br />1/2 cup half-and-half    <br />1/2 onion, diced    <br />4 strips of good, smoked bacon, cut into lardon shapes    <br />1/2 cup of shredded cheese    <br />salt and pepper to taste</p>
<p>Preheat the oven to 400 degrees.&#160; Heat a medium sized, oven-safe skillet over medium-high heat.&#160; </p>
<p>Cook the bacon, but you don’t want it too crispy.&#160; Remove the bacon and drain the excess fat.&#160; Cook the onion until translucent, and slightly brown.&#160; Remove the onion.</p>
<p>Whisk the six eggs and half-and-half together.&#160; Whisk briskly – you want to get some air into the eggs – they should be frothy.</p>
<p>Add the eggs, onion and bacon to the skillet.&#160; Fold the eggs frequently until the bottom is just set.&#160; Cover with the shredded cheese.&#160; Bake in the oven for 10 minutes, until the edges are golden brown and the cheese is melted.</p>
<p>Cut, and serve!</p>
<hr />
<p>When I made this, I used a pesto gouda cheese.&#160; It melted well, and added a nice herb flavor to the frittata.&#160; Any good melting cheese would work – my other favorite would be a gruyere.</p>
]]></content:encoded>
			<wfw:commentRss>http://robertroland.org/2010/11/28/bacon-and-onion-frittata/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Homemade BBQ sauce</title>
		<link>http://robertroland.org/2010/09/06/homemade-bbq-sauce/</link>
		<comments>http://robertroland.org/2010/09/06/homemade-bbq-sauce/#comments</comments>
		<pubDate>Mon, 06 Sep 2010 19:13:56 +0000</pubDate>
		<dc:creator>Robert Roland</dc:creator>
				<category><![CDATA[cooking]]></category>
		<category><![CDATA[bbq]]></category>

		<guid isPermaLink="false">http://robertroland.org/?p=7</guid>
		<description><![CDATA[Copyright © 2010 Robert Roland 1 cup ketchup 2/3 cup apple cider vinegar 1/2 cup brown sugar 2 1/2 tsp paprika 1 tsp cayenne pepper (more to taste, if you like a little heat) 1/4 tsp cumin 2 tbsp ground mustard 2 1/2 tbsp garlic powder 1 diced onion salt and pepper to taste Combine [...]]]></description>
			<content:encoded><![CDATA[<p>Copyright © 2010 Robert Roland</p>
<p>1 cup ketchup    <br />2/3 cup apple cider vinegar     <br />1/2 cup brown sugar     <br />2 1/2 tsp paprika     <br />1 tsp cayenne pepper (more to taste, if you like a little heat)     <br />1/4 tsp cumin     <br />2 tbsp ground mustard     <br />2 1/2 tbsp garlic powder     <br />1 diced onion     <br />salt and pepper to taste</p>
<p>Combine ketchup, vinegar, paprika, brown sugar, cayenne pepper, cumin, ground mustard, garlic powder in a large mixing bowl.&#160; Whisk together until lumps are removed.&#160; Add salt and pepper to taste.&#160; Add diced onion.&#160; The mixture will seem gritty, but texture will change as it cooks.</p>
<p>This recipe was originally intended for use in a slow cooker (I was making BBQ pulled pork).&#160; If you&#8217;d like to use it in other cooking, you can combine all ingredients inside a medium saucepan and heat on medium high heat, stirring, until all ingredients combine.</p>
]]></content:encoded>
			<wfw:commentRss>http://robertroland.org/2010/09/06/homemade-bbq-sauce/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Are development and operations a partnership in your organization?</title>
		<link>http://robertroland.org/2010/06/24/are-development-and-operations-a-partnership-in-your-organization/</link>
		<comments>http://robertroland.org/2010/06/24/are-development-and-operations-a-partnership-in-your-organization/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 07:12:44 +0000</pubDate>
		<dc:creator>Robert Roland</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[operations]]></category>

		<guid isPermaLink="false">http://robertroland.org/?p=5</guid>
		<description><![CDATA[I&#8217;m sitting at my gate at LAX waiting to board my flight to San Jose for the O&#8217;Reilly Velocity 2010 conference, the annual web performance conference. My employer, Shopzilla, Inc. is a sponsor of the event this year.  While sitting here, I started thinking about the importance of development and operations and their collaboration. I&#8217;m looking [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>I&#8217;m sitting at my gate at LAX waiting to board my flight to San Jose for the O&#8217;Reilly Velocity 2010 conference, the annual web performance conference. My employer, <a href="http://about.shopzilla.com">Shopzilla, Inc.</a> is a sponsor of the event this year.  While sitting here, I started thinking about the importance of development and operations and their collaboration.</p>
<p>I&#8217;m looking forward to great sessions on both web performance and some operations talks this year. As engineers, it&#8217;s important for us to understand both the code and the operational aspects of the designs we propose and implement. Without this basic knowledge, when outages occur (and they will!), you will be ill-prepared to assist your operations teams in recovering from the outage. You cannot adequate plan disaster recovery, nor can you plan for scalability without basic operational knowledge of the systems you rely on.</p>
<p>Basically, walk a mile in your operations teams shoes, see how they fit, and see what sort of systems you&#8217;re building that they have to help support and deploy. This will change your perspective on design greatly, it will make you a better engineer, and it will benefit your organization.</p>
<p>At Shopzilla, engineers such as myself regularly work directly with our configuration management, network operations and systems operations teams. Without this direct engagement and collaboration, software releases, outages, and our general software development lifecycle would be quite costly.</p>
<p>One line of the <a href="http://agilemanifesto.org">Agile Manifesto</a> really encompasses this idea for me:</p>
<p>[we have come to value] Individuals and interactions over processes and tools</p>
<p>See you at Velocity!</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://robertroland.org/2010/06/24/are-development-and-operations-a-partnership-in-your-organization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
