ActiveRecord-JDBC 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006 Nick Sieger <nick@nicksieger.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/init.rb ADDED
@@ -0,0 +1,8 @@
1
+ RAILS_CONNECTION_ADAPTERS << 'jdbc'
2
+ require 'active_record/connection_adapters/jdbc_adapter'
3
+
4
+ [:initialize_database, :initialize_framework_logging, :initialize_framework_settings].each do |cmd|
5
+ Rails::Initializer.run(cmd) do |config|
6
+ config.frameworks = [:active_record]
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+
2
+ require 'fileutils'
3
+
4
+ from_d=File.expand_path(File.join(File.dirname(__FILE__),'lib','active_record'))
5
+ to_d=File.expand_path(File.join(RAILS_ROOT,'lib','active_record'))
6
+
7
+ FileUtils.cp_r from_d, to_d
8
+
9
+ env_file = File.expand_path(File.join(RAILS_ROOT,"config","environment.rb"))
10
+ bck_file = File.expand_path(File.join(RAILS_ROOT,"config","~.environment.rb.before_jdbc"))
11
+
12
+ FileUtils.mv env_file,bck_file
13
+
14
+ File.open(bck_file,"r") {|inf|
15
+ File.open(env_file,"w") {|out|
16
+ inf.each_line do |ln|
17
+ if ln =~ /^Rails::Initializer\.run/
18
+ out.puts "# Added by ActiveRecord JDBC plugin"
19
+ out.puts "RAILS_CONNECTION_ADAPTERS = %w( jdbc mysql postgresql sqlite firebird sqlserver db2 oracle sybase openbase )"
20
+ out.puts
21
+ end
22
+ out.puts ln
23
+ end
24
+ }
25
+ }
@@ -0,0 +1,358 @@
1
+ require 'active_record/connection_adapters/abstract_adapter'
2
+
3
+ module ActiveRecord
4
+ class Base
5
+ def self.jdbc_connection(config)
6
+ ConnectionAdapters::JdbcAdapter.new(ConnectionAdapters::JdbcConnection.new(config), logger, config)
7
+ end
8
+ end
9
+
10
+ module ConnectionAdapters
11
+ module Jdbc
12
+ require 'java'
13
+ include_class 'java.sql.DriverManager'
14
+ include_class 'java.sql.Statement'
15
+ include_class 'java.sql.Types'
16
+ end
17
+
18
+ # I want to use JDBC's DatabaseMetaData#getTypeInfo to choose the best native types to
19
+ # use for ActiveRecord's Adapter#native_database_types in a database-independent way,
20
+ # but apparently a database driver can return multiple types for a given
21
+ # java.sql.Types constant. So this type converter uses some heuristics to try to pick
22
+ # the best (most common) type to use. It's not great, it would be better to just
23
+ # delegate to each database's existin AR adapter's native_database_types method, but I
24
+ # wanted to try to do this in a way that didn't pull in all the other adapters as
25
+ # dependencies. Suggestions appreciated.
26
+ class JdbcTypeConverter
27
+ # The basic ActiveRecord types, mapped to an array of procs that are used to #select
28
+ # the best type. The procs are used as selectors in order until there is only one
29
+ # type left. If all the selectors are applied and there is still more than one
30
+ # type, an exception will be raised.
31
+ AR_TO_JDBC_TYPES = {
32
+ :string => [ proc {|r| Jdbc::Types::VARCHAR == r['data_type']},
33
+ proc {|r| r['type_name'] =~ /^varchar/i} ],
34
+ :text => [ proc {|r| [Jdbc::Types::LONGVARCHAR, Jdbc::Types::CLOB].include?(r['data_type'])},
35
+ proc {|r| r['type_name'] =~ /^(text|clob)/i} ],
36
+ :integer => [ proc {|r| Jdbc::Types::INTEGER == r['data_type']},
37
+ proc {|r| r['type_name'] =~ /^integer/i} ],
38
+ :float => [ proc {|r| [Jdbc::Types::FLOAT,Jdbc::Types::DOUBLE].include?(r['data_type'])},
39
+ proc {|r| r['type_name'] =~ /^float/i},
40
+ proc {|r| r['type_name'] =~ /^double$/i} ],
41
+ :datetime => [ proc {|r| Jdbc::Types::TIMESTAMP == r['data_type']},
42
+ proc {|r| r['type_name'] =~ /^datetime/i} ],
43
+ :timestamp => [ proc {|r| Jdbc::Types::TIMESTAMP == r['data_type']},
44
+ proc {|r| r['type_name'] =~ /^timestamp/i},
45
+ proc {|r| r['type_name'] =~ /^datetime/i} ],
46
+ :time => [ proc {|r| Jdbc::Types::TIME == r['data_type']} ],
47
+ :date => [ proc {|r| Jdbc::Types::DATE == r['data_type']} ],
48
+ :binary => [ proc {|r| Jdbc::Types::LONGVARBINARY == r['data_type']},
49
+ proc {|r| r['type_name'] =~ /^blob/i} ],
50
+ :boolean => [ proc {|r| Jdbc::Types::TINYINT == r['data_type']} ]
51
+ }
52
+
53
+ def initialize(types)
54
+ @types = types
55
+ end
56
+
57
+ def choose_best_types
58
+ type_map = {}
59
+ AR_TO_JDBC_TYPES.each_key do |k|
60
+ typerow = choose_type(k)
61
+ type_map[k] = { :name => typerow['type_name'] }
62
+ type_map[k][:limit] = typerow['precision'] if [:integer,:string].include?(k)
63
+ type_map[k][:limit] = 1 if k == :boolean
64
+ end
65
+ type_map
66
+ end
67
+
68
+ def choose_type(ar_type)
69
+ procs = AR_TO_JDBC_TYPES[ar_type]
70
+ types = @types
71
+ procs.each do |p|
72
+ new_types = types.select(&p)
73
+ return new_types.first if new_types.length == 1
74
+ types = new_types if new_types.length > 0
75
+ end
76
+ raise "unable to choose type from: #{types.collect{|t| t['type_name']}.inspect}"
77
+ end
78
+ end
79
+
80
+ class JdbcDriver
81
+ def self.load(driver)
82
+ driver_class_const = (driver[0...1].capitalize + driver[1..driver.length]).gsub(/\./, '_')
83
+ unless Jdbc.const_defined?(driver_class_const)
84
+ Jdbc.module_eval do
85
+ include_class(driver) {|p,c| driver_class_const }
86
+ end
87
+ driver_class = Jdbc.const_get(driver_class_const.to_sym)
88
+ Jdbc::DriverManager.registerDriver(driver_class.new)
89
+ end
90
+ end
91
+ end
92
+
93
+ class JdbcConnection
94
+ def initialize(config)
95
+ config = config.symbolize_keys
96
+ driver = config[:driver].to_s
97
+ user = config[:username].to_s
98
+ pass = config[:password].to_s
99
+ url = config[:url].to_s
100
+
101
+ unless driver && url
102
+ raise ArgumentError, "jdbc adapter requires driver class and url"
103
+ end
104
+
105
+ JdbcDriver.load(driver)
106
+ @connection = Jdbc::DriverManager.getConnection(url, user, pass)
107
+ set_native_database_types
108
+ end
109
+
110
+ def set_native_database_types
111
+ types = unmarshal_result(@connection.getMetaData.getTypeInfo)
112
+ @native_types = JdbcTypeConverter.new(types).choose_best_types
113
+ end
114
+
115
+ def native_database_types
116
+ types = {
117
+ # TODO: this is copied from MySQL -- figure out how to
118
+ # generalize the primary key type
119
+ :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
120
+ }
121
+ @native_types.each_pair {|k,v| types[k] = v.inject({}) {|memo,kv| memo.merge({kv.first => kv.last.dup})}}
122
+ types
123
+ end
124
+
125
+ def columns(table_name, name = nil)
126
+ metadata = @connection.getMetaData
127
+ results = metadata.getColumns(nil, nil, table_name, nil)
128
+ columns = []
129
+ unmarshal_result(results).each do |col|
130
+ columns << ActiveRecord::ConnectionAdapters::Column.new(col['column_name'], col['column_def'],
131
+ "#{col['type_name']}(#{col['column_size']})", col['is_nullable'] != 'NO')
132
+ end
133
+ columns
134
+ end
135
+
136
+ def tables
137
+ metadata = @connection.getMetaData
138
+ results = metadata.getTables(nil, nil, nil, nil)
139
+ unmarshal_result(results).collect {|t| t['table_name']}
140
+ end
141
+
142
+ def execute_insert(sql, pk)
143
+ stmt = @connection.createStatement
144
+ stmt.executeUpdate(sql, Jdbc::Statement::RETURN_GENERATED_KEYS)
145
+ row = unmarshal_result(stmt.getGeneratedKeys)
146
+ row.first && row.first.values.first
147
+ ensure
148
+ stmt.close
149
+ end
150
+
151
+ def execute_update(sql)
152
+ stmt = @connection.createStatement
153
+ stmt.executeUpdate(sql)
154
+ ensure
155
+ stmt.close
156
+ end
157
+
158
+ def execute_query(sql)
159
+ stmt = @connection.createStatement
160
+ unmarshal_result(stmt.executeQuery(sql))
161
+ ensure
162
+ stmt.close
163
+ end
164
+
165
+ def begin
166
+ @connection.setAutoCommit(false)
167
+ end
168
+
169
+ def commit
170
+ @connection.commit
171
+ ensure
172
+ @connection.setAutoCommit(true)
173
+ end
174
+
175
+ def rollback
176
+ @connection.rollback
177
+ ensure
178
+ @connection.setAutoCommit(true)
179
+ end
180
+
181
+ private
182
+ def unmarshal_result(resultset)
183
+ metadata = resultset.getMetaData
184
+ column_count = metadata.getColumnCount
185
+ column_names = ['']
186
+ column_types = ['']
187
+ column_scale = ['']
188
+
189
+ 1.upto(column_count) do |i|
190
+ column_names << metadata.getColumnName(i)
191
+ column_types << metadata.getColumnType(i)
192
+ column_scale << metadata.getScale(i)
193
+ end
194
+
195
+ results = []
196
+
197
+ while resultset.next
198
+ row = {}
199
+ 1.upto(column_count) do |i|
200
+ row[column_names[i].downcase] = convert_jdbc_type_to_ruby(i, column_types[i], column_scale[i], resultset)
201
+ end
202
+ results << row
203
+ end
204
+
205
+ results
206
+ end
207
+
208
+ def to_ruby_time(java_date)
209
+ if java_date
210
+ tm = java_date.getTime
211
+ Time.at(tm / 1000, (tm % 1000) * 1000)
212
+ end
213
+ end
214
+
215
+ def convert_jdbc_type_to_ruby(row, type, scale, resultset)
216
+ if scale != 0
217
+ decimal = resultset.getString(row)
218
+ decimal.to_f
219
+ else
220
+ case type
221
+ when Jdbc::Types::CHAR, Jdbc::Types::VARCHAR, Jdbc::Types::LONGVARCHAR
222
+ resultset.getString(row)
223
+ when Jdbc::Types::SMALLINT, Jdbc::Types::INTEGER, Jdbc::Types::NUMERIC, Jdbc::Types::BIGINT
224
+ resultset.getInt(row)
225
+ when Jdbc::Types::BIT, Jdbc::Types::BOOLEAN, Jdbc::Types::TINYINT
226
+ resultset.getBoolean(row)
227
+ when Jdbc::Types::TIMESTAMP
228
+ to_ruby_time(resultset.getTimestamp(row))
229
+ when Jdbc::Types::TIME
230
+ to_ruby_time(resultset.getTime(row))
231
+ when Jdbc::Types::DATE
232
+ to_ruby_time(resultset.getDate(row))
233
+ else
234
+ types = Jdbc::Types.constants
235
+ name = types.find {|t| Jdbc::Types.const_get(t.to_sym) == type}
236
+ raise "jdbc_adapter: type #{name} not supported yet"
237
+ end
238
+ end
239
+ end
240
+ end
241
+
242
+ class JdbcAdapter < AbstractAdapter
243
+ def initialize(connection, logger, config)
244
+ super(connection, logger)
245
+ @config = config
246
+ end
247
+
248
+ def adapter_name #:nodoc:
249
+ 'JDBC'
250
+ end
251
+
252
+ def supports_migrations?
253
+ true
254
+ end
255
+
256
+ def native_database_types #:nodoc
257
+ @connection.native_database_types
258
+ end
259
+
260
+ def active?
261
+ true
262
+ end
263
+
264
+ def reconnect!
265
+ @connection.close rescue nil
266
+ @connection = JdbcConnection.new(@config)
267
+ end
268
+
269
+ def select_all(sql, name = nil)
270
+ select(sql, name)
271
+ end
272
+
273
+ def select_one(sql, name = nil)
274
+ select(sql, name).first
275
+ end
276
+
277
+ def execute(sql, name = nil)
278
+ log_no_bench(sql, name) do
279
+ if sql =~ /^select/i
280
+ @connection.execute_query(sql)
281
+ else
282
+ @connection.execute_update(sql)
283
+ end
284
+ end
285
+ end
286
+
287
+ # Oracle doesn't support limit and offset. Fake it instead.
288
+ def add_limit_offset!(sql, options) #:nodoc:
289
+ if /oracle/ =~ @config[:driver]
290
+ offset = options[:offset] || 0
291
+
292
+ if limit = options[:limit]
293
+ sql.replace "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_ where rownum <= #{offset+limit}) where raw_rnum_ > #{offset}"
294
+ elsif offset > 0
295
+ sql.replace "select * from (select raw_sql_.*, rownum raw_rnum_ from (#{sql}) raw_sql_) where raw_rnum_ > #{offset}"
296
+ end
297
+ else
298
+ super
299
+ end
300
+ end
301
+
302
+ alias :update :execute
303
+ alias :delete :execute
304
+
305
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
306
+ log_no_bench(sql, name) do
307
+ id = @connection.execute_insert(sql, pk)
308
+ id_value || id
309
+ end
310
+ end
311
+
312
+ def columns(table_name, name = nil)
313
+ @connection.columns(table_name)
314
+ end
315
+
316
+ def tables
317
+ @connection.tables
318
+ end
319
+
320
+ def begin_db_transaction
321
+ @connection.begin
322
+ end
323
+
324
+ def commit_db_transaction
325
+ @connection.commit
326
+ end
327
+
328
+ def rollback_db_transaction
329
+ @connection.rollback
330
+ end
331
+
332
+ private
333
+ def select(sql, name)
334
+ log_no_bench(sql, name) { @connection.execute_query(sql) }
335
+ end
336
+
337
+ def log_no_bench(sql, name)
338
+ if block_given?
339
+ if @logger and @logger.level <= Logger::INFO
340
+ result = yield
341
+ log_info(sql, name, 0)
342
+ result
343
+ else
344
+ yield
345
+ end
346
+ else
347
+ log_info(sql, name, 0)
348
+ nil
349
+ end
350
+ rescue Exception => e
351
+ # Log message and raise exception.
352
+ message = "#{e.class.name}: #{e.message}: #{sql}"
353
+ log_info(message, name, 0)
354
+ raise ActiveRecord::StatementInvalid, message
355
+ end
356
+ end
357
+ end
358
+ end
@@ -0,0 +1,25 @@
1
+ print "Using native JDBC (MySQL)\n"
2
+ require_dependency 'fixtures/course'
3
+ require 'logger'
4
+
5
+ RAILS_CONNECTION_ADAPTERS << 'jdbc'
6
+ require "active_record/connection_adapters/jdbc_adapter"
7
+
8
+ ActiveRecord::Base.logger = Logger.new("debug.log")
9
+
10
+ db1 = 'activerecord_unittest'
11
+ db2 = 'activerecord_unittest2'
12
+
13
+ ActiveRecord::Base.establish_connection(
14
+ :adapter => "jdbc",
15
+ :driver => "com.mysql.jdbc.Driver",
16
+ :url => "jdbc:mysql://localhost:3306/#{db1}",
17
+ :username => "rails"
18
+ )
19
+
20
+ Course.establish_connection(
21
+ :adapter => "jdbc",
22
+ :driver => "com.mysql.jdbc.Driver",
23
+ :url => "jdbc:mysql://localhost:3306/#{db2}",
24
+ :username => "rails"
25
+ )
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ for test in *_test.rb; do
4
+ ./jtest.sh $test
5
+ done
6
+
7
+ #jruby.sh -I connections/native_jdbc_mysql -e 'Dir.foreach(".") { |file| require file if file =~ /_test.rb$/ }' | tee all.log
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ jruby.sh -I connections/native_jdbc_mysql $1 | tee $1.log
@@ -0,0 +1,109 @@
1
+
2
+ $silentTests = false
3
+ $testnum=0
4
+ $ntest=0
5
+ $failed = []
6
+ $curtestOK=true
7
+
8
+ module MiniRUnit
9
+ class Failure
10
+ def initialize(what, testnum, msg, where)
11
+ @what, @testnum, @msg, @where = what, testnum, msg, where
12
+ end
13
+
14
+ def to_s
15
+ sprintf("FAILED %s %d %s-- %s\n", @what, @testnum, @msg, @where)
16
+ end
17
+ end
18
+
19
+ class Error
20
+ def initialize(what, testnum, boom)
21
+ @what, @testnum, @boom = what, testnum, boom
22
+ end
23
+
24
+ def to_s
25
+ sprintf("EXCEPTION raised %s %d -- \n\tException: %s\n\t%s",
26
+ @what, @testnum, @boom.to_s, @boom.backtrace.join("\n\t"))
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ def test_check(what)
33
+ printf "%s : ", what unless $silentTests
34
+ $what = what
35
+ $testnum = 0
36
+ end
37
+
38
+ def test_ok(cond, msg="")
39
+ $testnum+=1
40
+ $ntest+=1
41
+ if cond
42
+ print "." unless $silentTests
43
+ else
44
+ where = caller.reject {|where| where =~ /minirunit/}[0]
45
+ $failed.push(MiniRUnit::Failure.new($what, $testnum, msg, where))
46
+ print "F" unless $silentTests
47
+ $curtestOK=false
48
+ end
49
+ end
50
+
51
+ def test_fail(msg="")
52
+ test_ok(false, msg)
53
+ end
54
+
55
+ def test_equal(a,b)
56
+ test_ok(a == b, "expected #{a.inspect}, found #{b.inspect}")
57
+ end
58
+
59
+ def test_no_exception(&proc)
60
+ raised = false
61
+ begin
62
+ proc.call
63
+ rescue exception
64
+ raised = x
65
+ end
66
+ test_ok(!raised, "unexpected exception #{raised}")
67
+ end
68
+
69
+ def test_exception(type=Exception, &proc)
70
+ raised = false
71
+ begin
72
+ proc.call
73
+ rescue type=>e
74
+ raised = true
75
+ end
76
+ test_ok(raised, "#{type} expected")
77
+ e
78
+ end
79
+
80
+ def test_get_last_failed
81
+ if $failed.empty?
82
+ return nil
83
+ end
84
+ return $failed.last
85
+ end
86
+
87
+ def test_print_report
88
+ puts
89
+ puts "-" * 80
90
+ $failed.each { |error| puts error }
91
+ puts "-" * 80
92
+ puts "Tests: #$ntest. (Ok: #{$ntest - $failed.size}; Failed: #{$failed.size})"
93
+ end
94
+
95
+ def test_load(test)
96
+ begin
97
+ $curtestOK=true
98
+ load(test)
99
+ rescue Exception => boom
100
+ puts 'ERROR' unless $silentTests
101
+ $failed.push(MiniRUnit::Error.new($what, $testnum, boom))
102
+ else
103
+ if $curtestOK
104
+ puts 'OK' unless $silentTests
105
+ else
106
+ puts 'FAILED' unless $silentTests
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,14 @@
1
+ require 'test/minirunit'
2
+ RAILS_CONNECTION_ADAPTERS = ['abstract', 'jdbc']
3
+ require 'active_record'
4
+
5
+ connspec = ActiveRecord::Base.establish_connection(
6
+ :adapter => 'jdbc',
7
+ :driver => 'com.mysql.jdbc.Driver',
8
+ :url => 'jdbc:mysql://localhost:3306/test',
9
+ :username => 'rlsmgr',
10
+ :password => ''
11
+ )
12
+
13
+ puts "#{connspec}"
14
+ puts "#{ActiveRecord::Base.connection}"
@@ -0,0 +1,71 @@
1
+ # To run this script, run the following in a mysql instance:
2
+ #
3
+ # drop database if exists weblog_development;
4
+ # create database weblog_development;
5
+ # grant all on weblog_development.* to blog@localhost;
6
+
7
+ require 'test/minirunit'
8
+
9
+ config = {
10
+ :adapter => 'jdbc',
11
+ :username => 'sa',
12
+ :password => '',
13
+ :driver => 'org.hsqldb.jdbcDriver',
14
+ :url => 'jdbc:hsqldb:test.db'
15
+ }
16
+
17
+ require 'active_record'
18
+
19
+ ActiveRecord::Base.establish_connection(config)
20
+
21
+ class CreateEntries < ActiveRecord::Migration
22
+ def self.up
23
+ create_table "entries", :force => true do |t|
24
+ t.column :title, :string, :limit => 100
25
+ t.column :updated_on, :datetime
26
+ t.column :content, :text
27
+ end
28
+ end
29
+
30
+ def self.down
31
+ drop_table "entries"
32
+ end
33
+ end
34
+
35
+ CreateEntries.up
36
+
37
+ test_ok ActiveRecord::Base.connection.tables.include?('entries')
38
+
39
+ class Entry < ActiveRecord::Base
40
+ end
41
+
42
+ Entry.delete_all
43
+
44
+ test_equal 0, Entry.count
45
+
46
+ TITLE = "First post!"
47
+ CONTENT = "Hello from JRuby on Rails!"
48
+ NEW_TITLE = "First post updated title"
49
+
50
+ post = Entry.new
51
+ post.title = TITLE
52
+ post.content = CONTENT
53
+ post.save
54
+
55
+ test_equal 1, Entry.count
56
+
57
+ post = Entry.find(:first)
58
+ test_equal TITLE, post.title
59
+ test_equal CONTENT, post.content
60
+
61
+ post.title = NEW_TITLE
62
+ post.save
63
+
64
+ post = Entry.find(:first)
65
+ test_equal NEW_TITLE, post.title
66
+
67
+ post.destroy
68
+
69
+ test_equal 0, Entry.count
70
+
71
+ CreateEntries.down
@@ -0,0 +1,3 @@
1
+ require 'test/minirunit'
2
+ RAILS_CONNECTION_ADAPTERS = ['abstract']
3
+ test_load 'active_record'
@@ -0,0 +1,83 @@
1
+ # To run this script, run the following in a mysql instance:
2
+ #
3
+ # drop database if exists weblog_development;
4
+ # create database weblog_development;
5
+ # grant all on weblog_development.* to blog@localhost;
6
+
7
+ require 'test/minirunit'
8
+
9
+ config = {
10
+ :username => 'blog',
11
+ :password => ''
12
+ }
13
+
14
+ if RUBY_PLATFORM =~ /java/
15
+ RAILS_CONNECTION_ADAPTERS = ['abstract', 'jdbc']
16
+ config.update({
17
+ :adapter => 'jdbc',
18
+ :driver => 'com.mysql.jdbc.Driver',
19
+ :url => 'jdbc:mysql://localhost:3306/weblog_development',
20
+ })
21
+ else
22
+ config.update({
23
+ :adapter => 'mysql',
24
+ :database => 'weblog_development',
25
+ :host => 'localhost'
26
+ })
27
+ end
28
+
29
+ require 'active_record'
30
+
31
+ ActiveRecord::Base.establish_connection(config)
32
+
33
+ class CreateEntries < ActiveRecord::Migration
34
+ def self.up
35
+ create_table "entries", :force => true do |t|
36
+ t.column :title, :string, :limit => 100
37
+ t.column :updated_on, :datetime
38
+ t.column :content, :text
39
+ end
40
+ end
41
+
42
+ def self.down
43
+ drop_table "entries"
44
+ end
45
+ end
46
+
47
+ CreateEntries.up
48
+
49
+ test_ok ActiveRecord::Base.connection.tables.include?('entries')
50
+
51
+ class Entry < ActiveRecord::Base
52
+ end
53
+
54
+ Entry.delete_all
55
+
56
+ test_equal 0, Entry.count
57
+
58
+ TITLE = "First post!"
59
+ CONTENT = "Hello from JRuby on Rails!"
60
+ NEW_TITLE = "First post updated title"
61
+
62
+ post = Entry.new
63
+ post.title = TITLE
64
+ post.content = CONTENT
65
+ post.save
66
+
67
+ test_equal 1, Entry.count
68
+
69
+ post = Entry.find(:first)
70
+ test_equal TITLE, post.title
71
+ test_equal CONTENT, post.content
72
+
73
+ post.title = NEW_TITLE
74
+ post.save
75
+
76
+ post = Entry.find(:first)
77
+ test_equal NEW_TITLE, post.title
78
+
79
+ post.destroy
80
+
81
+ test_equal 0, Entry.count
82
+
83
+ CreateEntries.down
@@ -0,0 +1,24 @@
1
+
2
+ require 'test/minirunit'
3
+ RAILS_CONNECTION_ADAPTERS = ['abstract', 'jdbc']
4
+ require 'active_record'
5
+
6
+ connspec = ActiveRecord::Base.establish_connection(
7
+ :adapter => 'jdbc',
8
+ :driver => 'com.mysql.jdbc.Driver',
9
+ :url => 'jdbc:mysql://localhost:3306/weblog_development',
10
+ :username => 'blog',
11
+ :password => ''
12
+ )
13
+
14
+ connection = ActiveRecord::Base.connection
15
+
16
+ results = connection.execute "select * from entries"
17
+
18
+ test_equal results.length, 1
19
+
20
+ row = results.first
21
+ test_equal 'First post', row['title']
22
+ test_equal 'First post d00d!', row['content']
23
+
24
+ puts row.inspect
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: ActiveRecord-JDBC
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2006-08-07 00:00:00 +02:00
8
+ summary: JDBC support for ActiveRecord. Only usable within JRuby
9
+ require_paths:
10
+ - lib
11
+ email: ola@ologix.com
12
+ homepage: http://jruby-extras.rubyforge.org/
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: active_record/connection_adapters/jdbc_adapter
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors:
29
+ - JRuby-extras
30
+ files:
31
+ - lib/active_record
32
+ - lib/active_record/connection_adapters
33
+ - lib/active_record/connection_adapters/jdbc_adapter.rb
34
+ - test/activerecord
35
+ - test/minirunit
36
+ - test/minirunit.rb
37
+ - test/activerecord/connections
38
+ - test/activerecord/jall.sh
39
+ - test/activerecord/jtest.sh
40
+ - test/activerecord/connections/native_jdbc_mysql
41
+ - test/activerecord/connections/native_jdbc_mysql/connection.rb
42
+ - test/minirunit/testConnect.rb
43
+ - test/minirunit/testHsqldb.rb
44
+ - test/minirunit/testLoadActiveRecord.rb
45
+ - test/minirunit/testMysql.rb
46
+ - test/minirunit/testRawSelect.rb
47
+ - LICENSE
48
+ - init.rb
49
+ - install.rb
50
+ test_files: []
51
+
52
+ rdoc_options: []
53
+
54
+ extra_rdoc_files: []
55
+
56
+ executables: []
57
+
58
+ extensions: []
59
+
60
+ requirements: []
61
+
62
+ dependencies: []
63
+