Thursday, 13 June 2013

Dropwizard / JDBI String Templating

At first glance the documentation seems straight forward, but with some updates to dropwizard framework and some undocumented additions to JDBI

Based on Brian McCallisters' original blog post: http://skife.org/jdbi/java/2011/12/21/jdbi_in_clauses.html


@UseStringTemplate3StatementLocator("/sql/templates/TestDao.sql.stg")
public interface TestDao {

 @SqlQuery
 Iterator getDevicesWithInClause(
   @BindIn("guids") List guids,
   @Bind("limit") Integer limit);
}


The main pieces of information that I had to hunt around for are:

  • @UseStringTemplate3StatementLocator replaces the now deprecated @ExternalizedSqlViaStringTemplate3
  • you can pass a value to the @UseStringTemplate3StatementLocator which is the location (on the classpath) of the string template file.
  • In your string template file, for normal @Bind parameters you still use the standard colonprefix
sql/templates/TestDao.sql.stg

group TestDao;

getDevicesWithInClause(guids, limit) ::= <<
 select distinct(guid) from table where guid in () limit :limit
>>

Thursday, 2 May 2013

Ruby environment notes

IDEs


  • Eclipse with ruby DLT currently only supports up to Ruby 1.8 (Quite a big language change in 1.9 so not much good) 
  • RubyMine - excellent, but ~£90 (look out for offers from Jetbrains, they run them regularly) 
  • Aptana Studio - Built on eclipse but full ruby support (or at least 1.9 language support)

Build Tools

  • Rake - (Ruby mAKE). Like ant / make for ruby
    • Look in the 'Rakefile' and see targets defined. (e.g. 'rake test' will often run tests)
  • Gem - repository of compiled modules for ruby
    • See usage 'gem --help'. 
    • gem install <gem name> / gem uninstall <gem name>
  • Bundle - Used to manage dependencies for a project. (Use 'bundle install')
    • Gemfile contains list of repositories and files to use

Testing

  • Rake - Test call minitest / rspec files etc..
  • Minitest - https://github.com/seattlerb/minitest

Tuesday, 30 April 2013

Ruby notes

Not being familar with ruby, here's a few notes / cheat sheet as I keep forgetting the basics

Functions:

def name (param1="Default Value", paramN, *args, &block)
  // actions
  return val
end

*args - A variable sized argument (arg.length)
&block - a block to be automatically converted to Proc

Naming conventions:

Type Example Notes
constant Pi Starts with capital letter. Is mutable!!!
boolean test isEql? Methods with a boolean response are prepended with a '?'
destructive test delete! Makes changes to object on which the function is invoked on (ends with '!')
setter method name=(n) method name ends in '='s sign
instance variable @counter .
class variable @@times .
global variables $global .

Symbols:

Placeholders for identifiers and strings, always prefixed by a ':' (colon). Can't be directly created - for Strings - use to_sym or intern methods, use id2name to transform back.

Effectively transforms the string content into a label. Because of the interning symbols are more memory efficient then copies of strings.

name = "Matz"
name.to_sym # => :Matz
:Matz.id2name # => "Matz"
name == :Matz.id2name # => true

Conditionals:

if a == b then <do stuff> end
if a == b: <do stuff> end // : instead of 'then'
if a == b && b == c: <do stuff> end
puts "output" if a == b  // no need for then & end if used as a statement modifier

if a == 1
  puts 'one'
elsif a == 2
  puts 'two'
else
  puts '!(1 || 2)'
end

if a == :foo
  puts "test against symbol multi-line"
elsif a == :bar: puts "test against symbol single line (extra colon)"
end

case foo
  when :foo; "Foo"  // NOTE: the ':' operator was allowed in ruby 1.8
  when 1..3; "Range of value test"
  else "default"
end

Iteration:

while <condition> do   // 'do' is optional
  // code
end

begin
  // code
end while <condition>

for i in 1..5 do  // 'do' is optional
  print i, " "
end

// Alternatively, use 'times' method from the Integer class
5.times { |i| print i, " " }
// also there is upto and downto methods
2.upto(8) { |i| print i, " " }

unless - like a negated if statement
until - like a while loop, do until a condition is met
loop - creates a loop forever until a break condition is met (such as break statement)


Strings:

my_string = %{A string with customer delimiters defining start / end}
multi_line = <<#  // use -<< to keep indentation
  text across multiple
  lines with a custom delimiter
#
h = "Foo -".concat("bar") << "!" // concatenation methods
h.freeze // make string immutable, check with frozen? method
h[3] // access 3rd character code at index location (use h[3].chr for character)
h[start, len] // substring
h.index("b") // search for char
"a" <=> "a" // 'spaceship operator' contains character code of strings, returns 0, 1 or -1

== and eql? are slightly different(== returns true if two objects are Strings, eql? checks content and length)

Arrays:

Array.new || Array.new(12) || Array.new 12 || Array.new(12, <default>)
Array.new(10) { |e| e = e * 2 } // [0, 2, 4, ..., 18 ]
%w{ foo bar who har } // new array with whitespace separating entries
rg = Array(0..9) // [0, 1, 2, ..., 9]
rg = Array[ "one", "two", "three" ] || [ "foo", "bar" ]
rg[-1] // access last element in array, or rg.first / rg.last
rg.index("two") == 1 // lookup index of item
rg1 & rg2 // intersect of arrays (only common elements)
rg1 - rg2 // difference (only unique elements)
rg1 | rg2 // union (join with dupes removed)
rg.pop || rg.push || rg.shift || rg.unshift // stack operations

Array.clear
Array.empty? // true | false

Hash / Dictionary

Hash.new || Hash[ :key1, "Value1", ... ] || Hash[ :key1 => "Value1", ... ] 
Hash.new("month") // hash with a default value - the one returned if key has no value associated with it
h = {symbol: "value"} // 1.9 using symbol as hash key
h = {:symbol => "value"} // <1.9 ruby using symbol as hash key

h.has_key? :key1 || h.has_value? "Value1" || h[:key]
h.keys // list keys
h.values // list values

h.delete( :key )
h.delete_if { |k,v| v == "Value1" }
h.clear || h.empty?

h.each { |k,v| puts "#{k} / #{v}" } // loop through each key-value pair
h.each_key || h.each_value // just keys or values

Classes:

class Hello < Greeting // Hello extends (inherits) Greeting
  @@size = 0 // class variable

  attr :onlyget
  attr :getandset, true // second argument true
  attr_reader :gone, :here // getter
  attr_writer :count, :set // setters
  attr_accessor :start, :stop // accessors 
  def initialize( arg1 )  // c'tor
    @val = arg1   // @ == instance variable
  end

  class << self // singleton class, instantiated by the enclosing class
    def polygon(vertices, length)
      -- snip --
    end
  end

  def Hello.bye // Class method
    puts "Goodbye"
  end

  private  // methods below here are private (also can use protected)

  def hidden
    ... snip ...
  end

end

Hello.polygon(2, 5)

Hello.instance_methods - Object.instance_methods // print out the Hello specific methods

h = Hello.new( "Test" )
h.respond_to? (:gone)  // test if instance responds to method invocation

Blocks:

Nameless functions (effectively a closure). Can be wrapped in 'do' 'end' or or braces {}. Braces have higher precedence.
['purple', 'monkey', 'dishwasher'].each { |e| puts e }
or
['purple', 'monkey', 'dishwasher'].each do |element| puts element end
Automatically convert block to proc, prefix param with & (ampersand)

def return_proc( &proc )
  yield
end

return_proc { puts "Convert block to proc" }

Procs / Lambda:

Store procedures as objects complete with context. Invoke with call method (count.call)
count = Proc.new { [1,2,3,4,5].each do |i| print i end; puts } 
your_proc = lambda { puts "Lurch: 'You rang?'" }
my_proc = proc { puts "Morticia: 'Who was at the door, Lurch?'" }
Note: lambda / proc is preferred to Proc.new.

Modules:

like namespaces, a Module/class including a module inherits it's contents. 
Must be named as a constant (capital letter).

include Mymodule // if in same file
require 'Mymodule' // if module is in a separate file

Can define module methods by prefixing method with module name (e.g. def Mymodule.method)

Exception handling:

rescue analogous to catch, ensure analogous to finally in Java.
begin
  // do stuff
rescue ZeroDivisionError // type of exception
  // do stuff
ensure
  // do stuff
end

// throw / catch

def test(val)
  throw ( :zero ) if val <= 0
  return 5 / val
end

catch( :zero ) { test(-11) }

Metaprogramming:

write a program (or part of) using another program. 'define_method' in Module is key element - creates methods on the fly.

class Foo
  %w{ foo bar yar }.each do |n|
    define_method(n) { puts "method #{n}" }
  end
end

Foo.new.bar // prints 'method bar'

Miscellaneous:

  • alias - reference to another method. A way to have access to overridden methods. (alias <new-name> <existing-method>)
  • yield - Used within a method to execute a block associated with it. Can test for presence with block_given? test (def doit if block_given? yield else puts "no block" end end)
  • BEGIN / END can define blocks that execute before and after a program runs (BEGIN { puts "Date and time: " + Time.now.to_s } )
  • .class method returns type of object being called
  • irb - command line ruby interpreter
  • ri - command line ruby documentation, i.e. 'ri Array'