Skip to content
accelerando

Tag Archives: Code Snippets

Oracle: Drop table if exists replacement

16-Feb-10

Mysql has a nice “if exists” addition to the drop table statement. If the table to be dropped does not exists, it doesn’t raise an exception but only creates a warning.

In Oracle RDMBS you can emulate this behavior like so:

BEGIN execute immediate 'drop table INSERT_TABLE_NAME_HERE'; EXCEPTION WHEN others THEN IF SQLCODE != -942 THEN RAISE; END IF; END;
/

Ugly, but it works very well.

An iterable array

12-Jan-10

Java has the nice Iterable interface (since Java 5, i guess) that allows object oriented loops like

List<String> strings = new ArrayList<String>();
for(String string : strings) 
	System.out.println(string);

but guess what, a simple array is not iterable…

In case you need one, feel free to use this one:

package ac.simons;
 
import java.util.Iterator;
 
public class IterableArray<T> implements Iterable<T> {
	private class ArrayIteratorImpl implements Iterator<T> {
		private int position = 0;
		@Override
		public boolean hasNext() {
			return data != null && this.position < data.length;
		}
 
		@Override
		public T next() {
			return data[position++];
		}
 
		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}		
	}
 
	private final T[] data;
 
	public IterableArray(T[] data) {
		this.data = data;
	}
 
	@Override
	public Iterator<T> iterator() {
		return new ArrayIteratorImpl();
	}	
}

Today: Fun with Unicode, Regex and Java.

03-Nov-09

Some would say, i have 3 problems ;)

private final static Pattern placeholder = Pattern.compile("#\\{(\\w+?)\\}");

won’t match “Mot#{ö}rhead” for example.

To replace the word character \w you either need the list of possible unicodeblocks like [\p{InLatin}|\p{InEtc}] (you get the codes for the blocks through “Character.UnicodeBlock.forName” or you’re lazy like me and just use the dot:

private final static Pattern placeholder = Pattern.compile("#\\{(.+?)\\}");

Oh what a day… :/

Redcloth / Textilize :hard_breaks is broken in Rails 2.3.4

24-Sep-09

The default behavior for quite a long time was :hard_breaks in the textilize helper method in rails.

Hard Breaks means: All line breaks are turned into <br />’s.

Somebody changed the textilize helper in “actionpack-2.3.4/lib/action_view/helpers/text_helper.rb” in 2.3.4 and added the ability to pass some options but broke the default behavior here:

def textilize(text, *options)
        options ||= [:hard_breaks]
        # ...

Options will never be null.

I fixed this by monkey patching the module through the following code in config/initializers/textilizepatch.rb

module ActionView
  module Helpers
    module TextHelper
      def textilize(text, *options)
        options = [:hard_breaks] if options == nil || options.size == 0
 
        if text.blank?
          ""
        else
          textilized = RedCloth.new(text, options)
          textilized.to_html
        end
      end
    end
  end
end

Such changes should be tested… *grml*

Logging in Rails outside a controller

25-Aug-09

You can use

RAILS_DEFAULT_LOGGER.log "foobar"
# or
Rails.logger.log "blah"

outside a controller for logging.

Turn ruby heredocs from double-quoted into sinqle-quoted strings

17-May-09

By default, Rubys heredocs are interpreted as double-quoted strings, that is #{something} is evaluated, \r turns into newline and so forth.

You can change this behaviour by single quoting the heredoc identifier like so:

s = <<-'SINGLE_QUOTED'
#{i'm not interpreted}
SINGLE_QUOTED

Grails: Completely disable stacktrace.log file

24-Mar-09

Regarding my question on twitter about completely disabling the creation of stacktrace.log from a Grails application in production mode, here is my answer:

environments {
    production {
        log4j = {
            appenders {
               null name:'stacktrace'
            }
        }
    }
    development {
    }
}

Be careful: This overwrites all other log4j closures that are made outside the environment specific settings. I found no solution for that.

Background: One of my Grails 1.1 app fails to start on a Tomcat application container deployed on an Oracle Enterprise Linux server because it fails to create the stacktrace.log.

What annoyed me is that i needed to dig around in the Grails source code to find the answer to my question in “src/groovy/org/codehaus/groovy/grails/plugins/logging/Log4jConfig.groovy” within the method “createFullstackTraceAppender()”. Should be stated in the documentation (perfect place here).

Edit: If your Grails 1.1 still fails to start(*) look out for xercesImpl.jar and xml-apis.jar or similar somewhere in your Tomcat 5 directory. These are some kind of Java 1.4 compatibility layers which break things in Grails 1.1. Oracle puts these into common/endorsed. After removing them, everything went fine.

(*) Exception was:

java.lang.RuntimeException: XPathFactory#newInstance() failed to create an XPathFactory for the default object model:
http://java.sun.com/jaxp/xpath/dom with the XPathFactoryConfigurationException: javax.xml.xpath.XPathFactoryConfigurationException:
No XPathFctory implementation found for the object model: http://java.sun.com/jaxp/xpath/dom

Localizing dates and time with Rails’ I18n using procs

12-Feb-09

Ruby on Rails I18n infrastructure did a great job to internationalization in Rails applications. Most things work right out of the box.

Daily Fratze is fully internationalized and i wanted to use ordinal day numbers in the English version. Pity, there is no template for strftime that works that way.

As i already hat monkey patched a “t” method to all date and time related classes, i came up with the following solution:

Parallel to “en.yml” i now have “en.rb” in my locales folder which gets loaded in environment.rb via

config.i18n.load_path += Dir[File.join(RAILS_ROOT, 'app', 'locales', '*.{yml,rb}')]

The en.rb files defines some procs as translation values like so:

{
  :'en' => {
    :date => {
      :formats => {
        :dmy_with_long_month              => lambda { |date| "%B #{date.day.ordinalize}, %Y" },
      }
    },
    :time => {
      :formats => {
        :dmy_with_long_month                       => lambda { |date| "%B #{date.day.ordinalize}, %Y" },        
        :dmy_with_full_day_and_long_month_and_time => lambda { |date| "%A, %B #{date.day.ordinalize}, %Y at %H:%M" }
      }
    }
  }
}

Used with the standard I18n tools you’ll end up with the string representation of the proc object. Useless ;)

So time for monkeypatching like so:

module DateTimeSupport
  def t(format = nil)
    type = self.respond_to?(:sec) ? 'time' : 'date'
    formats = I18n.translate(:"#{type}.formats")
    format = formats[format.to_sym] if formats && formats[format.to_sym]
 
    I18n.localize(self, :format => format.respond_to?(:call) ? format.call(self) : format)
  end
end
 
class Time
  include DateTimeSupport
end
 
class Date
  include DateTimeSupport
end       
 
class DateTime
  include DateTimeSupport
end
 
class ActiveSupport::TimeWithZone
  include DateTimeSupport
end

Code resides in a file in config/initializers and gets loaded automatically. It adds a t method to all date and time related classes. The method tries to look up the translation of format just like I18n/Simple does.

If it is proc, it gets called and then passed to I18n, otherwise it the original parameter is used.

That way the t method can use “dmy_with_long_month”, :dmy_with_long_month and any other arbitrary format like “%B %Y” that is not defined in any language file.

Grails startup parameter

09-Feb-09

Just some snippets from the doku that I tend to forget:

Run grails on a different port:

grails -Dserver.port=9090 run-app

Run grails with a different environment:

grails prod run-app // production
grails -Dgrails.env=mycustomenv run-app  // mycustomenv

PDF::Writer and Ruby on Rails 2.2.2

24-Nov-08

If you followed the instructions here and used the method named PDF::Writer (Austin Ziegler), you we’re out of luck when Rails 2.1 appeared.

With Rails 2.2.2 once again the rendering mechanism seems to have changed big time and my previous post on how to make the pdf/writer gem work with a custom template handler doesn’t work anymore.

With the help of Josh Peek i was able to fix this. He gave me the following code to enable a rpdf template handler with pdf-writer:

module ActionView # :nodoc:
  require 'pdf/writer'
  class PDFRender < ActionView::TemplateHandler
    PAPER = 'A4'
    include ApplicationHelper                     
    include ActionView::Helpers::TranslationHelper
    include ActionView::Helpers::AssetTagHelper
    include ActionView::Helpers::TextHelper
    include ActionView::Helpers::TagHelper
    include ActionView::Helpers::UrlHelper
 
    def self.call(template)
      "ActionView::PDFRender.new(self).render(template, local_assigns)"
    end
 
    def initialize(action_view)
      @action_view = action_view
    end
 
    # Render the PDF
    def render(template, local_assigns = {})
      @action_view.controller.headers["Content-Type"] ||= 'application/pdf'
 
      # Retrieve controller variables
      @action_view.controller.instance_variables.each do |v|
        instance_variable_set(v,
        @action_view.controller.instance_variable_get(v))
      end
 
      pdf = ::PDF::Writer.new( :paper => PAPER )
      pdf.compressed = true if RAILS_ENV != 'development'
      eval template.source, nil, ''
 
      pdf.render
    end
  end
end
 
ActionView::Template.register_template_handler 'rpdf', ActionView::PDFRender

Just drop this under config/initializers and you’re fine.

Close
E-mail It