sequel-jdbc-hxtt-adapter 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,6 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ nbproject
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Colin Casey
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.
@@ -0,0 +1,23 @@
1
+ = sequel-jdbc-hxtt-adapter
2
+
3
+ A sequel adapter for working with MS Access files using HXTT's pure JDBC Access driver. JRuby is required when using this
4
+ adapter. It will not work in any other Ruby interpreter.
5
+
6
+ == HXTT Driver
7
+
8
+ The jar library containing the HXTT driver is not supplied but you can obtain a trial version or purchase it at http://www.hxtt.com
9
+
10
+ == Note on Patches/Pull Requests
11
+
12
+ * Fork the project.
13
+ * Make your feature addition or bug fix.
14
+ * Add tests for it. This is important so I don't break it in a
15
+ future version unintentionally.
16
+ * Commit, do not mess with rakefile, version, or history.
17
+ (if you want to have your own version, that is fine but
18
+ bump version in a commit by itself I can ignore when I pull)
19
+ * Send me a pull request. Bonus points for topic branches.
20
+
21
+ == Copyright
22
+
23
+ Copyright (c) 2010 Colin Casey. See LICENSE for details.
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "sequel-jdbc-hxtt-adapter"
8
+ gem.summary = %Q{Sequel adapter for working with MS Access files using JRuby and HXTT's pure JDBC Access driver}
9
+ gem.description = %Q{Sequel adapter for working with MS Access files using JRuby and HXTT's pure JDBC Access driver. Note: HXTT driver is not supplied but you can obtain a trial version or purchase it at http://www.hxtt.com/}
10
+ gem.email = "casey.colin@gmail.com"
11
+ gem.homepage = "http://github.com/colincasey/sequel-jdbc-hxtt-adapter"
12
+ gem.authors = ["Colin Casey"]
13
+ gem.add_dependency "sequel", ">= 3.8.0"
14
+ gem.add_development_dependency "thoughtbot-shoulda"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/*_test.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/*_test.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ if File.exist?('VERSION')
49
+ version = File.read('VERSION')
50
+ else
51
+ version = ""
52
+ end
53
+
54
+ rdoc.rdoc_dir = 'rdoc'
55
+ rdoc.title = "sequel-jdbc-hxtt-adapter #{version}"
56
+ rdoc.rdoc_files.include('README*')
57
+ rdoc.rdoc_files.include('lib/**/*.rb')
58
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.3
@@ -0,0 +1,180 @@
1
+ # encoding: utf-8
2
+
3
+ module Sequel
4
+ module JDBC
5
+ # Database and Dataset instance methods for MS Access specific support via JDBC.
6
+ module HXTT
7
+ # Database instance methods for MS Access databases accessed via JDBC.
8
+ module DatabaseMethods
9
+ AUTO_INCREMENT = 'AUTO_INCREMENT'.freeze
10
+ PRIMARY_KEY = 'PRIMARY KEY'.freeze
11
+ SQL_BEGIN = "START TRANSACTION".freeze
12
+ SQL_COMMIT = "COMMIT".freeze
13
+ SQL_SAVEPOINT = 'SAVEPOINT autopoint_%d'.freeze
14
+ SQL_ROLLBACK_TO_SAVEPOINT = 'ROLLBACK TO SAVEPOINT autopoint_%d'.freeze
15
+ NULL = "NULL".freeze
16
+ NOT_NULL = "NOT NULL".freeze
17
+ UNIQUE = "UNIQUE".freeze
18
+
19
+ # Return instance of Sequel::JDBC::HXTT::Dataset with the given opts.
20
+ def dataset(opts=nil)
21
+ Sequel::JDBC::HXTT::Dataset.new(self, opts)
22
+ end
23
+
24
+ def database_type
25
+ :access
26
+ end
27
+
28
+ def supports_savepoints?
29
+ true
30
+ end
31
+
32
+ def tables
33
+ ts = []
34
+ m = output_identifier_meth
35
+ metadata(:getTables, nil, nil, nil, ['TABLE'].to_java(:string)) do |h|
36
+ h = downcase_hash_keys(h)
37
+ ts << m.call(h[:table_name])
38
+ end
39
+ ts
40
+ end
41
+
42
+ private
43
+ def identifier_input_method_default
44
+ :to_s
45
+ end
46
+
47
+ def identifier_output_method_default
48
+ :to_s
49
+ end
50
+
51
+ def schema_parse_table(table, opts={})
52
+ m = output_identifier_meth
53
+ im = input_identifier_meth
54
+ ds = dataset
55
+ schema, table = schema_and_table(table)
56
+ schema ||= opts[:schema]
57
+ schema = im.call(schema) if schema
58
+ table = im.call(table)
59
+ pks, ts = [], []
60
+ metadata(:getPrimaryKeys, nil, schema, table) do |h|
61
+ h = downcase_hash_keys(h)
62
+ pks << h[:column_name]
63
+ end
64
+ metadata(:getColumns, nil, schema, table, nil) do |h|
65
+ h = downcase_hash_keys(h)
66
+ ts << [m.call(h[:column_name]), {:type=>schema_column_type(h[:type_name]), :db_type=>h[:type_name], :default=>(h[:column_def] == '' ? nil : h[:column_def]), :allow_null=>(h[:nullable] != 0), :primary_key=>pks.include?(h[:column_name]), :column_size=>h[:column_size]}]
67
+ end
68
+ ts
69
+ end
70
+
71
+ def downcase_hash_keys(h)
72
+ lh = {}
73
+ h.each { |k,v| lh[k.to_s.downcase.to_sym] = v }
74
+ lh
75
+ end
76
+
77
+ def column_definition_sql(column)
78
+ sql = "#{quote_identifier(column[:name])} #{type_literal(column)}"
79
+ sql << UNIQUE if column[:unique]
80
+ null = column.include?(:null) ? column[:null] : column[:allow_null]
81
+ sql << NOT_NULL if null == false
82
+ sql << NULL if null == true
83
+ sql << " DEFAULT #{column[:default].is_a?(String) ? "'\"#{column[:default]}\"'" : literal(column[:default])}" if column.include?(:default)
84
+ sql << " #{auto_increment_sql} " if column[:auto_increment]
85
+ sql << PRIMARY_KEY if column[:primary_key]
86
+ sql << column_references_column_constraint_sql(column) if column[:table]
87
+ sql
88
+ end
89
+
90
+ def auto_increment_sql
91
+ AUTO_INCREMENT
92
+ end
93
+
94
+ def begin_transaction_sql
95
+ SQL_BEGIN
96
+ end
97
+
98
+ def begin_savepoint_sql(depth)
99
+ SQL_SAVEPOINT % depth
100
+ end
101
+
102
+ def rollback_savepoint_sql(depth)
103
+ SQL_ROLLBACK_TO_SAVEPOINT % depth
104
+ end
105
+
106
+ def commit_transaction_sql
107
+ SQL_COMMIT
108
+ end
109
+
110
+ def type_literal_generic_float(column)
111
+ :float
112
+ end
113
+ end
114
+
115
+ # Dataset class for MS Access datasets accessed via JDBC.
116
+ class Dataset < JDBC::Dataset
117
+ BOOL_TRUE = 'TRUE'.freeze
118
+ BOOL_FALSE = 'FALSE'.freeze
119
+ SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'limit columns from where')
120
+
121
+ # access uses [] to quote identifiers
122
+ def quoted_identifier(name)
123
+ "[#{name}]"
124
+ end
125
+
126
+ def literal_false
127
+ BOOL_FALSE
128
+ end
129
+
130
+ def literal_true
131
+ BOOL_TRUE
132
+ end
133
+
134
+ def select_clause_methods
135
+ SELECT_CLAUSE_METHODS
136
+ end
137
+
138
+ def select_limit_sql(sql)
139
+ sql << " TOP #{@opts[:limit]}" if @opts[:limit]
140
+ end
141
+
142
+ def supports_is_true?
143
+ false
144
+ end
145
+
146
+ def process_result_set(result)
147
+ # get column names
148
+ meta = result.getMetaData
149
+ cols = []
150
+ i = 0
151
+ meta.getColumnCount.times{cols << [output_identifier(meta.getColumnLabel(i+=1)), i]}
152
+ @columns = cols.map{|c| c.at(0)}
153
+ row = {}
154
+ blk = if @convert_types
155
+ lambda{ |n, i|
156
+ # XXX: temporary fix until i can figure out how to get the access column default Date() not to throw an error
157
+ begin
158
+ row[n] = convert_type(result.getObject(i))
159
+ rescue Exception => e
160
+ if e.message == 'java.sql.SQLException: Failed to get a string value from com.hxtt.d.d: DATE()'
161
+ row[n] = 'DATE()'
162
+ else
163
+ raise
164
+ end
165
+ end
166
+ }
167
+ else
168
+ lambda{|n, i| row[n] = result.getObject(i)}
169
+ end
170
+ # get rows
171
+ while result.next
172
+ row = {}
173
+ cols.each(&blk)
174
+ yield row
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require 'sequel'
3
+ require 'sequel/adapters/jdbc'
4
+ require 'fileutils'
5
+
6
+ Sequel::JDBC::DATABASE_SETUP[:access] = proc do |db|
7
+ # ensure the mdb file exists if the URI specifies a local resource
8
+ if db.opts[:uri].match(/^jdbc:access:[\/]{3}(.*mdb)$/)
9
+ mdb = $1
10
+ unless File.exist?(mdb)
11
+ if db.opts.delete(:create)
12
+ #puts "No access database exists at #{mdb}, creating..."
13
+ empty_mdb = "#{File.dirname(__FILE__)}/adapters/jdbc/resources/empty.mdb"
14
+ FileUtils.cp(empty_mdb, mdb)
15
+ else
16
+ raise "No access database exists at #{mdb}"
17
+ end
18
+ end
19
+ end
20
+
21
+ # load the HXTT Access database functionality
22
+ require 'sequel/adapters/jdbc/hxtt'
23
+ db.extend(Sequel::JDBC::HXTT::DatabaseMethods)
24
+ com.hxtt.sql.access.AccessDriver
25
+ end
@@ -0,0 +1,58 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{sequel-jdbc-hxtt-adapter}
8
+ s.version = "0.1.3"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Colin Casey"]
12
+ s.date = %q{2010-03-01}
13
+ s.description = %q{Sequel adapter for working with MS Access files using JRuby and HXTT's pure JDBC Access driver. Note: HXTT driver is not supplied but you can obtain a trial version or purchase it at http://www.hxtt.com/}
14
+ s.email = %q{casey.colin@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/sequel/adapters/jdbc/hxtt.rb",
27
+ "lib/sequel/adapters/jdbc/resources/empty.mdb",
28
+ "lib/sequel/jdbc_hxtt_adapter.rb",
29
+ "sequel-jdbc-hxtt-adapter.gemspec",
30
+ "test/sequel_jdbc_hxtt_adapter_test.rb",
31
+ "test/test_helper.rb"
32
+ ]
33
+ s.homepage = %q{http://github.com/colincasey/sequel-jdbc-hxtt-adapter}
34
+ s.rdoc_options = ["--charset=UTF-8"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = %q{1.3.5}
37
+ s.summary = %q{Sequel adapter for working with MS Access files using JRuby and HXTT's pure JDBC Access driver}
38
+ s.test_files = [
39
+ "test/test_helper.rb",
40
+ "test/sequel_jdbc_hxtt_adapter_test.rb"
41
+ ]
42
+
43
+ if s.respond_to? :specification_version then
44
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
45
+ s.specification_version = 3
46
+
47
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
48
+ s.add_runtime_dependency(%q<sequel>, [">= 3.8.0"])
49
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
50
+ else
51
+ s.add_dependency(%q<sequel>, [">= 3.8.0"])
52
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
53
+ end
54
+ else
55
+ s.add_dependency(%q<sequel>, [">= 3.8.0"])
56
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
57
+ end
58
+ end
@@ -0,0 +1,260 @@
1
+ require 'test_helper'
2
+ require 'tempfile'
3
+
4
+ class SequelJdbcHxttAdapterTest < Test::Unit::TestCase
5
+ WRITABLE_FOLDER = "/home/colin"
6
+ ACCESS_DB = File.join(WRITABLE_FOLDER, 'sequel-jdbc-hxtt-adapter-test.mdb')
7
+
8
+ def create_test_database
9
+ Sequel.connect("jdbc:access:///#{ACCESS_DB}", :create => true)
10
+ end
11
+
12
+ def delete_test_database
13
+ File.delete(ACCESS_DB) if File.exist?(ACCESS_DB)
14
+ end
15
+
16
+ context "when connecting to an access database" do
17
+ should "fail to connect a non-existant database" do
18
+ assert_raise RuntimeError do
19
+ db = Sequel.connect('jdbc:access:///i-dont-exist.mdb')
20
+ end
21
+ end
22
+
23
+ should "create the database if requested and it doesn't exist" do
24
+ db_to_create = File.join(WRITABLE_FOLDER, 'sequel-jdbc-hxtt-adapter-create-test.mdb')
25
+ assert !File.exist?(db_to_create)
26
+ assert_nothing_raised do
27
+ Sequel.connect("jdbc:access:///#{db_to_create}", :create => true)
28
+ end
29
+ assert File.exist?(db_to_create)
30
+ File.delete(db_to_create)
31
+ end
32
+
33
+ should "not create a new database when the specified file already exists" do
34
+ temp = Tempfile.new('db.mdb')
35
+ temp.open
36
+ temp << 'the original file'
37
+ temp.close
38
+ mdb = temp.path
39
+ assert File.exist?(mdb)
40
+ assert_nothing_raised do
41
+ Sequel.connect("jdbc:hxtt:///#{mdb}", :create => true)
42
+ end
43
+ assert_equal "the original file", IO.read(mdb)
44
+ temp.delete
45
+ end
46
+ end
47
+
48
+ context "with test database" do
49
+ setup { @db = create_test_database }
50
+ teardown { delete_test_database }
51
+
52
+ should "report that the database type is access" do
53
+ assert_equal :access, @db.database_type
54
+ end
55
+
56
+ should "provide a list of existing tables" do
57
+ db = @db
58
+ db.drop_table(:testing) rescue nil
59
+ assert_kind_of Array, db.tables
60
+ assert_does_not_contain(db.tables, :testing)
61
+ db.create_table :testing do
62
+ boolean :ok
63
+ end
64
+ assert_contains(db.tables, :testing)
65
+ end
66
+
67
+ should "support sequential primary keys" do
68
+ @db.create_table(:with_pk) { primary_key :id; String :name }
69
+ @db[:with_pk] << {:name => 'abc'}
70
+ @db[:with_pk] << {:name => 'def'}
71
+ @db[:with_pk] << {:name => 'ghi'}
72
+ assert_equal @db[:with_pk].order(:name).all, [
73
+ {:id => 1, :name => 'abc'},
74
+ {:id => 2, :name => 'def'},
75
+ {:id => 3, :name => 'ghi'}
76
+ ]
77
+ end
78
+
79
+ should "support timestamps, dates, and times" do
80
+ @db.create_table(:time) do
81
+ timestamp :ts
82
+ date :d
83
+ time :t
84
+ end
85
+ t1 = Time.now
86
+ @db[:time] << { :ts => t1, :d => t1, :t => t1 }
87
+ assert_equal [t1], @db[:time].map(:ts)
88
+ assert_equal [t1], @db[:time].map(:d)
89
+ assert_equal [t1], @db[:time].map(:t)
90
+ end
91
+
92
+ should "should correctly parse the schema" do
93
+ @db.create_table(:schema_test) do
94
+ primary_key :id
95
+ boolean :b
96
+ integer :i
97
+ timestamp :t
98
+ String :s
99
+ date :d
100
+ end
101
+
102
+ assert_equal [
103
+ [:id,{:type=>:integer, :db_type=>"INTEGER AUTO_INCREMENT", :default=>nil, :allow_null=>true, :primary_key=>true, :column_size=>4, :ruby_default=>nil}],
104
+ [:b, {:type=>:boolean, :db_type=>"BOOLEAN", :default=>nil, :allow_null=>true, :primary_key=>false, :column_size=>0, :ruby_default=>nil}],
105
+ [:i, {:type=>:integer, :db_type=>"INTEGER", :default=>nil, :allow_null=>true, :primary_key=>false, :column_size=>4, :ruby_default=>nil}],
106
+ [:t, {:type=>:datetime, :db_type=>"TIMESTAMP", :default=>nil, :allow_null=>true, :primary_key=>false, :column_size=>8, :ruby_default=>nil}],
107
+ [:s, {:type=>:string, :db_type=>"VARCHAR", :default=>nil, :allow_null=>true, :primary_key=>false, :column_size=>510, :ruby_default=>nil}],
108
+ [:d, {:type=>:datetime, :db_type=>"TIMESTAMP", :default=>nil, :allow_null=>true, :primary_key=>false, :column_size=>8, :ruby_default=>nil}]
109
+ ], @db.schema(:schema_test, :reload => true)
110
+ end
111
+
112
+ should "be able to set a default value on a column" do
113
+ @db.create_table! :words do
114
+ String :word
115
+ String :language, :default => 'en'
116
+ end
117
+
118
+ @db[:words] << { :word => 'hello' }
119
+ @db[:words] << { :word => 'bonjour', :language => 'fr' }
120
+
121
+ assert_equal [
122
+ { :word => 'hello', :language => 'en' },
123
+ { :word => 'bonjour', :language => 'fr' }
124
+ ], @db[:words].all
125
+ end
126
+
127
+ should "be able to filter boolean columns" do
128
+ @db.create_table! :bool_test do
129
+ boolean :val
130
+ end
131
+ @db[:bool_test] << { :val => true }
132
+ @db[:bool_test] << { :val => true }
133
+ @db[:bool_test] << { :val => false }
134
+ assert_equal 3, @db[:bool_test].count
135
+ assert_equal 2, @db[:bool_test].filter(:val => true).count
136
+ assert_equal 1, @db[:bool_test].filter(:val => false).count
137
+ end
138
+
139
+ context "when comparing strings fields" do
140
+ setup do
141
+ @db.create_table! :case do
142
+ String :name
143
+ end
144
+ @db[:case] << { :name => 'colin casey' }
145
+ @db[:case] << { :name => 'Colin Casey' }
146
+ end
147
+
148
+ should "be case-sensitive" do
149
+ assert_equal 1, @db[:case].filter(:name => 'colin casey').count
150
+ assert_equal 1, @db[:case].filter(:name => 'Colin Casey').count
151
+ end
152
+
153
+ should "be able to convert a string field to lowercase" do
154
+ assert_equal 2, @db[:case].filter(:lower.sql_function(:name) => 'colin casey').count
155
+ end
156
+
157
+ should "be able to convert a string field to uppercase" do
158
+ assert_equal 2, @db[:case].filter(:upper.sql_function(:name) => 'COLIN CASEY').count
159
+ end
160
+
161
+ should "be able to do a case-sensitive string comparison" do
162
+ assert_equal 1, @db[:case].filter(:name.like('colin%')).count
163
+ end
164
+
165
+ should "be able to do a case-insensitive string comparison" do
166
+ assert_equal 2, @db[:case].filter(:name.ilike('colin%')).count
167
+ end
168
+ end
169
+
170
+ context "when handling deletions" do
171
+ setup do
172
+ @db.create_table! :items do
173
+ primary_key :id
174
+ String :name
175
+ Float :value
176
+ end
177
+ @items = @db[:items]
178
+ @items.delete # remove all records
179
+ @items << {:name => 'abc', :value => 1.23}
180
+ @items << {:name => 'def', :value => 4.56}
181
+ @items << {:name => 'ghi', :value => 7.89}
182
+ end
183
+
184
+ should "return the number of records affected when filtered" do
185
+ assert_equal 3, @items.count
186
+ assert_equal 1, @items.filter(:value.sql_number < 3).delete
187
+ assert_equal 2, @items.count
188
+ assert_equal 0, @items.filter(:value.sql_number < 3).delete
189
+ assert_equal 2, @items.count
190
+ end
191
+
192
+ should "return the number of records affected when unfiltered" do
193
+ assert_equal 3, @items.count
194
+ assert_equal 3, @items.delete
195
+ assert_equal 0, @items.count
196
+ assert_equal 0, @items.delete
197
+ end
198
+ end
199
+
200
+ context "using transactions" do
201
+ setup do
202
+ @db.create_table! :transaction_test do
203
+ primary_key :id
204
+ String :name
205
+ end
206
+ end
207
+
208
+ should "be able to commit a transaction" do
209
+ assert_equal 0, @db[:transaction_test].count
210
+ @db.transaction do
211
+ @db[:transaction_test] << { :name => 'commited' }
212
+ end
213
+ assert_equal 1, @db[:transaction_test].count
214
+ end
215
+
216
+ should "be re-entrant" do
217
+ assert_equal 0, @db[:transaction_test].count
218
+ @db.transaction do
219
+ @db[:transaction_test] << { :name => 'first' }
220
+ @db.transaction do
221
+ @db[:transaction_test] << { :name => 'second' }
222
+ end
223
+ end
224
+ assert_equal 2, @db[:transaction_test].count
225
+ end
226
+
227
+ should "be able to rollback a transaction" do
228
+ assert_equal 0, @db[:transaction_test].count
229
+ @db.transaction do
230
+ @db[:transaction_test] << { :name => 'rollback' }
231
+ raise(Sequel::Rollback)
232
+ end
233
+ assert_equal 0, @db[:transaction_test].count
234
+ end
235
+
236
+ should "automatically rollback a transaction on error" do
237
+ assert_equal 0, @db[:transaction_test].count
238
+ assert_raise(RuntimeError) do
239
+ @db.transaction do
240
+ @db[:transaction_test] << { :name => 'error-induced rollback' }
241
+ raise "some error occurred"
242
+ end
243
+ end
244
+ assert_equal 0, @db[:transaction_test].count
245
+ end
246
+
247
+ should "support savepoints" do
248
+ assert_equal 0, @db[:transaction_test].count
249
+ @db.transaction do
250
+ @db[:transaction_test] << { :name => 'Inigo Montoya' } # Inserted
251
+ @db.transaction(:savepoint => true) do # This savepoint is rolled back
252
+ @db[:transaction_test] << { :name => 'The 6-fingered Man' } # Not inserted
253
+ raise(Sequel::Rollback)
254
+ end
255
+ end
256
+ assert_equal 1, @db[:transaction_test].count
257
+ end
258
+ end
259
+ end
260
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'sequel/jdbc_hxtt_adapter'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel-jdbc-hxtt-adapter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Colin Casey
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-01 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sequel
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 3.8.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: thoughtbot-shoulda
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description: "Sequel adapter for working with MS Access files using JRuby and HXTT's pure JDBC Access driver. Note: HXTT driver is not supplied but you can obtain a trial version or purchase it at http://www.hxtt.com/"
36
+ email: casey.colin@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - .document
46
+ - .gitignore
47
+ - LICENSE
48
+ - README.rdoc
49
+ - Rakefile
50
+ - VERSION
51
+ - lib/sequel/adapters/jdbc/hxtt.rb
52
+ - lib/sequel/adapters/jdbc/resources/empty.mdb
53
+ - lib/sequel/jdbc_hxtt_adapter.rb
54
+ - sequel-jdbc-hxtt-adapter.gemspec
55
+ - test/sequel_jdbc_hxtt_adapter_test.rb
56
+ - test/test_helper.rb
57
+ has_rdoc: true
58
+ homepage: http://github.com/colincasey/sequel-jdbc-hxtt-adapter
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --charset=UTF-8
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ requirements: []
79
+
80
+ rubyforge_project:
81
+ rubygems_version: 1.3.5
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Sequel adapter for working with MS Access files using JRuby and HXTT's pure JDBC Access driver
85
+ test_files:
86
+ - test/test_helper.rb
87
+ - test/sequel_jdbc_hxtt_adapter_test.rb