<?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>Joe Lennon &#187; Tutorials</title>
	<atom:link href="http://www.joelennon.ie/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.joelennon.ie</link>
	<description>Rants, Raves &#38; Recommendations</description>
	<lastBuildDate>Wed, 28 Sep 2011 15:27:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Using Pydev for Google App Engine development on a Mac</title>
		<link>http://www.joelennon.ie/2011/03/25/using-pydev-for-google-app-engine-development-on-a-mac/</link>
		<comments>http://www.joelennon.ie/2011/03/25/using-pydev-for-google-app-engine-development-on-a-mac/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 13:25:57 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[aptana]]></category>
		<category><![CDATA[aptana studio 3.0]]></category>
		<category><![CDATA[aptana studio 3.0 beta]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[django_0_96]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[pydev]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.joelennon.ie/?p=623</guid>
		<description><![CDATA[I&#8217;ve been experimenting with Google App Engine a bit recently and although it&#8217;s not without its problems, it fits really well with a couple of small projects I&#8217;m working on at the moment. Up until now, I&#8217;ve been mainly working with TextMate and the Google App Engine launcher, which is fine, but hardly an ideal [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been experimenting with Google App Engine a bit recently and although it&#8217;s not without its problems, it fits really well with a couple of small projects I&#8217;m working on at the moment. Up until now, I&#8217;ve been mainly working with TextMate and the Google App Engine launcher, which is fine, but hardly an ideal development environment. That&#8217;s where Aptana Pydev comes in.</p>
<p>Pydev is an Eclipse/Aptana plugin for developing Python applications. It has great support for Django and other Python frameworks, and is a great all-round Python development tool. The feature that caught my eye the most was built-in support for Google App Engine development, but I ran into a few problems when I tried to get up and running with it on my Mac. In this post, I will walk through how I got it all working in the end.</p>
<p>There are several options for downloading Pydev. Eclipse developers can download it as a plugin, or if you don&#8217;t use Eclipse, Pydev comes bundled in Aptana Studio (an Eclipse-based IDE that is geared towards Web development). In this post I will cover the Aptana method, but it should be simple to extract the relevant parts if you are going down the plugin path.</p>
<p>Head to the <a title="http://aptana.org/products/studio3/download" href="http://aptana.org/products/studio3/download" target="_blank">Aptana Studio 3 download page</a> (product in beta at time of writing) and download the disk image to your Mac. When you mount this image and open it, you should see a Finder window like the one in Figure 1.</p>
<div id="attachment_625" class="wp-caption alignnone" style="width: 690px"><img class="size-full wp-image-625 " title="Figure 1. Aptana Studio disk image" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.00.23.png" alt="Figure 1. Aptana Studio disk image" width="680" height="746" /><p class="wp-caption-text">Figure 1. Aptana Studio disk image</p></div>
<p>Follow the simple instructions and drag the Aptana Studio 3 folder into the Applications directory shortcut. This will install Aptana in your Applications directory. You will see the files being copied from the image as shown in Figure 2.</p>
<div id="attachment_626" class="wp-caption alignnone" style="width: 489px"><img class="size-full wp-image-626 " title="Figure 2. Copying files" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.02.41.png" alt="Figure 2. Copying files" width="479" height="170" /><p class="wp-caption-text">Figure 2. Copying files</p></div>
<p>When this is completed, you can open the Aptana Studio 3 folder in your Applications directory and launch Aptana by opening the AptanaStudio3.app file, as seen in Figure 3.</p>
<div id="attachment_627" class="wp-caption alignnone" style="width: 630px"><img class="size-full wp-image-627 " title="Figure 3. Finding AptanaStudio3.app" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.04.17.png" alt="Figure 3. Finding AptanaStudio3.app" width="620" height="550" /><p class="wp-caption-text">Figure 3. Finding AptanaStudio3.app</p></div>
<p>When you first launch Aptana Studio, you will see a blank workspace, as shown in Figure 4.</p>
<div id="attachment_630" class="wp-caption alignnone" style="width: 655px"><img class="size-large wp-image-630    " title="Figure 4. Blank Aptana Studio Workspace" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.14.43-1024x816.png" alt="Figure 4. Blank Aptana Studio Workspace" width="645" height="514" /><p class="wp-caption-text">Figure 4. Blank Aptana Studio Workspace</p></div>
<p>Now it&#8217;s time for the fun stuff. First, you need to create a new project. Press <strong>[Cmd] + N</strong> to open the New Project wizard. In the list of Wizards, you should see a folder named &#8220;Pydev&#8221;. Expand this folder and you will find an option &#8220;Pydev Google App Engine Project&#8221;, as shown in Figure 5.</p>
<div id="attachment_634" class="wp-caption alignnone" style="width: 615px"><img class="size-full wp-image-634" title="Figure 5. New Project Wizard" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.20.15.png" alt="Figure 5. New Project Wizard" width="605" height="586" /><p class="wp-caption-text">Figure 5. New Project Wizard</p></div>
<p>Make sure you&#8217;ve selected the correct option, and hit the <strong>Next &gt;</strong> button to continue. On the next screen, you will need to enter details about the project, including the name of the project, the type of project (Python, Jython or Iron Python), the grammar version to use and the interpreter. Before you fill out this form, you&#8217;ll notice that there&#8217;s a link &#8220;Please configure an interpreter&#8221; in the related preferences before proceeding. This is shown in Figure 6.</p>
<div id="attachment_635" class="wp-caption alignnone" style="width: 615px"><img class="size-full wp-image-635" title="Figure 6. PyDev Project Wizard" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.22.57.png" alt="Figure 6. PyDev Project Wizard" width="605" height="627" /><p class="wp-caption-text">Figure 6. PyDev Project Wizard</p></div>
<p>Click on this link and the main Aptana Preferences window will open, and you will be brought straight to the &#8220;Interpreter &#8211; Python&#8221; page of the Pydev preferences section. On the right-hand-side, there&#8217;s a list (currently empty) of Python interpreters, with two enabled buttons to the right of the list, <strong>New</strong> and <strong>Auto Config</strong>, as can be seen in Figure 7.</p>
<p><em><strong>Warning: Don&#8217;t use Auto Config, on my system it found Python 2.6, and for Google App Engine development you&#8217;ll want to use Python 2.5.</strong></em></p>
<div id="attachment_636" class="wp-caption alignnone" style="width: 653px"><img class="size-full wp-image-636  " title="Figure 7. PyDev Python Interpreter Preferences" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.26.22.png" alt="Figure 7. PyDev Python Interpreter Preferences" width="643" height="534" /><p class="wp-caption-text">Figure 7. PyDev Python Interpreter Preferences</p></div>
<p>Click the &#8220;New&#8221; button and Aptana will open the Select interpreter dialog. Enter the following values into the relevant fields:</p>
<ul>
<li>Interpreter Name: Python 2.5</li>
<li>Interpreter Executable: /System/Library/Frameworks/Python.framework/Versions/2.5/bin/python2.5</li>
</ul>
<p>If you prefer, browse to the location of the executable and select it. The dialog should look like Figure 8.</p>
<div id="attachment_637" class="wp-caption alignnone" style="width: 642px"><img class="size-full wp-image-637" title="Figure 8. Select interpretor" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.30.39.png" alt="Figure 8. Select interpretor" width="632" height="303" /><p class="wp-caption-text">Figure 8. Select interpretor</p></div>
<p>Press the <strong>OK</strong> button to add this interpreter. Aptana will do some preparation, and before long you&#8217;ll be presented with another dialog that needs your attention. This one looks like the screen grab in Figure 9.</p>
<div id="attachment_638" class="wp-caption alignnone" style="width: 681px"><img class="size-full wp-image-638" title="Figure 9. Adding folders to the SYSTEM pythonpath" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.32.23.png" alt="Figure 9. Adding folders to the SYSTEM pythonpath" width="671" height="567" /><p class="wp-caption-text">Figure 9. Adding folders to the SYSTEM pythonpath</p></div>
<p>In my case I simply accepted the default selections and pressed <strong>OK</strong>, but if you need to, you can select the other options. When you press <strong>OK</strong>, you should be back in the Aptana Preferences window, which should now look more like Figure 10.</p>
<div id="attachment_639" class="wp-caption alignnone" style="width: 653px"><img class="size-full wp-image-639  " title="Figure 10. Updated PyDev Preferences" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.34.58.png" alt="Figure 10. Updated PyDev Preferences" width="643" height="534" /><p class="wp-caption-text">Figure 10. Updated PyDev Preferences</p></div>
<p>You can now close this screen by pressing <strong>OK</strong> in the bottom right of the window. After you do this, Aptana will go off and do some work, and you&#8217;ll see a window like the one shown in Figure 11. This might take a minute or two to complete so be patient.</p>
<div id="attachment_640" class="wp-caption alignnone" style="width: 606px"><img class="size-full wp-image-640" title="Figure 12. Aptana background work" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.36.25.png" alt="Figure 12. Aptana background work" width="596" height="256" /><p class="wp-caption-text">Figure 12. Aptana background work</p></div>
<p>When this progress window closes, you&#8217;ll be back at the Pydev Project setup screen. Enter whatever project name you like, I&#8217;ve called mine &#8220;game-planner&#8221; which is the same as the application ID for my Google App Engine application. Make sure &#8220;Python&#8221; is selected as the Project Type, and change the Grammar Version to 2.5. If you only set up the Python 2.5 interpreter, you can leave the Intepreter set to &#8220;Default&#8221;, or alternatively you can change this to &#8220;Python 2.5&#8243; if you are unsure. The completed project screen should look something like Figure 13.</p>
<div id="attachment_641" class="wp-caption alignnone" style="width: 615px"><img class="size-full wp-image-641" title="Figure 13. Project dialog, filled out" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.41.26.png" alt="Figure 13. Project dialog, filled out" width="605" height="627" /><p class="wp-caption-text">Figure 13. Project dialog, filled out</p></div>
<p>Press the <strong>Next &gt;</strong> button to move on to the next step of the Project Wizard. This step asks you to select the Google App Engine Directory. It is shown in Figure 14.</p>
<div id="attachment_642" class="wp-caption alignnone" style="width: 615px"><img class="size-full wp-image-642" title="Figure 14. Google App Engine Directory" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.48.40.png" alt="Figure 14. Google App Engine Directory" width="605" height="627" /><p class="wp-caption-text">Figure 14. Google App Engine Directory</p></div>
<p>You can use the <strong>Browse</strong> button, but unless you downloaded the zip archive of the App Engine Python SDK, you will not be able to find the directory in Finder. This is because the SDK package that comes in the form of the &#8220;Google App Engine Launcher&#8221; is wrapped up in a .app archive, which can&#8217;t be explored in Finder. See Figure 15 for an example of this.</p>
<div id="attachment_643" class="wp-caption alignnone" style="width: 627px"><img class="size-full wp-image-643" title="Figure 15. Cannot browse GoogleAppEngineLauncher.app" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.50.06.png" alt="Figure 15. Cannot browse GoogleAppEngineLauncher.app" width="617" height="480" /><p class="wp-caption-text">Figure 15. Cannot browse GoogleAppEngineLauncher.app</p></div>
<p>The location it is looking for is the location where the Google App Engine files <strong>dev_appserver.py</strong>, <strong>appcfg.py</strong>, the <strong>lib</strong> directory and so on are located. If you are using the launcher version of the SDK, this is usually in the following location:</p>
<pre style="width: 620px; overflow: auto;">/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine</pre>
<p>&nbsp;</p>
<p>If you paste this into the Google App Engine Directory field, however, you&#8217;ll notice that it results in an error. This error is shown in Figure 16.</p>
<div id="attachment_652" class="wp-caption alignnone" style="width: 615px"><img class="size-full wp-image-652" title="Figure 16. Error finding django lib directory" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-12.57.27.png" alt="Figure 16. Error finding django lib directory" width="605" height="627" /><p class="wp-caption-text">Figure 16. Error finding django lib directory</p></div>
<p>The reason for this error is relatively straightforward &#8211; Google App Engine doesn&#8217;t have a directory named django at that path. Apparently this issue will be fixed in the next release of Pydev. However, as seen in Figure 17, there are two other directories that are very similar, django_0_96 and django_1_2.</p>
<div id="attachment_653" class="wp-caption alignnone" style="width: 622px"><img class="size-full wp-image-653  " title="Figure 17. django directories that are available" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-13.00.48.png" alt="Figure 17. django directories that are available" width="612" height="373" /><p class="wp-caption-text">Figure 17. django directories that are available</p></div>
<p>To solve the problem, we can simply create a symbolic link named django, which will point to the django_0_96 directory. To do this, open Terminal (Applications &gt; Utilities &gt; Terminal) and issue the following commands:</p>
<pre style="width: 620px; overflow: auto;">$ cd /Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/
$ ln -s django_0_96 django</pre>
<p>&nbsp;</p>
<p>If you issue the <strong>ls</strong> command after doing this, you should see that there is now what looks like a <strong>django</strong> directory. This is a soft link to the <strong>django_0_96</strong> directory, and if any changes are made in <strong>django_0_96</strong>, they will automatically be reflected in the <strong>django</strong> directory. Sample Terminal output is shown in Figure 18.</p>
<div id="attachment_655" class="wp-caption alignnone" style="width: 654px"><img class="size-full wp-image-655 " title="Figure 18. Mac OS X Terminal Output" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-13.09.47.png" alt="Figure 18. Mac OS X Terminal Output" width="644" height="424" /><p class="wp-caption-text">Figure 18. Mac OS X Terminal Output</p></div>
<p>Next, go back to Aptana and enter the directory path again (cut it and re-paste it back) to refresh the wizard. This time, you should see a much friendlier result, like the one shown in Figure 19.</p>
<div id="attachment_656" class="wp-caption alignnone" style="width: 615px"><img class="size-full wp-image-656" title="Figure 19. No errors this time around" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-13.12.23.png" alt="Figure 19. No errors this time around" width="605" height="627" /><p class="wp-caption-text">Figure 19. No errors this time around</p></div>
<p>Click <strong>Finish</strong> and the project will be created. You might be asked to switch to the Pydev perspective, as shown in Figure 20. It&#8217;s up to you whether you do this, I personally checked the <strong>Remember my decision</strong> field and pressed the <strong>Yes</strong> button.</p>
<div id="attachment_657" class="wp-caption alignnone" style="width: 606px"><img class="size-full wp-image-657" title="Figure 20. Pydev Perspective" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-13.15.03.png" alt="Figure 20. Pydev Perspective" width="596" height="237" /><p class="wp-caption-text">Figure 20. Pydev Perspective</p></div>
<p>You should now be in your Pydev Google App Engine project. From here you can create, run and debug your Google App Engine applications. The default Pydev workspace is shown in Figure 21.</p>
<div id="attachment_658" class="wp-caption alignnone" style="width: 624px"><img class="size-large wp-image-658 " title="Figure 21. Pydev Eclipse Perspective" src="http://www.joelennon.ie/wp-content/uploads/2011/03/Screen-shot-2011-03-25-at-13.18.55-1024x816.png" alt="Figure 21. Pydev Eclipse Perspective" width="614" height="490" /><p class="wp-caption-text">Figure 21. Pydev Eclipse Perspective</p></div>
<p>If you have any questions about this post, or have comments, suggestions or improvements, please leave a comment. Thanks for reading!</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2011/03/25/using-pydev-for-google-app-engine-development-on-a-mac/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Basics of HTML5 Local Storage</title>
		<link>http://www.joelennon.ie/2011/02/11/basics-of-html5-local-storage/</link>
		<comments>http://www.joelennon.ie/2011/02/11/basics-of-html5-local-storage/#comments</comments>
		<pubDate>Fri, 11 Feb 2011 12:37:29 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[local storage]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://www.joelennon.ie/?p=582</guid>
		<description><![CDATA[This post is designed to be a no-frills introduction to using HTML5 local storage. It assumes that you are using the latest version of Mozilla Firefox and the Firebug plug-in. 1. Checking for browser support Open the Firebug console and enter the following command: 'localStorage' in window; You should see the following output: &#62;&#62;&#62; 'localStorage' [...]]]></description>
			<content:encoded><![CDATA[<p>This post is designed to be a no-frills introduction to using HTML5 local storage. It assumes that you are using the latest version of Mozilla Firefox and the Firebug plug-in.</p>
<h2>1. Checking for browser support</h2>
<p>Open the Firebug console and enter the following command:</p>
<p><code>'localStorage' in window;</code></p>
<p>You should see the following output:</p>
<p><code>&gt;&gt;&gt; 'localStorage' in window;<br />
true</code></p>
<h2>2. Storing data</h2>
<p>HTML5 local storage stores data in named key/value pairs. The key must be a String, and the value can be any JavaScript data type, although it will be stored as a String. To store data, you use localStorage.setItem:</p>
<p><code>localStorage.setItem("name", "Joe");</code></p>
<p>Alternatively, you can use the square bracket syntax to store data:</p>
<p><code>localStorage["age"] = 25;</code></p>
<p>Or, you can use dot notation if you prefer:</p>
<p><code>localStorage.location = "Ireland";</code></p>
<p>If the key you use already exists, the existing key/value pair will be overwritten without warning.</p>
<h2>3. Retrieving data</h2>
<p>To retrieve data you can use getItem:</p>
<p><code>localStorage.getItem("name");</code></p>
<p>Output:</p>
<p><code>&gt;&gt;&gt; localStorage.getItem("name");<br />
"Joe"</code></p>
<p>Alternatively, you can also use square bracket syntax:</p>
<p><code>localStorage["age"];</code></p>
<p>Output:</p>
<p><code>&gt;&gt;&gt; localStorage["age"];<br />
"25"</code></p>
<p>Or, you can use dot notation:</p>
<p><code>localStorage.location;</code></p>
<p>Output:<br />
<code>&gt;&gt;&gt; localStorage.location;<br />
"Ireland"</code></p>
<h2>4. Removing data</h2>
<p>There are two ways to remove data in local storage. Firstly, you can delete a single key:</p>
<p><code>localStorage.removeItem("age");</code></p>
<p>Alternatively, you can clear all local storage data as follows:</p>
<p><code>localStorage.clear();</code></p>
<h2>5. Finding data</h2>
<p>You can get the number of key/value pairs stored in local storage using the length property:</p>
<p><code>localStorage.length;</code></p>
<p>To get the name of a key at a particular index, you can use the key method:</p>
<p><code>localStorage.key(0);</code></p>
<p>You can combine the two to iterate over the local storage data as follows:</p>
<p><code> </code></p>
<p><code></p>
<pre>for(var i=0, len=localStorage.length; i&lt;len; i++) {
    var key = localStorage.key(i);
    var value = localStorage[key];
    console.log(key + " =&gt; " + value);
}</pre>
<p></code></p>
<h2>6. Events</h2>
<p>You can keep track of changes to local storage using event handling. The &#8220;storage&#8221; event is fired any time data changes in local storage. This event is fired by the window object. For example (Note: this won&#8217;t work in IE):</p>
<p><code> </code></p>
<p><code></p>
<pre>window.addEventListener("storage", function(e) {
    console.log("Local storage was modified");
}, false);</pre>
<p></code></p>
<p>The above will log a message to the Firebug console any time that the local storage data is modified (when adding, removing or replacing keys, clearing a non-empty storage, etc). At the time of writing, Firefox 3.6 did not include support for the storage event object properties key, oldValue, newValue and url.</p>
<h2>7. Summary</h2>
<p>So there you have it, a quick introduction to using HTML local storage. If you have any questions, leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2011/02/11/basics-of-html5-local-storage/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Flex and JavaScript</title>
		<link>http://www.joelennon.ie/2010/11/26/flex-and-javascript/</link>
		<comments>http://www.joelennon.ie/2010/11/26/flex-and-javascript/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 16:39:09 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[communication]]></category>
		<category><![CDATA[flash builder]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[interface]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[messaging]]></category>
		<category><![CDATA[mxml]]></category>

		<guid isPermaLink="false">http://www.joelennon.ie/?p=535</guid>
		<description><![CDATA[In this post, I show you how to create a basic application that will allow you to send messages from JavaScript to Flex and vice-versa using Flash Builder 4.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently working on a Web application project that is primarily coded in JavaScript. As part of the project however, I needed to use a Flex component for part of the application. I would also need a series of components (search boxes, trees and grids) to interact with this component. At first, it seemed to make sense to do all of this in Flex. However, when it comes to client-side development, we&#8217;re primarily a JavaScript shop, and would prefer to keep the amount of Flex we write to a minimum. Also, from a styling perspective, our existing JavaScript components would fit in better with our overall application, so it made much more sense for us to use them rather than Flex&#8217;s trees, grids and so on. Of course, this raised a problem &#8211; how do we communicate between JavaScript and Flex?</p>
<p>Fortunately, this is actually very straightforward. To prove the concept, I decided to write up a basic application that would allow you to pass messages between Flex and JavaScript components and output them on the screen. Here is a screenshot of this application in action (click for a larger image):</p>
<div id="attachment_536" class="wp-caption alignnone" style="width: 310px"><a href="http://www.joelennon.ie/wp-content/uploads/2010/11/Application.png"><img class="size-medium wp-image-536 " title="Sample Project in action" src="http://www.joelennon.ie/wp-content/uploads/2010/11/Application-300x119.png" alt="Sample Project in action" width="300" height="119" /></a><p class="wp-caption-text">Sample Project in action</p></div>
<p>So on the left hand side of the application, there is a standard HTML input field, button element and a read-only textarea element. The input field will allow the user to write a message to be passed to the Flex application, which gets sent when the user clicks the &#8220;Send to Flex&#8221; button. The textarea field will be updated with any messages that are sent to JavaScript by Flex. On the right-hand-side, you have the same thing, but this time it will allow you to enter a message to send to JavaScript from Flex, and has an area where messages sent by JavaScript to Flex will be shown.</p>
<p>Let&#8217;s walk through how I did this. It&#8217;s worth pointing out at this point that I used Flash Builder 4 and the Flex 4 SDK to create this application. If you have a different setup, you may need to change your code to suit your version.</p>
<p>In Flash Builder, create a new Flex Project, and call it <strong>TestJSFlex</strong>. Let&#8217;s start off with the Flex application interface. You can use the Design view if you wish, but for a simple application like this, it&#8217;s fairly straightforward to create everything in code. Just before the closing <code>&lt;/s:Application&gt;</code> tag in your source code, add the following three lines of code:</p>
<pre>
&lt;s:TextInput x="2" y="2" width="310" id="flexInput"/&gt;
&lt;s:Button x="320" y="3" width="100" label="Send to JS" /&gt;
&lt;s:TextArea x="2" y="32" width="416" height="200" id="flexMessages" editable="false"/&gt;
</pre>
<p>While you&#8217;re at it, add the following attributes to your opening <code>&lt;s:Application&gt;</code> element: </p>
<pre>
width="440" height="255"
</pre>
<p>That&#8217;s our Flex application user interface done. Pretty simple, huh? Next, let&#8217;s change the HTML template that Flash Builder produces to add some basic HTML elements for the JavaScript side of our application to use. In &#8220;Package Explorer&#8221; (usually at the top left hand side of Flash Builder), your project folder should contain a few subfolders: <em>src</em>, <em>Flex 4.0</em>, <em>bin-debug</em>, <em>html-template</em> and <em>libs</em>. Expand the <strong>html-template</strong> folder and you should see a file named <strong>index.template.html</strong>. Right-click this file, and from the context menu select &#8220;Open With -&gt; Text Editor&#8221;. The file should now open in a new editor tab in the main part of the IDE. In this file, locate the following section of HTML code:</p>
<pre>
&lt;div id="flashContent"&gt;
    &lt;p&gt;
        To view this page ensure that Adobe Flash Player version
        ${version_major}.${version_minor}.${version_revision} or greater is installed.
    &lt;/p&gt;
    &lt;script type="text/javascript"&gt;
        var pageHost = ((document.location.protocol == "https:") ? "https://" :Â "http://");
        document.write("&lt;a href='http://www.adobe.com/go/getflashplayer'&gt;&lt;img src='"
              + pageHost + "www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' /&gt;&lt;/a&gt;" );
    &lt;/script&gt;
&lt;/div&gt;
</pre>
<p>This is basically the element where the Flex application will appear on the HTML page. We&#8217;re going to wrap it in a <code>&lt;div&gt;</code> container and add a section before it with a HTML form:</p>
<pre>
&lt;div id="container"&gt;
    &lt;h1&gt;Flex and JavaScript&lt;/h1&gt;
    &lt;div class="section"&gt;
        &lt;h2&gt;JavaScript:&lt;/h2&gt;
        &lt;input type="text" id="js_value" /&gt;
        &lt;input type="button" id="js_button" value="Send to Flex" /&gt;
        &lt;br /&gt;
        &lt;textarea id="js_messages" readonly&gt;&lt;/textarea&gt;
    &lt;/div&gt;
    &lt;div class="section clearfix"&gt;
        &lt;h2&gt;Flex:&lt;/h2&gt;
        &lt;div id="flashContent"&gt;
            &lt;p&gt;
                To view this page ensure that Adobe Flash Player version
                ${version_major}.${version_minor}.${version_revision} or greater is installed.
            &lt;/p&gt;
            &lt;script type="text/javascript"&gt;
                var pageHost = ((document.location.protocol == "https:") ? "https://" :Â Â Â  "http://");
                document.write("&lt;a href='http://www.adobe.com/go/getflashplayer'&gt;&lt;img src='"
                     + pageHost + "www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' /&gt;&lt;/a&gt;" );
           &lt;/script&gt;
       &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>In the code above, we have added a few HTML form elements: a text field with the ID <strong>js_value</strong>, a button with the ID <strong>js_button</strong> and a read-only textarea with the ID <strong>js_messages</strong>. To make the whole thing look right, we&#8217;re going to add some CSS properties which will define the layout and size of the elements. In <strong>index.template.html</strong>, locate the CSS section of the code near the top of the file, which by default should contain:</p>
<pre>
&lt;style type="text/css" media="screen"&gt;
    html, bodyÂ { height:100%; }
    body { margin:0; padding:0; overflow:auto; text-align:center; background-color: ${bgcolor}; }
    #container { width: 900px; margin: 0px auto; text-align: left; }
    #flashContent { display:none; }
&lt;/style&gt;
</pre>
<p>Modify this so that it contains:</p>
<pre>
&lt;style type="text/css" media="screen"&gt;
    html, bodyÂ { height:100%; }
    body { margin:0; padding:0; overflow:auto; text-align:center; background-color: ${bgcolor}; }
    #container { width: 900px; margin: 0px auto; text-align: left; }
    #flashContent { display:none; }
    h1, h2 { font-family: Helvetica, Arial, sans-serif; }
    h2 { margin-top: 0px; }
    .section { width: 450px; float: left; }
    .clearfix:after {
        content: ".";
        display: block;
        height: 0;
        clear: both;
        visibility: hidden;
    }
    #js_value { width: 310px; }
    #js_button { width: 100px; }
    #js_messages { width: 416px; height: 195px; margin-top: 8px; }
&lt;/style&gt;
</pre>
<p>The CSS properties should be fairly self-explanatory. Basically, we have a container div 900 pixels wide, with two 450px sections inside it that appear side by side (using the <code>float</code> property), with a clearfix put in place so everything looks right in older browsers (just a note &#8211; I haven&#8217;t checked if this looks OK in anything other than Firefox 3.6, so don&#8217;t flame me if it doesn&#8217;t). Finally, we add some widths and heights to the form fields so they match up nicely with the Flex components.</p>
<p>That&#8217;s the UI section of the application taken care of. Next, let&#8217;s actually make Flex and JavaScript talk to each other. First, let&#8217;s get Flex talking to JavaScript. In the <strong>TestJSFlex.mxml</strong> file, just above where you entered the <code>&lt;s:TextInput&gt;</code> and other components a while back, add the following code:</p>
<pre>
&lt;fx:Script&gt;
    &lt;![CDATA[
        public function sendToJS():void {
            ExternalInterface.call("receiveFromFlex", flexInput.text);
        }
    ]]&gt;
&lt;/fx:Script&gt;
</pre>
<p>This script block simply defines a single function named <strong><code>sendToJS</code></strong>. This function uses the <code>ExternalInterface.call</code> function to call a JavaScript function. The first parameter here is the name of the JavaScript function you want to call, in our case <strong><code>receiveFromFlex</code></strong>, and this is followed by any parameters you want to pass to JavaScript. Here, we have simply passed the current value of the <code>text</code> property of our text box with the id <strong>flexInput</strong>. Next, find the following line of code near the bottom of <strong>TestJSFlex.mxml</strong>:</p>
<pre>
&lt;s:Button x="320" y="3" width="100" label="Send to JS" /&gt;
</pre>
<p>Let&#8217;s add a click event handler to this button, which will call the <code>sendToJS</code> function any time a user presses the button:</p>
<pre>
&lt;s:Button x="320" y="3" width="100" label="Send to JS" click="sendToJS()" /&gt;
</pre>
<p>That&#8217;s everything that we need to do on the Flex side to call a JavaScript function. Of course, this is pretty much useless unless we actually declare the JavaScript function it is trying to call, so let&#8217;s hop over to <strong>index.template.html</strong> and create that now. Just before the closing <code>&lt;/head&gt;</code> tag in this file, add the following code:</p>
<pre>
&lt;script type="text/javascript"&gt;
    function receiveFromFlex(str) {
        var msgs = document.getElementById("js_messages");
        msgs.value += 'Flex says: '+str+'\n';
    }
&lt;/script&gt;
</pre>
<p>This function simply accepts a string value as a parameter, and appends it (followed by a new line) to the element with the ID <strong>js_messages</strong> (the textarea element). Save all your files and run the application by pressing the green Play/Run button in the Flash Builder toolbar. At this point, you should be able to enter a message in the input box on the right hand side (the Flex side) and hit &#8220;Send to JS&#8221;. This message should then appear on the left hand side. That was pretty easy, huh? Ok, now all that&#8217;s left for us to do is implement the reverse scenario &#8211; sending messages from JavaScript to Flex.</p>
<p>In the previous section, you created a <code>&lt;script&gt;</code> block in the <strong>index.template.html</strong> file. Inside this block, just below the <code>receiveFromFlex</code> function, add the following code:</p>
<pre>
function sendToFlex() {
    var flexApp = document.getElementById("${application}");
    flexApp.sendToFlex(document.getElementById("js_value").value);
}

window.onload = function() {
    var btn = document.getElementById("js_button");
    btn.onclick = sendToFlex;
}
</pre>
<p>The first function, <strong><code>sendToFlex</code></strong>, gets a handle to the Flex application object using <code>document.getElementById</code>. You&#8217;ll notice that the <code>${application}</code> template variable is used. This is recommended so that if you change the name of your Flex application, you won&#8217;t need to change the value in your template file. The function then calls the <code>sendToFlex</code> function in the Flex application object. Finally, we attach this function as an event handler to the HTML button element with the ID <strong>js_button</strong>. That&#8217;s it on the JavaScript side of things. Save <strong>index.template.html</strong> and jump back to <strong>TestJSFlex.mxml</strong>. Now, let&#8217;s add the code necessary to handle this on the Flex side of things. Inside the <code>&lt;fx:Script&gt;</code> block, below the <strong>sendToJS</strong> function, add the following two functions:</p>
<pre>
public function initApp():void {
    ExternalInterface.addCallback("sendToFlex", receiveFromJS);
}

public function receiveFromJS(str:String):void {
    flexMessages.text += 'JS says: '+str+'\n';
}
</pre>
<p>The first function, <strong><code>initApp</code></strong>, uses the <code>ExternalInterface.addCallback</code> function to map a JavaScript function to a Flex function. Here, we tell the <code>sendToFlex</code> JavaScript function callback to execute the Flex function named <strong><code>receiveFromJS</code></strong>. This function accepts a <code>String</code> parameter and appends it to the <code>&lt;s:TextArea&gt;</code> element followed by a newline. The final piece of the puzzle is to wire up the <code>initApp</code> function to be called when the Flex application has finished loading. In your <code>&lt;s:Application&gt;</code> element, add the attribute </p>
<pre>
creationComplete="initApp()"
</pre>
<p>and you&#8217;re done! You can now run the application and enter messages in the HTML input field, which will appear in the Flex message box when you hit &#8220;Send to Flex&#8221;. Easy as pie! For reference purposes, here are the full listings for the two source files we&#8217;ve worked with in this post.</p>
<h3>TestJSFlex.mxml:</h3>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
           xmlns:s="library://ns.adobe.com/flex/spark"
           xmlns:mx="library://ns.adobe.com/flex/mx" width="440" height="255"
           creationComplete="initApp()"&gt;
    &lt;fx:Declarations&gt;
        &lt;!-- Place non-visual elements (e.g., services, value objects) here --&gt;
    &lt;/fx:Declarations&gt;
    &lt;fx:Script&gt;
        &lt;![CDATA[
            public function sendToJS():void {
                ExternalInterface.call("receiveFromFlex", flexInput.text);
            }

            public function initApp():void {
                ExternalInterface.addCallback("sendToFlex", receiveFromJS);
            }

            public function receiveFromJS(str:String):void {
                flexMessages.text += 'JS says: '+str+'\n';
            }
        ]]&gt;
    &lt;/fx:Script&gt;
    &lt;s:TextInput x="2" y="2" width="310" id="flexInput"/&gt;
    &lt;s:Button x="320" y="3" width="100" label="Send to JS" click="sendToJS()" /&gt;
    &lt;s:TextArea x="2" y="32" width="416" height="200" id="flexMessages" editable="false"/&gt;
&lt;/s:Application&gt;
</pre>
<h3>index.template.html:</h3>
<pre>
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;!-- saved from url=(0014)about:internet --&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"&gt;
    &lt;!--
    Smart developers always View Source.

    This application was built using Adobe Flex, an open source framework
    for building rich Internet applications that get delivered via the
    Flash Player or to desktops via Adobe AIR.

    Learn more about Flex at http://flex.org
    // --&gt;
    &lt;head&gt;
        &lt;title&gt;${title}&lt;/title&gt;
        &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
        &lt;!-- Include CSS to eliminate any default margins/padding and set the height of the html element and
             the body element to 100%, because Firefox, or any Gecko based browser, interprets percentage as
             the percentage of the height of its parent container, which has to be set explicitly.Â  Initially,
             don't display flashContent div so it won't show if JavaScript disabled.
        --&gt;
        &lt;style type="text/css" media="screen"&gt;
            html, bodyÂ { height:100%; }
            body { margin:0; padding:0; overflow:auto; text-align:center; background-color: ${bgcolor}; }
            #container { width: 900px; margin: 0px auto; text-align: left; }
            #flashContent { display:none; }
            h1, h2 { font-family: Helvetica, Arial, sans-serif; }
            h2 { margin-top: 0px; }
            .section { width: 450px; float: left; }
            .clearfix:after {
                content: ".";
                display: block;
                height: 0;
                clear: both;
                visibility: hidden;
            }
            #js_value { width: 310px; }
            #js_button { width: 100px; }
            #js_messages { width: 416px; height: 195px; margin-top: 8px; }
        &lt;/style&gt;

        &lt;!-- Enable Browser History by replacing useBrowserHistory tokens with two hyphens --&gt;
        &lt;!-- BEGIN Browser History required section ${useBrowserHistory}&gt;
        &lt;link rel="stylesheet" type="text/css" href="history/history.css" /&gt;
        &lt;script type="text/javascript" src="history/history.js"&gt;&lt;/script&gt;
        &lt;!${useBrowserHistory} END Browser History required section --&gt;

        &lt;script type="text/javascript" src="swfobject.js"&gt;&lt;/script&gt;
        &lt;script type="text/javascript"&gt;
            &lt;!-- For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection. --&gt;
            var swfVersionStr = "${version_major}.${version_minor}.${version_revision}";
            &lt;!-- To use express install, set to playerProductInstall.swf, otherwise the empty string. --&gt;
            var xiSwfUrlStr = "${expressInstallSwf}";
            var flashvars = {};
            var params = {};
            params.quality = "high";
            params.bgcolor = "${bgcolor}";
            params.allowscriptaccess = "sameDomain";
            params.allowfullscreen = "true";
            var attributes = {};
            attributes.id = "${application}";
            attributes.name = "${application}";
            attributes.align = "middle";
            swfobject.embedSWF(
                "${swf}.swf", "flashContent",
                "${width}", "${height}",
                swfVersionStr, xiSwfUrlStr,
                flashvars, params, attributes);
            &lt;!-- JavaScript enabled so display the flashContent div in case it is not replaced with a swf object. --&gt;
            swfobject.createCSS("#flashContent", "display:block;text-align:left;");
        &lt;/script&gt;

        &lt;script type="text/javascript"&gt;
            function receiveFromFlex(str) {
                var msgs = document.getElementById("js_messages");
                msgs.value += 'Flex says: '+str+'\n';
            }

            function sendToFlex() {
                var flexApp = document.getElementById("${application}");
                flexApp.sendToFlex(document.getElementById("js_value").value);
            }

            window.onload = function() {
                var btn = document.getElementById("js_button");
                btn.onclick = sendToFlex;
            }
        &lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;!-- SWFObject's dynamic embed method replaces this alternative HTML content with Flash content when enough
              JavaScript and Flash plug-in support is available. The div is initially hidden so that it doesn't show
              when JavaScript is disabled.
        --&gt;
        &lt;div id="container"&gt;
            &lt;h1&gt;Flex and JavaScript&lt;/h1&gt;
            &lt;div class="section"&gt;
                &lt;h2&gt;JavaScript:&lt;/h2&gt;
                &lt;input type="text" id="js_value" /&gt;
                &lt;input type="button" id="js_button" value="Send to Flex" /&gt;
                &lt;br /&gt;
                &lt;textarea id="js_messages" readonly&gt;&lt;/textarea&gt;
            &lt;/div&gt;
            &lt;div class="section clearfix"&gt;
                &lt;h2&gt;Flex:&lt;/h2&gt;
                &lt;div id="flashContent"&gt;
                    &lt;p&gt;
                        To view this page ensure that Adobe Flash Player version
                        ${version_major}.${version_minor}.${version_revision} or greater is installed.
                    &lt;/p&gt;
                    &lt;script type="text/javascript"&gt;
                        var pageHost = ((document.location.protocol == "https:") ? "https://" :Â Â Â  "http://");
                        document.write("&lt;a href='http://www.adobe.com/go/getflashplayer'&gt;&lt;img src='"
                                + pageHost + "www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' /&gt;&lt;/a&gt;" );
                    &lt;/script&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;

        &lt;noscript&gt;
            &lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="${width}" height="${height}" id="${application}"&gt;
                &lt;param name="movie" value="${swf}.swf" /&gt;
                &lt;param name="quality" value="high" /&gt;
                &lt;param name="bgcolor" value="${bgcolor}" /&gt;
                &lt;param name="allowScriptAccess" value="sameDomain" /&gt;
                &lt;param name="allowFullScreen" value="true" /&gt;
                &lt;!--[if !IE]&gt;--&gt;
                &lt;object type="application/x-shockwave-flash" data="${swf}.swf" width="${width}" height="${height}"&gt;
                    &lt;param name="quality" value="high" /&gt;
                    &lt;param name="bgcolor" value="${bgcolor}" /&gt;
                    &lt;param name="allowScriptAccess" value="sameDomain" /&gt;
                    &lt;param name="allowFullScreen" value="true" /&gt;
                &lt;!--&lt;![endif]--&gt;
                &lt;!--[if gte IE 6]&gt;--&gt;
                    &lt;p&gt;
                        Either scripts and active content are not permitted to run or Adobe Flash Player version
                        ${version_major}.${version_minor}.${version_revision} or greater is not installed.
                    &lt;/p&gt;
                &lt;!--&lt;![endif]--&gt;
                    &lt;a href="http://www.adobe.com/go/getflashplayer"&gt;
                        &lt;img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash Player" /&gt;
                    &lt;/a&gt;
                &lt;!--[if !IE]&gt;--&gt;
                &lt;/object&gt;
                &lt;!--&lt;![endif]--&gt;
            &lt;/object&gt;
        &lt;/noscript&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>If you&#8217;d prefer to just take the sample Flex project, you can download a zip file of it below:</p>
<p><a href="http://www.joelennon.ie/wp-content/uploads/2010/11/TestJSFlex.zip">TestJSFlex.zip (2,286 KB)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2010/11/26/flex-and-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle XE Gateway Debug Mode</title>
		<link>http://www.joelennon.ie/2010/11/16/oracle-xe-gateway-debug-mode/</link>
		<comments>http://www.joelennon.ie/2010/11/16/oracle-xe-gateway-debug-mode/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 18:09:34 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[10g]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[dbms_epg]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[errors]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[plsql]]></category>
		<category><![CDATA[xe]]></category>

		<guid isPermaLink="false">http://www.joelennon.ie/?p=519</guid>
		<description><![CDATA[When developing Web applications using Oracle XE and the embedded PL/SQL gateway, you may find that debugging is a pain due to the lack of log files (like you'd normally find in Apache folders in a full Oracle application server install). Well, the good news is, that you can configure errors to be reported directly in the browser, so that rather than getting very unhelpful 404 and other HTTP error messages, you get a full debug trace of the error that occurred. Full credit for this find goes to Dietmar Aust, who has a great blog on Oracle XE and Application Express. See his original post for even more insight into this.]]></description>
			<content:encoded><![CDATA[<p>When developing Web applications using Oracle XE and the embedded PL/SQL gateway, you may find that debugging is a pain due to the lack of log files (like you&#8217;d normally find in Apache folders in a full Oracle application server install). Well, the good news is, that you can configure errors to be reported directly in the browser, so that rather than getting very unhelpful 404 and other HTTP error messages, you get a full debug trace of the error that occurred. Full credit for this find goes to Dietmar Aust, who has a great blog on Oracle XE and Application Express. See his <a title="Dietmar Aust's original blog post" href="http://daust.blogspot.com/2008/04/troubleshooting-404-not-found-error-on.html" target="_blank">original post</a> for even more insight into this.</p>
<p>To switch on error reporting and the printing of debug messages to the browser, simply issue the following commands. Of course, be sure to replace &#8220;embosa&#8221; on line 3 with your own DAD name. Also, be sure to turn this back off again in a production environment, this should only be used for development and testing purposes.</p>
<pre>
begin
dbms_epg.set_global_attribute('log-level',Â 3);
dbms_epg.set_dad_attribute('embosa',Â 'error-style',Â 'DebugStyle');
end;
/
</pre>
<p>To test, simply go to a URL that doesn&#8217;t exist, and you should see a useful error message instead of a unhelpful &#8220;Not Found&#8221; message. See the screenshot below for an example of what this error message looks like.</p>
<div id="attachment_520" class="wp-caption alignleft" style="width: 510px"><a href="http://www.joelennon.ie/wp-content/uploads/2010/11/Untitled.png"><img class="size-full wp-image-520" title="Useful PL/SQL error message" src="http://www.joelennon.ie/wp-content/uploads/2010/11/Untitled.png" alt="" width="500" height="297" /></a><p class="wp-caption-text">Useful PL/SQL error message</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2010/11/16/oracle-xe-gateway-debug-mode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CouchDB 1.0 on Windows</title>
		<link>http://www.joelennon.ie/2010/07/29/couchdb-1-0-on-windows/</link>
		<comments>http://www.joelennon.ie/2010/07/29/couchdb-1-0-on-windows/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 11:31:49 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[couchdb]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.joelennon.ie/?p=476</guid>
		<description><![CDATA[In case you haven't heard by now, CouchDB 1.0 was released earlier this month. One of the questions I've been asked most about CouchDB is how can one go about installing it on Windows.]]></description>
			<content:encoded><![CDATA[<p>In case you haven&#8217;t heard by now, CouchDB 1.0 was released earlier this month. One of the questions I&#8217;ve been asked most about CouchDB is how can one go about installing it on Windows. Up until recently, there were a few hacked installers available, each of which would install CouchDB and its dependencies, but these far from perfect, with most of CouchDB&#8217;s test suite failing when run under this setup. Thankfully, there is now an official Windows binary available which will have you up and running with CouchDB in no time.</p>
<p><strong>Step 1:</strong> Grab the binary from <a title="Download CouchDB 1.0.0 for Windows" href="http://www.couch.io/get" target="_blank">http://www.couch.io/get</a><br />
<strong>Step 2:</strong> Unzip to your hard drive (I unzipped to C:\ and renamed the extracted folder to couchdb).<br />
<strong>Step 3:</strong> Go into the bin directory and run couchdb.bat. This will launch the Erlang command line and run CouchDB. You should see a DOS window with the message &#8220;CouchDB 1.0.0 &#8211; prepare to relax&#8230;&#8221;.<br />
<strong>Step 4:</strong> Open your browser and point it to <a title="Open Futon" href="http://127.0.0.1:5984/_utils/" target="_blank">http://127.0.0.1:5984/_utils/</a> to launch Futon<br />
<strong>Step 5:</strong> From the navigation bar on the right hand side, click on &#8220;Test Suite&#8221; and at the top of the test suite&#8217;s page, click the &#8220;Run All&#8221; button to start the tests. Leave your browser do its thing (it&#8217;ll lock up while it&#8217;s performing the tests) and all going well, each of 66 tests should return with a success message.<br />
<strong>Step 6:</strong> Click on &#8220;Overview&#8221; at the top right of the browser and start creating CouchDB databases!</p>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2010/07/29/couchdb-1-0-on-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tags in Oracle Nested Tables</title>
		<link>http://www.joelennon.ie/2010/07/13/storing-tags-in-oracle-using-nested-tables/</link>
		<comments>http://www.joelennon.ie/2010/07/13/storing-tags-in-oracle-using-nested-tables/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 14:12:44 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[arrays]]></category>
		<category><![CDATA[nested tables]]></category>
		<category><![CDATA[plsql]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[tags]]></category>

		<guid isPermaLink="false">http://www.joelennon.ie/?p=395</guid>
		<description><![CDATA[Tags are a useful means of associating keyword metadata with a data structure such as an image, a video, audio or a piece of text. There are many ways of storing tags in a database - for example one could store a string of tags separated by a space, comma or semi-colon. Alternatively, one could store tags in a database table and then create another table to hold the list of tags for a given entity. My preferred method of storing tags, in an Oracle database at least, is to use the concept of nested tables.]]></description>
			<content:encoded><![CDATA[<p>Tags are a useful means of associating keyword metadata with a data structure such as an image, a video, audio or a piece of text. There are many ways of storing tags in a database &#8211; for example one could store a string of tags separated by a space, comma or semi-colon. Alternatively, one could store tags in a database table and then create another table to hold the list of tags for a given entity. My preferred method of storing tags, in an Oracle database at least, is to use the concept of nested tables.</p>
<p>Nested tables are a type of PL/SQL collection which may be compared to arrays or objects in other programming languages. One of the advantages of using nested tables over other PL/SQL collection types is that they don&#8217;t have a fixed size, and they can be stored in a database table (not just in a program unit, like regular PL/SQL tables or associative arrays). The best way to show how nested tables work is to use an example, so let&#8217;s dive right in and set up our database for the tags example.</p>
<p>The first thing we want to do is create the nested table type in our database. I&#8217;m going to keep it nice and simple and name my type &#8220;tags&#8221;:</p>
<pre>CREATE TYPE tags IS TABLE OF VARCHAR2(50);</pre>
<p>If you are familiar with PL/SQL tables, the above should look very similar to the syntax for creating a PL/SQL table, but without the typical &#8220;index by binary_integer&#8221; bit stuck at the end. With our type created, we can now go ahead and use this in a database table. I&#8217;m going to create a table named &#8220;post&#8221;, which one might use to store blog posts. This table will have three columns &#8211; post_id, post_title and post_tags.</p>
<pre>
CREATE TABLE post (
    post_idÂ Â Â Â Â Â Â Â Â Â Â  NUMBER(11),
    post_titleÂ Â Â Â Â Â Â   VARCHAR2(50),
    post_tagsÂ Â Â Â Â Â Â    tags
) NESTED TABLE post_tags STORE AS tags_table;
</pre>
<p>Great &#8211; you now have a database table with a column of type &#8220;tags&#8221; which is itself a table. The next thing we want to do is insert some records into our new table.</p>
<pre>
INSERT INTO post(post_id, post_title, post_tags)
VALUES(1, 'First Post', tags('oracle', 'tags', 'example'));

INSERT INTO post(post_id, post_title, post_tags)
VALUES(2, 'Second Post', tags('oracle', 'tags'));

INSERT INTO post(post_id, post_title, post_tags)
VALUES(3, 'Third Post', tags('oracle'));

COMMIT;
</pre>
<p>As you can see from the above INSERT statements, inserting tags into our nested table is very straightforward, we simply tell Oracle that we are using the type &#8220;tags&#8221; and pass the VARCHAR2 values we want to store to it. If you try to insert a tag with over 50 characters you will get an error as we defined the tags table as a table of VARCHAR2(50) fields. So what does our new table look like when we go to retrieve data from it? Let&#8217;s take a look.</p>
<pre>SELECT * FROM post;</pre>
<p>You should see output like the following</p>
<pre>
POST_ID      POST_TITLEÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â    POST_TAGS
------------ ----------------------------------------------------------- ---------
1            First PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  &lt;Object&gt;
2            Second PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  &lt;Object&gt;
3            Third PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  &lt;Object&gt;
</pre>
<p>Hardly ideal is it? Fortunately, we can use the TABLE function to easily get back a list of tags for a given post quite easily. Try the following SQL statement:</p>
<pre>
SELECT column_value
FROM TABLE(
    SELECT post_tags FROM post WHERE post_id = 1
);
</pre>
<p>This outputs the following:</p>
<pre>
COLUMN_VALUE
--------------------------------------------------
oracle
tags
example
</pre>
<p>Try the statement again, but this time pass in the post_id value for another row. This is useful, as it gives us a means of getting the tag data out of the database, but what if we want to get back all the tags when retrieving the other columns in the table? This requires a bit more work, but it&#8217;s not exactly complex:</p>
<pre>
SELECT p.post_id, p.post_title, t.column_value
FROM post p, TABLE(
    SELECT post_tags FROM post WHERE post_id = p.post_id
) t;
</pre>
<p>The above statement should produce the following:</p>
<pre>
POST_ID      POST_TITLEÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  COLUMN_VALUE
------------ ------------------------------------------------------- ---------------
1            First PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  oracle
1            First PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  tags
1            First PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  example
2            Second PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â   oracle
2            Second PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  tags
3            Third PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  Â  oracle
</pre>
<p>A step in the right direction, but the post_id and post_title are duplicated for each tag for that record. Surely there&#8217;s a way of outputting all the tags on a single row, joining them together with a delimiting character such as a comma? There are a number of ways of doing this, from using a stored function to using 11g&#8217;s WITHIN GROUP feature. The method with the least code that works on 9i and above is to use the XMLAGG function to produce the concatenated result. The SQL to achieve the desired result in this manner is as follows:</p>
<pre>
SELECT p.post_id, p.post_title,
    RTRIM(XMLAGG(XMLELEMENT(e, t.column_value || ',')).EXTRACT('//text()'), ',') tags
FROM post p, TABLE(
    SELECT post_tags FROM post WHERE post_id = p.post_id
) t
GROUP BY p.post_id, p.post_title;
</pre>
<p>This produces the following result:</p>
<pre>
POST_ID      POST_TITLEÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  TAGS
------------ ---------------------------------------- -----------------------
1            First PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  oracle,tags,example
2            Second PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  oracle,tags
3            Third PostÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  oracle
</pre>
<p>So far we haven&#8217;t seen any particular reason why one would necessarily use a nested table to store tags over any other method. For me, the primary advantage is that it makes it very simple to perform group functions on the tags &#8211; making it ridiculously easy to generate tag clouds based on how many times a tag is used. In the above example, we can easily see that the tag &#8220;oracle&#8221; is used 3 times, &#8220;tags&#8221; is used twice and &#8220;example&#8221; only once. But in a scenario where you have many posts and many, many tags, it is impossible to do this counting in your head. Let&#8217;s take a look at just how easy it is to do this counting with our nested table.</p>
<pre>
SELECT t.column_value, COUNT(*)
FROM post p, TABLE(
    SELECT post_tags FROM post WHERE post_id = p.post_id
) t
GROUP BY t.column_value;
</pre>
<p>And the output:</p>
<pre>
COLUMN_VALUEÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  COUNT(*)
-------------------------------------------------- ----------
tagsÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  2
exampleÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  1
oracleÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  3
</pre>
<p>Want to order the results? Simply add an ORDER BY clause and Bob&#8217;s your uncle.</p>
<pre>
SELECT t.column_value, COUNT(*)
FROM post p, TABLE(
    SELECT post_tags FROM post WHERE post_id = p.post_id
) t
GROUP BY t.column_value
ORDER BY 2 DESC;
</pre>
<p>The result:</p>
<pre>
COLUMN_VALUEÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  COUNT(*)
-------------------------------------------------- ----------
oracleÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  3
tagsÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  2
exampleÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  1
</pre>
<p>For me, this is the main reason I store tags in a nested table &#8211; but there are other advantages, too. What if you are editing a post and you want to change one of the tags? Nested tables make this simple:</p>
<pre>
UPDATE TABLE(SELECT post_tags FROM post WHERE post_id = 1)
SET column_value = 'sample'
WHERE column_value = 'example'
</pre>
<p>Similarly, if you wanted to delete a tag from a row, this is also very straightforward:</p>
<pre>
DELETE FROM TABLE(
    SELECT post_tags FROM post WHERE post_id = 1
)
WHERE column_value = 'tags';
</pre>
<p>Nested tables are a powerful PL/SQL collection type, and you can do even more powerful things with them if you start using PL/SQL procedures and functions. But the beauty about nested tables for me is how powerful and flexible they are using nothing but raw SQL statements. For further information about nested tables and other PL/SQL collection types, see the following resources:</p>
<ul>
<li><a href="http://www.developer.com/db/article.php/10920_3379271_1/Oracle-Programming-with-PLSQL-Collections.htm" target="_blank">http://www.developer.com/db/article.php/10920_3379271_1/Oracle-Programming-with-PLSQL-Collections.htm</a></li>
<li><a href="http://www.dba-oracle.com/t_display_multiple_column_values_same_rows.htm" target="_blank">http://www.dba-oracle.com/t_display_multiple_column_values_same_rows.htm</a></li>
<li><a href="http://www.devshed.com/c/a/Oracle/Database-Interaction-with-PLSQL-Nested-Tables/" target="_blank">http://www.devshed.com/c/a/Oracle/Database-Interaction-with-PLSQL-Nested-Tables/</a></li>
<li><a href="http://soft.buaa.edu.cn/oracle/bookshelf/Oreilly/prog2/ch19_01.htm" target="_blank">http://soft.buaa.edu.cn/oracle/bookshelf/Oreilly/prog2/ch19_01.htm</a></li>
<li><a href="http://sql-plsql.blogspot.com/2007/05/oracle-plsql-nested-tables.html" target="_blank">http://sql-plsql.blogspot.com/2007/05/oracle-plsql-nested-tables.html</a></li>
<li><a href="http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/05_colls.htm" target="_blank">http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/05_colls.htm</a></li>
<li><a href="# http://www.smart-soft.co.uk/Oracle/oracle-plsql-tutorial-part-9.htm" target="_blank">http://www.smart-soft.co.uk/Oracle/oracle-plsql-tutorial-part-9.htm</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2010/07/13/storing-tags-in-oracle-using-nested-tables/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Oracle XE and mod_plsql</title>
		<link>http://www.joelennon.ie/2010/03/09/oracle-xe-and-mod-plsql/</link>
		<comments>http://www.joelennon.ie/2010/03/09/oracle-xe-and-mod-plsql/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 18:50:32 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[dad]]></category>
		<category><![CDATA[dbms_epg]]></category>
		<category><![CDATA[mod_owa]]></category>
		<category><![CDATA[mod_plsql]]></category>
		<category><![CDATA[Oracle XE]]></category>
		<category><![CDATA[utl_http]]></category>
		<category><![CDATA[web server]]></category>
		<category><![CDATA[xe]]></category>

		<guid isPermaLink="false">http://embosa.wordpress.com/?p=78</guid>
		<description><![CDATA[In this post you will learn how to get a sandboxed PL/SQL web development environment up and running on a Windows machine. You will use the VMware Player virtualization system to run an Ubuntu 9.10 server image, on which you will install Oracle XE. You will then configure a DAD using DBMS_EPG which basically acts in the same way as mod_plsql does in Oracle HTTP Server. This will allow you to create Web applications using PL/SQL. Finally, you will learn how to work with virtual directories so you can store things like images, external stylesheets and external JavaScript files.]]></description>
			<content:encoded><![CDATA[<p>In this post you will learn how to get a sandboxed PL/SQL web development environment up and running on a Windows machine. You will use the VMware Player virtualization system to run an Ubuntu 9.10 server image, on which you will install Oracle XE. You will then configure a DAD using DBMS_EPG which basically acts in the same way as mod_plsql does in Oracle HTTP Server. This will allow you to create Web applications using PL/SQL. Finally, you will learn how to work with virtual directories so you can store things like images, external stylesheets and external JavaScript files.</p>
<p>The first step you need to follow is to download and install the free VMware Player application on your system. This can be downloaded from <a title="Download VMware Player" href="https://www.vmware.com/tryvmware/?p=player&amp;lp=1" target="_blank">https://www.vmware.com/tryvmware/?p=player&amp;lp=1</a>. Once this has downloaded, follow the simple instructions to install VMware Player. This application allows you to run other operating systems that are packaged in virtual machine images. Head over to <a title="Download Ubuntu 9.10 Server VM Image" href="http://www.thoughtpolice.co.uk/vmware/#ubuntu9.10" target="_blank">http://www.thoughtpolice.co.uk/vmware/#ubuntu9.10</a> and download the appropriate image for Ubuntu 9.10 Karmic Koala. When this has finished downloading, extract the files to a convenient location on your file system, and find the file ubuntu-server-9.10-i386.vmx, and double-click it to start the virtual machine.</p>
<p>At this point, VMware Player should open and your Ubuntu VM will launch and boot up. After a few moments, you should see a prompt like the one shown in Figure 1:</p>
<div id="attachment_83" class="wp-caption alignnone" style="width: 590px"><img class="size-full wp-image-83 " title="Figure 1 - Ubuntu Login Prompt" src="http://embosa.files.wordpress.com/2010/03/fig011.png" alt="Figure 1 - Ubuntu Login Prompt" width="580" height="365" /><p class="wp-caption-text">Figure 1 - Ubuntu Login Prompt</p></div>
<p>To login, enter the login <strong>notroot</strong> and the password <strong>thoughtpolice</strong>. You will now be logged in and should see the Ubuntu shell prompt.</p>
<p>By default, the VM image you are using has 905208 bytes of swap space allocated. Unfortunately, this will cause the Oracle XE installer to fail, as its minimum is 1024MB. To prevent this from happening, you first need to assign some more swap space. Use the following commands to bump up the swap space to 1058800 bytes. If you are asked for your [sudo] password for notroot (you will be), enter <strong>thoughtpolice</strong>.</p>
<pre>
$ sudo dd if=/dev/zero of=/tmp/swap bs=1M count=150
$ sudo mkswap /tmp/swap
$ sudo swapon /tmp/swap
$ free
</pre>
<p>If the commands worked correctly, the output from the <strong>free</strong> command should look similar to the results shown in Figure 2 below:</p>
<div id="attachment_86" class="wp-caption alignnone" style="width: 590px"><img class="size-full wp-image-86" title="Figure 2 - Configuring swap space" src="http://embosa.files.wordpress.com/2010/03/fig02.png" alt="Figure 2 - Configuring swap space" width="580" height="365" /><p class="wp-caption-text">Figure 2 - Configuring swap space</p></div>
<p>With the swap space issue resolved, you can now move on to the steps required to download, install and configure Oracle XE. First, you&#8217;ll need to add the Oracle repository to your apt sources list. Issue the following command to open the list in the nano text editor:</p>
<pre>
$ sudo nano /etc/apt/sources.list
</pre>
<p>Navigate to the end of this file (use Ctrl+V to scroll down page by page) and at the bottom add the following line:</p>
<pre>
deb http://oss.oracle.com/debian unstable main non-free
</pre>
<p>Save the file by pressing Ctrl+O, and then exit using Ctrl+X.</p>
<p>Now you can go ahead and download Oracle XE using the following commands:</p>
<pre>
$ wget http://oss.oracle.com/el4/RPM-GPG-KEY-oracle -O- | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install oracle-xe
</pre>
<p>This process may take some time (XE is a 221MB package) and you may need to answer <strong>Y</strong> when asked if you wish to continue.</p>
<blockquote><p><span style="color:#888888;">It&#8217;s worth pointing out that when I ran the above commands, I found that the download would sometimes freeze at a certain point. If this happens to you, press Ctrl+C to force exit the process and then re-issue the command to pick up from where you left off (you can press the up arrow key to quickly bring up the last command you entered).</span></p></blockquote>
<p>When the process has finished, Oracle XE is now installed. Before you can use it, however, you will need to configure it. Issue the following command to start the Oracle Database configuration tool:</p>
<pre>
$ sudo /etc/init.d/oracle-xe configure
</pre>
<p>When asked for a port number for Application Express, accept the default option of <strong>8080</strong> by pressing Enter. Do the same when offered port <strong>1521</strong> for the database listener. Next, enter a system password, and confirm it when requested. Finally, accept the default setting of <strong>y</strong> when asked if you want XE to be started on boot. Oracle will now configure the Net Listener and the Database &#8211; this may take a few minutes. When it is done you should see a message like the one shown in Figure 3.</p>
<div id="attachment_90" class="wp-caption alignnone" style="width: 590px"><img class="size-full wp-image-90" title="Figure 3 - Oracle install complete" src="http://embosa.files.wordpress.com/2010/03/fig03.png" alt="Figure 3 - Oracle install complete" width="580" height="365" /><p class="wp-caption-text">Figure 3 - Oracle install complete</p></div>
<p>The next step you need to follow is to set up the ORACLE_HOME and PATH variables on your system, which will make it easier to run the SQL*Plus client. Create your user .bash_profile file by issuing the following commands:</p>
<pre>
$ cd ~
$ nano .bash_profile
</pre>
<p>In the nano editor, insert the following two lines:</p>
<pre>
export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
export PATH=${PATH}:${ORACLE_HOME}/bin
</pre>
<p>Press Ctrl+O to save and then Ctrl+X to quit nano. Now, log out of Ubuntu using the following command:</p>
<pre>
$ logout
</pre>
<p>You&#8217;ll be returned to the login prompt. Login once again using the username <strong>notroot</strong> and password <strong>thoughtpolice</strong>. Now, issue the following command to start the SQL*Plus client as the SYSTEM user:</p>
<pre>
$ sqlplus system@xe
</pre>
<p>Enter the password you chose when configuring Oracle when requested at the prompt. You should then see a message informing you that you are connected to Oracle. Now that you are logged in to the database, it is a good time to allow remote access to the Oracle XE web server, which runs Apex and which we will be using to run our PL/SQL web applications. To do this, issue the following command:</p>
<pre>
SQL&gt; exec dbms_xdb.setlistenerlocalaccess(false);
</pre>
<p>You should see the message &#8220;The PL/SQL procedure successfully completed.&#8221; before being returned to the SQL prompt. Next, exit SQL*Plus by entering the following command:</p>
<pre>
SQL&gt; exit
</pre>
<p>You will now be back at the Ubuntu shell prompt. The next thing you&#8217;ll need to doÂ  is determine the IP address of your virtual machine. To do this, use the command:</p>
<pre>
$ ifconfig
</pre>
<p>You should see output similar to the one shown below. You need to look for the entry for <strong>eth0</strong>, specifically for the value next to <strong>inet addr:</strong> &#8211; in my case it is 192.168.133.131, as shown in the screenshot in Figure 4.</p>
<div id="attachment_91" class="wp-caption alignnone" style="width: 590px"><img class="size-full wp-image-91" title="Figure 4 - VM IP address" src="http://embosa.files.wordpress.com/2010/03/fig04.png" alt="Figure 4 - VM IP address" width="580" height="365" /><p class="wp-caption-text">Figure 4 - VM IP address</p></div>
<p>Now, back in Windows, fire up your favourite Web browser and enter the following address into the Address box, replacing my IP address with the one for your virtual machine:</p>
<p>http://192.168.133.131:8080/apex</p>
<p>You should see a screen like the one shown in Figure 5.</p>
<div id="attachment_92" class="wp-caption alignnone" style="width: 590px"><img class="size-full wp-image-92" title="Figure 5 - Oracle Application Express Home Page" src="http://embosa.files.wordpress.com/2010/03/fig05.png" alt="Figure 5 - Oracle Application Express Home Page" width="580" height="466" /><p class="wp-caption-text">Figure 5 - Oracle Application Express Home Page</p></div>
<p>This interface is actually very useful, so let&#8217;s login and create a new database user, which you will later use as the schema for your PL/SQL web application. Enter the username SYSTEM and the password you entered during the Oracle configuration. From the next screen, click the arrow next to the Administration icon, and from the Database Users menu, select &#8220;Create User&#8221;. This will bring you to a form where you can enter the details for the new database user. Enter the username <strong>embosa</strong> and whatever password you like (for the sake of simplicity it would be wise to use the same password as you chose for the SYSTEM user &#8211; of course you would never do this on a production system!). Make sure that the roles <strong>CONNECT</strong>, <strong>RESOURCE</strong> and <strong>DBA</strong> are all checked, and press the &#8220;Create&#8221; button at the top right hand side of the form to create the user.</p>
<p>Next, hop back to your Ubuntu VM and enter the following command to login to Oracle using your new user:</p>
<pre>
$ sqlplus embosa@xe
</pre>
<p>Enter the password when asked, and hey presto, you&#8217;re logged in as the user embosa! Now, let&#8217;s go about creating a DAD so that we can publish HTML using PL/SQL. The following block of code will create, authorize and configure a DAD named embosa which will be accessible at the URL http://192.168.133.131:8080/embosa (again, replace the IP address with your own VM&#8217;s IP).</p>
<pre>
begin
dbms_epg.create_dad(dad_name=&gt;'embosa', path=&gt;'/embosa/*');
dbms_epg.authorize_dad(dad_name=&gt;'embosa', user=&gt;'EMBOSA');
dbms_epg.set_dad_attribute(dad_name=&gt;'embosa', attr_name=&gt;'default-page', attr_value=&gt;'home');
dbms_epg.set_dad_attribute(dad_name=&gt;'embosa', attr_name=&gt;'database-username', attr_value=&gt;'EMBOSA');
end;
/
</pre>
<p>This will create the DAD, next you need to create the &#8220;default page&#8221; by creating a procedure named home. To do so, use the following:</p>
<pre>
create or replace procedure home as
begin
htp.p('Hello, world!');
end home;
/
</pre>
<p>Now, hop back over to Windows and in your Web browser, navigate to the URL http://192.168.133.131:8080/embosa, replacing the IP address accordingly. You should see something like that shown in Figure 6.</p>
<div id="attachment_93" class="wp-caption alignnone" style="width: 590px"><img class="size-full wp-image-93" title="Figure 6 - A basic PL/SQL Web Application" src="http://embosa.files.wordpress.com/2010/03/fig06.png" alt="Figure 6 - A basic PL/SQL Web Application" width="580" height="474" /><p class="wp-caption-text">Figure 6 - A basic PL/SQL Web Application</p></div>
<p>The final piece of configuration to do is to configure a virtual directory where you can store images, external styles and scripts and so on. Back in your Ubuntu VM, you should still be logged into SQL*Plus. In here, run the following command to open port 2100 for FTP connections:</p>
<pre>
SQL&gt; exec dbms_xdb.setftpport('2100');
</pre>
<p>Now, enter <strong>exit</strong> to leave SQL*Plus, and create a test text file by issuing the following command:</p>
<pre>
$ echo testing! &gt; test.txt
</pre>
<p>Next enter the command <strong>ftp</strong> to open the FTP client. At the ftp prompt, issue the following commands (you will be prompted for your username and password, these are your <strong>database</strong> username and password, so if you followed the instructions above your username will be <strong>embosa</strong>):</p>
<pre>
ftp&gt; open localhost 2100
ftp&gt; ls
ftp&gt; mkdir images
ftp&gt; cd images
ftp&gt; send test.txt
</pre>
<p>Now, go back to your web browser, and this time enter the URL http://192.168.133.131:8080/images/test.txt (again, change the IP as required) -Â  you should see the message &#8220;testing!&#8221;. That&#8217;s it, your virtual directory is now created and you can use your favourite FTP client to upload images and other files to this directory. To connect to this folder from Windows, just enter the Ubuntu VM&#8217;s IP as the hostname, be sure to enter 2100 as the port number, and use the database username and password to login.</p>
<p>You should now have a usable alternative to mod_plsql up and running, which will allow you to create PL/SQL web applications on Oracle XE alone. I hope to post some more tutorials in the near future that will capitalise on this setup, showing you how to create useful PL/SQL Web applications. If you have any questions, comments or suggestions, feel free to leave a comment on this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2010/03/09/oracle-xe-and-mod-plsql/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PL/SQL and the Twitter API</title>
		<link>http://www.joelennon.ie/2010/02/27/plsql-and-the-twitter-api/</link>
		<comments>http://www.joelennon.ie/2010/02/27/plsql-and-the-twitter-api/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 12:19:11 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[http request]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[pl/json]]></category>
		<category><![CDATA[plsql]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[utl_http]]></category>

		<guid isPermaLink="false">http://embosa.wordpress.com/?p=67</guid>
		<description><![CDATA[In this post, you will use the UTL_HTTP database package and the PL/JSON library to connect to the Twitter API and retrieve status updates from the Twitter microblogging service.]]></description>
			<content:encoded><![CDATA[<p>In this post, you will use the UTL_HTTP database package and the PL/JSON library to connect to the Twitter API and retrieve status updates from the Twitter microblogging service.</p>
<p>This post assumes you have access to an Oracle database with the UTL_HTTP package available (Oracle Database 10g Express Edition does) and that you have installed the PL/JSON library, a set of tools for working with JSON data in PL/SQL. For a guide to installing PL/JSON and getting to grips with the basics of the library, see <a title="Oracle and JSON: Using PL/JSON" href="http://embosa.wordpress.com/2010/02/26/oracle-and-json-using-pljson/">this previous post</a>.</p>
<p>The UTL_HTTP package is not usually granted to database users other than SYS, so the first step is to log on to your Oracle database as SYS and run the following command:</p>
<pre>
grant execute on utl_http to embosa;
</pre>
<p>Of course, be sure to replace &#8220;embosa&#8221; with your Oracle username. You should now have access to the UTL_HTTP package. Next, let&#8217;s verify that UTL_HTTP can connect to the Twitter API and return data from it. Execute the following PL/SQL block to do so:</p>
<pre>
declare
    req   utl_http.req;
    resp  utl_http.resp;
    value varchar2(32767);
begin
    req := utl_http.begin_request('http://api.twitter.com/1/statuses/public_timeline.json');
    resp := utl_http.get_response(req);
    loop
        utl_http.read_line(resp, value, true);
        dbms_output.put_line(substr(value, 1, 255));
    end loop;
    utl_http.end_response(resp);
exception
    when utl_http.end_of_body then
        utl_http.end_response(resp);
end;
/
</pre>
<p>This should return a response similar to the following:</p>
<pre>
[{&quot;in_reply_to_user_id&quot;:67594046,&quot;in_reply_to_status_id&quot;:null,&quot;created_at&quot;:&quot;Sat Feb 27 11:30:06 +0000 2010&quot;,&quot;favorited&quot;:false,&quot;source&quot;:&quot;web&quot;,&quot;geo&quot;:null,&quot;in_reply_to_screen_name&quot;:&quot;pemoutinho&quot;,&quot;truncated&quot;:false,&quot;contributors&quot;:null,&quot;user&quot;:{&quot;geo_enabled&quot;:fals
</pre>
<blockquote><p><span style="color:#888888;">Note that in the above example, the output has been trimmed down to 255 characters so that the DBMS_OUTPUT buffer would not overflow. In a moment you will parse the entire response as JSON and access individual properties using the PL/JSON library.</span></p></blockquote>
<p>Now that you have verified that UTL_HTTP can connect to the Twitter API, let's parse the JSON and print out the status updates in a more meaningful format:</p>
<pre>
declare
    req            utl_http.req;
    resp           utl_http.resp;
    value          varchar2(32767);

    jsonArray     json_list;
    jsonObj        json;
begin
    begin
        req := utl_http.begin_request('http://api.twitter.com/1/statuses/public_timeline.json');
        resp := utl_http.get_response(req);
        utl_http.read_text(resp, value);
        utl_http.end_response(resp);
    exception
        when utl_http.end_of_body then
            utl_http.end_response(resp);
    end;

    jsonArray := json_list(value);
    dbms_output.put_line('---------------------------------------------------------------');
    for i in 1..jsonArray.count loop
        jsonObj := json.to_json(jsonArray.get_elem(i));
        dbms_output.put_line(json_ext.get_varchar2(jsonObj, 'text'));
        dbms_output.put_line('Posted by ' ||json_ext.get_varchar2(jsonObj, 'user.screen_name'));
        dbms_output.put_line('Posted on ' ||json_ext.get_varchar2(jsonObj, 'created_at'));
        dbms_output.put_line('---------------------------------------------------------------');
    end loop;
end;
/
</pre>
<p>In this example, you get the entire response from the Twitter API using UTL_HTTP.READ_TEXT, and parse it using PL/JSON's json_list object (as Twitter's API is a JSON array containing several JSON objects). You then loop through each item in this list, extracting the text, user screen name and created at properties for each status update and outputting them. Each tweet is separated by a line of hyphens to make it easier to read. The final output should look something like the following:</p>
<pre>
---------------------------------------------------------------
Am reading this blog and a girl mentione Habana Outpost. Oh Brooklyn, sometimes I miss you. though I heard Habana was wack now...
Posted by thefashionbomb
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@0oo \u75b2\u308c\u3061\u3083\u3044\u307e\u3057\u305f\uff1f\u3061\u3087\u3063\u3068\u4f11\u307f\u307e\u3057\u3087\u3046\u304b
Posted by naoko_bot
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@papodebola sobre o horario dos jogos em sampa, uma frase que todo politico teme: Ninguem aguentaria 15 min de fama no Jornal Nacional <img src='http://www.joelennon.ie/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />
Posted by ReeFzera
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@abogado_kaito \u308f\u304b\u308c\u3070\u3044\u3044\u306e\u3088\uff01
Posted by renkon_0
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
Just write something about Nicks cars:D
Posted by love_ncarter
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@Reema226: The book store?
Posted by amitgupta
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
\u3057\u304b\u3057TV\u306e\u30d6\u30e9\u30c7\u30a3\u30de\u30f3\u30c7\u30a4\u306f\u30d5\u30a1\u30eb\u30b3\u30f3\u5f31\u3044\u306a\u301c\u3002
Posted by kazuwitter
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
ya abisnya kamu rese di;iatin org tau <img src='http://www.joelennon.ie/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  RT @ninomayday: yehee siapa suruh coba lagian maksa dasar lu yaang hahaha :p
Posted by karinutriansyah
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
\u3053\u3046\u3044\u3046\u3053\u3068\u77e5\u3063\u3066\u308b\u304b\u3089\u306a\u306b\uff1f\u3063\u3066\u601d\u3044\u307e\u3059\u3002\u81ea\u5206\u306e\u884c\u52d5\u3068\u306e\u9023\u9396\u3092\u8003\u3048\u3082\u3057\u306a\u3044\u3067\u3002\u3042\u3068\u81ea\u5206\u306e\u56fd\u306e\u8ca7\u56f0\u3082\u77e5\u3089\u306a\u3044\u306e\u306b\u304b\u308f\u3044\u305d\u3046\u3068\u304b\u4e2d\u9014\u534a\u7aef\u3059\u304e\u308b\u3068\u601d\u3044\u307e\u3059\u3002RT @gaitifujiyama \u65e5\u30c6\u30ec\u306e\u4e16\u754c\u4e00\u53d7\u3051\u305f\u3044\u6388\u696d\u3001\u6642\u305f\u307e\u3044\u3044\u4e8b\u3084\u308b\u3093\u3060\u3088\u306d\u3002\u4eca\u3001\u6b63\u306b\u305d\u308c\u3084\u3063\u3066\u3044\u308b
Posted by machuiii
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@_rica \uc544 \uc774\uac74 tiltshiftgen \uc774\ub77c\ub294 \uc571\uc758 \ud798\uc744 \ube4c\ub9b0 \uc870\uc791[..] \uc2e4\uc81c \uce74\uba54\ub77c\uc5d0\uc11c\ub294 \ud2f8\ud305 \ub80c\uc988\uac00 \uc774\ub7f0 \ubbf8\ub2c8\uc5b4\ucc98 \ud6a8\uacfc\ub97c \ub0b4\uc900\ub2e4\uace0 \ud558\ub354\uad70\uc694.
Posted by jstrane
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@micaelquental, fala maluco,,,
Posted by Jeankarllus
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
Ask me anything http://formspring.me/CassiGLAMOUR
Posted by Cassi_Hopeful
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
I killed a plant, and I disliked it!
Posted by Malantur
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
Can someone give me Ro's link to his page on here just with the @ so I get onto it since I can't do it on the search bar!? =/ x
Posted by Feehilys_Angelx
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
RT @terrycavanagh: Really excited by the concept behind Jason Rohrer's new game - check it out: http://sleepisdeath.net/
Posted by sonneveld
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@zzz_ral \u53ef\u611b\u3044\u3001\u3063\u3066\u3044\u3046\u304b\u30a8\u30ed\u3044\u3001\u30c9\u30a8\u30ed\u3060\u3088\u306d\uff01
Posted by chamber11
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@nano_limpid %\u8077\u306f\u5927\u5909\u3063\u3059\u306d\uff57\uff57\uff57\uff57\uff57
Posted by Syana
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
Aku suka perkataan cacu tadi sore...
Posted by masagakenaldema
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@dildillaa dih pede geelaaahhh hahha
Posted by satriavisabrina
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
@555hamako \u3042\u307c\u30fc\u3093\u3068\u30ad\u30dc\u30f3\u30cc\u304c\u3054\u3063\u3061\u3083\u306b\u306a\u3063\u3066\u307e\u3059\u306d\u3048w\u3002
Posted by florestan854
Posted on Sat Feb 27 11:55:17 +0000 2010
---------------------------------------------------------------
</pre>
<blockquote><p><span style="color:#888888;">You may notice that some tweets seem to be made up of gibberish with \u all over the place. These are Unicode characters and usually represent non-Latin characters such as Chinese characters, which Twitter stores as Unicode.</span></p></blockquote>
<p>There you have it, in this post you have created a basic Twitter public timeline reader using PL/SQL, the UTL_HTTP package and the PL/JSON library. It should be relatively straightforward to build on this foundation to create a more complete Twitter client using PL/SQL. For more information about the Twitter API see the <a href="http://apiwiki.twitter.com/">official Twitter API wiki</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2010/02/27/plsql-and-the-twitter-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle and JSON: Using PL/JSON</title>
		<link>http://www.joelennon.ie/2010/02/26/oracle-and-json-using-pljson/</link>
		<comments>http://www.joelennon.ie/2010/02/26/oracle-and-json-using-pljson/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 19:47:13 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[pl/json]]></category>
		<category><![CDATA[plsql]]></category>

		<guid isPermaLink="false">http://embosa.wordpress.com/?p=55</guid>
		<description><![CDATA[In this post, you will learn how to install and use PL/JSON to work with JSON data in your own PL/SQL applications.]]></description>
			<content:encoded><![CDATA[<p>JSON (JavaScript Object Notation) is a lightweight data format that is very well suited for transmitting data over the Internet. Despite the reference to JavaScript in its name, JSON is a language-independent syntax and native support for it has been included in many modern programming languages. In fact, JSON is so popular nowadays that entire database management systems have built their record structure around it, for example <a title="Apache CouchDB" href="http://couchdb.apache.org" target="_blank">Apache CouchDB</a>.</p>
<p>As a Web developer who does a lot of work with PL/SQL, I have recently found myself creating PL/SQL procedures that output JSON data, and making these procedures available as RESTful HTTP services that are then consumed by Ajax functions in the front-end of my applications. This can be a bit of a pain, however, as I need to output the JSON data manually, making it very prone to errors and very difficult to debug in many cases.</p>
<p>Thankfully, an open source library for PL/SQL called PL/JSON is available that resolves some of the issues associated with working with JSON data in an Oracle application. In this post, you will learn how to install and use PL/JSON to work with JSON data in your own PL/SQL applications.</p>
<h3>Download and install the library</h3>
<p>The latest version of PL/JSON, at the time of writing, is version 0.8.6. The compressed archive is less than 200KB in size. You can download PL/JSON from SourceForge at <a title="Download PL/JSON from SourceForge" href="http://sourceforge.net/projects/pljson/files/" target="_blank">http://sourceforge.net/projects/pljson/files/</a>. Unzip the library to your hard drive and install it in a SQL*Plus session using the following command:</p>
<pre>
@install
</pre>
<p>You should see the following output:</p>
<pre>
-----------------------------------
-- Compiling objects for PL/JSON --
-----------------------------------
PL/SQL procedure successfully complete

Type created.
No errors.

Type body created.
No errors.

Type created.
No errors.

Type body created.
No errors.

Type created.
No errors.

Type created.
No errors.

Type created.
No errors.

Type created.
No errors.

Type created.
No errors.

Type created.
No errors.

Package created.

Package body created.

Package created.

Package body created.

Type body created.
No errors.

Type body created.
No errors.

Package created.

Package body created.
</pre>
<p>Assuming you see no errors from running the install script, PL/JSON is now installed in your Oracle database.</p>
<h3>Using PL/JSON</h3>
<p>With PL/JSON installed, you can now start working with the traditional &#8220;Hello, world&#8221; example, using the following PL/SQL code:</p>
<pre>
set serveroutput on
declare
    jsonObj        json;
begin
    --Create a new JSON object, passing the JSON code as the constructor
    jsonObj := json('{&quot;greeting&quot;:&quot;Hello World&quot;}');
    --Output the value for the JSON data with the key &quot;greeting&quot;
    dbms_output.put_line(json_ext.get_varchar2(jsonObj, 'greeting'));
end;
/
</pre>
<p>This produces the following output:</p>
<pre>
Hello, World
</pre>
<p>As you can see from the above output, PL/JSON parses JSON data. But what if you want to create a JSON object without actually providing the data in JSON format. Take the following example:</p>
<pre>
set serveroutput on
declare
    jsonObj       json;
begin
    --Use an empty constructor to create a blank JSON object
    jsonObj := json();
    -- Use the put procedure to add a string, number, boolean and null property to the JSON object
    jsonObj.put('name', 'Joe Lennon');
    jsonObj.put('age', 24);
    jsonObj.put('awesome', json_bool(true));
    jsonObj.put('children', json_null());

    --Print the string representation of the JSON object (pretty-print)
    jsonObj.print;
    dbms_output.put_line('Am I awesome?');
    --Use getters to retrieve the value of the boolean property &quot;awesome&quot; and print the result
    dbms_output.put_line(json_ext.get_json_bool(jsonObj, 'awesome').to_char);
end;
/
</pre>
<p>The output for the above looks like:</p>
<pre>
{
  &quot;name&quot; : &quot;Joe Lennon&quot;,
  &quot;age&quot; : 24,
  &quot;awesome&quot; : true,
  &quot;children&quot; : null
}
Am I awesome?
true
</pre>
<h3>JSON Arrays</h3>
<p>JSON objects can contain data in several types &#8211; number, string, boolean, null or array. At this point, you&#8217;ve seen how to work with the first four of these types, but not arrays. PL/JSON refers to these as a json_list. Working with json_list objects is very similar to working with a regular JSON object, as shown in the following example:</p>
<pre>
set serveroutput on
declare
    jsonArray        json_list;
    jsonObj           json;
begin
    jsonArray := json_list('[{&quot;name&quot;:&quot;Joe&quot;,&quot;age&quot;:24},{&quot;name&quot;:&quot;Jill&quot;,&quot;age&quot;:26}]');
    jsonObj := json.to_json(jsonArray.get_elem(1));
    dbms_output.put_line(json_ext.get_varchar2(jsonObj, 'name'));
    jsonObj := json.to_json(jsonArray.get_elem(2));
    dbms_output.put_line(to_char(json_ext.get_number(jsonObj, 'age')));
end;
/
</pre>
<p>The above code create a JSON array (or json_list) containing two objects with two properties, name and age. The first object has the name &#8220;Joe&#8221; and age 24, the second has name &#8220;Jill&#8221; and age 26. The get_elem function is used to return an item in the JSON array, and the to_json function casts this is a JSON object. In the above example, you first assign jsonObj to the first object in the JSON array, printing out the value of the name property for this object (in this case, the string value &#8220;Joe&#8221;). Next, you assign jsonObj to the second object in the array, and print out the value of the age property (in this case, age is 26). The output for this example is as follows:</p>
<pre>
Joe
26
</pre>
<p>To wrap up this post, let&#8217;s have a look at a more complex scenario for using JSON in PL/SQL. Let&#8217;s say that you want to create a JSON representation of the result of a SQL statement. The following example demonstrates just that:</p>
<pre>
set serveroutput on
declare
    jsonArray     json_list;
    jsonObj       json;

    cursor get_data is
        select initcap(lower(object_type)) name, count(*) count
        from all_objects
        where upper(object_type) like 'INDEX%'
        group by object_type;
begin
   jsonArray := json_list();
   for objType in get_data loop
       jsonObj := json();
       jsonObj.put('object_type', objType.name);
       jsonObj.put('count', objType.count);
       jsonArray.add_elem(jsonObj.to_anydata);
   end loop;

   jsonArray.print;

   dbms_output.new_line;

   for i in 1..jsonArray.count loop
       dbms_output.put_line(
           json_ext.get_varchar2(
               json.to_json(jsonArray.get_elem(i)),
               'object_type'
           )||'-&gt;'||
           to_char(json_ext.get_number(
               json.to_json(jsonArray.get_elem(i)),
               'count'
           ))
       );
   end loop;
end;
/
</pre>
<p>In the example above, you first initialize the JSON array to an empty json_list. Next, you loop through the get_data cursor, which selects back the counts for all object types in the database that begin with &#8220;INDEX&#8221;. For each iteration of this loop, a JSON object is created, the object type name and count are added as properties to the object, and the object is added to the JSON array. Then the string representation of the array is printed as output. Next, you loop through the JSON array itself, and print out the object_type and count properties for each item in the list. The overall output should look as follows:</p>
<pre>
[{
  &quot;object_type&quot; : &quot;Index Partition&quot;,
  &quot;count&quot; : 99
}, {
  &quot;object_type&quot;: &quot;Index&quot;,
  &quot;count&quot; : 1411
}, {
  &quot;object_type&quot; : &quot;Indextype&quot;,
  &quot;count&quot; : 8
}]

Index Partition-&gt;99
Index-&gt;1411
Indextype-&gt;8
</pre>
<blockquote><p><span style="color:#808080;">It&#8217;s important to note that the &#8220;print&#8221; function which outputs a string representation of JSON objects or arrays merely uses the DBMS_OUTPUT.PUT_LINE Oracle function to dump data to the SQL prompt. There are buffer limitations with this function, particularly on clients before 10g Release 2 (10.2). As a result, on large sets of data you may get an error:<br />
</span></p>
<p><span style="color:#808080;"><strong>ORA-06502: PL/SQL: numeric or value error: host bind array too small</strong></span></p>
<p><span style="color:#808080;">This is not an issue with PL/JSON, but rather an issue with the Oracle DBMS_OUTPUT.PUT_LINE function. Your JSON objects can be used in other means perfectly fine, but the print member function for the json and json_list objects suffer from this limitation.</span></p></blockquote>
<p>PL/JSON provides a ton of excellent features for working with JSON in PL/SQL. The best way to grips with it is to get your hands dirty and try it out for yourself. This post should be a good base to start from, and you can find out more by reading the doc.pdf file that comes with PL/JSON. Also, be sure to check out the examples folder, as it contains some good sample usages that are ready for you to test out. Finally, check the source code itself, particularly the type specification files:</p>
<ul>
<li>json.typ</li>
<li>json_list.typ</li>
</ul>
<p>As these will give you a good idea of the member functions available for json and json_list objects. If you have any specific questions about PL/JSON, leave a comment and I will do my best to answer them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2010/02/26/oracle-and-json-using-pljson/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Flex 4 and PL/SQL</title>
		<link>http://www.joelennon.ie/2010/02/25/flex-4-and-plsql/</link>
		<comments>http://www.joelennon.ie/2010/02/25/flex-4-and-plsql/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 13:11:08 +0000</pubDate>
		<dc:creator>Joe Lennon</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[flex 4]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[plsql]]></category>

		<guid isPermaLink="false">http://embosa.wordpress.com/?p=48</guid>
		<description><![CDATA[In this post, you will create a PL/SQL web procedure that outputs JSON data, and then you will create a Flex application that displays this data in a DataGrid component.]]></description>
			<content:encoded><![CDATA[<p>I was recently asked by someone to give them some help with connecting to a MySQL database from Adobe Flex 4. In Flex Builder 3, there was a feature which allowed you to create a Flex application based on the tables in a MySQL database, taking care of the PHP code in the middle for you. In Adobe FlashBuilder 4 Beta 2 (which is basically the new version of Flex Builder), this feature does not exist, so you&#8217;re kind of left on your own.</p>
<p>Thankfully, on the Adobe Labs website there are a set of good tutorials on getting up and running with Flex connecting to a MySQL database via PHP using Zend AMF (Action Message Format) remoting. The following is a PDF document including all of those tutorials:</p>
<ul>
<li><a title="Flex 4 Tutorials PDF" href="http://help.adobe.com/en_US/Flex/4.0/FlexTutorials/flex_4_tutorials.pdf" target="_blank">Learn to Use Flash Builder 4 and Flex 4</a></li>
</ul>
<p>Working with data stored in a database management system such as MySQL is very easy if you develop applications in PHP, ColdFusion or Java. But, what if you use a more obscure language such as PL/SQL? You&#8217;re not completely out of luck, as Flex can also consume any HTTP service that responds with XML or JSON data. In this post, you will create a PL/SQL web procedure that outputs JSON data, and then you will create a Flex application that displays this data in a DataGrid component.</p>
<p>In order to follow this guide, you will need the following:</p>
<ul>
<li>An Oracle database, Oracle Database 10g Express Edition (XE) will do fine.</li>
<li>A suitable PL/SQL web deployment environment, with a DAD (Document Access Descriptor) configured. This can be either an Oracle HTTP Server which uses mod_plsql, the Apache HTTP Server with the open source mod_plsql variant mod_owa, or even Oracle XE&#8217;s APEX web server, with a DAD set up using the DBMS_EPG package. Basically you need to be able to access a PL/SQL package via a URL. If none of this makes sense to you, you probably don&#8217;t need this guide!</li>
<li>Adobe FlashBuilder 4 Beta 2</li>
</ul>
<p>The first thing you need to do is create the PL/SQL stored procedure that will be used to return the JSON data that we will use later to fill the Flex DataGrid component. This procedure uses a cursor to get a list of the different object types present in the Oracle database, and how many objects of each type is currently stored. The procedure then loops through this cursor and produces JSON output.</p>
<pre>
create or replace procedure json_object_types as
    cursor get_data is
        select initcap(lower(object_type)) object_type, count(*) as object_count
        from all_objects
        group by object_type;

    i       number := 0;
begin
    htp.init;
    owa_util.mime_header('application/json', false);
    owa_util.http_header_close;
    htp.p('[');
    for obj_type in get_data loop
        i := i + 1;
        if i = 1 then
            htp.p('{');
        else
            htp.p(', {');
        end if;
        htp.p('&quot;object_type&quot;: &quot;'||obj_type.object_type||'&quot;,');
        htp.p('&quot;object_count&quot;: '||obj_type.object_count);
        htp.p('}');
    end loop;
    htp.p(']');
end json_object_types;
</pre>
<p>This code should produce an output like the following. Note that I have formatted the JSON code to make it somewhat easier to read, and also the counts shown here will most likely differ from the values returned for your own database.</p>
<pre>
[
    { &quot;object_type&quot;: &quot;Consumer Group&quot;, &quot;object_count&quot;: 2 },
    { &quot;object_type&quot;: &quot;Sequence&quot;, &quot;object_count&quot;: 7 },
    { &quot;object_type&quot;: &quot;Schedule&quot;, &quot;object_count&quot;: 1 },
    { &quot;object_type&quot;: &quot;Procedure&quot;, &quot;object_count&quot;: 24 },
    { &quot;object_type&quot;: &quot;Operator&quot;, &quot;object_count&quot;: 45 },
    { &quot;object_type&quot;: &quot;Window&quot;, &quot;object_count&quot;: 2 },
    { &quot;object_type&quot;: &quot;Package&quot;, &quot;object_count&quot;: 247 },
    { &quot;object_type&quot;: &quot;Library&quot;, &quot;object_count&quot;: 15 },
    { &quot;object_type&quot;: &quot;Package Body&quot;, &quot;object_count&quot;: 1 },
    { &quot;object_type&quot;: &quot;Xml Schema&quot;, &quot;object_count&quot;: 13 },
    { &quot;object_type&quot;: &quot;Job Class&quot;, &quot;object_count&quot;: 1 },
    { &quot;object_type&quot;: &quot;Table&quot;, &quot;object_count&quot;: 70 },
    { &quot;object_type&quot;: &quot;Synonym&quot;, &quot;object_count&quot;: 2765 },
    { &quot;object_type&quot;: &quot;View&quot;, &quot;object_count&quot;: 1166 },
    { &quot;object_type&quot;: &quot;Function&quot;, &quot;object_count&quot;: 159 },
    { &quot;object_type&quot;: &quot;Window Group&quot;, &quot;object_count&quot;: 1 },
    { &quot;object_type&quot;: &quot;Indextype&quot;, &quot;object_count&quot;: 8 },
    { &quot;object_type&quot;: &quot;Type&quot;, &quot;object_count&quot;: 767 },
    { &quot;object_type&quot;: &quot;Evaluation Context&quot;, &quot;object_count&quot;: 1 }
]
</pre>
<p>Be sure to note the URL you use to access this procedure &#8211; in my case it was http://localhost:8080/embosa/json_object_types &#8211; where embosa is the DAD name I have configured on my web server.</p>
<p>With the PL/SQL procedure created, we can now create a Flex project in Adobe FlashBuilder that will consume the JSON data that the procedure produces. Fire up FlashBuilder and create a new Flex project (File -&gt; New Flex Project). In the dialog box for &#8220;New Flex Project&#8221;, enter &#8220;PlSqlService&#8221; as the Project name, make sure that &#8220;Web&#8221; is selected under Application type and that &#8220;None/Other&#8221; is selected for Application server type. Press the Finish button to create the project.</p>
<p>The next thing you need to do is connect to the PL/SQL procedure you created earlier. To do this, open Data -&gt; Connect to Data/Service. This will open a dialog which gives you a number of service type options &#8211; BlazeDS, ColdFusion, HTTP, LCDS, PHP and Web Service. Select the HTTP option and press Next.</p>
<p>You will now be required to configure the HTTP service. To do this, you need to define the operation for the service and give the service a name. Under Operations, change the Operation name to &#8220;getObjectTypes&#8221;, keep &#8220;GET&#8221; selected as the Method, and enter the URL for your PL/SQL procedure that you earlier noted in the URL field. Then, under Service details, give the Service a name &#8220;PlSqlService&#8221;. The Service package will be created automatically based on your service name. Press &#8220;Finish&#8221; to create the connection.</p>
<p>In the Data/Services window you should now see an entry named PlSqlService with the function getObjectTypes() listed. Right-click on the getObjectTypes() item in this window, and select &#8220;Configure Return Type&#8221;. In the dialog box, make sure that &#8220;Auto-detect the return type from sample data&#8221; is selected and press the Next button. On the next screen, just accept the default option (&#8220;Enter parameter values and call the operation&#8221;) and press the Next button again. You should now see that the Return Type was detected successfully. Under Data type, choose to enter a name to create a new data type and enter the value &#8220;ObjType&#8221; in the textbox. You&#8217;ll notice that the object_type and object_count properties have been automatically detected and their correct types (String and int, respectively) have been picked up by FlashBuilder. You don&#8217;t need to change anything else here, so just press the Finish button to return to the main FlashBuilder window.</p>
<p>The file PlSqlService.mxml is open &#8211; but probably in &#8220;Source&#8221; view. Switch to &#8220;Design&#8221; mode, and from the Components window, drag a DataGrid from the controls list to the empty canvas area. By default it should have three columns named Column 1, Column 2 and Column 3. Right-click on the DataGrid and select the option &#8220;Bind to Data&#8221; from the context menu. This will open a dialog box for binding the DataGrid control to a data service. The option &#8220;New service call&#8221; should be selected by default, and you&#8217;ll notice that the &#8220;PlSqlService&#8221; and &#8220;getObjectTypes()&#8221; service and operation have been automatically selected. Accept these defaults and press the OK button to bind the control to this data.</p>
<p>You&#8217;ll notice that the DataGrid has changed to only show two columns: object_type and object_count. Let&#8217;s change the Column headings so they look a bit better. With the DataGrid selected, click the &#8220;Configure Columns&#8221; button in the Properties window. In here you can select each column, and change the &#8220;Header text&#8221; property to modify the text that displays in each column&#8217;s header. Change the text for the object_type column to &#8220;Type&#8221; and for the object_count column to &#8220;Count&#8221;. Press the OK button when you are finished.</p>
<p>Save your work (File-&gt;Save or Ctrl+S) and then run the project by pressing the green Run button on the FlashBuilder toolbar, or by selecting Run-&gt;Run PlSqlService. Your default Web browser will launch and you will see a page with a DataGrid, populated with the data from the Oracle database. The end result looks like the screenshot below.</p>
<div id="attachment_51" class="wp-caption alignnone" style="width: 220px"><a href="http://embosa.files.wordpress.com/2010/02/flex4plsql.png"><img class="size-full wp-image-51" title="The Final Result" src="http://embosa.files.wordpress.com/2010/02/flex4plsql.png" alt="The Final Result" width="210" height="184" /></a><p class="wp-caption-text">The Final Result</p></div>
<p>The DataGrid control is simple but powerful, and allows you to adjust the width of each columns and sort the data by clicking on the column headers.</p>
<p>So there you have it, a Flex DataGrid connecting to an Oracle database using a PL/SQL web procedure &#8211; if you have any questions about the techniques covered in this guide, feel free to leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.joelennon.ie/2010/02/25/flex-4-and-plsql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

