<?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>tatiyants.com</title>
	<atom:link href="http://tatiyants.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://tatiyants.com/</link>
	<description>geek humor and other drivel</description>
	<lastBuildDate>Sun, 01 Jan 2023 21:20:59 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7</generator>
	<item>
		<title>How To Navigate JSON Trees in Postgres using Recursive CTEs</title>
		<link>http://tatiyants.com/how-to-navigate-json-trees-in-postgres-using-recursive-ctes/</link>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Thu, 09 Feb 2017 15:24:55 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[howTo]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Postgres]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=3001</guid>

					<description><![CDATA[Tutorial on using Postgres recursive Common Table Expressions (CTEs) to navigate a JSON tree structure.]]></description>
										<content:encoded><![CDATA[<p>I recently ran into an interesting challenge trying to use&nbsp;Postgres to work with JSON trees. Specifically, I had to figure out how to navigate a tree structure stored as <code>JSONB</code> in a Postgres table. Here&#8217;s how I did it.</p>
<h2>The Setup</h2>
<p>Let&#8217;s start by defining the schema. We&#8217;ll create a table that will store org charts as a <code>JSONB</code> object:</p>
<pre class="brush: sql">CREATE TABLE org_charts (
  id    BIGSERIAL PRIMARY KEY,
  chart JSONB
);</pre>
<p>Next, let&#8217;s define the&nbsp;JSON. It&#8217;s going to be a recursive structure of employee nodes with a <code>reports</code>&nbsp;collection containing&nbsp;the employee&#8217;s direct reports. Since there can be multiple levels of reporting, our org chart can be arbitrarily deep:</p>
<pre class="brush: js">{
    "id": 1,
    "name": "Charles Montgomery Burns",
    "title": "Owner",
    "reports": [
        {
            "id": 2,
            "name": "Waylon Smithers, Jr."
        },
        {
            "id": 3,
            "name": "Inanimate carbon rod",
            "reports": [
                {
                    "id": 4,
                    "name": "Homer Simpson",
                    "title": "Safety Engineer"
                }
            ]
        },
        {
            "id": 5,
            "name": "Lenny Leonard"
        },
        {
            "id": 6,
            "name": "Carl Carlson"
        },
        {
            "id": 7,
            "name": "Frank Grimes",
            "status": "deceased"
        }
    ]
}</pre>
<h2>The Query</h2>
<p>We would like to write a query that can navigate this tree and, for instance, print out the names of all employees. To do that, we need to use Postgres&#8217; powerful <a href="https://www.postgresql.org/docs/9.1/static/queries-with.html">recursive common table expression (CTE)</a>. Recursive CTEs sound very intimidating, but are actually fairly straight forward to write.&nbsp;Here&#8217;s the one I wrote for this purpose:</p>
<pre class="brush: sql">WITH RECURSIVE reports (id, json_element) AS (
  -- non recursive term
  SELECT
    id,
    chart
  FROM org_charts

  UNION

  -- recursive term
  SELECT
    id,
    CASE
    WHEN jsonb_typeof(json_element) = 'array'
      THEN jsonb_array_elements(json_element)
    WHEN jsonb_exists(json_element, 'reports')
      THEN jsonb_array_elements(json_element -&gt; 'reports')
    END AS json_element
  FROM
    reports
  WHERE
    jsonb_typeof(json_element) = 'array' OR jsonb_typeof(json_element) = 'object'
)</pre>
<p>Let&#8217;s dissect this a bit. The query starts with:</p>
<pre class="brush: sql">WITH RECURSIVE reports (id, json_element) AS (
</pre>
<p>Here, we&#8217;re declaring a recursive CTE called <code>reports</code>, which takes two parameters <code>id</code>&nbsp;and <code>json_element</code>. Note that parameters represent&nbsp;the columns being returned by the overall query as well as internal subqueries.</p>
<p>Next, we define the <strong>non-recursive term</strong>:</p>
<pre class="brush: sql">-- non recursive term
  SELECT
    id,
    chart
  FROM org_charts
</pre>
<p>This query tells Postgres how to start evaluating the CTE.&nbsp;It&#8217;s evaluated first (and only once) and its results drive the rest of the query. Note that this query <strong>must</strong> return two columns that match those defined by the CTE (<code>id</code>&nbsp;and <code>json_element</code>&nbsp;in this case).</p>
<p>After the non-recursive term,&nbsp;we need to define <strong>the recursive term</strong>:</p>
<pre class="brush: sql">-- recursive term
  SELECT
    id,
    CASE
    WHEN jsonb_typeof(json_element) = 'array'
      THEN jsonb_array_elements(json_element)
    WHEN jsonb_exists(json_element, 'reports')
      THEN jsonb_array_elements(json_element -&gt; 'reports')
    END AS json_element
  FROM
    reports
  WHERE
    jsonb_typeof(json_element) = 'array' OR jsonb_typeof(json_element) = 'object'
</pre>
<p>A few things to note here:</p>
<ul>
<li>this query references the CTE itself (<code>FROM reports</code>), which is what allows it to be recursive.</li>
<li>this query <strong>must</strong> also return two columns that represent the <code>id</code>&nbsp;and <code>json_element</code>.</li>
<li>You <strong>must</strong> combine the results of the non recursive term and the recursive term using <code>UNION</code>&nbsp;or <code>UNION ALL</code>.</li>
</ul>
<p>Now, let&#8217;s talk about what this query is doing. Essentially, it&#8217;s unrolling the nested JSON structure into rows. If it runs into a JSON array, it creates one row per each member using <code>jsonb_array_elements()</code> function. If it runs into an element that contains the&nbsp;<code>reports</code>&nbsp;collection, it unrolls that as well using <code>jsonb_array_elements()</code>. Finally, it only looks at&nbsp;JSON arrays or objects (and not values or NULLs).</p>
<h2>The Results</h2>
<p>So, how do we actually run this CTE?&nbsp;By simply treating <code>reports</code>&nbsp;as any other table:</p>
<pre class="brush: sql">SELECT * FROM reports;
</pre>
<p>Running the query above results in the following:</p>
<table>
<thead>
<tr>
<th>id</th>
<th>json_element</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>
<pre class="brush: js; gutter: false">{
    "id": 1,
    "name": "Charles Montgomery Burns",
    "title": "Owner",
    "reports": [
        {
            "id": 2,
            "name": "Waylon Smithers, Jr."
        },
        {
            "id": 3,
            "name": "Inanimate carbon rod",
            "reports": [
                {
                    "id": 4,
                    "name": "Homer Simpson",
                    "title": "Safety Engineer"
                }
            ]
        },
        {
            "id": 5,
            "name": "Lenny Leonard"
        },
        {
            "id": 6,
            "name": "Carl Carlson"
        },
        {
            "id": 7,
            "name": "Frank Grimes",
            "status": "deceased"
        }
    ]
}</pre>
</td>
</tr>
<tr>
<td>1</td>
<td>
<pre class="brush:js; gutter: false">{
    "id": 2, 
    "name": "Waylon Smithers, Jr."
}
</pre>
</td>
</tr>
<tr>
<td>1</td>
<td>
<pre class="brush:js; gutter: false">{
    "id": 3, 
    "name": "Inanimate carbon rod", 
    "reports": [
        {
            "id": 4, 
            "name": "Homer Simpson", 
            "title": "Safety Engineer"
        }
    ]
}
</pre>
</td>
</tr>
<tr>
<td>1</td>
<td>
<pre class="brush:js; gutter: false">{
    "id": 5, 
    "name": "Lenny Leonard"
}
</pre>
</td>
</tr>
<tr>
<td>1</td>
<td>
<pre class="brush:js; gutter: false">{
    "id": 6, 
    "name": "Carl Carlson"
}
</pre>
</td>
</tr>
<tr>
<td>1</td>
<td>
<pre class="brush:js; gutter: false">{
    "id": 7, 
    "name": "Frank Grimes", 
    "status": "deceased"
}
</pre>
</td>
</tr>
<tr>
<td>1</td>
<td>NULL</td>
</tr>
<tr>
<td>1</td>
<td>
<pre class="brush:js; gutter: false">{    
    "id": 4, 
    "name": "Homer Simpson", 
    "title": "Safety Engineer"
}
</pre>
</td>
</tr>
</tbody>
</table>
<p>As you can see here, our query created one row per employee plus a NULL. To be honest, I&#8217;m not sure why the NULL row is being returned (I tried but failed to get rid of it). That said, it&#8217;s easy enough to filter the NULL row out.</p>
<p>To get the list of names (which was our original goal), we can do this:</p>
<pre class="brush: sql">SELECT json_element -&gt; 'name' AS employee_name
FROM reports
WHERE jsonb_exists(json_element, 'name');
</pre>
<p>Here&#8217;s we&#8217;re looking only at those rows that contain the element <code>name</code>&nbsp;and then returning&nbsp;the value of <code>name:</code></p>
<table>
<thead>
<tr>
<th>employee_name</th>
</tr>
</thead>
<tbody>
<tr>
<td>&#8220;Charles Montgomery Burns&#8221;</td>
</tr>
<tr>
<td>&#8220;Waylon Smithers, Jr.&#8221;</td>
</tr>
<tr>
<td>&#8220;Inanimate carbon rod&#8221;</td>
</tr>
<tr>
<td>&#8220;Lenny Leonard&#8221;</td>
</tr>
<tr>
<td>&#8220;Carl Carlson&#8221;</td>
</tr>
<tr>
<td>&#8220;Frank Grimes&#8221;</td>
</tr>
<tr>
<td>&#8220;Homer Simpson&#8221;</td>
</tr>
</tbody>
</table>
<p>Overall,&nbsp;using Postgres recursive CTEs to navigate JSON trees proved to be a challenging, but rewarding exercise. If you grok the basics, it&#8217;s fairly straight forward to build up complex queries.</p>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/postgres-query-plan-visualization/" title="Postgres Query Plan Visualization">Postgres Query Plan Visualization</a></li>
<li><a href="https://tatiyants.com/xml-databases/" title="XML Databases">XML Databases</a></li>
<li><a href="https://tatiyants.com/how-and-when-to-use-various-gorm-querying-options/" title="How and When to Use Various GORM Querying Options">How and When to Use Various GORM Querying Options</a></li>
<li><a href="https://tatiyants.com/how-to-create-a-bar-chart-archive-widget-in-wordpress/" title="How to Create a Bar Chart Archive Widget In WordPress">How to Create a Bar Chart Archive Widget In WordPress</a></li>
<li><a href="https://tatiyants.com/how-to-use-html5-data-attributes-with-jquery-and-selenium/" title="How To Use HTML5 Data-* Attributes with JQuery and Selenium">How To Use HTML5 Data-* Attributes with JQuery and Selenium</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Postgres Query Plan Visualization</title>
		<link>http://tatiyants.com/postgres-query-plan-visualization/</link>
					<comments>http://tatiyants.com/postgres-query-plan-visualization/#comments</comments>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Tue, 19 Jan 2016 14:51:21 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[pev]]></category>
		<category><![CDATA[Postgres]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=2971</guid>

					<description><![CDATA[Postgres Explain Visualizer (Pev) is a tool I wrote to make EXPLAIN output easier to grok. It creates a graphical representation of the query plan.]]></description>
										<content:encoded><![CDATA[<p>After a recent stint in query optimization, I once again found myself wanting a better way to view query plans produced by <a href="http://www.postgresql.org/docs/current/static/sql-explain.html">EXPLAIN</a>. So, I finally decided to do something about it and the result is <a href="http://tatiyants.com/pev/">Postgres EXPLAIN Visualizer (or Pev)</a>:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2016/01/pev_plan.png"><img decoding="async" class="aligncenter" width="1033" src="http://tatiyants.com/wp-content/uploads/2016/01/pev_plan.png" alt="Pev plan"></a></p>
<h2>Why Pev</h2>
<p>I wanted a tool that can make plans simple to understand and be visually pleasing. More specifically, I wanted:</p>
<ul>
<li>minimal visual noise</li>
<li>insights</li>
<li>high degree of customization</li>
<li>plan in context of the query</li>
</ul>
<p>Let&#8217;s see how Pev helps with these. I&#8217;ll use the plan produced by the query below for illustration (you can run this query against the <a href="http://pgfoundry.org/projects/dbsamples/">dellstore2 database</a>):</p>
<pre class="brush: sql">SELECT C.STATE,SUM(O.NETAMOUNT), SUM(O.TOTALAMOUNT)
FROM CUSTOMERS C
  INNER JOIN CUST_HIST CH ON C.CUSTOMERID = CH.CUSTOMERID
  INNER JOIN ORDERS O ON CH.ORDERID = O.ORDERID
GROUP BY C.STATE
  LIMIT 10 OFFSET 1
</pre>
<p>I should also note that Pev only works with EXPLAIN Plans in JSON format. To produce one, use this code:</p>
<pre class="brush: sql">EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)
</pre>
<h2>Node Visualization</h2>
<p>First off, Pev uses a classic tree graph to visualize the plan. I find this to be easier to view than the left-to-right tree used by PgAdmin:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2016/01/pgadmin_query_plan.png"><img decoding="async" class="aligncenter" width="823" src="http://tatiyants.com/wp-content/uploads/2016/01/pgadmin_query_plan.png" alt="pgAdmin query plan"></a></p>
<p>By default, each node displays its type + relevant details (like the object being scanned or the join condition), duration, and key insights (like whether this node is some type of outlier):</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2016/01/pev_default_node_view.png"><img decoding="async" class="aligncenter" width="551" src="http://tatiyants.com/wp-content/uploads/2016/01/pev_default_node_view.png" alt="pev default node view"></a></p>
<p>Speaking of insights, Pev currently calculates the following:<br />
&#8211; outlier nodes (largest, slowest, costliest)<br />
&#8211; nodes with bad planner estimates (planner missed by a factor of 100 or more)</p>
<p>Pev also allows for various customizations, like showing planner estimate details and a graph of either rows, duration, or cost:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2016/01/pev_node_expanded_view.png"><img decoding="async" class="aligncenter" width="420" src="http://tatiyants.com/wp-content/uploads/2016/01/pev_node_expanded_view.png" alt="Pev node expanded view"></a></p>
<p>If you want to see absolutely everything Postgres knows about the node, just click on the title to get the extended view:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2016/01/pev_expanded_view.png"><img decoding="async" class="aligncenter" width="426" src="http://tatiyants.com/wp-content/uploads/2016/01/pev_expanded_view.png" alt="Pev expanded view"></a></p>
<p>Using these customizations (available in the settings menu on the left), you can easily create graphs like the one below which shows how fast each node is:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2016/01/pev_node_speed_tree.png"><img decoding="async" class="aligncenter" width="535" src="http://tatiyants.com/wp-content/uploads/2016/01/pev_node_speed_tree.png" alt="pev node speed tree"></a></p>
<h2>Query Display</h2>
<p>I personally find it hard to mentally map the plan I&#8217;m seeing to the query that generated it. Pev helps in this regard by showing you the query right next to your node and <em>highlighting the relevant part</em> wherever possible. Just click the little blue database icon inside the node:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2016/01/pev_highlighted_query.png"><img decoding="async" class="aligncenter" width="460" src="http://tatiyants.com/wp-content/uploads/2016/01/pev_highlighted_query.png" alt="Pev highlighted query"></a></p>
<p>I must admit that highlighting the relevant part of the query is quite rudimentary at this point, but I&#8217;m hopeful that it can be improved in the future.</p>
<h2>Two more things</h2>
<p>Pev is heavily influenced by the excellent <a href="http://explain.depesz.com/">explain.depesz.com</a>. I learned a lot about how Postgres planner works from using it and reading the help.</p>
<p>If you do use Pev, please let me know how you like it at <a href="https://twitter.com/AlexTatiyants">@alexTatiyants</a>. If you want to make it better, the code is on <a href="https://github.com/AlexTatiyants/pev">github</a>.</p>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/how-to-navigate-json-trees-in-postgres-using-recursive-ctes/" title="How To Navigate JSON Trees in Postgres using Recursive CTEs">How To Navigate JSON Trees in Postgres using Recursive CTEs</a></li>
<li><a href="https://tatiyants.com/how-and-when-to-use-various-gorm-querying-options/" title="How and When to Use Various GORM Querying Options">How and When to Use Various GORM Querying Options</a></li>
<li><a href="https://tatiyants.com/xml-databases/" title="XML Databases">XML Databases</a></li>
<li><a href="https://tatiyants.com/good-devs-dont-like-magic/" title="Good Devs Don&#8217;t Like Magic">Good Devs Don&#8217;t Like Magic</a></li>
<li><a href="https://tatiyants.com/database-source-control-revisited/" title="Database Source Control Revisited">Database Source Control Revisited</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>http://tatiyants.com/postgres-query-plan-visualization/feed/</wfw:commentRss>
			<slash:comments>19</slash:comments>
		
		
			</item>
		<item>
		<title>How to Automatically Back up Photos from Android to Mac for Free</title>
		<link>http://tatiyants.com/how-to-automatically-back-up-photos-from-android-to-mac-for-free/</link>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Mon, 04 Aug 2014 14:20:59 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[ Automator]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[photography]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=2956</guid>

					<description><![CDATA[If you'd like to automatically download pics and videos from your Android phone to your Mac, this post is for you. All you need is a free Dropbox account and some elbow grease.]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;d like to automatically download pics and videos from your Android phone to your Mac, this post is for you. Here&#8217;s what you&#8217;ll need:</p>
<ol>
<li>Android phone with pictures on it</li>
<li><strong>Free</strong> Dropbox account &#8211; feel free to use <a href="https://db.tt/gj4vyuxo">my referral link</a></li>
<li><strong>Free</strong> <a href="https://www.dropbox.com/android">Dropbox app on your Android</a></li>
<li><strong>Free</strong> <a href="https://www.dropbox.com/install">Dropbox app on your Mac</a></li>
<li>Automator script</li>
</ol>
<p>Here&#8217;s a diagram of the overall process:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/08/android_mac_dropbox_photo_backup.png"><img decoding="async" class="aligncenter" width="470" src="http://tatiyants.com/wp-content/uploads/2014/08/android_mac_dropbox_photo_backup.png" alt="android mac dropbox photo backup"></a></p>
<h3>1. Install / Configure Dropbox Android App</h3>
<p>First thing you need to do is to enable &#8220;Camera Upload&#8221; capability in the Dropbox Android app. If you&#8217;re installing it for the first time, the app will prompt you during setup. Otherwise, <em>go to Settings &gt; Turn on Camera Upload</em>.</p>
<h3>2. Install Dropbox Mac App</h3>
<p>If you haven&#8217;t done so already, install Dropbox on your Mac. Once the phone starts uploading pictures, you&#8217;ll see them a folder called &#8220;Camera Uploads&#8221;.</p>
<h3>3. Set up Automator script</h3>
<p>At this point, you should have pictures automatically downloading to your Mac. You could stop here, and if you&#8217;re already paying for Dropbox, you very well may. However, if you&#8217;re using the free 2GB version, you&#8217;ll need to make sure that you don&#8217;t run out of space.</p>
<p>The way to do that is with an Automator script. You can configure your Mac to automatically move files from the folder used by Dropbox to another folder. To do this, follow the steps below:</p>
<ol>
<li>launch Automator</li>
<li>select &#8220;Folder&#8221; action</li>
<li>select &#8220;Files and Folders&#8221; from the Library list</li>
<li>select &#8220;Move Finder Items&#8221;</li>
<li>drag the action to the large empty part of the screen</li>
<li>select &#8220;Camera Uploads&#8221; as the source folder</li>
<li>select some other folder (like Pictures) as the destination (To:) folder</li>
<li>save the action</li>
</ol>
<p>Here&#8217;s a screenshot of the configured action:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/08/automator_dropbox_backup.png"><img decoding="async" class="aligncenter" width="860" src="http://tatiyants.com/wp-content/uploads/2014/08/automator_dropbox_backup.png" alt="automator dropbox backup"></a></p>
<p>And that&#8217;s all there is to it!</p>
<h2>So Why Not Just Use Google Auto Backup?</h2>
<p>You may be wondering why not just use Google+ Auto Backup. It comes standard on your Android and does indeed back up your photos to the Google&#8217;s cloud. However, getting those photos onto your computer <strong>automatically</strong> is not easy (or, in my case, possible).</p>
<p>As of today (August 2014), you have 2 options: (1) use the web UI to individually select photos and then download them or (2) use Picasa&#8217;s &#8220;import from Google+&#8221; feature. The first option is a non-starter and the second option didn&#8217;t work for me. For some reason, Picasa can only see (and sync) last day&#8217;s photos.</p>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/how-to-debug-in-ie-on-a-mac/" title="How to Debug in IE on a Mac">How to Debug in IE on a Mac</a></li>
<li><a href="https://tatiyants.com/upgrading-my-mac-mini/" title="Upgrading My Mac Mini">Upgrading My Mac Mini</a></li>
<li><a href="https://tatiyants.com/lytro-a-revolution-in-picture-taking/" title="Lytro: A revolution in picture taking?">Lytro: A revolution in picture taking?</a></li>
<li><a href="https://tatiyants.com/living-in-cloud-city/" title="Living in Cloud City">Living in Cloud City</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Customize JFree Charts</title>
		<link>http://tatiyants.com/how-to-customize-jfree-charts/</link>
					<comments>http://tatiyants.com/how-to-customize-jfree-charts/#comments</comments>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Thu, 31 Jul 2014 23:08:37 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[charting]]></category>
		<category><![CDATA[JFree]]></category>
		<category><![CDATA[UX]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=2949</guid>

					<description><![CDATA[In this tutorial, I'll explain how to customize JFree charts to look clean and modern.]]></description>
										<content:encoded><![CDATA[<p><a href="http://www.jfree.org/jfreechart/index.html">JFree Chart</a> is an open-source charting library for the JVM. It&#8217;s been around forever, it&#8217;s got a ton of options, and it&#8217;s capable of generating some really great charts.</p>
<p>That said, it&#8217;s default output is not great. There&#8217;s a fair amount of visual noise and default color choices could be better. So, in this tutorial, I&#8217;ll explain how to customize your JFree chart to look clean and modern.</p>
<h2>1. Generate Basic Chart</h2>
<p>We&#8217;ll start by generating a <a href="http://www.java2s.com/Code/Java/Chart/JFreeChartBarChartDemo.htm">simple bar chart</a>:</p>
<pre class="brush: groovy">Integer width = 500, height = 300

JFreeChart chart = ChartFactory.createBarChart(
    "",                         // chart title
    "",                         // domain axis label
    "",                         // range axis label
    createDataset(),            // data
    PlotOrientation.VERTICAL,   // orientation
    true,                       // include legend
    true,                       // tooltips?
    false                       // URLs?
)

ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection())
ChartUtilities.saveChartAsPNG(new File("bar-chart.png"), chart, width, height, info)
</pre>
<p>This is what the output looks like:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_default_output.png"><img decoding="async" class="aligncenter" width="505" src="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_default_output.png" alt="JFree bar chart default output"></a></p>
<p>Though it&#8217;s not terrible, there are a few issues:</p>
<ul>
<li>unnecessary borders for both the overall chart, the plot area, and the label</li>
<li>unnecessary gradient fill for the bars</li>
<li>unnecessary gray plot background</li>
<li>default color scheme is not aesthetically pleasing (at least to my eye)</li>
<li>legend values are smushed together</li>
</ul>
<p>So, let&#8217;s fix that shall we?</p>
<h2>2. Format the Plot Area</h2>
<p>Let&#8217;s start by cleaning up the plot area. In particular, let&#8217;s get rid of various lines as well as that background gray:</p>
<pre class="brush: groovy">CategoryPlot plot = chart.categoryPlot
plot.backgroundPaint = Color.white
plot.domainGridlinePaint = Color.white
plot.rangeGridlinePaint = Color.white
plot.outlineVisible = false
</pre>
<p>This is what the chart now looks like:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_with_plot_area_cleaned_up.png"><img decoding="async" class="aligncenter" width="499" src="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_with_plot_area_cleaned_up.png" alt="Jfree bar chart with plot area cleaned up"></a></p>
<h2>3. Format the Bars</h2>
<p>Next, let&#8217;s make the bars look nicer. We&#8217;ll remove the gradient change the default colors:</p>
<pre class="brush: groovy">// remove the gradient fill
plot.renderer.gradientPaintTransformer = null           
plot.renderer.barPainter = new StandardBarPainter()

Paint[] colors = [
    new Color(0, 172, 178),      // blue
    new Color(239, 70, 55),      // red
    new Color(85, 177, 69)       // green
]

// change the default colors
for (int i = 0; i &lt; 4; i++) {
    plot.renderer.setSeriesPaint(i, colors[i % colors.length])
}
</pre>
<p>Our chart now looks like this:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_with_formatted_plot_area_and_bars.png"><img decoding="async" class="aligncenter" width="498" src="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_with_formatted_plot_area_and_bars.png" alt="Jfree bar chart with formatted plot area and bars"></a></p>
<h2>4. Format the Legend</h2>
<p>The next item on our hit list is the legend. There are many ways one can format the legend, but I&#8217;m going to focus on (1) removing the border and separating it with extra padding and (2) giving each item its own line. Note that the second fix will require us to increase the height of the chart (In my example I&#8217;ll increase it from 300px to 400px).</p>
<p>Here&#8217;s the code:</p>
<pre class="brush: groovy">chart.legend.frame = BlockBorder.NONE
chart.legend.itemLabelPadding = new RectangleInsets(5.0, 2.0, 10.0, width)
chart.legend.padding = new RectangleInsets(20.0, 20.0, 0.0, 0.0)
</pre>
<p>Although there doesn&#8217;t appear to be an option to automatically put legend items on separate lines, there&#8217;s a trick you can use. The trick is to set the right padding to something large, like the width of the chart.</p>
<p>Ok, here&#8217;s what our chart now looks like:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_fully_formatted.png"><img decoding="async" class="aligncenter" width="497" src="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_fully_formatted.png" alt="Jfree bar chart fully formatted"></a></p>
<h2>5. Remove Even More Clutter</h2>
<p>For the final step, I will simplify the chart even more by getting rid of the range (Y) axis and putting value labels directly on the bars. Furthermore, I will make the category labels less pronounced.</p>
<pre class="brush: groovy">// add values to bars
plot.renderer.baseItemLabelGenerator = new StandardCategoryItemLabelGenerator()
plot.renderer.baseItemLabelsVisible = true

// hide y axis
NumberAxis rangeAxis = (NumberAxis) plot.rangeAxis
rangeAxis.visible = false

// format the x axis
CategoryAxis domainAxis = plot.domainAxis
domainAxis.tickLabelPaint = new Color(160, 163, 165)
domainAxis.categoryLabelPositionOffset = 4
domainAxis.lowerMargin = 0
domainAxis.upperMargin = 0
domainAxis.categoryMargin = 0.2
</pre>
<p>And here&#8217;s the final chart:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_final_version.png"><img decoding="async" class="aligncenter" width="496" src="http://tatiyants.com/wp-content/uploads/2014/07/jfree_bar_chart_final_version.png" alt="jfree bar chart final version"></a></p>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/jenkins-build-monitor/" title="Jenkins Build Monitor">Jenkins Build Monitor</a></li>
<li><a href="https://tatiyants.com/lipstick-on-a-pig-is-not-ux/" title="Lipstick on a Pig is Not UX">Lipstick on a Pig is Not UX</a></li>
<li><a href="https://tatiyants.com/charting-libraries-for-web-applications/" title="Charting Libraries For Web Applications">Charting Libraries For Web Applications</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>http://tatiyants.com/how-to-customize-jfree-charts/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>A Second Look at Facebook&#8217;s React</title>
		<link>http://tatiyants.com/a-second-look-at-facebooks-react/</link>
					<comments>http://tatiyants.com/a-second-look-at-facebooks-react/#comments</comments>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Tue, 27 May 2014 17:31:48 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[angular]]></category>
		<category><![CDATA[React]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=2934</guid>

					<description><![CDATA[React is a very impressive library for developing fast, component-based UIs. That said, it's not a full framework and will likely require additional libraries in order to build large apps.]]></description>
										<content:encoded><![CDATA[<p>When I first heard about Facebook&#8217;s <a href="http://facebook.github.io/react/index.html">React library</a>, I came away unimpressed. First, it came from Facebook (groan!). Second, aside from claims of really fast rendering, I didn&#8217;t see what the big deal was. And finally, it seemed like React&#8217;s proponents went out of their way to bash current leaders, namely Angular and Ember.</p>
<p>Well, I was (and still am) a huge fan of Angular. I&#8217;ve made the necessary (and significant) time investment to learn it and can now do pretty much whatever I need with it. Therefore, constantly hearing about how some wet-behind-the-ears framework from Facebook (groan!) was so much better than my beloved Angular did nothing to endear me to it.</p>
<p>And so, as is my custom, I assumed that React was a flash-in-the-pan, here-today-gone-tomorrow kind of framework and decided to simply ignore it until that happened. This was a fine plan except for one flaw: React refused to go away. On the contrary, it seemed like every other day someone was signing its praises.</p>
<p>Since ignoring React was getting me nowhere, I decided to give in and take a closer look. Here&#8217;s what I found.</p>
<p><em>tldr; React is a very impressive library for developing fast, component-based UIs. That said, it&#8217;s not a full framework and will likely require additional libraries in order to build large apps.</em></p>
<h2>What Is This React You Speak Of?</h2>
<p>React is a JavaScript library designed around component-based UIs and one-way data flow. It&#8217;s simple, internally consistent, and theoretically sound. Oh, and it&#8217;s very, very fast.</p>
<h3>Component Driven UI</h3>
<p>React is all about components. Its creators firmly believe in components as the right way to do UI and they&#8217;ve built a framework which goes out of its way to push the developer in that direction.</p>
<p>I couldn&#8217;t agree more with this approach. Components <em>are</em> a really good way to structure application UI for two reasons. First, it&#8217;s much easier to reason about (and build and debug) an application when you can restrict your mental model to a specific component within it.</p>
<p>Second, a component-centric mindset forces you to look for and extract common patterns used in your application into reusable pieces. Instead of thinking <em>&#8220;To implement a table filter, I&#8217;ll just add a few tags to my template&#8221;</em>, you think <em>&#8220;To implement a table filter, I&#8217;ll add a new component to my app and drop that component into my template&#8221;</em>.</p>
<p>By the way, unless component orientation is front and center in your framework, you won&#8217;t think this way. In fact, unless your framework not only encourages, but <em>makes it easy</em> to create components, you won&#8217;t. For example, Angular definitely has the concept of components in the form of <a href="https://docs.angularjs.org/guide/directive">directives</a>. This is great, except that creating directives is not trivial.</p>
<p>To create directives you need to have a deep understanding of how Angular&#8217;s runtime is managed (compiling vs linking), how scope inheritance works (isolated vs. parent vs. child), and possibly what transclusion is. And so, many Angular devs simply ignore directives and use templates instead (I certainly was in this category until fairly recently).</p>
<h3>Immutability</h3>
<p>React is also all about immutability. Data flow between components is one-way and immutable by default. There&#8217;s a special ceremony around mutating state.</p>
<p>Again, this is a fantastic idea. Making state mutations so explicit and intentional forces the developer to really think about the flow of data within the app. It encourages eliminating needless state (such as creating separate variables to keep track of list counts) and makes bugs due to state inconsistencies between different parts of the app less likely.</p>
<h2>Ok, So Can You Build Apps With It?</h2>
<p>It&#8217;s important to remember that React (unlike Angular or Ember) is not a full framework. It is about the UI (or, as its website puts it <em>&#8220;React is the V in MVC&#8221;</em>). It gives you everything you need to create and render components, but it is missing a few things:</p>
<ul>
<li>module system</li>
<li>routing</li>
<li>model management</li>
<li>server access</li>
</ul>
<p>There are many options for each of these available on <a href="https://github.com/facebook/react/wiki/Complementary-Tools">React&#8217;s Complementary Tools page</a>.</p>
<p>Another thing to consider is testing. Facebook has its own <a href="http://facebook.github.io/jest/">test runner called Jest</a>, which makes it easier to test React components. I haven&#8217;t tried it yet, but it does look similar to <a href="http://karma-runner.github.io/0.12/index.html">Angular&#8217;s Karma</a> (which by the way is an excellent test runner).</p>
<h3>Integration With Angular</h3>
<p>Looking at the list of missing items, one can&#8217;t help but notice that Angular has support for all of these. Given that, one can&#8217;t help but wonder whether Angular and React can be combined.</p>
<p>It turns out that it&#8217;s at least <a href="http://www.quora.com/Pete-Hunt/Posts/Facebooks-React-vs-AngularJS-A-Closer-Look">possible to combine React and Angular</a>. It boils down to calling React&#8217;s <code>renderComponent()</code> method from Angular directive&#8217;s <code>$watch()</code> method.</p>
<p>I haven&#8217;t made up my mind about whether this is a good idea. After all, you still need to go through the hassle of creating directives, and you now have to also figure out what belongs in that directive and what belongs in React&#8217;s component.</p>
<h3>React or Angular</h3>
<p>So, should Angular devs switch to React? It&#8217;s difficult for me to answer this question because, while I understand where React excels, I don&#8217;t know what the warts are. I don&#8217;t know what it&#8217;s like to write large apps in React, what it&#8217;s like to debug weird issues in React.</p>
<p>I suspect that skilled Angular devs can get by just fine with Angular. If you know what you&#8217;re doing with Angular, you can get a lot of mileage out of it. Unless you have some crazy performance problem which requires a rewrite, there may not be enough of a reason to switch.</p>
<p>On the other hand, new Angular devs could well benefit from taking a closer look at React. It does a better job than Angular in forcing you to do the right thing (whether it is organizing your application in terms of components or forcing you to manage state better).</p>
<h2>Final Thought</h2>
<p>React is a great library for creating UI. It solves some very complex problems in a clever and elegant way. It strongly encourages good habits. It is simple to grok.</p>
<p>It&#8217;s also true that React doesn&#8217;t give you everything you need to build apps. You need to make choices about a set of supporting technologies before you can really get going with it. Some may really like this best-of-breed approach, while others prefer a single, comprehensive framework.</p>
<p>I think that React&#8217;s adoption may be aided by a comprehensive framework built around it (à la <a href="http://marionettejs.com/">Marionette</a>). Facebook seems to be moving in that direction with <a href="http://facebook.github.io/react/blog/2014/05/06/flux.html">Flux</a>, but nothing concrete has materialized as of yet.</p>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/groking-angular-dependency-injection-and-testing/" title="Groking Angular: Dependency Injection and Testing">Groking Angular: Dependency Injection and Testing</a></li>
<li><a href="https://tatiyants.com/how-to-configure-intellij-idea-for-angular-js-testing/" title="How to Configure IntelliJ IDEA For Angular JS Testing">How to Configure IntelliJ IDEA For Angular JS Testing</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>http://tatiyants.com/a-second-look-at-facebooks-react/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Groking Angular: Dependency Injection and Testing</title>
		<link>http://tatiyants.com/groking-angular-dependency-injection-and-testing/</link>
					<comments>http://tatiyants.com/groking-angular-dependency-injection-and-testing/#comments</comments>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Mon, 19 May 2014 13:42:59 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[angular]]></category>
		<category><![CDATA[dependencyInjection]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[testing]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=2927</guid>

					<description><![CDATA[Although Angular's syntax for Dependency Injection is sometimes difficult to understand, it's actually quite straight forward to use for testing.]]></description>
										<content:encoded><![CDATA[<p>When I first learned about testing Angular applications, I found it surprisingly difficult to understand. In particular, I kept getting hung up on the strange syntax required to set up test dependencies.</p>
<p>As it turns out, there is nothing especially hard about DI and testing in Angular. You just need to get used to the syntax. One way to do so is to pretend that it&#8217;s something else. Allow me to explain.</p>
<h2>Angular Testing The Easy (but Non-Existent) Way</h2>
<p>Let&#8217;s imagine that we&#8217;re writing a Pastry Shop application. Our application needs a service for baking cakes, which we&#8217;ll call <code>Baker</code>. The <code>Baker</code> service requires a few things to do its work. For example, it needs access to a <code>Store</code> where it can get the necessary ingredients. It also needs a <code>Mixer</code> and an <code>Oven</code>. In other words, it has certain <strong>dependencies</strong>.</p>
<p>Now, let&#8217;s imagine that we&#8217;re using a special version of JavaScript, which makes it easy to express dependencies using <strong>annotations</strong>. Here&#8217;s what our Baker service might look like:</p>
<pre class="brush: js">@inject(Store, Mixer, Oven)
function Baker() {
    var bake = function(item) {
        if (item === 'vanilla cake') {
            var ingredients = [ 
                Store.get('sugar'),
                Store.get('flower'),
                Store.get('eggs')
            ];
            var dough = Mixer.mix(ingredients);
            var cake = Oven.cook(dough);    
            cake.frosting = 'vanilla';
            return cake;         
        };
    };

    return: {
        bake: bake
    };
};
</pre>
<p>We&#8217;re using an annotation called <code>@inject</code> to specify that <code>Baker</code> needs <code>Store</code>, <code>Mixer</code>, and <code>Oven</code> to do its work. This same annotation could be used in writing the corresponding tests:</p>
<pre class="brush: js">@inject(Baker, Store, Mixer, Oven)
describe('Baker Service tests', function () {
    it('should bake vanilla cake', function () {
        // arrange
        spyOn(Store, 'get').andReturnValue({});
        spyOn(Mixer, 'mix').andReturnValue({});
        spyOn(Oven, 'cook').andReturnValue({});
        // act
        var cake = Baker.bake('cake');        
        // assert
        expect(Store.get).toHaveBeenCalledWith('sugar');
        expect(Store.get).toHaveBeenCalledWith('flower');
        expect(Store.get).toHaveBeenCalledWith('baking soda');
        expect(Store.get).toHaveBeenCalledWith('eggs');
        expect(Mixer.mix).toHaveBeenCalled();
        expect(Oven.cook).toHaveBeenCalled();
        expect(cake.frosting).toEqual('vanilla');
    });
});
</pre>
<h2>Angular Testing the (less) Easy (but actually possible) Way</h2>
<p>Sadly, the code above won&#8217;t work in JavaScript. The good news is that Angular gives us <a href="https://docs.angularjs.org/guide/di">multiple ways to do the same thing</a>:</p>
<ol>
<li><strong>Implicit dependencies</strong> &#8211; use function parameter names to indicate the dependencies. This method doesn&#8217;t work for minified code and should therefore be avoided.</li>
<li><strong><code>$inject</code></strong> &#8211; set <code>$inject</code> property on the object which requires dependencies to an array of dependency names.</li>
<li><strong>Inline array annotation</strong> &#8211; pass the list of dependencies as an array to the constructor function (like <code>factory()</code> or <code>controller()</code>).</li>
</ol>
<p>Of the three methods described above, #3 seems to be the most widely accepted. So, let&#8217;s rewrite our code above using this method. First, let&#8217;s look at the service:</p>
<pre class="brush: js">// simple, but not possible
@inject(Store, Mixer, Oven)
function Baker() {...}
// noisy, but possible
angular.module('PastryShop').factory('Baker', ['Store', 'Mixer', 'Oven', 
    function(Store, Mixer, Oven) {...}
]);
</pre>
<p>Next, let&#8217;s rewrite the test:</p>
<pre class="brush: js">// simple, but not possible
@inject(Store, Mixer, Oven)
describe('Baker Service tests', function () {
    it('should bake vanilla cake', function () {...});
});

// noisy, but possible
describe('Baker Service tests', function () {
    var Baker, Store, Mixer, Oven;

    beforeEach(angular.mock.module('PastryShop'));

    beforeEach(function () {
        angular.mock.inject(function (_Baker_, _Store_, _Mixer_, _Oven_) {
            Baker = _Baker_;
            Store = _Store_;
            Mixer = _Mixer_;
            Oven = _Oven_;
        });
    });

    it('should bake vanilla cake', function () {...});
});
</pre>
<p>Let&#8217;s understand what&#8217;s going on here. Angular provides a special module called <a href="https://docs.angularjs.org/api/ngMock/function/angular.mock.module">ngMock</a>, which exposes (among other things) two very useful methods:</p>
<ol>
<li><strong><a href="https://docs.angularjs.org/api/ngMock/function/angular.mock.module"><code>module()</code></a></strong> &#8211; used to bootstrap your app before every test.</li>
<li><strong><a href="https://docs.angularjs.org/api/ngMock/function/angular.mock.inject"><code>inject()</code></a></strong> &#8211; used to get instances of various services injected into your tests. By convention, if you wrap the name of the service in underscores, Angular will strip those underscores before giving you the right service.</li>
</ol>
<p>Once we obtain the necessary services from <code>inject()</code>, we simply store them within the scope of our <code>describe()</code> block and they become available to all of our tests.</p>
<h2>A Note on Controllers</h2>
<p>When testing controllers, there are a couple of extra things to consider. First, to actually create a controller for our tests, we need to use the <a href="https://docs.angularjs.org/api/ng/service/$controller"><code>$controller</code> service</a>. Second, since most controllers need a <code>$scope</code> to work with, we can get one by using <code>$rootScope</code>&#8216;s <code>$new()</code> method.</p>
<p>Here&#8217;s the code:</p>
<pre class="brush: js">describe('Baker Controller tests', function () {
    var scope, BakerController, Baker;

    beforeEach(angular.mock.module('PastryShop'));

    beforeEach(function () {
        angular.mock.inject(function ($rootScope,  $controller, _Baker_) {
            scope = $rootScope.$new();
            Baker = _Baker_;

            BakerController = $controller('BakerController', {
                $scope: scope,
                Baker: Baker
            });
        });
    });
});
</pre>
<p>Once again, we&#8217;re using the <code>inject()</code> method to get our dependencies, which in this case include <code>$rootScope</code> and <code>$controller</code>. We create an instance of a <code>$scope</code> and inject it, along with an instance of <code>Baker</code>, into the <code>BakerController</code>.</p>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/how-to-configure-intellij-idea-for-angular-js-testing/" title="How to Configure IntelliJ IDEA For Angular JS Testing">How to Configure IntelliJ IDEA For Angular JS Testing</a></li>
<li><a href="https://tatiyants.com/a-second-look-at-facebooks-react/" title="A Second Look at Facebook&#8217;s React">A Second Look at Facebook&#8217;s React</a></li>
<li><a href="https://tatiyants.com/tests-prevent-rot/" title="Tests Prevent Code Rot">Tests Prevent Code Rot</a></li>
<li><a href="https://tatiyants.com/how-to-use-json-objects-with-twitter-bootstrap-typeahead/" title="How to Use JSON Objects With Twitter Bootstrap Typeahead">How to Use JSON Objects With Twitter Bootstrap Typeahead</a></li>
<li><a href="https://tatiyants.com/introducing-js-js/" title="Introducing JS.js">Introducing JS.js</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>http://tatiyants.com/groking-angular-dependency-injection-and-testing/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>How and When to Use Various GORM Querying Options</title>
		<link>http://tatiyants.com/how-and-when-to-use-various-gorm-querying-options/</link>
					<comments>http://tatiyants.com/how-and-when-to-use-various-gorm-querying-options/#comments</comments>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Mon, 28 Apr 2014 14:30:45 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[GORM]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Hibernate]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=2904</guid>

					<description><![CDATA[Grails GORM supports five increasingly powerful querying mechanisms: 1) dynamic finders, 2) where clauses, 3) criteria, 4) HQL, and 5) SQL.]]></description>
										<content:encoded><![CDATA[<p>Grails Object Relational Mapper (<a href="http://grails.org/doc/2.3.7/guide/GORM.html">GORM</a>) is a really nice ORM. What started as a Groovy DSL on top of <a href="http://hibernate.org/">Hibernate</a> baked into Grails, has evolved into a <a href="http://www.grails.org/plugin/neo4j">persistence</a> <a href="http://grails.org/plugin/mongodb">agnostic</a>, <a href="http://www.grails.org/GORM+-+StandAlone+Gorm">Grails-independent</a> library for working with databases.</p>
<p>GORM uses good API design and some Groovy magic to be both novice and expert friendly. It does this via five increasingly powerful data querying mechanisms:</p>
<ol>
<li><a href="http://grails.org/doc/latest/guide/single.html#finders">Dynamic finders</a></li>
<li><a href="http://grails.org/doc/latest/guide/single.html#whereQueries">Where clauses</a></li>
<li><a href="http://grails.org/doc/latest/guide/single.html#criteria">Criteria</a></li>
<li><a href="http://grails.org/doc/latest/guide/single.html#hql">HQL</a></li>
<li>SQL</li>
</ol>
<p>In this post I&#8217;ll cover how each mechanism works and, perhaps even more importantly, when to use each one. But first, a disclaimer: <em>information presented below is based on GORM documentation and confirmed by my own experiments. It is current as of Grails version 2.3.7. If I missed or misrepresented anything, please let me know.</em></p>
<p>With that out of the way, here&#8217;s summary of when each method should be used:</p>
<table>
<thead>
<tr>
<th align="left"></th>
<th align="center">dynamic finder</th>
<th align="center">where clause</th>
<th align="center">criteria</th>
<th align="center">HQL</th>
<th align="center">SQL</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">simple queries</td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">complex filters</td>
<td align="center"></td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">associations</td>
<td align="center"></td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">property comparisons</td>
<td align="center"></td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">some subqueries</td>
<td align="center"></td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">eager fetches w/ complex filters</td>
<td align="center"></td>
<td align="center"></td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">projections</td>
<td align="center"></td>
<td align="center"></td>
<td align="center">x</td>
<td align="center">x</td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">queries with arbitrary return sets</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center">x</td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">highly complex queries (like self joins)</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">some database specific features</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center">x</td>
</tr>
<tr>
<td align="left">performance-optimized queries</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center">x</td>
</tr>
</tbody>
</table>
<h2>The Setup</h2>
<h3>1. Define Domain Model</h3>
<p>Before we can get into GORM, we&#8217;ll need to define a few domain objects to work with:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/04/grom_how_to_objet_model.png"><img decoding="async" class="aligncenter" width="325" src="http://tatiyants.com/wp-content/uploads/2014/04/grom_how_to_objet_model.png" alt="GROM How To Objet Model"></a></p>
<p>Here, we have a Company and a Store. Company manufactures Products, which are sold at Stores. Details of each sale (which Product got sold and which Store sold it) are recorded in a Transaction. Here&#8217;s the code:</p>
<pre class="brush: groovy">class Company {
    String name
    String location
}

class Store {
    String name
    String city
    String state
}

class Product {
    String name
    Company manufacturer
    BigDecimal salesPrice
}

class Transaction {
    Product product
    Store store
    Date salesDate
    Integer quantity
}
</pre>
<h3>2. Change GORM Defaults (optional)</h3>
<p>This is definitely a matter of personal preference, but I dislike that (1) GORM assumes all properties to be non-nullable by default and (2) it fails silently on error. I also find it useful to see the SQL generated by Hibernate while I&#8217;m developing and testing. So, I&#8217;ll make the following tweaks to Config.groovy and DataSource.groovy:</p>
<pre class="brush: groovy">// *** in Config.groovy ***
// 1. make all properties nullable by default
grails.gorm.default.constraints = {
    '*'(nullable: true)
}

// 2. turn off silent GORM errors
grails.gorm.failOnError = true


// *** in DataSource.groovy ***
// 3. enable logging of Hibernate's SQL queries
test {
    dataSource {
        logSql = true
        // .... other settings
    }
}

development {
    dataSource {
        logSql = true
        // .... other settings
    }
}
</pre>
<p>Ok, we&#8217;re finally ready to query some data.</p>
<h2>1. Dynamic Finders</h2>
<p>The simplest way of querying in GORM is by using <strong>dynamic finders</strong>. Dynamic finders are methods on a domain object that start with <code>findBy</code>, <code>findAllBy</code>, and <code>countBy</code>. For example, we can use dynamic finders to get a list of products filtered in different ways:</p>
<pre class="brush: groovy">Company ACME = Company.findByName('ACME')
Product.findAllByManufacturer(ACME)
Product.findAllByManufacturerAndSalesPriceBetween(ACME, 200, 500)
</pre>
<p>We can also get counts:</p>
<pre class="brush: groovy">Product.countByManufacturer(ACME)
</pre>
<p>The interesting thing about dynamic finders methods is that they don&#8217;t actually exist on the domain object. Instead, GORM uses Groovy&#8217;s Meta Object Programming (MOP) hooks to <a href="http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing">intercept calls to them and construct queries on the fly</a>.</p>
<p>Another thing to note about dynamic finders is that they&#8217;re lazily loaded by default. This can be changed by specifying how specific objects should be fetched:</p>
<pre class="brush: groovy">Product fluxCapacitor = Product.findByName('flux capacitor')
Transaction.findAllByProduct(fluxCapacitor, [fetch: [product: 'eager', store: 'eager']])
</pre>
<h2>2. Where Clauses</h2>
<p>Originally introduced in Grails 2.0, the <strong><code>where</code> clause</strong> gives us another simple option for querying data. Here&#8217;s how the examples above can be done using it:</p>
<pre class="brush: groovy">// Product.findAllByManufacturer(ACME)
Product.where {
    manufacturer == ACME
}.list()

// Product.findAllByManufacturerAndSalesPriceBetween(ACME, 200, 500)
Product.where {
    manufacturer == ACME &amp;&amp; (salesPrice &gt; 200 &amp;&amp; salesPrice &lt; 800)
}.list()

// Product.countByManufacturer(ACME)
Product.where {
    manufacturer == ACME
}.count()
</pre>
<h3>Complex filters</h3>
<p>Although the <code>where</code> clause can do the same stuff as dynamic finders, it&#8217;s definitely more powerful. For instance, you can define more complex filter conditions.</p>
<p>Imagine that you want to get a list of all sales with either 1 item sold or sales of a specific product over a specific date range. Doing that with a dynamic finder could look like <code>findAllByQuantityOrProductAndSalesDateBetween</code>, but this doesn&#8217;t actually work. Instead, we&#8217;ll use a <code>where</code> clause:</p>
<pre class="brush: groovy">Transaction.where {
    quantity == 1 || 
    (product == fluxCapacitor &amp;&amp; 
        (salesDate &gt;= '1/1/2014' &amp;&amp; salesDate &lt;= '1/10/2014')
    )
}.list()
</pre>
<h3>Querying Associations</h3>
<p>Another place where the <code>where</code> clause helps is when querying associations. For example, to get the list of transactions for a specific manufacturer we can do this:</p>
<pre class="brush: groovy">Transaction.where {
    product.manufacturer.name == 'ACME'
}.list()
</pre>
<p>Note that <code>product.manufacturer</code> references an associated object. The query above will result in the following SQL joins:</p>
<pre class="brush: sql">FROM transaction this_ 
  INNER JOIN product product_al1_ ON this_.product_id = product_al1_.id
  INNER JOIN company manufactur2_ ON product_al1_.manufacturer_id = manufactur2_.id
WHERE manufactur2_.name = ?
</pre>
<h3>Property Comparisons and Subqueries</h3>
<p>There are two other use cases where the <code>where</code> clause can be useful: property comparison and subqueries:</p>
<pre class="brush: groovy">// find stores named after the city they're located in
Store.where {
    name == city
}.list()

// find the largest sales of the flux capacitor 
Transaction.where {
    quantity == max(quantity) &amp;&amp; product == fluxCapacitor
}.list()
</pre>
<p>I should note that subqueries for the <code>where</code> clause are limited to projections (i.e. aggregates like <code>min</code>, <code>max</code>, or <code>avg</code>).</p>
<h2>3. Criteria</h2>
<p>The two methods we&#8217;ve covered so far are certainly straight-forward, but can be limiting. For example, imagine that you wanted to get a list of all products and the stores they were sold in for a given manufacturer.</p>
<p>To do this efficiently, you&#8217;d want all product and store information to be retrieved in one shot (eagerly). Unfortunately, <code>where</code> clauses don&#8217;t (yet) allow you to specify which objects should be eagerly fetched. Fortunately, there is a way to do just this by using <strong>Criteria</strong>:</p>
<pre class="brush: groovy">Transaction.createCriteria().list {
    fetchMode 'product', FetchMode.JOIN
    fetchMode 'store', FetchMode.JOIN

    product {
        manufacturer {
            eq 'id', ACME.id
        }
    }
}
</pre>
<p>In this example we&#8217;re using <code>fetchMode</code> of <code>JOIN</code> to indicate that both <code>product</code> and <code>store</code> properties should be eagerly retrieved. We&#8217;re also using a nested condition to get at the right <code>manufacturer</code>.</p>
<p>Keep in mind that GORM&#8217;s Criteria is actually a DSL for <a href="http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/querycriteria.html">Hibernate&#8217;s criteria builder</a>. Therefore, it allows you to build up quite sophisticated queries.</p>
<h3>Projections</h3>
<p>Aside from eager joins, Criteria can also be useful for projections. Projections are a way to further shape a data set and are typically used for aggregate functions like <code>sum()</code>, <code>count()</code>, and <code>average()</code>.</p>
<p>For example, here&#8217;s a projection that gets product quantities sold for a given manufacturer:</p>
<pre class="brush: groovy">Transaction.createCriteria().list {
    projections {
        groupProperty 'product'
        sum 'quantity'
    }

    product {
        manufacturer {
            eq 'id', ACME.id
        }
    }
}
</pre>
<p>Note that we&#8217;re creating a <code>projections</code> clause and specifying both the aggregate (<code>sum</code>) and the grouping (via <code>groupProperty</code>).</p>
<h2>4. HQL</h2>
<p>Dynamic finders, <code>where</code> clauses, and criteria give us a lot of power over how and what we can query. However, there are a few situations where we need even more power and that&#8217;s where HQL comes in.</p>
<p>But before we talk about HQL and its use cases, there is one important thing to realize. If you&#8217;re using the first 3 ways of querying, GORM will always give you strongly typed domain objects (unless you&#8217;re using counts or projections). This is not necessarily true if you&#8217;re using HQL.</p>
<h3>Find() and FindAll()</h3>
<p>GORM gives you two ways of using HQL. The first is to use it in combination with <code>find()</code> or <code>findAll()</code> methods of the domain object. If you&#8217;re using it this way, you&#8217;re essentially limited to specifying the <code>WHERE</code> clause. For example:</p>
<pre class="brush: groovy">Transaction.findAll('from Transaction as t where t.product.manufacturer.id = :companyId', [companyId: 1])
</pre>
<p>Here, we&#8217;re asking for all transactions for a given manufacturer. Note that, like the other methods we&#8217;ve discussed so far, using HQL this way still allows GORM to give you back domain objects.</p>
<p>On a separate note, this example uses <strong>named maps</strong> (<code>[companyId: 1]</code>) to pass in query parameters. Although you can also use positional maps, I definitely prefer named maps because they&#8217;re explicit and you can use the same parameter multiple times in your query without having to specify it multiple times.</p>
<h3>ExecuteQuery()</h3>
<p>Up to now, every querying method we&#8217;ve used returned strongly typed domain objects. This is great, but sometimes you need something different. That&#8217;s where <code>executeQuery()</code> comes in.</p>
<p>GORM allows you to execute arbitrary HQL using <code>executeQuery()</code>. For example, here&#8217;s a query that returns names of the Store, the Product, and the Manufacturer sold over a given time period:</p>
<pre class="brush: groovy">String query = $/
    select
    s.name,
    m.name,
    p.name
    from Transaction as t
    inner join t.product as p
    inner join t.store as s
    inner join p.manufacturer as m
    where t.product.manufacturer.id = :companyId
    and t.salesDate between :startDate and :endDate
/$

List queryResults = Transaction.executeQuery(query,
        [companyId: ACME.id, startDate: new Date('1/1/2014'), endDate: new Date('1/31/2014')]
)
</pre>
<p>What&#8217;s really noteworthy here is that we can shape the return set however we want. Obviously this makes it impossible for GORM to give us the right domain objects, but in certain instances the tradeoff is justified.</p>
<p>Another point I should make is that the data set returned by this query is a List of Arrays. To make it more useful, we could post-process it and convert it to a List of Maps with named properties:</p>
<pre class="brush: groovy">Transaction.executeQuery(query,
        [companyId: ACME.id, startDate: new Date('1/1/2014'), endDate: new Date('1/31/2014')]
).collect {
    [
            storeName: it[0],
            manufacturerName: it[1],
            productName: it[2]
    ]
}
</pre>
<p>The output of this query can, for instance, be easily serialized into JSON and rendered as a response from a controller.</p>
<h2>5. SQL</h2>
<p>For better or worse, quite a few devs believe that using an ORM means never having to look at SQL. While this may be true for a large majority of queries, certain situations require it.</p>
<p>Consider a query which wants to compare sales of all products for a given manufacturer to a similar time period last year. This query requires joining the Transaction table to itself (over different time ranges).</p>
<p>HQL joins (including self-joins) are possible if there&#8217;s an association defined between objects. In other words, we&#8217;d need to modify our Transaction class like this:</p>
<pre class="brush: groovy">class Transaction {
    Product product
    Store store
    Date salesDate
    Integer quantity

    Transaction baseline
}
</pre>
<p>If we did that, we could then define the following HQL query:</p>
<pre class="brush: sql">String query = $/
    select
    t1.product.name,
    sum(t1.quantity),
    sum(t2.quantity)
    from Transaction as t1
    inner join t1.baseline as t2
    where t1.product.manufacturer.id = :companyId
    and t1.salesDate between :startDate and :endDate
    and t2.salesDate between :baselineStartDate and :baselineEndDate
    group by t1.product.name
/$
</pre>
<p>Now, while this is possible to do, I find the solution distasteful. After all, doing this forces us to pollute the domain object with almost arbitrary associations just to make the query work.</p>
<p>The other option is to use native SQL:</p>
<pre class="brush: groovy">String query = $/
SELECT p.name,
sum(t1.quantity),
sum(t2.quantity)
FROM transaction t1
LEFT OUTER JOIN transaction t2 ON t1.product_id = t2.product_id
INNER JOIN product p ON t1.product_id = p.id
WHERE p.manufacturer_id = :companyId
AND t1.sales_date between :startDate and :endDate
AND t2.sales_date between :baselineStartDate and :baselineEndDate
GROUP BY p.name
/$

new Transaction()
.domainClass
.grailsApplication
.mainContext
.sessionFactory
.currentSession
.createSQLQuery(query)
        .setLong('companyId', 1)
        .setDate('startDate', new Date('1/1/2014'))
        .setDate('endDate', new Date('1/31/2014'))
        .setDate('baselineStartDate', new Date('1/1/2013'))
        .setDate('baselineEndDate', new Date('1/31/2013'))
        .list()
</pre>
<p>There are a couple of things to note here. First, in order to execute this query we need to get a hold of Hibernate&#8217;s current session and call its <code>createSQLQuery()</code> method. The two ways to do is are (1) get <code>sessionFactory</code> injected into our class by Grails or (2) new up the domain class inside of the method and walk a long chain of dependencies to get it.</p>
<p>I&#8217;m using option 2 here because I put the method which implements this query inside my domain class and I wanted to keep it static:</p>
<pre class="brush: groovy">class Transaction {
   ...
   static List<map> findAllTransactionsForManufacturerAndDateRangeWithBaseline() {
   }
}
</map></pre>
<p>If you were putting this method somewhere other than your domain class (like controller or service), I would recommend using option 1.</p>
<p>The other thing I want to point out is that because we&#8217;re using the actual Hibernate method, we cannot pass it a map of parameters. Instead, we have to use Hibernate&#8217;s strongly types <code>set*()</code> methods.</p>
<h3>Database Specific SQL</h3>
<p>Aside from complex-yet-still-generic SQL queries, we sometimes need to take advantage of database specific constraints. For example, Postgres allows storing data as arrays, maps (hstore), or JSON. Certain types of queries using these data types are difficult, if not impossible, to write using HQL.</p>
<h3>Performance Tuning</h3>
<p>There&#8217;s one other reason to use native SQL from GORM: performance tuning. Though Hibernate is typically pretty good about how it creates the necessary SQL, it&#8217;s definitely not perfect. So, there are rare instances where hand-tuned SQL can give you a significant performance boost.</p>
<h2>Final Thought</h2>
<p>Querying options supported by GORM are all appropriate under the right circumstances. I personally try to use the simplest option wherever possible (less code to test and maintain). On the other hand, if the unthinkable happens and either HQL (or SQL) is required, it&#8217;s good to understand how to make it work.</p>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/how-to-navigate-json-trees-in-postgres-using-recursive-ctes/" title="How To Navigate JSON Trees in Postgres using Recursive CTEs">How To Navigate JSON Trees in Postgres using Recursive CTEs</a></li>
<li><a href="https://tatiyants.com/postgres-query-plan-visualization/" title="Postgres Query Plan Visualization">Postgres Query Plan Visualization</a></li>
<li><a href="https://tatiyants.com/xml-databases/" title="XML Databases">XML Databases</a></li>
<li><a href="https://tatiyants.com/good-devs-dont-like-magic/" title="Good Devs Don&#8217;t Like Magic">Good Devs Don&#8217;t Like Magic</a></li>
<li><a href="https://tatiyants.com/database-source-control-revisited/" title="Database Source Control Revisited">Database Source Control Revisited</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>http://tatiyants.com/how-and-when-to-use-various-gorm-querying-options/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>How to Configure IntelliJ IDEA For Angular JS Testing</title>
		<link>http://tatiyants.com/how-to-configure-intellij-idea-for-angular-js-testing/</link>
					<comments>http://tatiyants.com/how-to-configure-intellij-idea-for-angular-js-testing/#comments</comments>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Thu, 03 Apr 2014 14:55:22 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[angular]]></category>
		<category><![CDATA[IntelliJIDEA]]></category>
		<category><![CDATA[testing]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=2897</guid>

					<description><![CDATA[Here's a simple guide on how to configure IntelliJ IDEA to use Karma/Jasmine to run Angular tests]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;re using IntelliJ IDEA and writing Angular tests using Karma/Jasmine, IDEA can make this a very pleasant experience:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/04/intellij_13_running_karma_jasmine_tests.png"><img decoding="async" class="aligncenter" width="700" src="http://tatiyants.com/wp-content/uploads/2014/04/intellij_13_running_karma_jasmine_tests.png" alt="IntelliJ 13 running Karma Jasmine tests"></a></p>
<p>Note the fact that IDEA is aware of Jasmine syntax and uses the built-in test runner to run Karma tests. Here&#8217;s a quick summary of how to do it.</p>
<h3>1. Install Karma</h3>
<p>At the command line, type the following (assumes you&#8217;ve already installed node/npm):</p>
<p><code>npm install -g karma</code></p>
<h3>2. Install Karma plugin</h3>
<p>Go to Settings &gt; Plugins &gt; Browse Repositories &gt; search for &#8220;karma&#8221;:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/04/intellij_13_install_karma_plugin.png"><img decoding="async" class="aligncenter" width="675" src="http://tatiyants.com/wp-content/uploads/2014/04/intellij_13_install_karma_plugin.png" alt="IntelliJ 13 install Karma plugin"></a></p>
<p>Note that this requires IDEA 13.</p>
<h3>3. Configure Karma Run Configuration</h3>
<p>Go to Run &gt; Edit Configurations, add new configuration of type Karma:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/04/intellij_configure_run_configufation.png"><img decoding="async" class="aligncenter" width="808" src="http://tatiyants.com/wp-content/uploads/2014/04/intellij_configure_run_configufation.png" alt="IntelliJ Configure run configufation"></a></p>
<h3>4. Configure Jasmine</h3>
<p>Go to Settings &gt; JavaScript &gt; Libraries, add a new Global Library. Then, navigate to wherever npm installs its modules (probably <code>/usr/local/lib/</code>) and select the jasmine.js file from <code>node_modules/karma-jasmine/lib/jasmine.js</code>:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/04/intellij_13_global_library_jasmine_configuration.png"><img decoding="async" class="aligncenter" width="793" src="http://tatiyants.com/wp-content/uploads/2014/04/intellij_13_global_library_jasmine_configuration.png" alt="IntelliJ 13 Global Library Jasmine configuration"></a></p>
<h3>5. Enable Jasmine library for your project</h3>
<p>Click on the &#8220;Hector&#8221; icon (a little guy in a bowler hat at the bottom right of the screen) and click &#8220;Configure Inspections&#8221;:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/04/intellij_configure_inspections.png"><img decoding="async" class="aligncenter" width="401" src="http://tatiyants.com/wp-content/uploads/2014/04/intellij_configure_inspections.png" alt="IntelliJ Configure inspections"></a></p>
<p>Select <code>jasmine</code> library click OK:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/04/intellij_13_enable_library_for_project.png"><img decoding="async" class="aligncenter" width="647" src="http://tatiyants.com/wp-content/uploads/2014/04/intellij_13_enable_library_for_project.png" alt="Intellij 13 enable library for project"></a></p>
<h2>References</h2>
<ul>
<li><a href="http://karma-runner.github.io/0.10/intro/installation.html">Install Karma</a></li>
<li><a href="http://www.jetbrains.com/idea/webhelp/configuring-javascript-libraries.html">IntelliJ Configure JavaScript Library</a></li>
</ul>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/groking-angular-dependency-injection-and-testing/" title="Groking Angular: Dependency Injection and Testing">Groking Angular: Dependency Injection and Testing</a></li>
<li><a href="https://tatiyants.com/a-second-look-at-facebooks-react/" title="A Second Look at Facebook&#8217;s React">A Second Look at Facebook&#8217;s React</a></li>
<li><a href="https://tatiyants.com/tests-prevent-rot/" title="Tests Prevent Code Rot">Tests Prevent Code Rot</a></li>
<li><a href="https://tatiyants.com/intellij-idea-dark-theme/" title="IntelliJ IDEA Dark Theme">IntelliJ IDEA Dark Theme</a></li>
<li><a href="https://tatiyants.com/dont-write-tests-for-code-you-dont-control/" title="Don&#8217;t Write Tests For Code You Don&#8217;t Control">Don&#8217;t Write Tests For Code You Don&#8217;t Control</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>http://tatiyants.com/how-to-configure-intellij-idea-for-angular-js-testing/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>A Rating System For Free Apps</title>
		<link>http://tatiyants.com/a-rating-system-for-free-apps/</link>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Mon, 31 Mar 2014 13:45:06 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[geekHumor]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=2885</guid>

					<description><![CDATA[Every time I install a new free app, I wonder about exactly how its creators intend to make money. Am I going to see a bunch of ads? Are they going to sell me something? Are they going to sell me to someone?]]></description>
										<content:encoded><![CDATA[<p>The world is full of free apps, some good, others great. Yet as great as they all are, they do have one big problem. Namely, every time I install a new free app, I wonder about exactly how its creators intend to make money. Am I going to see a bunch of ads? Are they going to sell me something? Are they going to sell me to someone?</p>
<p>Now, I should note that this guessing game can be a lot of fun, especially if you take into account what permissions the app is asking for. That said, I would like to propose an explicit rating system for free apps. Using simple iconography, app makers can finally let their users know exactly how they plan to generate revenue:</p>
<p style="text-align: center;"><a href="http://tatiyants.com/wp-content/uploads/2014/03/rating_system_for_free_apps.png"><img decoding="async" class="aligncenter" width="674" src="http://tatiyants.com/wp-content/uploads/2014/03/rating_system_for_free_apps.png" alt="rating system for free apps"></a></p>
<p>Though this set is incomplete, it does cover a good range of free app money making options. If you think of anything I missed, please do let me know here or on Twitter <a href="https://twitter.com/AlexTatiyants">@AlexTatiyants</a>.</p>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/online-commenter-types-2/" title="Online Commenter Types">Online Commenter Types</a></li>
<li><a href="https://tatiyants.com/my-startup-story/" title="My Startup Story">My Startup Story</a></li>
<li><a href="https://tatiyants.com/my-2012-in-blogging/" title="My 2012 in Blogging">My 2012 in Blogging</a></li>
<li><a href="https://tatiyants.com/unused-geek-humor-headlines/" title="Unused Geek Humor Headlines">Unused Geek Humor Headlines</a></li>
<li><a href="https://tatiyants.com/a-sermon-from-the-church-of-restafarianism/" title="A Sermon from the Church of RESTafarianism">A Sermon from the Church of RESTafarianism</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Write a Children&#8217;s Book</title>
		<link>http://tatiyants.com/how-to-write-a-childrens-book/</link>
		
		<dc:creator><![CDATA[Alex Tatiyants]]></dc:creator>
		<pubDate>Mon, 17 Mar 2014 14:48:10 +0000</pubDate>
				<category><![CDATA[none]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[parenting]]></category>
		<category><![CDATA[writing]]></category>
		<guid isPermaLink="false">http://tatiyants.com/?p=2865</guid>

					<description><![CDATA[As a parent, I read a lot of children's books. Each time I pick up one of these literary masterpieces, I can't help but stare at amazement at the words in front of me. It's hard to believe that such a delightful work of art was conceived of, written, edited, printed, distributed, and sold by and to adults.]]></description>
										<content:encoded><![CDATA[<p>As a parent, I read a lot of children&#8217;s books. Almost every time I pick up one of these literary masterpieces, I can&#8217;t help but stare in amazement at the words in front of me. It&#8217;s hard to believe that such a delightful work of art was conceived of, written, edited, printed, distributed, and sold by and to adults.</p>
<p>Now, these books are clearly written by talented professionals at the top of their game. They&#8217;re all unique and wonderful, each in their own special way. However, if you study these gems as much as I have, you will notice subtle similarities among them.</p>
<p>In fact, I was able to synthesize these similarities, as subtle as they are, into a framework of sorts. This framework (which I call Child Readership Authoring Plan) can be used by non-talented un-professionals nowhere near the top (or even the middle) of their game to write their very own children&#8217;s book.</p>
<p>And so, without further delay, I present to you this framework. Please use it responsibly.</p>
<h2>1. Pick a name</h2>
<p>The first step is to pick a name. It should be common, but not too common, fashionable, but not too fashionable. And it should preferably be a girl&#8217;s name.</p>
<p><em>For my book, I&#8217;ll pick <strong>Wendy</strong>.</em></p>
<h2>2. Rhyme it</h2>
<p>Next, find an adjective that rhymes with the name from step 1. It could be any adjective at all. It doesn&#8217;t need to be related in any way to the story you&#8217;ll write. It just has to rhyme.</p>
<p><em>Hmm, let&#8217;s see, what rhymes with Wendy&#8230; How about Bendy? Yes, <strong>Bendy Wendy</strong>, sounds great!</em></p>
<h3>2b. Check name for appropriateness</h3>
<p>Make sure that the adjective name combo you ended up with is appropriate for a children&#8217;s book. For this step, I would recommend running your idea by an editor or spouse.</p>
<p><em>It has been pointed out to me that Bendy Wendy may not work. My bad, I see what I did wrong there. No problem, I&#8217;ll change it to <strong>Trendy Wendy</strong></em>.</p>
<h2>3. Get some words</h2>
<p>Next, get a random collection of words. Again, they don&#8217;t have to make sense as a collection or be meaningful in any way, they just have to rhyme. In case you have trouble coming up with words on your own, I&#8217;d recommend a site like <a href="http://www.rhymezone.com/">rhymezone</a>. Pro tip: if you aren&#8217;t able to get enough real words that rhyme, feel free to make some up.</p>
<p><em>For my book, I came up with the following: <strong>bike, spike, mike, like, alike, tyke, and trike</strong>. Also, just to be safe, I made up <strong>fyke and drike</strong>.</em></p>
<h2>4. Rhyme them</h2>
<p>You&#8217;re finally ready to write something. Remember that it&#8217;s not <em>at all</em> necessary for your story to be interesting, educational, life affirming, or morally unambiguous. In fact, it doesn&#8217;t even have to make sense.</p>
<p>All it has to do is sound as cute as possible. Also remember that no amount of alliteration, no matter how labored, is too much. The same is true for repetition.</p>
<p><em>Here&#8217;s what I came up with:</em></p>
<h3>Trendy Wendy Sees a Bike</h3>
<p>On her Sunday morning hike<br />
With her fluffy kitty Fyke,<br />
And her little brother Mike,<br />
And his fluffy doggy Drike<br />
Trendy Wendy saw a bike<br />
Chained with something to a spike.</p>
<p><em>&#8220;Wowy wow, this bike I like!&#8221;</em><br />
Trendy Wendy said to Mike<br />
And his fluffy doggy Drike<br />
Who was looking at the bike.<br />
<em>&#8220;Great for boys and girls alike,<br />
Let&#8217;s unchain it from that spike!&#8221;</em></p>
<p><em>&#8220;I too like this snazzy bike,</em><br />
<em>It is very nice!&#8221;</em> said Mike.<br />
<em>&#8220;But it&#8217;s too big for a tyke,</em><br />
<em>So don&#8217;t unchain it from that spike!</em><br />
<em>Trendy Wendy, Fyke, and Drike,</em><br />
<em>Let&#8217;s go home and ride my trike.&#8221;</em></p>
<p>So there you have it, a brand new children&#8217;s book written using a simple 4 step framework in roughly 20 minutes (your results may vary). Feel free to use this framework to unleash the majesty of the written word.</p>
<h3 class='related_post_title'>You may also like: </h3>
<ul class='related_post'>
<li><a href="https://tatiyants.com/my-most-spammed-posts/" title="My Most Spammed Posts">My Most Spammed Posts</a></li>
<li><a href="https://tatiyants.com/on-parenting/" title="On Parenting">On Parenting</a></li>
<li><a href="https://tatiyants.com/should-i-hate-my-job-new-poll-says-yes/" title="Should I Hate My Job? New Poll Says Yes">Should I Hate My Job? New Poll Says Yes</a></li>
<li><a href="https://tatiyants.com/distraction-free-writing/" title="Distraction Free Writing">Distraction Free Writing</a></li>
<li><a href="https://tatiyants.com/fun-with-financial-crashes/" title="Fun With Financial Crashes">Fun With Financial Crashes</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/


Served from: tatiyants.com @ 2026-05-18 08:35:28 by W3 Total Cache
-->