<?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>David Cassel &#187; Software Development</title>
	<atom:link href="http://blog.davidcassel.net/category/software-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.davidcassel.net</link>
	<description>on Software Development and Entrepreneurism</description>
	<lastBuildDate>Thu, 19 Jan 2012 02:34:05 +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>Sneak Peak: ImageMagick in MarkLogic</title>
		<link>http://blog.davidcassel.net/2012/01/sneak-peak-imagemagick-in-marklogic/</link>
		<comments>http://blog.davidcassel.net/2012/01/sneak-peak-imagemagick-in-marklogic/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 19:38:49 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[CurioVault]]></category>
		<category><![CDATA[image magick]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[sneak peak]]></category>
		<category><![CDATA[xquery]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=380</guid>
		<description><![CDATA[Today I get to give you a sneak peak into a feature that's not yet officially present, but you'll find if you know where to look: XQuery-level integration with ImageMagick! In this post I demonstrate automatically scaling down large images for CurioVault.com. ]]></description>
			<content:encoded><![CDATA[<p>Today I get to give you a sneak peak into a feature that&#8217;s not yet officially present, but you&#8217;ll find if you know where to look: XQuery-level integration with ImageMagick!</p>
<p>Before we go any further, let&#8217;s be clear that this is neither documented nor supported in the current version &#8212; and if it becomes official, the interface with the feature may very well change. If you are interested in this feature, please contact <a href="mailto:Stephen.Buxton@marklogic.com">Stephen Buxton</a> in Product Management and let him know.</p>
<p>With all that out of the way, let&#8217;s take a look.</p>
<p><a href="http://www.imagemagick.org/script/index.php" target="_blank">ImageMagick</a> is &#8220;a software suite to create, edit, compose or convert bitmap images&#8221;, as stated on its web site. If you have ImageMagick installed on your server when MarkLogic 5 starts up, you&#8217;ll see something like this line slide by in your ErrorLog.txt:</p>
<blockquote>
<pre>2012-01-09 17:10:41.557 Info: ImageMagick 6.7.4-4 2012-01-09 Q16 http://www.imagemagick.org</pre>
</blockquote>
<p>If you don&#8217;t have it installed, you&#8217;ll still see some reference to ImageMagick, but it will be a message indicating that it was not able to load ImageMagick.</p>
<p>Regular readers will have seen that I&#8217;m now running a site with the MarkLogic Express license: <a title="CurioVault" href="http://www.curiovault.com" target="_blank">CurioVault.com</a>. The site lets users upload information about collectibles they have, including when and where they got the item, an interesting story connected to it, and a picture of it. CurioVault is more about the stories than the pictures. It&#8217;s not Flickr &#8212; I don&#8217;t want the site to get bogged down with a bunch of multi-megabyte images. So, I set up the code so that I can specify a maximum size for an image in bytes, and automatically scale down any uploaded images that exceed that size. I also set up a maximum image dimension (in pixels) to use when scaling. Here&#8217;s the code that does it:</p>
<pre>declare function item:scale-image($img as binary()) as binary()
{
  if (xdmp:binary-size($img) &gt; $MAX-IMG-SIZE) then
    let $wand := <a href="http://www.imagemagick.org/api/magick-image.php#MagickReadImageBlob" target="_blank">magick:read-image</a>(<a href="http://www.imagemagick.org/api/magick-wand.php#NewMagickWand" target="_blank">magick:wand()</a>, $img)
    let $height := <a href="http://www.imagemagick.org/api/magick-image.php#MagickGetImageHeight" target="_blank">magick:get-image-height</a>($wand)
    let $width := <a href="http://www.imagemagick.org/api/magick-image.php#MagickGetImageWidth" target="_blank">magick:get-image-width</a>($wand)
    let $wand :=
      <a href="http://www.imagemagick.org/api/magick-image.php#MagickScaleImage" target="_blank">magick:scale-image</a>(
        $wand,
        fn:min((fn:ceiling($width * $MAX-IMG-DIM div $height), $MAX-IMG-DIM)),
        fn:min((fn:ceiling($height * $MAX-IMG-DIM div $width), $MAX-IMG-DIM)))
    return <a href="http://www.imagemagick.org/api/magick-image.php#MagickGetImageBlob" target="_blank">magick:write-image</a>($wand)
  else
    $img
};</pre>
<p>The trickery with the 2nd and 3rd parameters to magick:scale-image() is to make sure the aspect ratio remains the same, while setting a maximum for either dimension. But simple as that, I pass in binary image that a user uploaded and when it comes back, I know that it won&#8217;t be huge. (People who do a lot of image manipulation may have suggestions for a better approach; such comments are welcome, but don&#8217;t let that distract you from celebrating this feature!) Previously, to accomplish this would have required calls out to MLJAM or a service.</p>
<p>This integration is so new that even the internal documentation is mostly references to <a href="http://www.imagemagick.org/api/magick-wand.php" target="_blank">ImageMagick&#8217;s documentation</a> at this point. If you want to play around a bit, you can map the code above to the corresponding functions on ImageMagick&#8217;s documentation and probably figure out how to make some other kinds of calls.</p>
<p>Be sure to let Stephen know what you think.</p>
<p>Next up for CurioVault: letting users crop images at upload time.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2012/01/sneak-peak-imagemagick-in-marklogic/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CurioVault: putting the Express License to work</title>
		<link>http://blog.davidcassel.net/2012/01/curiovault-putting-the-express-license-to-work/</link>
		<comments>http://blog.davidcassel.net/2012/01/curiovault-putting-the-express-license-to-work/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 20:15:23 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Entrepreneurism]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[CurioVault]]></category>
		<category><![CDATA[express]]></category>
		<category><![CDATA[marklogic]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=374</guid>
		<description><![CDATA[MarkLogic 5 includes the Express license, which allows for small production deployments. I decided to take advantage of that to put onto the web a little hobby site I&#8217;ve had in prototype mode for a year or so. I&#8217;ve collected lapel pins since 1984. In that time, I&#8217;ve gotten more than 150 and I&#8217;ve started [...]]]></description>
			<content:encoded><![CDATA[<p>MarkLogic 5 includes the Express license, which allows for small production deployments. I decided to take advantage of that to put onto the web a little hobby site I&#8217;ve had in prototype mode for a year or so.</p>
<p>I&#8217;ve collected lapel pins since 1984. In that time, I&#8217;ve gotten more than 150 and I&#8217;ve started to forget when I got some of them, where I got them, and the stories that went with them. Hence <a href="http://www.curiovault.com" target="_blank">CurioVault.com</a>. Give it a look!</p>
<p>The site runs on a computer I bought for $150 on Amazon Marketplace &#8212; a used box with Intel Core 2 Duo, 2GB of RAM (upgradable to 4GB) and a 500 GB hard drive. Not a very hefty machine, but good enough to get a small site online. </p>
<p>I&#8217;ve seen many examples of MarkLogic being a great solution for huge data sets. But the productivity advantages apply just as well when dealing with a small site. Great tools help on big jobs and little. Throw in the hope that a small site will one day grow up to be a big one, and I&#8217;m excited to be building a site for myself on MarkLogic.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2012/01/curiovault-putting-the-express-license-to-work/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Models in XQuery</title>
		<link>http://blog.davidcassel.net/2011/12/models-in-xquery/</link>
		<comments>http://blog.davidcassel.net/2011/12/models-in-xquery/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 03:49:38 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[xquery]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=369</guid>
		<description><![CDATA[At MarkLogic, I work on a team that is charged with building Proof-of-Concept systems quickly and building them well enough that the developers who take over later will have a good starting point. I&#8217;d like to talk more about the framework that we&#8217;ve built to help us with those goals in future posts, but for [...]]]></description>
			<content:encoded><![CDATA[<p>At MarkLogic, I work on a team that is charged with building Proof-of-Concept systems quickly and building them well enough that the developers who take over later will have a good starting point. I&#8217;d like to talk more about the framework that we&#8217;ve built to help us with those goals in future posts, but for today, I&#8217;ll limit myself to the fact that this framework uses MVC as the major design pattern.</p>
<p>Yes, we&#8217;re talking about Model-View-Controller. I&#8217;ve had a number of conversations with people about whether MVC makes sense in an XQuery world, and I wanted to share my reasons for thinking it does.</p>
<p>The conversation typically centers on the Model part of MVC. The argument against MVC in XQuery points out that a big part of the Model&#8217;s job is to get rid of the impedance mismatch between the way data is stored (perhaps rows and columns in a relational database) and the way it is used (perhaps Java objects). In XQuery, data is both stored and used in XML, so there is no mismatch, ergo a Model is overkill. That&#8217;s a valid point as far as it goes &#8212; after all, that is one of the benefits of working with XQuery in general and MarkLogic in particular.</p>
<p>When we started with our framework, we took a VC approach &#8212; we used Views to separate out the presentation logic, and we used Controllers to handle request inputs. However, we still used library modules to do the work of taking those request inputs and turning them into some data to present. We wanted to isolate that logic so that we could write unit tests. Before long, we recognized that we were, in fact, building Models.</p>
<p>So what role does a model play in XQuery? A simpler one. Once you leave the impedance mismatch problem behind, the benefit you are left with is encapsulation. Many of our applications need functions to register, log in, and log out users, along with updating passwords and identifying the current user. Each of these is a function that we store together in a library module, which we write unit tests for and can easily pull out of one project and put into another. That&#8217;s our user model. Likewise, many applications have some central concepts to them that lend themselves to building a model, even though there is no corresponding table, as we would have in the relational world.</p>
<p>Yes, this is a thinner version of how people think of a Model in the relational world. But there are benefits to having divisions between the parts of your application, and MVC is an approach that is familiar and (when used properly) has been useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2011/12/models-in-xquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Modules databases versus the file system</title>
		<link>http://blog.davidcassel.net/2011/11/modules-databases-versus-the-file-system/</link>
		<comments>http://blog.davidcassel.net/2011/11/modules-databases-versus-the-file-system/#comments</comments>
		<pubDate>Wed, 09 Nov 2011 13:00:57 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[marklogic]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=344</guid>
		<description><![CDATA[When you point a MarkLogic application server to some source code, that code can either reside on the file system or in a modules database. Here are some reasons why you might pick one of those over the other. Modules Database Deploying code is a transactional update &#8212; there&#8217;s no need to worry that the [...]]]></description>
			<content:encoded><![CDATA[<p>When you point a MarkLogic application server to some source code, that code can either reside on the file system or in a modules database. Here are some reasons why you might pick one of those over the other.</p>
<h2>Modules Database</h2>
<ol>
<li>Deploying code is a transactional update &#8212; there&#8217;s no need to worry that the server will be reading your source files while you&#8217;re in the middle of updating them.</li>
<li>Related to #1, if you&#8217;re working in a cluster and an application server is present on multiple instances, deploying to a modules database that spans those instances will let the application server on all instances update to the new code at the same time.</li>
<li>When you&#8217;re migrating an application from one server to another, you can use <a href="http://developer.marklogic.com/code/xqsync" target="_blank">XQSync</a> to move the source code as well as the data.</li>
<li>Using a modules database is actually required for CPF. In a database where you set up content processing, check the Configure tab for the domain &#8212; the evaluation context has to be a database.</li>
</ol>
<h2>File System</h2>
<ol>
<li>When you make a change in your code, there&#8217;s no deploy step. Just hit save and then refresh your browser (or however you are accessing results). Very simple.</li>
<li>You&#8217;ve got your code in a version control system like SVN or GIT (right?), and those expect to live on the file system. I guess you could set up WebDAV and do an &#8220;svn checkout &#8230;&#8221; right into a modules database, but that feels a little weird to me. Your code probably lives in a file system directory somewhere, and you interact with the version control system from there.</li>
<li>When deploying to an integration or production server, I&#8217;ve sometimes pointed the application server to a soft link, then update the soft link on the file system after setting up a directory with the new code. I think that addresses point #1 under Module Databases, but not #2 unless you do it on a volume that is visible to all instances.</li>
</ol>
<h2>What Do I Do?</h2>
<p>Common practice among my colleagues seems to be use the file system while developing on your local box, then deploy to a modules database for integration or production servers. I&#8217;ve actually been using a modules database even for local work lately, because I&#8217;ve got an ant script that makes it simple and fast. Even with that, every now and then I forget to deploy.</p>
<p>Where does your code live? Any reasons I haven&#8217;t covered?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2011/11/modules-databases-versus-the-file-system/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Element constructors: computed and direct</title>
		<link>http://blog.davidcassel.net/2011/10/element-constructors-computed-and-direct/</link>
		<comments>http://blog.davidcassel.net/2011/10/element-constructors-computed-and-direct/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 15:30:47 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[techniques]]></category>
		<category><![CDATA[xquery]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=334</guid>
		<description><![CDATA[In XQuery, you can build an element one of two ways: computed or direct. Direct This is the simpler case, so I&#8217;ll take it first. Direct means that your XQuery code has the XML you want to build: declare namespace blog = "http://davidcassel.net/blog"; &#60;blog:example simple="true"&#62;   &#60;blog:pointless/&#62; &#60;/blog:example&#62; XML is a natural data structure for [...]]]></description>
			<content:encoded><![CDATA[<p>In XQuery, you can build an element one of two ways: computed or direct.</p>
<h2>Direct</h2>
<p>This is the simpler case, so I&#8217;ll take it first. Direct means that your XQuery code has the XML you want to build:</p>
<pre>declare namespace blog = "http://davidcassel.net/blog";</pre>
<pre>&lt;blog:example simple="true"&gt;
  &lt;blog:pointless/&gt;
&lt;/blog:example&gt;</pre>
<p>XML is a natural data structure for XQuery and this is a very simple way to construct it.</p>
<h2>Computed</h2>
<p>A computed element is less direct, but it has its benefits. Let&#8217;s take a look:</p>
<pre>declare namespace blog = "http://davidcassel.net/blog";

element { xs:QName("blog:example") } {
  attribute simple { "true" },
  element { xs:QName("blog:pointless") } { }
}</pre>
<h2>Benefits</h2>
<p>The direct method is more concise, so why would we use the computed? There are two reasons why I typically end up using them.</p>
<h3>A Conditional Attribute</h3>
<p>Sometimes you want to include an attribute only under certain circumstances. The trick is, this doesn&#8217;t work:</p>
<pre>&lt;blog:example { if ($condition) then simple="true" else () }/&gt;</pre>
<p>That&#8217;s not valid syntax &#8212; the attribute either has to be there or not, though its value can be the result of an XQuery expression. One way we can conditionally include an attribute is to build the element different in the if and else branches of the condition:</p>
<pre>if ($condition) then
  &lt;blog:example simple="true"/&gt;
else
  &lt;blog:example/&gt;</pre>
<p>As you can imagine, that can be a lousy way to go if the element has some complexity to it, for instance if it has a lot of attributes. This is one place where computed construction makes your life easier:</p>
<pre>declare namespace blog = "http://davidcassel.net/blog";

element { xs:QName("blog:example") } {
  if ($condition) then attribute simple { "true" } else (),
  element { xs:QName("blog:pointless") } { }
}</pre>
<h3>Computing the Name</h3>
<p>Another case where the computed version comes in handy is when the name of the element itself will be the result of a computation. Let&#8217;s suppose you have a map that you want to turn into a set of elements.</p>
<pre>&lt;root&gt;{
  for $key in map:keys($map)
  return element { $key } { map:get($map, $key) }
}&lt;/root&gt;</pre>
<p>There&#8217;s really no other way to do this case, but it&#8217;s simple to do this way.</p>
<p>Any other cases you can think of where computed elements are the easier way to go?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2011/10/element-constructors-computed-and-direct/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Douglas Crockford on coding standards</title>
		<link>http://blog.davidcassel.net/2011/10/douglas-crockford-on-coding-standards/</link>
		<comments>http://blog.davidcassel.net/2011/10/douglas-crockford-on-coding-standards/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 23:29:54 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=316</guid>
		<description><![CDATA[The team I&#8217;m working recently put together a set of coding standards for our XQuery work. This team was generally happy to do so and we came to agreement on a set of standards pretty quickly. The exercise brought to mind a time at a previous company where two of us started discussing aloud whether [...]]]></description>
			<content:encoded><![CDATA[<p>The team I&#8217;m working recently put together a set of coding standards for our XQuery work. This team was generally happy to do so and we came to agreement on a set of standards pretty quickly. The exercise brought to mind a time at a previous company where two of us started discussing aloud whether some coding standards would be helpful for that group. One member of the team overheard us and chimed in with an emphatic: NO! It was pretty funny in a way, because in the 2+ years I worked with him, I think that was the only time I saw him get excited about something. He was a very calm kind of guy.</p>
<p>Anyway, as we set up our XQuery standards, we chose to rely on Douglas Crockford&#8217;s <a href="http://jslint.com/">JSLint</a> to set the standards for our JavaScript code. I found the quote below in <a href="https://github.com/douglascrockford/JSLint">a README file</a> as part of JSLint and I thought it was worth sharing.</p>
<blockquote><p>The place to express yourself in programming is in the quality of your ideas,and the efficiency of execution. The role of style is the same as in literature. A great writer doesn&#8217;t express himself by putting the spaces before his commas instead of after, or by putting extra spaces inside his parentheses. A great writer will slavishly conform to some rules of style, and that in no way constrains his power to express himself creatively. See for example William Strunk&#8217;s The Elements of Style [<a href="http://www.crockford.com/wrrrld/style.html">http://www.crockford.com/wrrrld/style.html</a>].</p>
<p>This applies to programming as well. Conforming to a consistent style improves readability, and frees you to express yourself in ways that matter. JSLint here plays the part of a stern but benevolent editor, helping you to get the style right so that you can focus your creative energy where it is most needed.</p></blockquote>
<p>As someone who writes both code and prose, I could relate well to both aspects of what he was saying. I keep my copy of Strunk pretty close at handy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2011/10/douglas-crockford-on-coding-standards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Queries and Updates</title>
		<link>http://blog.davidcassel.net/2011/10/queries-and-updates/</link>
		<comments>http://blog.davidcassel.net/2011/10/queries-and-updates/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 02:10:41 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[locking]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[transactions]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=342</guid>
		<description><![CDATA[You may already know that MarkLogic sometimes runs modules as queries (read-only) and updates (read-write). The advantage of queries is that, because they run at a particular timestamp, they don&#8217;t need to deal with locks &#8212; nothing will change at that timestamp. How does the server know whether a module is a query or an [...]]]></description>
			<content:encoded><![CDATA[<p>You may already know that MarkLogic sometimes runs modules as queries (read-only) and updates (read-write). The advantage of queries is that, because they run at a particular timestamp, they don&#8217;t need to deal with locks &#8212; nothing will change at that timestamp. How does the server know whether a module is a query or an update? It performs a lexical analysis of the source code. This is all explained in section 2.3 of the <a href="http://developer.marklogic.com/learn/4.2/app-developer-guide" target="_blank">Application Developer&#8217;s Guide</a>.</p>
<p>Reading through that I was left with a couple questions. In particular, I wanted to know how smart the lexical analysis is. Turns out its pretty good (no surprise)!</p>
<h2>A Simple Query</h2>
<p>Time for some code. Here&#8217;s a simple module that we hit to see whether we have a query or an update.</p>
<pre>&lt;h1&gt;{
  if (xdmp:request-timestamp()) then "query"
  else "update"
}&lt;/h1&gt;</pre>
<p>As the documentation tells us, xdmp:request-timestamp() will return a value if and only if we&#8217;re doing a read-only query. Sure enough, when we run this module, we get &lt;h1&gt;query&lt;/h1&gt;.</p>
<h2>A Simple Update</h2>
<pre>if (0 = 1) then xdmp:document-insert("/foo.xml", &lt;foo/&gt;) else (),
&lt;h1&gt;{
  if (xdmp:request-timestamp()) then "query"
  else "update"
}&lt;/h1&gt;</pre>
<p>This one announces itself as an update. Despite the fact that the xdmp:document-insert() will never be called, the server sees this as a potential update. We&#8217;re going to use this expression as our trigger to put us into update mode.</p>
<h2>A Library Update</h2>
<p>Let&#8217;s introduce a simple library module.</p>
<pre>module namespace lib1 = "lib1";</pre>
<pre>declare function lib1:f1()
{
  if (0 = 1) then xdmp:document-insert("/foo.xml", &lt;foo/&gt;) else ()
};</pre>
<pre>declare function lib1:f2()
{
  &lt;harmless/&gt;
};</pre>
<p>The lib1:f1() function has our trigger. Let&#8217;s see what happens if we import the module but don&#8217;t call the function.</p>
<pre>import module namespace lib1 = "lib1" at "lib1.xqy";</pre>
<pre>&lt;h1&gt;{
  lib1:f2(),
  if (xdmp:request-timestamp()) then "query"
  else "update"
}&lt;/h1&gt;</pre>
<p>That&#8217;s a query &#8212; MarkLogic Server is smart enough to see that while there are update expressions in the library module, there are no calls that invoke that expression. Now let&#8217;s put in a call to f1() &#8212; our trigger function &#8212; and see what happens.</p>
<pre>import module namespace lib1 = "lib1" at "lib1.xqy";</pre>
<pre>&lt;h1&gt;{
  lib1:f1(),
  if (xdmp:request-timestamp()) then "query"
  else "update"
}&lt;/h1&gt;</pre>
<p>You guessed it, now we have an update function.</p>
<h2>Apply a Test</h2>
<p>One last thing to try: can we fool the analysis with xdmp:apply()?</p>
<pre>xquery version "1.0-ml";</pre>
<pre>import module namespace lib1 = "lib1" at "lib1.xqy";</pre>
<pre>&lt;h1&gt;{
  xdmp:apply(xdmp:function(xs:QName("lib1:f1"))),
  if (xdmp:request-timestamp()) then "query"
  else "update"
}&lt;/h1&gt;</pre>
<p>What do we get this time? The analysis shows that this is a query statement, but when the server actually runs the code, it finds itself doing an update. That breaks the rules &#8212; a query runs at a particular timestamp without locks. An update without locks would obviously cause problems. So what do we get running the query above?</p>
<pre>500 Internal Server Error</pre>
<pre>XDMP-UPDATEFUNCTIONFROMQUERY: xdmp:apply(xdmp:function(xs:QName("lib1:f1"))) --</pre>
<pre>Cannot apply an update function from a query</pre>
<p>Kaboom. Check for this when using xdmp:apply().</p>
<h2>Columbo Moment</h2>
<p>Oh and, there is just one more thing&#8230;. If you want to tell MarkLogic Server explicitly that a module should run in update mode without using a trigger expression like the one above, you can put this into your module:</p>
<pre>declare option xdmp:update "true";</pre>
<p>You might do that to avoid an XDMP-UPDATEFUNCTIONFROMQUERY while using xdmp:apply().</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2011/10/queries-and-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An XQuery Sequence question</title>
		<link>http://blog.davidcassel.net/2011/10/an-xquery-sequence-question/</link>
		<comments>http://blog.davidcassel.net/2011/10/an-xquery-sequence-question/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 22:26:16 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[xquery]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=289</guid>
		<description><![CDATA[A while ago I was posed a question by a colleague: (1,3,2)[.] -&#62; 1 (1,2,3)[.] -&#62; 1 2 3 (2,3,4)[.] -&#62; no result why? To find the answer, we need to think about what&#8217;s happening in the brackets. As discussed in one of my earlier posts, the expression in brackets gets evaluated once for each [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I was posed a question by a colleague:</p>
<blockquote>
<pre>(1,3,2)[.] -&gt; 1
(1,2,3)[.] -&gt; 1 2 3
(2,3,4)[.] -&gt; no result
why?</pre>
</blockquote>
<p>To find the answer, we need to think about what&#8217;s happening in the brackets. As discussed in <a href="http://blog.davidcassel.net/2010/07/gotcha-sequence-index-evaluation/">one of my earlier posts</a>, the expression in brackets gets evaluated once for each item in the sequence. The result of that evaluation on each item determines whether that item gets selected.</p>
<p>My initial thought was that the answer to this question was pretty simple: the &#8220;.&#8221; refers to &#8220;self&#8221;, the current item being evaluated, and the evaluation used the value of the current item. That gets us a number, which when used as a filter expression for a sequence, indicates the index of the item we want to select. We can expand the example above to this:</p>
<blockquote>
<pre>(1, 3, 2)[fn:data(.) eq fn:position()]</pre>
</blockquote>
<p>Now it&#8217;s pretty clear why we get just (1) as our answer &#8212; for this case, 1 is the only item where the value matches the position.</p>
<p>But wait, the plot thickens! XQuery allows us to throw mixed types of items into a sequence. What do we get from this:</p>
<blockquote><p>(1, &lt;a/&gt;, 3, 2, &#8220;blah&#8221;)[.]</p></blockquote>
<p>The answer is (1, &lt;a/&gt;, 3, &#8220;blah&#8221;). The expansion I gave above doesn&#8217;t hold here, because we can&#8217;t compare fn:data(&lt;a/&gt;) and fn:position() &#8212; I get an error about trying to compare an xs:untypedAtomic(&#8220;&#8221;) to a number. So what really happens? To find out, I turned to MarkLogic&#8217;s own <a href="http://john.snelson.org.uk" target="_blank">John Snelson</a>, whose familiarity with the XQuery spec is a good deal deeper than mine. Here&#8217;s what I found out:</p>
<blockquote><p>The implicit operation in the predicate is more like this:</p>
<pre>typeswitch(.)
case xs:decimal | xs:float | xs:double return . eq position()
default return fn:boolean(.)</pre>
<p>The fn:boolean() function returns true for a sequence containing a single node &#8211; so the constructed node in your last example passes the predicate. Similarly, a non-zero length string returns true from fn:boolean().</p></blockquote>
<p>So there we have it. If the value is a number, it&#8217;s compared to the position. If it&#8217;s not a number, we check whether the value is, to borrow from Douglas Crockford, &#8220;truthy&#8221;. More precisely, XQuery finds the <a href="http://www.w3.org/TR/xquery/#id-ebv" target="_blank">Effective Boolean Value</a> for the context item and uses that to decide whether the item in the sequence should be returned by the <a href="http://www.w3.org/TR/xquery/#id-filter-expr" target="_blank">filter expression</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2011/10/an-xquery-sequence-question/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Meaningful XML</title>
		<link>http://blog.davidcassel.net/2011/10/meaningful-xml/</link>
		<comments>http://blog.davidcassel.net/2011/10/meaningful-xml/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 20:05:05 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[anti-pattern]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[xquery]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=329</guid>
		<description><![CDATA[Another day, another code review. Today I came across a function that generates non-meaningful XML. This is something that at first glance feels like it has a nice structure to it, but there&#8217;s a better way. First, let take a look at the XML (I&#8217;ve changed the XML and the code to make it anonymous, [...]]]></description>
			<content:encoded><![CDATA[<p>Another day, another code review. Today I came across a function that generates non-meaningful XML. This is something that at first glance feels like it has a nice structure to it, but there&#8217;s a better way. First, let take a look at the XML (I&#8217;ve changed the XML and the code to make it anonymous, but preserved the idea; the original had several distinct param elements):</p>
<pre>&lt;search-criteria id="1"&gt;
  &lt;param key="keywords"&gt;food&lt;/param&gt;
  &lt;param key="project-name"&gt;Important Work&lt;/param&gt;
  &lt;param key="date"&gt;2011-12-31&lt;/param&gt;
&lt;/search-criteria&gt;</pre>
<p>As you can see, the function is creating generic element names (&#8220;param&#8221;) with an attribute designed to give it meaning. And here&#8217;s the function:</p>
<pre>declare function local:create-search-criteria($params as map:map) as element(search-criteria)
{
  let $form-elements := (
    "project-name",
    "date"
  )  

  let $keywords as xs:string := (map:get($params, "keyword"), "")[1]
  let $grant-id as xs:unsignedLong := local:get-next-id()

  return
    &lt;search-criteria id="{ $grant-id }"&gt;
      &lt;param key="keywords"&gt;{ $keywords }&lt;/param&gt;
      {
        for $key in $form-elements
        let $value := map:get($params, $key)
        return
          &lt;param key="{ $key }"&gt;{ $value }&lt;/param&gt;
      }
    &lt;/search-criteria&gt;
};</pre>
<h2>Why Not?</h2>
<p>It&#8217;s certainly fair to ask, &#8220;Why not do it this way?&#8221; After all, we can still use XPath to select a specific part of the XML. For instance:</p>
<pre>local:create-search-criteria($params)/param[@key = "date"]</pre>
<p>That&#8217;s good enough to get the date parameter element.</p>
<p>While that&#8217;s true, I can think of two arguments against doing it this way, one specific to MarkLogic, one that is perhaps a purist&#8217;s argument.</p>
<h2>Meaningful Structure</h2>
<p>The first reason I would avoid this structure is simply that there is a way to express it that is more concise without being unclear. As with writing, if you can say the same thing more briefly without losing clarity, then it is probably a good idea. In this situation, the param element name does not contribute to our understanding of the content.</p>
<h2>Indexes</h2>
<p>In MarkLogic, there is no way to set up a range element index that is dependent on the value of an attribute. For instance, we could not set up a range element index on param that only had the values where the key parameter is &#8220;date&#8221;. A range element attribute index doesn&#8217;t solve the problem, because that indexes the values in the attribute itself.</p>
<h2>Revised</h2>
<p>Let&#8217;s start with how we might like the XML to look:</p>
<pre>&lt;search-criteria id="1"&gt;
  &lt;keyword&gt;food&lt;/keyword&gt;
  &lt;project-name&gt;Important Work&lt;/project-name&gt;
  &lt;date&gt;2011-12-31&lt;/date&gt;
&lt;/search-criteria&gt;</pre>
<p>Now our structure is simple and concise and it will be easy to set up some useful indexes.</p>
<p>For the function, we can let the $param map govern the output structure.</p>
<pre>declare function local:create-search-criteria($params as map:map) as element(search-criteria)
{
  &lt;search-criteria id="{ local:get-next-id() }"&gt;
  {
    for $key in map:keys($params)
    return element { $key } { map:get($params, $key) }
  }
  &lt;/search-criteria&gt;
};</pre>
<p>Or if we prefer to control which fields get pulled out of the map, that&#8217;s a simple matter of setting up a sequence, similar to the original.</p>
<pre>declare function local:create-search-criteria($params as map:map) as element(search-criteria)
{
  &lt;search-criteria id="{ local:get-next-id() }"&gt;
  {
    for $key in ("keyword", "project", "date")
    return element { $key } { map:get($params, $key) }
  }
  &lt;/search-criteria&gt;
};</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2011/10/meaningful-xml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exceptional code</title>
		<link>http://blog.davidcassel.net/2011/10/exceptional-code/</link>
		<comments>http://blog.davidcassel.net/2011/10/exceptional-code/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 20:11:18 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[anti-pattern]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[xquery]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=324</guid>
		<description><![CDATA[Today I was looking into some code that was running slower than it should, and I happened across this little tidbit: let $normal :=   try {     xs:int($value)   }   catch($e) {     $value   } Yes, MarkLogic extends XQuery to add try/catch, and this is a tremendously useful feature, when [...]]]></description>
			<content:encoded><![CDATA[<p>Today I was looking into some code that was running slower than it should, and I happened across this little tidbit:</p>
<pre>let $normal :=
  try {
    xs:int($value)
  }
  catch($e) {
    $value
  }</pre>
<p>Yes, MarkLogic extends XQuery to add try/catch, and this is a tremendously useful feature, when used in the right place. In this situation, I think the person who wrote the code either didn&#8217;t know how to write this a different way, or didn&#8217;t realize that try/catch is typically slower. Here it is, properly done:</p>
<pre>let $normal :=
  if ($value castable as xs:int) then
    xs:int($value)
  else
    $value</pre>
<p>Does it matter? To find out, let&#8217;s ask the profiler. I made a call to the function in CQ and clicked the profiler button, once for each case. Of course, other things happen in the function. In fact, this function calls the above expression over 800 times for a real-world case.</p>
<ul>
<li>try/catch &#8212; 0.29 seconds</li>
<li>if/then &#8212; 0.029 seconds</li>
</ul>
<p>That&#8217;s an order of magnitude difference.</p>
<p>Moral of the story: as with most languages, exception handling is meant for exception cases. If the catch gets invoked, it should be an unusual case that can&#8217;t reasonably be handled by the normal flow of the program.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2011/10/exceptional-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

