activerecord-jdbcsqlanywhere-adapter 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/README.md +2 -2
- data/Rakefile +8 -0
- data/lib/activerecord-jdbcsqlanywhere-adapter.rb +1 -1
- data/lib/arjdbc/sqlanywhere/adapter.rb +146 -0
- data/lib/arjdbc/sqlanywhere/adapter_java.jar +0 -0
- data/lib/arjdbc/sqlanywhere/connection_methods.rb +8 -2
- data/src/java/arjdbc/sqlanywhere/SQLAnywhereRubyJdbcConnection.java +15 -0
- data/test/db/sqlanywhere.rb +3 -2
- data/test/my-minitest-loader.rb +13 -0
- data/test/sqlanywhere_limit_offset_test.rb +159 -0
- metadata +10 -24
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -23,6 +23,14 @@ end
|
|
23
23
|
task :build => [:java_compile, :git_local_check]
|
24
24
|
|
25
25
|
require 'rake/testtask'
|
26
|
+
|
27
|
+
# overriding the default rake tests loader
|
28
|
+
class Rake::TestTask
|
29
|
+
def rake_loader
|
30
|
+
'test/my-minitest-loader.rb'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
26
34
|
Rake::TestTask.new(:test) do |test|
|
27
35
|
test.libs << 'lib' << 'test'
|
28
36
|
ar_jdbc = ENV['AR_JDBC'] ||
|
@@ -12,6 +12,152 @@ module ::ArJdbc
|
|
12
12
|
def init_column(name, default, *args)
|
13
13
|
@name = name.downcase
|
14
14
|
end
|
15
|
+
|
16
|
+
# Post process default value from JDBC into a Rails-friendly format (columns{-internal})
|
17
|
+
def default_value(value)
|
18
|
+
# jdbc returns column default strings with actual single quotes around the value.
|
19
|
+
return $1 if value =~ /^'(.*)'$/
|
20
|
+
|
21
|
+
value
|
22
|
+
end
|
23
|
+
|
24
|
+
def simplified_type(field_type)
|
25
|
+
case field_type
|
26
|
+
when /int|bigint|smallint|tinyint/i then :integer
|
27
|
+
when /numeric/i then (@scale.nil? || @scale == 0) ? :integer : :decimal
|
28
|
+
when /float|double|decimal|money|real|smallmoney/i then :decimal
|
29
|
+
when /datetime|smalldatetime/i then :datetime
|
30
|
+
when /timestamp/i then :timestamp
|
31
|
+
when /time/i then :time
|
32
|
+
when /date/i then :date
|
33
|
+
when /text|ntext|xml/i then :text
|
34
|
+
when /binary|image|varbinary/i then :binary
|
35
|
+
when /char|nchar|nvarchar|string|varchar/i then (@limit == 1073741823 ? (@limit = nil; :text) : :string)
|
36
|
+
when /bit/i then :boolean
|
37
|
+
when /uniqueidentifier/i then :string
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def type_cast(value)
|
42
|
+
return nil if value.nil? || value == "(null)" || value == "(NULL)"
|
43
|
+
case type
|
44
|
+
when :primary_key then value == true || value == false ? value == true ? 1 : 0 : value.to_i
|
45
|
+
when :boolean then value == true or (value =~ /^t(rue)?$/i) == 0 or value=="1"
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def quote_column_name(name)
|
53
|
+
"\"#{name}\""
|
54
|
+
end
|
55
|
+
|
56
|
+
def quoted_true
|
57
|
+
quote(1)
|
58
|
+
end
|
59
|
+
|
60
|
+
def quoted_false
|
61
|
+
quote(0)
|
62
|
+
end
|
63
|
+
|
64
|
+
def sybaseserver_version
|
65
|
+
@sybaseserver_version ||= select_value("select @@version").split('.').map(&:to_i)
|
66
|
+
end
|
67
|
+
|
68
|
+
def last_insert_id
|
69
|
+
Integer(select_value("SELECT @@IDENTITY"))
|
70
|
+
end
|
71
|
+
|
72
|
+
def _execute(sql, name = nil)
|
73
|
+
result = super
|
74
|
+
ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id : result
|
75
|
+
end
|
76
|
+
|
77
|
+
def modify_types(tp) #:nodoc:
|
78
|
+
tp[:primary_key] = "NUMERIC(22,0) DEFAULT AUTOINCREMENT PRIMARY KEY"
|
79
|
+
tp[:integer][:limit] = nil
|
80
|
+
tp[:boolean] = {:name => "bit"}
|
81
|
+
tp[:binary] = {:name => "image"}
|
82
|
+
tp
|
83
|
+
end
|
84
|
+
|
85
|
+
def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
|
86
|
+
limit = nil if %w(text binary).include? type.to_s
|
87
|
+
return 'uniqueidentifier' if (type.to_s == 'uniqueidentifier')
|
88
|
+
return super unless type.to_s == 'integer'
|
89
|
+
|
90
|
+
if limit.nil? || limit == 4
|
91
|
+
'int'
|
92
|
+
elsif limit == 2
|
93
|
+
'smallint'
|
94
|
+
elsif limit == 1
|
95
|
+
'tinyint'
|
96
|
+
else
|
97
|
+
'bigint'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def add_limit_offset!(sql, options)
|
102
|
+
if options[:limit] and options[:offset] and options[:offset] > 0
|
103
|
+
sql.sub!(/^\s*SELECT(\s+DISTINCT)?/i, "SELECT\\1 TOP #{options[:limit]} START AT #{options[:offset]+1}")
|
104
|
+
elsif sql !~ /^\s*SELECT (@@|COUNT\()/i
|
105
|
+
sql.sub!(/^\s*SELECT(\s+DISTINCT)?/i) do
|
106
|
+
"SELECT#{$1} TOP #{options[:limit]}"
|
107
|
+
end unless options[:limit].nil?
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_column_options!(sql, options) #:nodoc:
|
112
|
+
super
|
113
|
+
if options[:null] != false
|
114
|
+
sql << " NULL"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Adds a new column to the named table.
|
119
|
+
# See TableDefinition#column for details of the options you can use.
|
120
|
+
def add_column(table_name, column_name, type, options = {})
|
121
|
+
add_column_sql = "ALTER TABLE #{table_name} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
122
|
+
fix_null = false
|
123
|
+
if options[:null] == false
|
124
|
+
fix_null = true
|
125
|
+
options.delete(:null)
|
126
|
+
end
|
127
|
+
add_column_options!(add_column_sql, options)
|
128
|
+
# TODO: Add support to mimic date columns, using constraints to mark them as such in the database
|
129
|
+
# add_column_sql << " CONSTRAINT ck__#{table_name}__#{column_name}__date_only CHECK ( CONVERT(CHAR(12), #{quote_column_name(column_name)}, 14)='00:00:00:000' )" if type == :date
|
130
|
+
execute(add_column_sql)
|
131
|
+
execute("ALTER TABLE #{table_name} MODIFY #{quote_column_name(column_name)} NOT NULL") if fix_null
|
132
|
+
end
|
133
|
+
|
134
|
+
def remove_column(table_name, column_name)
|
135
|
+
remove_from_primary_key(table_name, column_name)
|
136
|
+
remove_from_index(table_name, column_name)
|
137
|
+
remove_check_constraints(table_name, column_name)
|
138
|
+
execute "ALTER TABLE #{table_name} DROP #{quote_column_name(column_name)}"
|
139
|
+
end
|
140
|
+
|
141
|
+
def remove_from_index(table_name, column_name)
|
142
|
+
end
|
143
|
+
|
144
|
+
def remove_check_constraints(table_name, column_name)
|
145
|
+
end
|
146
|
+
|
147
|
+
def remove_from_primary_key(table_name, column_name)
|
148
|
+
columns = select "select col.cname from SYS.syscolumns col WHERE col.tname = '#{table_name}' AND in_primary_key = 'Y'"
|
149
|
+
the_column, columns = columns.partition{|c| c['cname'].casecmp(column_name.to_s) == 0 }
|
150
|
+
if the_column.size > 0
|
151
|
+
execute "ALTER TABLE #{table_name} DROP PRIMARY KEY"
|
152
|
+
if columns.size > 0
|
153
|
+
columns.map! {|c| quote_column_name(c['cname'])}
|
154
|
+
execute "ALTER TABLE #{table_name} ADD PRIMARY KEY (#{columns.join(', ')})"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def remove_index(table_name, options = {})
|
160
|
+
execute "DROP INDEX #{table_name}.#{index_name(table_name, options)}"
|
15
161
|
end
|
16
162
|
end
|
17
163
|
end
|
Binary file
|
@@ -1,9 +1,15 @@
|
|
1
1
|
class ActiveRecord::Base
|
2
2
|
class << self
|
3
3
|
def sqlanywhere_connection( config )
|
4
|
+
version4 = true
|
5
|
+
begin
|
6
|
+
Java::com.sybase.jdbc4.jdbc.SybDriver
|
7
|
+
rescue NameError
|
8
|
+
version4 = false
|
9
|
+
end
|
4
10
|
config[:port] ||= 2638
|
5
|
-
config[:url] ||= "jdbc:sybase:Tds:#{config[:
|
6
|
-
config[:driver] ||= "com.sybase.jdbc3.jdbc.SybDriver"
|
11
|
+
config[:url] ||= "jdbc:sybase:Tds:#{config[:host]}:#{config[:port]}?serviceName=#{config[:database]}"
|
12
|
+
config[:driver] ||= version4 ? "com.sybase.jdbc4.jdbc.SybDriver" : "com.sybase.jdbc3.jdbc.SybDriver"
|
7
13
|
config[:dialect] = "sqlanywhere"
|
8
14
|
jdbc_connection(config)
|
9
15
|
end
|
@@ -31,6 +31,7 @@ import java.sql.DatabaseMetaData;
|
|
31
31
|
import java.sql.ResultSet;
|
32
32
|
import java.sql.SQLException;
|
33
33
|
import java.sql.Statement;
|
34
|
+
import java.sql.Connection;
|
34
35
|
import java.sql.Types;
|
35
36
|
|
36
37
|
import arjdbc.jdbc.RubyJdbcConnection;
|
@@ -64,18 +65,32 @@ public class SQLAnywhereRubyJdbcConnection extends RubyJdbcConnection {
|
|
64
65
|
}
|
65
66
|
};
|
66
67
|
|
68
|
+
protected static IRubyObject booleanToRuby(Ruby runtime, ResultSet resultSet, boolean booleanValue)
|
69
|
+
throws SQLException {
|
70
|
+
if (booleanValue == false && resultSet.wasNull()) return runtime.getNil();
|
71
|
+
return runtime.newBoolean(booleanValue);
|
72
|
+
}
|
73
|
+
|
67
74
|
/**
|
68
75
|
* Treat LONGVARCHAR as CLOB on Informix for purposes of converting a JDBC value to Ruby.
|
69
76
|
*/
|
70
77
|
@Override
|
71
78
|
protected IRubyObject jdbcToRuby(Ruby runtime, int column, int type, ResultSet resultSet)
|
72
79
|
throws SQLException {
|
80
|
+
if ( Types.BOOLEAN == type || Types.BIT == type ) {
|
81
|
+
return booleanToRuby(runtime, resultSet, resultSet.getBoolean(column));
|
82
|
+
}
|
73
83
|
if (type == Types.LONGVARCHAR) {
|
74
84
|
type = Types.CLOB;
|
75
85
|
}
|
76
86
|
return super.jdbcToRuby(runtime, column, type, resultSet);
|
77
87
|
}
|
78
88
|
|
89
|
+
@Override
|
90
|
+
protected IRubyObject unmarshalKeysOrUpdateCount(ThreadContext context, Connection c, Statement stmt) throws SQLException {
|
91
|
+
return context.getRuntime().newFixnum(stmt.getUpdateCount());
|
92
|
+
}
|
93
|
+
|
79
94
|
@Override
|
80
95
|
protected IRubyObject unmarshalResults(ThreadContext context, DatabaseMetaData metadata,
|
81
96
|
Statement stmt, boolean downCase) throws SQLException {
|
data/test/db/sqlanywhere.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
config = {
|
2
2
|
:username => 'dba',
|
3
|
-
:password => '
|
3
|
+
:password => 'sql',
|
4
4
|
:adapter => 'sqlanywhere',
|
5
5
|
:host => ENV[ "SQLANYWHERE_HOST" ] || 'localhost',
|
6
|
-
:
|
6
|
+
:port => ENV[ "SQLANYWHERE_PORT" ] || nil,
|
7
|
+
:database => ENV[ "SQLANYWHERE_NAMESPACE" ] || 'ARTest'
|
7
8
|
}
|
8
9
|
|
9
10
|
ActiveRecord::Base.establish_connection( config )
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'jdbc_common'
|
2
|
+
require 'db/sqlanywhere'
|
3
|
+
|
4
|
+
ActiveRecord::Schema.verbose = false
|
5
|
+
|
6
|
+
class CreateLongShips < ActiveRecord::Migration
|
7
|
+
|
8
|
+
def self.up
|
9
|
+
create_table "long_ships", :force => true do |t|
|
10
|
+
t.string "name", :limit => 50, :null => false
|
11
|
+
t.integer "width", :default => 123
|
12
|
+
t.integer "length", :default => 456
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
drop_table "long_ships"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
class LongShip < ActiveRecord::Base
|
23
|
+
has_many :vikings
|
24
|
+
end
|
25
|
+
|
26
|
+
class CreateVikings < ActiveRecord::Migration
|
27
|
+
|
28
|
+
def self.up
|
29
|
+
create_table "vikings", :force => true do |t|
|
30
|
+
t.integer "long_ship_id", :null => false
|
31
|
+
t.string "name", :limit => 50, :default => "Sven"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.down
|
36
|
+
drop_table "vikings"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
class Viking < ActiveRecord::Base
|
42
|
+
belongs_to :long_ship
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
class CreateNoIdVikings < ActiveRecord::Migration
|
47
|
+
def self.up
|
48
|
+
create_table "no_id_vikings", :force => true do |t|
|
49
|
+
t.string "name", :limit => 50, :default => "Sven"
|
50
|
+
end
|
51
|
+
remove_column "no_id_vikings", "id"
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.down
|
55
|
+
drop_table "no_id_vikings"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class NoIdViking < ActiveRecord::Base
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
class SQLAnywhereLimitOffsetTest < Test::Unit::TestCase
|
65
|
+
|
66
|
+
def setup
|
67
|
+
CreateLongShips.up
|
68
|
+
CreateVikings.up
|
69
|
+
CreateNoIdVikings.up
|
70
|
+
@connection = ActiveRecord::Base.connection
|
71
|
+
end
|
72
|
+
|
73
|
+
def teardown
|
74
|
+
CreateVikings.down
|
75
|
+
CreateLongShips.down
|
76
|
+
CreateNoIdVikings.down
|
77
|
+
ActiveRecord::Base.clear_active_connections!
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_limit_with_no_id_column_available
|
81
|
+
NoIdViking.create!(:name => 'Erik')
|
82
|
+
assert_nothing_raised(ActiveRecord::StatementInvalid) do
|
83
|
+
NoIdViking.find(:first)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_limit
|
88
|
+
%w(one two three four five six seven eight).each do |name|
|
89
|
+
LongShip.create!(:name => name)
|
90
|
+
end
|
91
|
+
ship_names = LongShip.find(:all, :limit => 3).map(&:name)
|
92
|
+
assert_equal(%w(one two three), ship_names)
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_limit_and_offset
|
96
|
+
return if @connection.sybaseserver_version[0] < 10
|
97
|
+
|
98
|
+
%w(one two three four five six seven eight).each do |name|
|
99
|
+
LongShip.create!(:name => name)
|
100
|
+
end
|
101
|
+
ship_names = LongShip.find(:all, :offset => 2, :limit => 3).map(&:name)
|
102
|
+
assert_equal(%w(three four five), ship_names)
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_limit_with_order
|
106
|
+
%w(one two three four five six seven eight).each do |name|
|
107
|
+
LongShip.create!(:name => name)
|
108
|
+
end
|
109
|
+
ship_names = LongShip.find(:all, :order => "name", :limit => 2).map(&:name)
|
110
|
+
assert_equal(%w(eight five), ship_names)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_limit_and_offset_with_order
|
114
|
+
return if @connection.sybaseserver_version[0] < 10
|
115
|
+
|
116
|
+
%w(one two three four five six seven eight).each do |name|
|
117
|
+
LongShip.create!(:name => name)
|
118
|
+
end
|
119
|
+
ship_names = LongShip.find(:all, :order => "name", :offset => 4, :limit => 2).map(&:name)
|
120
|
+
assert_equal(%w(seven six), ship_names)
|
121
|
+
end
|
122
|
+
|
123
|
+
# TODO: work out how to fix DISTINCT support without breaking :include
|
124
|
+
# def test_limit_and_offset_with_distinct
|
125
|
+
# %w(c a b a b a c d c d).each do |name|
|
126
|
+
# LongShip.create!(:name => name)
|
127
|
+
# end
|
128
|
+
# ship_names = LongShip.find(:all, :select => "DISTINCT name", :order => "name", :offset => 1, :limit => 2).map(&:name)
|
129
|
+
# assert_equal(%w(b c), ship_names)
|
130
|
+
# end
|
131
|
+
|
132
|
+
def test_limit_and_offset_with_include
|
133
|
+
return if @connection.sybaseserver_version[0] < 10
|
134
|
+
|
135
|
+
skei = LongShip.create!(:name => "Skei")
|
136
|
+
skei.vikings.create!(:name => "Bob")
|
137
|
+
skei.vikings.create!(:name => "Ben")
|
138
|
+
skei.vikings.create!(:name => "Basil")
|
139
|
+
ships = Viking.find(:all, :include => :long_ship, :offset => 1, :limit => 2)
|
140
|
+
assert_equal(2, ships.size)
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_limit_and_offset_with_include_and_order
|
144
|
+
return if @connection.sybaseserver_version[0] < 10
|
145
|
+
|
146
|
+
boat1 = LongShip.create!(:name => "1-Skei")
|
147
|
+
boat2 = LongShip.create!(:name => "2-Skei")
|
148
|
+
|
149
|
+
boat1.vikings.create!(:name => "Adam")
|
150
|
+
boat2.vikings.create!(:name => "Ben")
|
151
|
+
boat1.vikings.create!(:name => "Carl")
|
152
|
+
boat2.vikings.create!(:name => "Donald")
|
153
|
+
|
154
|
+
vikings = Viking.find(:all, :include => :long_ship, :order => "long_ships.name, vikings.name", :offset => 0, :limit => 3)
|
155
|
+
assert_equal(["Adam", "Carl", "Ben"], vikings.map(&:name))
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-jdbcsqlanywhere-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 1
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
version: 1.0.0
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.1
|
10
6
|
platform: ruby
|
11
7
|
authors:
|
12
8
|
- Brian Olsen
|
@@ -14,20 +10,16 @@ autorequire:
|
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
12
|
|
17
|
-
date: 2011-
|
18
|
-
default_executable:
|
13
|
+
date: 2011-10-17 00:00:00 Z
|
19
14
|
dependencies:
|
20
15
|
- !ruby/object:Gem::Dependency
|
21
16
|
name: activerecord-jdbc-adapter
|
22
17
|
prerelease: false
|
23
18
|
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
24
20
|
requirements:
|
25
21
|
- - ~>
|
26
22
|
- !ruby/object:Gem::Version
|
27
|
-
segments:
|
28
|
-
- 1
|
29
|
-
- 1
|
30
|
-
- 1
|
31
23
|
version: 1.1.1
|
32
24
|
type: :runtime
|
33
25
|
version_requirements: *id001
|
@@ -35,13 +27,10 @@ dependencies:
|
|
35
27
|
name: bundler
|
36
28
|
prerelease: false
|
37
29
|
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
38
31
|
requirements:
|
39
32
|
- - ">="
|
40
33
|
- !ruby/object:Gem::Version
|
41
|
-
segments:
|
42
|
-
- 1
|
43
|
-
- 0
|
44
|
-
- 0
|
45
34
|
version: 1.0.0
|
46
35
|
type: :development
|
47
36
|
version_requirements: *id002
|
@@ -70,9 +59,10 @@ files:
|
|
70
59
|
- src/java/arjdbc/sqlanywhere/AdapterJavaService.java
|
71
60
|
- src/java/arjdbc/sqlanywhere/SQLAnywhereRubyJdbcConnection.java
|
72
61
|
- test/db/sqlanywhere.rb
|
62
|
+
- test/my-minitest-loader.rb
|
63
|
+
- test/sqlanywhere_limit_offset_test.rb
|
73
64
|
- test/sqlanywhere_simple_test.rb
|
74
65
|
- lib/arjdbc/sqlanywhere/adapter_java.jar
|
75
|
-
has_rdoc: true
|
76
66
|
homepage: http://github.com/griff/activerecord-jdbcsqlanywhere-adapter
|
77
67
|
licenses: []
|
78
68
|
|
@@ -82,25 +72,21 @@ rdoc_options: []
|
|
82
72
|
require_paths:
|
83
73
|
- lib
|
84
74
|
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
85
76
|
requirements:
|
86
77
|
- - ">="
|
87
78
|
- !ruby/object:Gem::Version
|
88
|
-
segments:
|
89
|
-
- 0
|
90
79
|
version: "0"
|
91
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
92
82
|
requirements:
|
93
83
|
- - ">="
|
94
84
|
- !ruby/object:Gem::Version
|
95
|
-
segments:
|
96
|
-
- 1
|
97
|
-
- 3
|
98
|
-
- 6
|
99
85
|
version: 1.3.6
|
100
86
|
requirements: []
|
101
87
|
|
102
88
|
rubyforge_project:
|
103
|
-
rubygems_version: 1.
|
89
|
+
rubygems_version: 1.8.10
|
104
90
|
signing_key:
|
105
91
|
specification_version: 3
|
106
92
|
summary: Sybase SQLAnywhere JDBC adapter for JRuby on Rails
|