<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Workin' on it. &#187; deployment</title>
	<atom:link href="http://jameshalberg.wordpress.com/category/deployment/feed/" rel="self" type="application/rss+xml" />
	<link>http://jameshalberg.wordpress.com</link>
	<description></description>
	<lastBuildDate>Sat, 19 Nov 2011 14:15:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='jameshalberg.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Workin' on it. &#187; deployment</title>
		<link>http://jameshalberg.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://jameshalberg.wordpress.com/osd.xml" title="Workin&#039; on it." />
	<atom:link rel='hub' href='http://jameshalberg.wordpress.com/?pushpress=hub'/>
		<item>
		<title>MySQL Triggers w/Rails</title>
		<link>http://jameshalberg.wordpress.com/2010/02/28/mysql-triggers-wrails/</link>
		<comments>http://jameshalberg.wordpress.com/2010/02/28/mysql-triggers-wrails/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 02:54:24 +0000</pubDate>
		<dc:creator>Jim</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Test Driven Development (TDD)]]></category>
		<category><![CDATA[triggers]]></category>

		<guid isPermaLink="false">http://jameshalberg.com/?p=391</guid>
		<description><![CDATA[I recently incorporated db-triggers with a Rails app to maintain some counts that were otherwise fairly expensive to retrieve.  Rails wasn&#8217;t super-pumped about the idea (what with the &#8220;keep all the logic in the app&#8221; approach and all), but sometimes&#8230; you &#8230; <a href="http://jameshalberg.wordpress.com/2010/02/28/mysql-triggers-wrails/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jameshalberg.wordpress.com&amp;blog=160606&amp;post=391&amp;subd=jameshalberg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently incorporated db-triggers with a Rails app to maintain some counts that were otherwise fairly expensive to retrieve.  Rails wasn&#8217;t super-pumped about the idea (what with the &#8220;keep all the logic in the app&#8221; approach and all), but sometimes&#8230; you know&#8230; you know better than your framework.</p>
<p>Some things I was aiming for:</p>
<ol>
<li>Set them up with normal migrations.</li>
<li>Test them with the normal test suite/normal fixtures.</li>
<li>Make recovery/reset simple for when the table (inevitably) is somehow out of sync.</li>
</ol>
<p><strong>The &#8220;frequent counts&#8221; table</strong></p>
<p>I&#8217;ll have multiple counts but not TOO many &#8212; enough that I don&#8217;t want to have a column per count but not enough that I mind using &#8220;LIKE&#8221; to lookup patterns, so my table has: id, code, current_count.</p>
<p>Code will be a unique key (important later) and be formatted like &#8220;style_ABC_size_456&#8243;.</p>
<p>So, when a new item is added it&#8217;ll be associated with a style and some sizes &#8211; each combination will either need to be setup (with a current_count = 1) or an existing combo will be found and +=1.</p>
<p>The FrequentCount class has the fairly straightforward finders that you&#8217;d expect + methods to reset each of the counts that it contains.  The reset methods follow the pattern &#8220;reset_frequent_count_COUNT_NAME&#8221; -&gt; they clear the existing counts that they maintain before repopulating them.</p>
<p>I also threw in a reset_all method that looks for anything on the class following the &#8220;reset_frequent_count_COUNT_NAME&#8221; pattern and runs them.</p>
<p><strong>The trigger-SQL</strong></p>
<p>The SQL for creating the triggers will be needed by the migration as well as the test suite.  In fact, the test suite will need to run them somewhat often due to the way the standard tests &#8221;prepare&#8221; the database.</p>
<p>I ended up throwing it in lib/trigger_sql.rb.  Methods there are named with the pattern &#8220;sql_for_TABLE_OPERATION_TRIGGER_NAME&#8221; ex: sql_for_items_insert_style_and_size</p>
<div id="_mcePaste">Many of the triggers could not rely on pre-existing rows.  i.e. a new style/size combination needs to INSERT where an existing combo could update ( +=1 ).  To get around this, I relied on the unique key setup earlier on the &#8220;code&#8221; field for the frequent counts table.  &lt;&#8211; that allowed me to lean on insert statements with &#8220;ON DUPLICATE KEY&#8221; clauses with update statements.  Something like this&#8230;</div>
<blockquote style="margin:25px 0;">
<div>create trigger items_insert_style_and_size after insert on items<br />
for each row<br />
begin<br />
insert into frequent_counts(code, current_count)<br />
values (concat(&#8216;style_&#8217;, new.style, &#8216;_size_&#8217;, new.size), 1)<br />
on duplicate key update current_count = current_count + 1;<br />
end;</div>
</blockquote>
<div><strong><span style="font-weight:normal;"><strong>The Migration</strong></p>
<div id="_mcePaste">I&#8217;ve already given away most of the fun stuff about the migration.  It just needs to run through the triggers that are being setup at this specific time, doing things like:</div>
<blockquote style='margin:25px 0;'>
<div>TriggerSql.connection.execute(TriggerSql.sql_for_items_insert_items_by_style_and_size)</div>
</blockquote>
<div>and then make sure to populate it all (with that reset_all) method when we&#8217;re done. &lt;&#8211; next time out I may want to call specific methods to reset just the ones I care about but this first time, I can just do the whole table.</div>
<div></div>
<p></span></strong></div>
<div><strong>Testing with Fixtures</strong></div>
<div>Rails goes a little too far when running the default test tasks for us &#8211; it ends up nuking the triggers on us, but not to fear: it&#8217;s a quick hack in the Rakefile.</div>
<div></div>
<div>I&#8217;m going to spare you some details (drop me a line if you want them) but I basically overrode the db:test:prepare method to call a special version of the clone_structure task.  My version has a dependent task that does:</div>
<blockquote style='margin:25px 0;'>
<div>
<div># find methods that follow our pattern of &#8220;methods providing trigger sql&#8221; and execute the contents of each</div>
<div>TriggerSql.methods.select{ |m| m =~ /sql_for_.+/ }.each do |method_name|</div>
<div>ActiveRecord::Base.connection.execute(TriggerSql.send(method_name))</div>
<div>end</div>
</div>
</blockquote>
<div>As you see there, it&#8217;s leaning on that naming convention &#8220;sql_for_TABLE_OPERATION_TRIGGER_NAME&#8221; to find the sql to (re)apply.</div>
<div></div>
<div style='margin-top:10px;'><strong>That&#8217;s it!</strong></div>
<div>Migrations set them up and share the code to do so with the fixtures that can repeat the tests whenever we need.  Those reset methods also come in handy not only for the initial population (by the migration) but we can call them manually should we need them.</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jameshalberg.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jameshalberg.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jameshalberg.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jameshalberg.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jameshalberg.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jameshalberg.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jameshalberg.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jameshalberg.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jameshalberg.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jameshalberg.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jameshalberg.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jameshalberg.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jameshalberg.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jameshalberg.wordpress.com/391/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jameshalberg.wordpress.com&amp;blog=160606&amp;post=391&amp;subd=jameshalberg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jameshalberg.wordpress.com/2010/02/28/mysql-triggers-wrails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">jameshalberg</media:title>
		</media:content>
	</item>
		<item>
		<title>What Time(stamp) is it?</title>
		<link>http://jameshalberg.wordpress.com/2006/03/31/what-timestamp-is-it/</link>
		<comments>http://jameshalberg.wordpress.com/2006/03/31/what-timestamp-is-it/#comments</comments>
		<pubDate>Fri, 31 Mar 2006 22:30:32 +0000</pubDate>
		<dc:creator>Jim</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">https://jameshalberg.wordpress.com/2006/03/31/what-timestamp-is-it/</guid>
		<description><![CDATA[The app I am currently developing (in Java, not the Ruby tutorial I&#8217;ve been talking about) relies on a timestamp to report only the most recent activity to it&#8217;s clients. So, why was it not properly reporting our test data? &#8230; <a href="http://jameshalberg.wordpress.com/2006/03/31/what-timestamp-is-it/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jameshalberg.wordpress.com&amp;blog=160606&amp;post=13&amp;subd=jameshalberg&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The app I am currently developing (in Java, not the Ruby tutorial I&#8217;ve been talking about) relies on a timestamp to report only the  most recent activity to it&#8217;s clients.  So, why was it not properly  reporting our test data?</p>
<p>After some deliberation I ran the simple statement:<br />
select distinct trim(current_timestamp) from xxx.yyy</p>
<p>Why the &#8216;trim&#8217;?  Well because for some reason WinSQL (on my machine) won&#8217;t properly retrieve a dataset containing a timestamp for me otherwise (but that&#8217;s  another story).</p>
<p>Anyway, at 10:46AM it reports that it is currently 2:46PM.  So, simple  timezone issue, right?  Well&#8230; maybe.</p>
<p>select dbtimezone from xxx.yyy</p>
<p>This gives me a &#8216;-6&#8242;.  So, it does seem to know where we are.</p>
<p>Maybe it&#8217;s another WinSQL timestamp issue?  Nope, I hack my app to report  the timestamp to me &#8211; also seems to think it&#8217;s 2 this afternoon.</p>
<p>I have my buddy copy/paste my timestamp retrieval (against the same db): he gets 10:46AM!  Ok,  now this is quickly becoming a pain.</p>
<p>Checking the internet&#8230; Some rants are close but not much out there.</p>
<p>After much effort I get a statement mocked up to tell me what it looks like out on the development server.  How long does it take for the &#8220;automated&#8221; deployment tool to get everything out on the dev server and restarted for me to do this?  Why, a meer 15 minutes &#8211; no, I am serious; I literally timed it with my watch 14:47.  Anyway, it comes up with the same (incorrect) stamp that I have locally!</p>
<p>After some effort I&#8217;ve found that systimestamp (as opposed to current_timestamp) will report consistenly for me.  According to  the documentation this is the same as saying &#8220;TIMESTAMP WITH TIME ZONE&#8221; &#8211;  but now I don&#8217;t even have to worry about what the proper timezone is.  Not  that the server&#8217;s going to be crossing any statelines in the near future,  but hey: it works!</p>
<p>The big mystery though is why the timestamp is applied to current_timestamp on some machines (seemingly) by default, while on others: it is not.  Softaware?  Configuration?  Who will solve this mystery?  Not me!  It works and it&#8217;s 5PM on Friday!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/jameshalberg.wordpress.com/13/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/jameshalberg.wordpress.com/13/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jameshalberg.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jameshalberg.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jameshalberg.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jameshalberg.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jameshalberg.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jameshalberg.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jameshalberg.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jameshalberg.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jameshalberg.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jameshalberg.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jameshalberg.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jameshalberg.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jameshalberg.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jameshalberg.wordpress.com/13/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jameshalberg.wordpress.com&amp;blog=160606&amp;post=13&amp;subd=jameshalberg&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://jameshalberg.wordpress.com/2006/03/31/what-timestamp-is-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">jameshalberg</media:title>
		</media:content>
	</item>
	</channel>
</rss>
