jdbc-wrapper 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +13 -0
- data/Rakefile +25 -0
- data/examples/derby.rb +21 -0
- data/examples/h2.rb +15 -0
- data/examples/mysql.rb +15 -0
- data/lib/jdbc/adapters/derby.rb +29 -0
- data/lib/jdbc/adapters/h2.rb +23 -0
- data/lib/jdbc/adapters/hsqldb.rb +23 -0
- data/lib/jdbc/adapters/mysql.rb +24 -0
- data/lib/jdbc/adapters/postgresql.rb +24 -0
- data/lib/jdbc/adapters.rb +7 -0
- data/lib/jdbc/db.rb +85 -0
- data/lib/jdbc/prepared_statement.rb +31 -0
- data/lib/jdbc/result.rb +106 -0
- data/lib/jdbc.rb +11 -0
- data/test/test_db.rb +38 -0
- data/test/test_prepared_statement.rb +46 -0
- metadata +63 -0
data/README
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Minimum Requirements
|
2
|
+
====================
|
3
|
+
|
4
|
+
* Java 1.5
|
5
|
+
* JRuby 1.1 (tested with RC2)
|
6
|
+
* JDBC Drivers
|
7
|
+
|
8
|
+
How to Install
|
9
|
+
==============
|
10
|
+
|
11
|
+
* gem install jdbc-wrapper
|
12
|
+
* get your jdbc driver jars on your classpath
|
13
|
+
(the easier way to do this is drop them in $JRUBY_HOME/lib)
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
desc 'run all unit tests'
|
2
|
+
task :test do
|
3
|
+
require 'rake/runtest'
|
4
|
+
Rake.run_tests 'test/test_*.rb'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
Gem::manage_gems
|
9
|
+
require 'rake/gempackagetask'
|
10
|
+
|
11
|
+
gemspec = Gem::Specification.new do |s|
|
12
|
+
s.name = "jdbc-wrapper"
|
13
|
+
s.version = "0.2"
|
14
|
+
s.author = "Larry Myers"
|
15
|
+
s.email = "larry@larrymyers.com"
|
16
|
+
s.platform = Gem::Platform::RUBY
|
17
|
+
s.summary = "A basic JDBC wrapper for JRuby"
|
18
|
+
s.files = FileList["{examples,lib,test}/**/*","Rakefile","README"].to_a
|
19
|
+
s.require_path = "lib"
|
20
|
+
s.has_rdoc = false
|
21
|
+
end
|
22
|
+
|
23
|
+
Rake::GemPackageTask.new(gemspec) do |pkg|
|
24
|
+
pkg.need_tar = true
|
25
|
+
end
|
data/examples/derby.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'jdbc'
|
5
|
+
|
6
|
+
db_path = File.join(File.dirname(__FILE__),'..','derby-example')
|
7
|
+
|
8
|
+
JDBC::DB.start(:derby,nil,nil,nil,nil,db_path) do |db|
|
9
|
+
db.query("CREATE TABLE records " +
|
10
|
+
"(name VARCHAR(80), created_on TIMESTAMP)")
|
11
|
+
|
12
|
+
db.query("INSERT INTO records (name, created_on) " +
|
13
|
+
"VALUES ('foo', '#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}')")
|
14
|
+
|
15
|
+
db.query("SELECT * FROM records").each_hash do |row|
|
16
|
+
puts row
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
FileUtils.rm_r(db_path, :force => true) if File.exist?(db_path)
|
21
|
+
FileUtils.rm("derby.log") if File.exist?("derby.log")
|
data/examples/h2.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'jdbc'
|
4
|
+
|
5
|
+
JDBC::DB.start(:h2,nil,nil,nil,nil,'foo') do |db|
|
6
|
+
db.query("CREATE TABLE records " +
|
7
|
+
"(name VARCHAR(80), created_on TIMESTAMP)")
|
8
|
+
|
9
|
+
db.query("INSERT INTO records (name, created_on) " +
|
10
|
+
"VALUES ('foo', '#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}')")
|
11
|
+
|
12
|
+
db.query("SELECT * FROM records").each_hash do |row|
|
13
|
+
row.each { |k,v| puts "#{k} = #{v}" }
|
14
|
+
end
|
15
|
+
end
|
data/examples/mysql.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'jdbc'
|
4
|
+
|
5
|
+
JDBC::DB.start(:mysql,"localhost","3306","root","root","tasks_dev") do |db|
|
6
|
+
db.query("select * from jobs limit 1").each do |row|
|
7
|
+
row.each { |v| puts v }
|
8
|
+
puts
|
9
|
+
end
|
10
|
+
|
11
|
+
db.query("select * from jobs limit 1").each_hash do |row|
|
12
|
+
row.each { |k,v| puts "#{k} = #{v}, #{v.class}" }
|
13
|
+
puts
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module JDBC
|
2
|
+
module Adapters
|
3
|
+
class Derby
|
4
|
+
attr_reader :host, :port, :user, :password, :schema
|
5
|
+
|
6
|
+
def initialize(host, port, user, password, schema)
|
7
|
+
@host = host
|
8
|
+
@port = port
|
9
|
+
@user = user
|
10
|
+
@password = password
|
11
|
+
@schema = schema
|
12
|
+
end
|
13
|
+
|
14
|
+
def connection_string
|
15
|
+
str = "jdbc:derby:#{@schema}"
|
16
|
+
|
17
|
+
if ! File.exist?(@schema)
|
18
|
+
str << ";create=true"
|
19
|
+
end
|
20
|
+
|
21
|
+
return str
|
22
|
+
end
|
23
|
+
|
24
|
+
def class_name
|
25
|
+
"org.apache.derby.jdbc.EmbeddedDriver"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module JDBC
|
2
|
+
module Adapters
|
3
|
+
class H2
|
4
|
+
attr_reader :host, :port, :user, :password, :schema
|
5
|
+
|
6
|
+
def initialize(host, port, user, password, schema)
|
7
|
+
@host = host
|
8
|
+
@port = port
|
9
|
+
@user = user
|
10
|
+
@password = password
|
11
|
+
@schema = schema
|
12
|
+
end
|
13
|
+
|
14
|
+
def connection_string
|
15
|
+
"jdbc:h2:mem:#{@schema}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def class_name
|
19
|
+
"org.h2.Driver"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module JDBC
|
2
|
+
module Adapters
|
3
|
+
class Hsqldb
|
4
|
+
attr_reader :host, :port, :user, :password, :schema
|
5
|
+
|
6
|
+
def initialize(host, port, user, password, schema)
|
7
|
+
@host = host
|
8
|
+
@port = port
|
9
|
+
@user = user
|
10
|
+
@password = password
|
11
|
+
@schema = schema
|
12
|
+
end
|
13
|
+
|
14
|
+
def connection_string
|
15
|
+
"jdbc:hsqldb:mem:#{@schema}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def class_name
|
19
|
+
"org.hsqldb.jdbcDriver"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module JDBC
|
2
|
+
module Adapters
|
3
|
+
class Mysql
|
4
|
+
attr_reader :host, :port, :user, :password, :schema
|
5
|
+
|
6
|
+
def initialize(host, port, user, password, schema)
|
7
|
+
@host = host
|
8
|
+
@port = port
|
9
|
+
@user = user
|
10
|
+
@password = password
|
11
|
+
@schema = schema
|
12
|
+
end
|
13
|
+
|
14
|
+
def connection_string
|
15
|
+
"jdbc:mysql://#{@host}:#{@port}/#{@schema}" +
|
16
|
+
"?user=#{@user}&password=#{@password}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def class_name
|
20
|
+
"com.mysql.jdbc.Driver"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module JDBC
|
2
|
+
module Adapters
|
3
|
+
class Postgresql
|
4
|
+
attr_reader :host, :port, :user, :password, :schema
|
5
|
+
|
6
|
+
def initialize(host, port, user, password, schema)
|
7
|
+
@host = host
|
8
|
+
@port = port
|
9
|
+
@user = user
|
10
|
+
@password = password
|
11
|
+
@schema = schema
|
12
|
+
end
|
13
|
+
|
14
|
+
def connection_string
|
15
|
+
"jdbc:postgresql://#{@host}:#{@port}/#{@schema}" +
|
16
|
+
"?user=#{@user}&password=#{@password}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def class_name
|
20
|
+
"org.postgresql.Driver"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/jdbc/db.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'.')
|
2
|
+
|
3
|
+
require 'java'
|
4
|
+
require 'time'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
require 'adapters'
|
8
|
+
|
9
|
+
module JDBC
|
10
|
+
class DB
|
11
|
+
def initialize(engine, host, port, user, password, schema)
|
12
|
+
adapter = get_adapter(engine, host, port, user, password, schema)
|
13
|
+
|
14
|
+
begin
|
15
|
+
java.lang.Class.forName(adapter.class_name).newInstance()
|
16
|
+
|
17
|
+
@conn = JavaSql::DriverManager.getConnection(
|
18
|
+
adapter.connection_string)
|
19
|
+
rescue JavaSql::SQLException => e
|
20
|
+
raise RuntimeError.new(e.message)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.start(db_class, host, port, user, password, database)
|
25
|
+
db = nil
|
26
|
+
|
27
|
+
begin
|
28
|
+
db = DB.new(db_class, host, port, user, password, database)
|
29
|
+
|
30
|
+
yield(db)
|
31
|
+
rescue JavaSql::SQLException => e
|
32
|
+
raise RuntimeError.new(e.message)
|
33
|
+
ensure
|
34
|
+
db.close unless db.nil?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def query(sql)
|
39
|
+
stmt = nil
|
40
|
+
result = nil
|
41
|
+
|
42
|
+
begin
|
43
|
+
stmt = @conn.createStatement
|
44
|
+
|
45
|
+
res = stmt.execute(sql)
|
46
|
+
|
47
|
+
if res == false
|
48
|
+
return stmt.getUpdateCount
|
49
|
+
end
|
50
|
+
|
51
|
+
return Result.new(stmt.getResultSet, stmt)
|
52
|
+
rescue JavaSql::SQLException => e
|
53
|
+
stmt.close unless stmt.nil?
|
54
|
+
raise RuntimeError.new(e.message)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def prepare(sql)
|
59
|
+
return PreparedStatement.new(@conn.prepareStatement(sql))
|
60
|
+
end
|
61
|
+
|
62
|
+
def close
|
63
|
+
@conn.close unless @conn.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def get_adapter(engine, host, port, user, password, schema)
|
69
|
+
case engine
|
70
|
+
when :derby
|
71
|
+
return Adapters::Derby.new(host, port, user, password, schema)
|
72
|
+
when :h2
|
73
|
+
return Adapters::H2.new(host, port, user, password, schema)
|
74
|
+
when :hsqldb
|
75
|
+
return Adapters::Hsqldb.new(host, port, user, password, schema)
|
76
|
+
when :mysql
|
77
|
+
return Adapters::Mysql.new(host, port, user, password, schema)
|
78
|
+
when :postgresql
|
79
|
+
return Adapters::Postgresql.new(host, port, user, password, schema)
|
80
|
+
end
|
81
|
+
|
82
|
+
raise InvalidException("#{engine} is not supported.")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module JDBC
|
2
|
+
class PreparedStatement
|
3
|
+
def initialize(stmt)
|
4
|
+
@stmt = stmt
|
5
|
+
@meta_data = stmt.getParameterMetaData
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute(*args)
|
9
|
+
if args.length != @meta_data.getParameterCount
|
10
|
+
raise RuntimeError.new("Got #{args.length} params, " +
|
11
|
+
"expected #{@meta_data.getParameterCount}.")
|
12
|
+
end
|
13
|
+
|
14
|
+
@stmt.clearParameters
|
15
|
+
|
16
|
+
args.each_with_index do |arg, i|
|
17
|
+
@stmt.setObject(i+1, arg, @meta_data.getParameterType(i+1))
|
18
|
+
end
|
19
|
+
|
20
|
+
if @stmt.execute
|
21
|
+
return Result.new(@stmt.getResultSet, @stmt)
|
22
|
+
end
|
23
|
+
|
24
|
+
return @stmt.getUpdateCount
|
25
|
+
end
|
26
|
+
|
27
|
+
def close
|
28
|
+
@stmt.close
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/jdbc/result.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
module JDBC
|
2
|
+
class Result
|
3
|
+
def initialize(resultSet, statement)
|
4
|
+
@rs = resultSet
|
5
|
+
@stmt = statement
|
6
|
+
@columns = get_rs_meta_data
|
7
|
+
end
|
8
|
+
|
9
|
+
def fetch
|
10
|
+
if @rs.next
|
11
|
+
result = []
|
12
|
+
|
13
|
+
@columns.each do |column|
|
14
|
+
result << fetch_and_cast(@rs, column)
|
15
|
+
end
|
16
|
+
|
17
|
+
return result
|
18
|
+
end
|
19
|
+
|
20
|
+
close
|
21
|
+
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def fetch_hash
|
26
|
+
if @rs.next
|
27
|
+
result = {}
|
28
|
+
|
29
|
+
@columns.each do |column|
|
30
|
+
result[column[:name]] = fetch_and_cast(@rs, column)
|
31
|
+
end
|
32
|
+
|
33
|
+
return result
|
34
|
+
end
|
35
|
+
|
36
|
+
close
|
37
|
+
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def each
|
42
|
+
while(result = fetch)
|
43
|
+
yield(result)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def each_hash
|
48
|
+
while(result = fetch_hash)
|
49
|
+
yield(result)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def close
|
54
|
+
@rs.close unless @rs.nil?
|
55
|
+
@stmt.close unless @stmt.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def get_rs_meta_data
|
61
|
+
meta_data = @rs.getMetaData
|
62
|
+
|
63
|
+
columns = []
|
64
|
+
|
65
|
+
meta_data.getColumnCount.times do |i|
|
66
|
+
columns << {
|
67
|
+
:name => meta_data.getColumnName(i+1).downcase,
|
68
|
+
:type => meta_data.getColumnType(i+1)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
return columns
|
73
|
+
end
|
74
|
+
|
75
|
+
def fetch_and_cast(rs, column)
|
76
|
+
if column[:type] == JavaSql::Types::NULL
|
77
|
+
return nil
|
78
|
+
end
|
79
|
+
|
80
|
+
if column[:type] == JavaSql::Types::INTEGER ||
|
81
|
+
column[:type] == JavaSql::Types::SMALLINT ||
|
82
|
+
column[:type] == JavaSql::Types::TINYINT ||
|
83
|
+
column[:type] == JavaSql::Types::BIGINT
|
84
|
+
return rs.getInt(column[:name])
|
85
|
+
end
|
86
|
+
|
87
|
+
if column[:type] == JavaSql::Types::DECIMAL ||
|
88
|
+
column[:type] == JavaSql::Types::FLOAT
|
89
|
+
return rs.getDouble(column[:name])
|
90
|
+
end
|
91
|
+
|
92
|
+
if column[:type] == JavaSql::Types::DATE ||
|
93
|
+
column[:type] == JavaSql::Types::TIME ||
|
94
|
+
column[:type] == JavaSql::Types::TIMESTAMP
|
95
|
+
|
96
|
+
val = rs.getString(column[:name])
|
97
|
+
|
98
|
+
return nil if val.nil?
|
99
|
+
|
100
|
+
return Time.parse(val)
|
101
|
+
end
|
102
|
+
|
103
|
+
return rs.getString(column[:name])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/jdbc.rb
ADDED
data/test/test_db.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'jdbc'
|
5
|
+
|
6
|
+
class TestDB < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@db = JDBC::DB.new(:h2,nil,nil,nil,nil,'test')
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
@db.close
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_create_table
|
16
|
+
assert_equal(0, create_records_table)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_insert_and_select
|
20
|
+
create_records_table
|
21
|
+
|
22
|
+
count = @db.query("INSERT INTO records (name) VALUES ('foo')")
|
23
|
+
|
24
|
+
assert_equal(1, count)
|
25
|
+
|
26
|
+
result = @db.query("SELECT * FROM records").fetch
|
27
|
+
|
28
|
+
assert_equal('foo', result[0])
|
29
|
+
|
30
|
+
result = @db.query("SELECT * FROM records").fetch_hash
|
31
|
+
|
32
|
+
assert_equal('foo', result['name'])
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_records_table
|
36
|
+
@db.query("CREATE TABLE records (name VARCHAR(80))")
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'jdbc'
|
5
|
+
|
6
|
+
class TestDB < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@db = JDBC::DB.new(:h2,nil,nil,nil,nil,'test')
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
@db.close
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_insert_and_select
|
16
|
+
create_and_populate_records_table
|
17
|
+
|
18
|
+
stmt = @db.prepare("INSERT INTO records (name,id) VALUES (?,?)")
|
19
|
+
|
20
|
+
assert_equal(1, stmt.execute('bar', 2))
|
21
|
+
|
22
|
+
stmt = @db.prepare("SELECT * FROM records where id = ?")
|
23
|
+
|
24
|
+
row = stmt.execute(2).fetch
|
25
|
+
|
26
|
+
assert_equal('bar', row[0])
|
27
|
+
assert_equal(2, row[1])
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_runtime_error_on_invalid_arg_count
|
31
|
+
create_and_populate_records_table
|
32
|
+
|
33
|
+
stmt = @db.prepare("SELECT * FROM records WHERE name = ?")
|
34
|
+
|
35
|
+
begin
|
36
|
+
stmt.execute('arg1','bad_arg2')
|
37
|
+
flunk
|
38
|
+
rescue RuntimeError => e
|
39
|
+
assert_equal("Got 2 params, expected 1.", e.message)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_and_populate_records_table
|
44
|
+
@db.query("CREATE TABLE records (name VARCHAR(80), id INT)")
|
45
|
+
end
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
extensions: []
|
3
|
+
homepage:
|
4
|
+
executables: []
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: !str 0.2
|
7
|
+
post_install_message:
|
8
|
+
date: 2008-03-13 04:00:00 +00:00
|
9
|
+
files:
|
10
|
+
- examples/derby.rb
|
11
|
+
- examples/h2.rb
|
12
|
+
- examples/mysql.rb
|
13
|
+
- lib/jdbc
|
14
|
+
- lib/jdbc.rb
|
15
|
+
- lib/jdbc/adapters
|
16
|
+
- lib/jdbc/adapters.rb
|
17
|
+
- lib/jdbc/db.rb
|
18
|
+
- lib/jdbc/prepared_statement.rb
|
19
|
+
- lib/jdbc/result.rb
|
20
|
+
- lib/jdbc/adapters/derby.rb
|
21
|
+
- lib/jdbc/adapters/h2.rb
|
22
|
+
- lib/jdbc/adapters/hsqldb.rb
|
23
|
+
- lib/jdbc/adapters/mysql.rb
|
24
|
+
- lib/jdbc/adapters/postgresql.rb
|
25
|
+
- test/test_db.rb
|
26
|
+
- test/test_prepared_statement.rb
|
27
|
+
- Rakefile
|
28
|
+
- README
|
29
|
+
rubygems_version: 1.0.1
|
30
|
+
rdoc_options: []
|
31
|
+
signing_key:
|
32
|
+
cert_chain: []
|
33
|
+
name: jdbc-wrapper
|
34
|
+
has_rdoc: false
|
35
|
+
platform: ruby
|
36
|
+
summary: A basic JDBC wrapper for JRuby
|
37
|
+
default_executable:
|
38
|
+
bindir: bin
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
version:
|
41
|
+
requirements:
|
42
|
+
- - '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: !str 0
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
version:
|
47
|
+
requirements:
|
48
|
+
- - '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: !str 0
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
specification_version: 2
|
54
|
+
test_files: []
|
55
|
+
dependencies: []
|
56
|
+
description:
|
57
|
+
email: larry@larrymyers.com
|
58
|
+
authors:
|
59
|
+
- Larry Myers
|
60
|
+
extra_rdoc_files: []
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project:
|
63
|
+
autorequire:
|