<?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>Ghosted Notes &#187; SQL</title>
	<atom:link href="http://ghostednotes.com/category/sql/feed" rel="self" type="application/rss+xml" />
	<link>http://ghostednotes.com</link>
	<description>The writings of a technology ronin</description>
	<lastBuildDate>Thu, 14 Apr 2011 19:30:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>If libraries were like relational databases&#8230;</title>
		<link>http://ghostednotes.com/2010/12/31/if-libraries-were-like-relational-databases</link>
		<comments>http://ghostednotes.com/2010/12/31/if-libraries-were-like-relational-databases#comments</comments>
		<pubDate>Fri, 31 Dec 2010 21:19:26 +0000</pubDate>
		<dc:creator>Brian Panulla</dc:creator>
				<category><![CDATA[Semantic Web]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://ghostednotes.com/?p=184</guid>
		<description><![CDATA[I was inspired by XKCD to draw this cartoon for a recent presentation on the Semantic Web. We have this habit of dismembering data when we use relational modeling. Consequently, we spend a lot of our development time figuring out how to reassemble entities to use them in our applications, particularly with large, heavily-normalized databases. [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.flickr.com/photos/bpanulla/5310748684/in/photostream/"><img class="alignnone" title="It gets even grizzlier if we start talking about human resource data." src="http://farm6.static.flickr.com/5130/5310748684_f0fe7311dd.jpg" alt="" width="500" height="375" /></a></p>
<p>I was inspired by <a href="http://xkcd.com" target="_blank">XKCD</a> to draw this cartoon for a <a href="http://www.meetup.com/coldfusionmeetup/calendar/15721290/" target="_blank">recent presentation on the Semantic Web</a>. We have this habit of dismembering data when we use relational modeling. Consequently, we spend a lot of our development time figuring out how to  reassemble entities to use them in our applications, particularly with large, heavily-normalized databases. It&#8217;s occasionally good to remind ourselves that relational modeling is an optimized form of data storage. But it&#8217;s not the only one, and it isn&#8217;t always the right one for a given problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://ghostednotes.com/2010/12/31/if-libraries-were-like-relational-databases/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Neo4j Graph Databases With ColdFusion</title>
		<link>http://ghostednotes.com/2010/04/29/using-neo4j-graph-databases-with-coldfusion</link>
		<comments>http://ghostednotes.com/2010/04/29/using-neo4j-graph-databases-with-coldfusion#comments</comments>
		<pubDate>Thu, 29 Apr 2010 21:56:31 +0000</pubDate>
		<dc:creator>Brian Panulla</dc:creator>
				<category><![CDATA[Adobe]]></category>
		<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[neo4j]]></category>
		<category><![CDATA[Semantic Web]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://ghostednotes.com/?p=135</guid>
		<description><![CDATA[After last week, I decided to put off picking a new frontend platform for my Semantic Web rubric project and focus a bit on the server backend. Since this is just a proof-of-concept project at this point I can afford to take some risks in choosing technologies. I&#8217;ve been following the developments around using graph [...]]]></description>
			<content:encoded><![CDATA[<p>After <a href="http://ghostednotes.com/2010/04/21/losing-my-religion" target="_blank">last week</a>,  I decided to put off picking a new frontend platform for my Semantic  Web rubric project and focus a bit on the server backend.</p>
<p>Since this is just a proof-of-concept project at this point I can afford to take some risks in  choosing technologies. I&#8217;ve been following the developments  around using <a href="http://en.wikipedia.org/wiki/Graph_database" target="_blank"><em>graph databases</em></a> for storing data, especially for Semantic Web applications. One project that kept coming up was <a href="http://neo4j.org/" target="_blank">Neo4j</a>, a graph database engine built in Java. I figured now was a good time to try it out. My server-side logic is built in <a href="http://en.wikipedia.org/wiki/ColdFusion" target="_blank">ColdFusion</a>, and integrating open source Java projects like Neo4j into CF applications is generally a snap.</p>
<p>Aside from one hiccup, porting Neo4j&#8217;s <a href="http://wiki.neo4j.org/content/Getting_Started_In_One_Minute_Guide" target="_blank">1-minute Java &#8220;Hello World&#8221; example</a> to CFML proved to be fairly straightforward. The process I used to get this working is detailed below. I&#8217;d suggest that you skim over the <a href="http://wiki.neo4j.org/content/Getting_Started_In_One_Minute_Guide" target="_blank">Java example</a> before continuing &#8211; I&#8217;m sure I left out some of the exposition.</p>
<p>First add the Neo4j Jar files to the ColdFusion server:</p>
<ul>
<li>Download the Neo4j &#8220;Apoc&#8221; distribution and unpack it somewhere convenient. I&#8217;m using Mac OS X, so I put things like this in <strong>~/lib/neo4j-apoc-1.0</strong></li>
<li>Add the Neo4j JAR files to the ColdFusion classpath. Log into your ColdFusion Administrator, and select <strong>Server Settings -&gt; Java and JVM</strong>. Enter the path to the <strong>lib</strong> folder in your Neo4j distribution in <strong>ColdFusion Class Path<br />
</strong></li>
<li>Restart your ColdFusion server. If you&#8217;re at all nervous, log back in to the ColdFusion Administrator and verify that the Neo4j jars are indeed listed on your classpath.</li>
</ul>
<p>Once this is complete, you can initialize a new database for your ColdFusion app. Decide where you want the CF server to create the Neo4j data files and pass that to the object&#8217;s init() method. I put mine in a folder under /tmp on Mac OS X.</p>
<pre>&lt;cfset dbroot = "/tmp/neo4jtest/" /&gt;

&lt;cfset graphDb = createObject('java',
                  "org.neo4j.kernel.EmbeddedGraphDatabase") /&gt;
&lt;cfset graphDb.init(dbroot &amp; "var/graphdb") /&gt;</pre>
<p><em>[Aside for non-ColdFusion folks: CF doesn't instantiate Java objects quite how you'd expect. The call to CreateObject() just gets a handle on the class itself. Calling init() on the resulting handle actually instantiates the class via the appropriate constructor.]</em></p>
<p>Just as in the Java example, it&#8217;s good to surround your connection with a try/catch block that will close your database connection if you throw an error. As I was working with Neo4j I would periodically lock up my database and not be able to connect without restarting CF. Adding a CFTRY/CFCATCH block cleared this right up.</p>
<pre>&lt;cftry&gt;
   &lt;cfset tx = graphDb.beginTx() /&gt;

   &lt;cfscript&gt;
     tx.success();
     WriteOutput("Success.");
   &lt;/cfscript&gt;

   &lt;cfset tx.finish() /&gt;

  &lt;cfcatch type="any"&gt;
     &lt;cfset graphDb.shutdown() /&gt;
     &lt;cfdump var="#cfcatch#"&gt;
   &lt;/cfcatch&gt;
&lt;/cftry&gt;

&lt;cfset graphDb.shutdown() /&gt;
</pre>
<p>Where things got really sticky was the use of Java enumerations to declare the available relationship types for the graph:</p>
<pre> /* Java code */
 public enum  MyRelationshipTypes implements RelationshipType
 {
    KNOWS
 }
</pre>
<p>To my knowledge there&#8217;s no way to declare something like this in standard CFML. I likely could have wrapped this in a Java class of some sort and loaded it through CreateObject(), but that wouldn&#8217;t have been true to the spirit of ColdFusion. So I dug around in the Neo4j docs and found an answer: relationships can be created dynamically at runtime from a static method on the class <strong>org.neo4j.graphdb.DynamicRelationshipType</strong>. I created an instance of DynamicRelationshipType for the &#8220;KNOWS&#8221; relationship and loaded it into a Struct, anticipating caching them in Application scope for a real application.</p>
<pre> relationship = CreateObject("java",
                             "org.neo4j.graphdb.DynamicRelationshipType");
 MyRelationshipTypes = structNew();
 MyRelationshipTypes.KNOWS = relationship.withName( "KNOWS" );
</pre>
<p>It might be interesting to see if these relationship enumerations could be generated and compiled by something like <a href="http://javaloader.riaforge.org/" target="_blank">JavaLoader</a>. I&#8217;m not yet aware of any downsides with dynamic relationships besides the obvious lack of compile-time checking.</p>
<p>The rest of the exercise follows without any real suprises:</p>
<pre> firstNode = graphDb.createNode();
 secondNode = graphDb.createNode();
 relationship = firstNode.createRelationshipTo( secondNode,
                                         MyRelationshipTypes.KNOWS );

 firstNode.setProperty( "message", "Hello, " );
 secondNode.setProperty( "message", "world!" );
 relationship.setProperty( "message", "brave Neo4j " );

 WriteOutput( firstNode.getProperty( "message" ) );
 WriteOutput( relationship.getProperty( "message" ) );
 WriteOutput( secondNode.getProperty( "message" ) );
</pre>
<p>And there you have it! A quick and dirty Neo4j application built with CFML.</p>
<p>I&#8217;ve put a little work into developing a Neo4j helper class that hides some of these warts in a nice clean CFC. As soon as I can get eGit to behave I&#8217;ll <a href="http://github.com/bpanulla/cf_neo4j" target="_blank">post the files on GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ghostednotes.com/2010/04/29/using-neo4j-graph-databases-with-coldfusion/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CFQUERY and autonumber primary keys</title>
		<link>http://ghostednotes.com/2008/04/25/cfquery-and-autonumber-primary-keys</link>
		<comments>http://ghostednotes.com/2008/04/25/cfquery-and-autonumber-primary-keys#comments</comments>
		<pubDate>Fri, 25 Apr 2008 22:04:00 +0000</pubDate>
		<dc:creator>Brian Panulla</dc:creator>
				<category><![CDATA[ColdFusion]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://ghostednotes.com/2008/04/25/CFQUERY-and-autonumber-primary-keys</guid>
		<description><![CDATA[After reading a post by Ben Nadel, it occurred to me that I should write up my technique of getting new autogenerated primary key values back from the database. It&#8217;s very common for database designers to use columns that generate a unique, artificial primary key value for every row inserted into a database table. Different [...]]]></description>
			<content:encoded><![CDATA[<p>After reading a <a href="http://www.bennadel.com/index.cfm?dax=blog:1209.view">post by Ben Nadel</a>, it occurred to me that I should write up my technique of getting new autogenerated primary key values back from the database.</p>
<p>It&#8217;s very common for database designers to use columns that generate a unique, artificial primary key value for every row inserted into a database table. Different platforms have different names for this type of column:</p>
<ul>
<li>Microsoft SQL Server: identity column property</li>
<li>Microsoft Access: AutoNumber field type</li>
<li>MySQL: AUTO_INCREMENT column property</li>
</ul>
<p>PostgreSQL and Oracle use an alternative method called a <em>sequence</em>. Sequences are easier to use in some ways, and the technique I&#8217;ll describe below doesn&#8217;t really apply.</p>
<p>If you have child tables in your database related to your main table with Foreign Key constraints, you&#8217;re going to need to retrieve this autogenerated value before you can insert data into these child tables.</p>
<p>Let&#8217;s take a typical INSERT statement that pulls data from an HTML form POST operation:</p>
<p><code><br />
<cfquery name="insertNewRecord" datasource="myDB"><br />
INSERT INTO tblPeople (<br />
nameLast,<br />
nameFirst,<br />
emailAddress<br />
) VALUES (<br />
<cfqueryparam value="#form.nameLast#" cfsqltype="cf_sql_varchar" /><br />
<cfqueryparam value="#form.nameFirst#" cfsqltype="cf_sql_varchar" /><br />
<cfqueryparam value="#form.emailAddress#" cfsqltype="cf_sql_varchar" /><br />
)<br />
</cfquery><br />
</code></p>
<p>Although INSERT CFQUERY tags don&#8217;t require a <em>name</em> attribute, I make sure to add one here. You&#8217;ll see why in a moment.</p>
<p>One handy property of the CFQUERY tag is that it can contain multiple SQL queries if you separate them with semicolons. You can use this trick to fetch the newly-created ID in this first query. This example works with MS SQL Server 2000 or higher:</p>
<p><code><br />
<cfquery name="insertNewRecord" datasource="myDB"><br />
INSERT INTO tblPeople (<br />
nameLast,<br />
nameFirst,<br />
emailAddress<br />
) VALUES (<br />
<cfqueryparam value="#form.nameLast#" cfsqltype="cf_sql_varchar" /><br />
<cfqueryparam value="#form.nameFirst#" cfsqltype="cf_sql_varchar" /><br />
<cfqueryparam value="#form.emailAddress#" cfsqltype="cf_sql_varchar" /><br />
);</p>
<p>SELECT SCOPE_IDENTITY() AS peopleID;<br />
</cfquery><br />
</code></p>
<p>Because I named the CFQUERY instance, I can now reference the autogenerated ID value in my succeeding queries as:</p>
<p><code><br />
#insertNewRecord.peopleID#<br />
</code></p>
<p>Don&#8217;t forget to wrap your entire batch of related CFQUERY tags inside a CFTRANSACTION tag to make them one complete operation.</p>
<p>One final note: The <strong>SCOPE_IDENTITY()</strong> function used above only works with SQL Server 2000 and higher. Anyone on SQL Server 7 (??) and before must use the special <strong>@@IDENTITY</strong> variable to accomplish the same thing. @@IDENTITY has some limitations with regards to databases with triggers, and may not retrieve the right value in all cases. <a href="http://www.sqlteam.com/article/alternatives-to-identity-in-sql-server-2000" target="_blank">Here&#8217;s a more thorough explanation</a> of the problem.</p>
<p>People using MySQL can substitute the function <strong>LAST_INSERT_ID()</strong> to accomplish the same thing.</p>
]]></content:encoded>
			<wfw:commentRss>http://ghostednotes.com/2008/04/25/cfquery-and-autonumber-primary-keys/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

