Tuesday, April 19, 2011

ActiveRecord JDBC adapter multiple database bug

My rails application need to two database simultaneously, one is db2 and the other is SQL server. Unfortunately I got an error called "undefined method `identity=' for". After googling, there is a bug reported here https://github.com/nicksieger/activerecord-jdbc-adapter/issues/25.

After tracing JDBC adapter source, I found the reason for my case: the class method column_types in arjdbc/jdbc/column.rb

@column_types ||= ::ArJdbc.constants.map{|c|
::ArJdbc.const_get c }.select{ |c|
c.respond_to? :column_selector }.map{|c|
c.column_selector }.inject({}) { |h,val|
h[val[0]] = val[1]; h }

Both MsSQL and DB2 are lazy loaded. When you have multiple databases, once @column_types is instantiated for db2, it will never be changed. But it is possible that MsSQL module is not loaded yet and so its column_selector is never called.

def self.column_selector
[/sqlserver|tds|Microsoft SQL/i, lambda {|cfg,col| col.extend(::ArJdbc::MsSQL::Column)}]
end

column_selector extends JdbcColumn with MsSQL version Column, and it defines :identity. If it is not called, "undefined method 'identity='" will be thrown.

The simple way I found to fix this issue: put the following in config/application.rb

# overcome activerecord-jdbc-adapter bug "undefined method 'identity='"
# for multiple databases by preloading the driver
if defined?(ArJdbc::Version::VERSION)
require 'arjdbc/db2'
require 'arjdbc/mssql'
end

Rails filters for Ajax pages

1. layout/application generate the application frame, jquery tabs
2. for each tab, the content is loaded by ajax call
3. the response of an ajax call is just a segment of html or json data
4. Need an easy way to send a request to the server just like ajax call so that I can debug the issue without load the whole page.

SOLUTION 1:

1. Routing .js or .html
2. ajax always asks for .js

SOLUTION 2: Filter

Rails 3 SSO using JRuby, Tomcat, and Waffle

Friday, April 15, 2011

Get JRE 6 zip

You can only find JRE installation exe file from Oracle.com. But you can extract the zip file from it.

* Download JRE installation exe file
* Launch the installation, but stop when the first dialog is shown
* Go to C:\Users\yourname\AppData\LocalLow\Sun\Java\jre1.6.0_24
* Open Data1.cab in WinRAR
* You will find core.zip.

Friday, April 8, 2011

Warbler configuration

Warbler is so simple and powerful to package all files you need for a Rails application into a war. However, you may want to customize how warbler packages the war file because you may not want to deploy a tens mega-bytes war file every time and you Rails application is very small. I just thinner my 36MB war file to 1MB by removing all slow-changed dependent jars and gems. Of course, doing so you have to have some additional steps to maintain the dependencies.

1. Three jars in WEB-INF/lib, jruby-core, jruby-rack and jruby-stdlib, use 12MB
2. All rails dependent gems may use 6MB

And all the above files are not changed too frequently.

1. How to exclude all dependent gems in war

config.gem_dependencies = false

2. How to exclude jruby jars

config.java_libs = []

After

Monday, April 4, 2011

SyntaxHighlighter hints

SyntaxHighlighter provides a simple method to highlight the code:

SyntaxHighlighter.all();

But this method is actually hooked with body's onload() event. When I use some ajax call and want to format the page dynamically, this method won't work. It is actually easy to fix that: use highlight method directly.

SyntaxHighlighter.highlight();

And default font size of SyntaxHighlighter is too small. Found this page by googling

http://www.kerrywong.com/2009/04/05/changing-syntaxhighlighter-font-size/

it works, but there is an issue that the line numbers in gutter won't match the lines. You can fix this use the same font-size as below:

.syntaxhighlighter a,
.syntaxhighlighter div,
.syntaxhighlighter code,
.syntaxhighlighter table,
.syntaxhighlighter table td,
.syntaxhighlighter table tr,
.syntaxhighlighter table tbody,
.syntaxhighlighter table thead,
.syntaxhighlighter table caption,
.syntaxhighlighter textarea {
...
font-size: 1.01em;
...
}

.syntaxhighlighter table td.gutter .line {
text-align: right !important;
padding: 0 0.5em 0 1em !important;
font-size: 1.01em;
}