<?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>daydreaming &#187; dev</title>
	<atom:link href="http://n79.org/category/dev/feed/" rel="self" type="application/rss+xml" />
	<link>http://n79.org</link>
	<description></description>
	<lastBuildDate>Sat, 31 Jul 2010 08:58:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Fire Eagle Sample App &#8211; whereis</title>
		<link>http://n79.org/2008/03/07/fireeagle-sample-app-whereis/</link>
		<comments>http://n79.org/2008/03/07/fireeagle-sample-app-whereis/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 17:36:04 +0000</pubDate>
		<dc:creator>nikhilb</dc:creator>
				<category><![CDATA[camping]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[fireeagle]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://n79.org/2008/03/07/fireeagle-sample-app-whereis/</guid>
		<description><![CDATA[Fire Eagle (not fireeagle) is a new location platform from some of my colleagues here at Yahoo! Brickhouse. I&#8217;ve put together a simple sample app called whereis which shows off the power of the platform. What is whereis? Each instance of whereis lets you share location within a trusted group of people. Whereis does not [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fn79.org%2F2008%2F03%2F07%2Ffireeagle-sample-app-whereis%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fn79.org%2F2008%2F03%2F07%2Ffireeagle-sample-app-whereis%2F&amp;source=nikibobb&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://fireeagle.com">Fire Eagle</a> (not fireeagle) is a new location platform from some of my colleagues here at <a href="http://yahoo.com">Yahoo!</a> Brickhouse. I&#8217;ve put together a simple sample app called whereis which shows off the power of the platform. </p>
<h3>What is whereis?</h3>
<p>Each instance of whereis lets you share location within a trusted group of people. Whereis <b>does not</b> update location in Fire Eagle, you should do this using other apps (eg. Fire Eagle automatic device updaters, or other sites).  This screenshot basically sums it up -</p>
<p><img src='http://n79.org/wp-content/uploads/2008/03/whereis.gif' alt='whereis screenshot' /></p>
<h3>What can I use it for?</h3>
<ul>
<li>Run it on your intranet to easily share location between your co-workers</li>
<li>Run it on the internet so friends and family can share location</li>
</ul>
<h3>Who is whereis intended for?</h3>
<p>Whereis is intended for developers who have familiarity with Ruby and access to a server.</p>
<h3>Why are you releasing it?</h3>
<p>It is a simple app (~200 lines of code) built on top of the <a href="http://code.whytheluckystiff.net/camping/">camping framework</a>. If you understand Ruby and the <a href="http://en.wikipedia.org/wiki/Model-view-controller">MVC</a> pattern, it will give you a good idea of how FE works and can be used. I think the code is pretty self explanatory, drop me a line if you have any suggestions.</p>
<p><span id="more-27"></span></p>
<h3>What else should I do with it?</h3>
<ul>
<li>run an instance for your group</li>
<li>use it to experiment with fireeagle</li>
<li>skin it with CSS to make it look good</li>
<li>build a service around it</li>
<li>add a subscriptions table with acls to have a twitter like mode</li>
<li>anything else</li>
</ul>
<h3>How do I use it?</h3>
<ul>
<li>download the <a href='http://n79.org/wp-content/uploads/2008/03/whereis.tgz' title='whereis.tgz'>files</a></li>
<li>make sure you and everyone you want to use whereis have fireeagle accounts</li>
<li>install camping (via gem)</li>
<li>install dependencies</li>
<li>get a fireeagle consumer token and secret from the FE website and set up the correct callback URL</li>
<li>insert the token and secret in getFEClient &#8211; whereis.rb</li>
<li>change the login password in createTheBasics &#8211; whereis.rb</li>
<li>&#8220;camping whereis.rb&#8221; on the command line</li>
</ul>
<h3>Caveats</h3>
<ul>
<li>Whereis uses sqlite as it&#8217;s database so it&#8217;s probably not suitable for large scale deployments.</li>
<li>I&#8217;m using a very early version of the fireeagle gem, before you write anything make sure to look at the newest version.</li>
<li>This code might be a bit slow in production if the fireeagle servers are heavily loaded. If you want to take initiative and fix the problem this is how you would do it (via <a href="http://mojodna.net/">Seth Fitzsimmons</a>) &#8211; instead of updating the locations on query, update them periodically using a cron job or some other method.
</ul>
<pre name="code" class="ruby">

#!ruby
#whereis - a simple fireeagle demo
#IMPORTANT: make sure to use the version of fireeagle.rb included in the tarball
#Nikhil Bobb (nikhilb at yahoo-inc.com)
#26th Feb 08

require 'camping/session'
require 'FireEagle'
require 'JSON'

Camping.goes :Whereis

module Whereis
  include Camping::Session
  table_style = &quot;border-width:1px; border-style:outset&quot;

  def getFEClient(access_token = &quot;&quot;, access_token_secret = &quot;&quot;)
    client = FireEagle::Client.new \
	  :consumer_key        =&gt; &quot;&quot;,
	  :consumer_secret     =&gt; &quot;&quot;,
	  :access_token        =&gt; access_token,
          :access_token_secret =&gt; access_token_secret
  end

  #gets a user's location from fireEagle and returns a nice
  #string
  def getFELocation(access_token, access_token_secret)
    client = getFEClient(access_token, access_token_secret)
    location_obj = client.user
    #query the JSON object to get the location
    #where best guess = true
    hierarchy = location_obj[&quot;user&quot;][&quot;location_hierarchy&quot;]
    current_loc = hierarchy.select {|l| l[&quot;best_guess&quot;]}.first
    [current_loc[&quot;name&quot;], current_loc[&quot;located_at&quot;]]
  end
end

module Whereis::Models

  class User &lt; Base;
    has_one :request_token
    serialize :access_token
  end

  class RequestToken &lt; Base;
    belongs_to :user
    serialize :bin
  end 

  class Login &lt; Base; end

  class CreateTheBasics &lt; V 1.0
    def self.up
      create_table :whereis_logins do |t|
        t.column :username, :string
        t.column :password, :string
      end
      create_table :whereis_users do |t|
        t.column :name, :string
        t.column :access_token, :text
      end
      create_table :whereis_request_tokens do |t|
        t.column :str, :string
        t.column :bin, :text
        t.column :user_id, :integer
      end
      Login.create :username =&gt; 'admin', :password =&gt; &quot;eagle123&quot;
    end
    def self.down
      drop_table :whereis_users
      drop_table :whereis_request_tokens
      drop_table :whereis_logins
    end
  end
end

module Whereis::Controllers
  class Style &lt; R '/styles.css'
    def get
      @headers[&quot;Content-Type&quot;] = &quot;text/css; charset=utf-8&quot;
      @body = %{
        table {
          border-width:1px;
          border-style: dotted;
        }
        td {
          border-width: 1px 1px 1px 1px;
          border-style: solid;
        }
      }
    end
  end
  class Auth &lt; R '/auth'
    def post
      @logged_in_user = Login.find :first, :conditions =&gt; ['username = ? AND password = ?', input.username, input.password]
      if @logged_in_user
        @login = 'login success !'
        @state.user_id = @logged_in_user.id
        redirect R(Index)
      else
        @login = 'wrong user name or password'
        render :id
      end

    end
    def get
      render :id
    end
  end

  class Index &lt; R '/'
    def get
      if @state.user_id.blank?
        redirect R(Auth)
        return
      end

      @users = []
      User.find(:all).each do |u|
        t = u.access_token
        if t
          location = getFELocation(t.token, t.secret)
          @users &lt;&lt; [u.name, location[0], location[1]]
        end
      end
      render :whereis
    end

    def post
      if @state.user_id.blank?
        redirect R(Auth)
        return
      end

      client = getFEClient
      request_token = client.get_access_token_part1
      rt = RequestToken.create :bin =&gt; request_token, :str =&gt; request_token.token
      u = User.create :name =&gt; input.user, :request_token =&gt; rt
      redirect &quot;#{FireEagle::AUTHORIZATION_URL}?oauth_token=#{request_token.token}&quot;
    end
  end

  class Callback &lt; R '/callback'
    def get

      if @state.user_id.blank?
        redirect R(Auth)
        return
      end

      client = getFEClient
      rt = RequestToken.find_by_str(input.oauth_token)
      at = client.get_access_token_part2(rt.bin)
      user = rt.user
      user.access_token = at
      user.save
      rt.destroy
      redirect &quot;/&quot;
    end
  end
end

module Whereis::Views
  def layout
    html do
      head do
        title { &quot;Where is everyone?&quot; }
        link :rel =&gt; 'stylesheet', :type =&gt; 'text/css',
             :href =&gt; '/styles.css', :media =&gt; 'screen'
      end
    end
    body { self &lt;&lt; yield }
  end

  def id
    p @login
    form :action =&gt; R(Auth), :method =&gt; 'post' do
      label 'Username', :for =&gt; 'username'; br
      input :name =&gt; 'username', :type =&gt; 'text'; br

      label 'Password', :for =&gt; 'password'; br
      input :name =&gt; 'password', :type =&gt; 'text'; br

      input :type =&gt; 'submit', :name =&gt; 'login', :value =&gt; 'Login'
    end

  end

  def whereis
    form :method =&gt; &quot;post&quot; do
      input :type =&gt; &quot;text&quot;, :name =&gt; &quot;user&quot;
      input :type =&gt; &quot;submit&quot;, :value =&gt; &quot;add me&quot;
    end
    table do
      tr do
        td &quot;name&quot;
        td &quot;location&quot;
        td &quot;time&quot;
      end
      tr do
        @users.each do |u|
          u.each{|c| td c}
        end
      end
    end
  end
end

def Whereis.create
  Camping::Models::Session.create_schema
  Whereis::Models.create_schema :assume =&gt; (Whereis::Models::User.table_exists? ? 1.0 : 0.0)
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://n79.org/2008/03/07/fireeagle-sample-app-whereis/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Overrides in Camping</title>
		<link>http://n79.org/2008/03/05/overrides-in-camping/</link>
		<comments>http://n79.org/2008/03/05/overrides-in-camping/#comments</comments>
		<pubDate>Wed, 05 Mar 2008 08:18:06 +0000</pubDate>
		<dc:creator>nikhilb</dc:creator>
				<category><![CDATA[camping]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://n79.org/2008/03/05/overrides-in-camping/</guid>
		<description><![CDATA[If you want to add a call to all the controllers in your Camping miroframework app you can use before or after overrides. These are similar to the before_filter in Rails. Remember to return the superclass or Camping will throw a &#8220;Read error: #&#60;NoMethodError: undefined method `status&#8217; for nil:NilClass&#62;&#8221; because it can&#8217;t call back into [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fn79.org%2F2008%2F03%2F05%2Foverrides-in-camping%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fn79.org%2F2008%2F03%2F05%2Foverrides-in-camping%2F&amp;source=nikibobb&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>If you want to add a call to all the controllers in your  <a href="http://code.whytheluckystiff.net/camping/" title="Camping Microframework" target="_blank">Camping miroframework</a> app you can use <a href="http://code.whytheluckystiff.net/camping/wiki/BeforeAndAfterOverrides" title="Before or After Override for camping" target="_blank">before or after overrides</a>. These are similar to the <em>before_filter</em> in Rails.</p>
<p>Remember to return the superclass or Camping will throw a <em>&#8220;Read error: #&lt;NoMethodError: undefined method `status&#8217; for nil:NilClass&gt;</em>&#8221; because it can&#8217;t call back into the returned controller. A <font color="#ff0000">modification</font> of the above linked wiki page example illustrates -</p>
<pre name="code" class="ruby">

Camping.goes :YourApp

module YourSession
  def service(*a)
    @session = YourApp::Session.new
    s = super(*a)
    @session.close
    #return s from above after completing
    s
  end
end

module YourApp
  include YourSession
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://n79.org/2008/03/05/overrides-in-camping/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Optimizing an SQL LIKE Query</title>
		<link>http://n79.org/2006/03/07/optimizing-an-sql-like-query/</link>
		<comments>http://n79.org/2006/03/07/optimizing-an-sql-like-query/#comments</comments>
		<pubDate>Wed, 08 Mar 2006 03:58:20 +0000</pubDate>
		<dc:creator>nikhilb</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[dev]]></category>

		<guid isPermaLink="false">http://thoughts.n79.org/2006/03/07/optimizing-an-sql-like-query/</guid>
		<description><![CDATA[Carlos did a quick test earlier in the day on our Apache Derby backend and found that in a particular like query Derby was 23x slower than on a equality query over the same data set. Very often, databases do not optimize LIKE queries, partially because it is rare for them to support the types [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fn79.org%2F2006%2F03%2F07%2Foptimizing-an-sql-like-query%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fn79.org%2F2006%2F03%2F07%2Foptimizing-an-sql-like-query%2F&amp;source=nikibobb&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><a title="Carlos Maltzahn" href="http://www.soe.ucsc.edu/~carlosm/">Carlos</a> did a quick test earlier in the day on our <a title="Apache Derby" href="http://db.apache.org/derby/">Apache Derby</a> backend and found that in a particular like query Derby was 23x slower than on a equality query over the same data set. Very often, databases do not optimize LIKE queries, partially because it is rare for them to support the types of indices such optimizations would require.</p>
<p>It took me a little while to find this <a target="_blank" title="Apache Derby LIKE Transformations" href="http://db.apache.org/derby/docs/10.0/manuals/tuning/perf96.html#HDRSII-TRANSFORM-37208">gem on LIKE Transformations  </a>in the Derby tuning manual. Basically the document covers some transformations which the Derby SQL parser goes through to make LIKE queries optimizable. For me, this solved the problem as it allowed me to rewrite my query into a form that was optimizable albeit with a slight loss of functionality in my application. Unfortunately, this is not the case for all LIKE queries. The transformations are quite obvious and easy to follow once you see them, so take a look if you are having similar performance problems.</p>
<blockquote><p><strong>Before:</strong></p>
<blockquote><p>SELECT checksum FROM tags WHERE tag LIKE &#8216;%element%&#8217;</p>
<p><strong>Gets parsed into &#8211;</strong>  SELECT checksum FROM tags WHERE tag LIKE &#8216;%element%&#8217;</p></blockquote>
<p><strong>After</strong></p>
<blockquote><p>SELECT checksum FROM tags WHERE tag LIKE &#8216;element%&#8217;</p>
<p><strong>Gets parsed into &#8211;</strong>  SELECT checksum FROM tags WHERE tag >= &#8216;element&#8217;   AND tag < 'elemenu'</p></blockquote>
</blockquote>
<p>These transformations are also potentially useful with databases other than Derby when LIKE queries are running slow, as you could do them manually on your statements to the fullest extent possible potentially eliminating LIKE altogether.</p>
]]></content:encoded>
			<wfw:commentRss>http://n79.org/2006/03/07/optimizing-an-sql-like-query/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.378 seconds -->
