xid 0.0.2 → 0.0.3

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/Gemfile CHANGED
@@ -4,4 +4,6 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem 'pg'
7
+ gem 'mysql', '>= 2.8.1'
8
+ gem 'mysql2', '>= 0.3.10'
7
9
  gem 'activerecord', '~> 3.0'
data/README.md CHANGED
@@ -4,9 +4,17 @@ Adds ability to ActiveRecord to retrieve the current transaction ID. This can be
4
4
  for the purposes of grouping operations performed on many records across many tables. In particular I
5
5
  had its usage with auditing libraries in mind.
6
6
 
7
- Currently supports:
7
+ Currently supported adapters:
8
8
 
9
9
  - PostgreSQL
10
+ - OracleEnhanced (untested, help!)
11
+ - Mysql, Mysql2 (help! user needs PROCESS privileges and requires a query returning/modifying records before you can get an id!!!)
12
+
13
+ Adapters with no support for retreiving the transactions ID:
14
+
15
+ - Sqlite
16
+ - Sqlite3
17
+
10
18
 
11
19
  Please fork and add functionality for other databases.
12
20
 
@@ -33,6 +41,11 @@ Simply call this to get the current ID:
33
41
 
34
42
  ## Contributing
35
43
 
44
+ You must have the ActiveRecord test suite databases set up. The gem uses these to connect to
45
+ for each adapter's specs.
46
+
47
+ See [ActiveRecord's RUNNING_UNIT_TESTS](https://github.com/rails/rails/blob/master/activerecord/RUNNING_UNIT_TESTS)
48
+
36
49
  1. Fork it
37
50
  2. Create your feature branch (`git checkout -b my-new-feature`)
38
51
  3. Commit your changes (`git commit -am 'Added some feature'`)
data/lib/xid.rb CHANGED
@@ -1,9 +1,24 @@
1
1
  require "xid/version"
2
2
 
3
3
  module XID
4
+ class << self
5
+ attr_accessor :adapter, :synthetic_id
6
+ end
7
+
8
+ self.synthetic_id = false
9
+
4
10
  def self.load
5
- adapter_name = ActiveRecord::Base.connection_pool.spec.config[:adapter]
6
- require "xid/connection_adapters/#{adapter_name}_adapter"
11
+ @adapter ||= ActiveRecord::Base.connection_pool.spec.config[:adapter]
12
+ require "xid/connection_adapters/#{@adapter}_adapter"
13
+ rescue LoadError
14
+ puts "XID was unable to load the transaction ID extension for the '#{@adapter}' adapter"
15
+ end
16
+
17
+ def self.use_synthetic_id!
18
+ @synthetic_id = true
19
+ @adapter = :synthetic
20
+ require "xid/connection_adapters/synthetic_adapter"
21
+ ActiveRecord::Base.connection.class.send :include, XID::ConnectionAdapters::SyntheticAdapter
7
22
  end
8
23
  end
9
24
 
@@ -7,7 +7,20 @@ module XID
7
7
  end
8
8
 
9
9
  def transaction_id
10
- nil
10
+ @transaction_id ||= select_transaction_id unless open_transactions == 0
11
+ end
12
+
13
+ def transaction(*args, &block)
14
+ if block_given? && block.arity > 0
15
+ super(*args, &lambda { block.call(transaction_id) })
16
+ else
17
+ super
18
+ end
19
+ ensure
20
+ @transaction_id = nil if open_transactions == 0
21
+ end
22
+
23
+ def select_transaction_id
11
24
  end
12
25
 
13
26
  end
@@ -0,0 +1,20 @@
1
+ # TODO this is just duplicate of Mysql, so you know, could be DRYer.
2
+ module XID
3
+ module ConnectionAdapters
4
+ module Mysql2Adapter
5
+
6
+ def supports_transaction_id?
7
+ true
8
+ end
9
+
10
+ def select_transaction_id
11
+ select_value('SELECT trx_id FROM information_schema.innodb_trx WHERE trx_mysql_thread_id = CONNECTION_ID()')
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+
18
+ ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do
19
+ include XID::ConnectionAdapters::Mysql2Adapter
20
+ end
@@ -0,0 +1,19 @@
1
+ module XID
2
+ module ConnectionAdapters
3
+ module MysqlAdapter
4
+
5
+ def supports_transaction_id?
6
+ true
7
+ end
8
+
9
+ def select_transaction_id
10
+ select_value('SELECT trx_id FROM information_schema.innodb_trx WHERE trx_mysql_thread_id = CONNECTION_ID()')
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+
17
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
18
+ include XID::ConnectionAdapters::MysqlAdapter
19
+ end
@@ -0,0 +1,20 @@
1
+ module XID
2
+ module ConnectionAdapters
3
+ module OracleEnhancedAdapter
4
+
5
+ def supports_transaction_id?
6
+ true
7
+ end
8
+
9
+ def select_transaction_id
10
+ select_value('SELECT dbms_transaction.local_transaction_id FROM dual')
11
+ end
12
+
13
+ end
14
+ end
15
+ end
16
+
17
+ ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do
18
+ include XID::ConnectionAdapters::OracleEnhancedAdapter
19
+ end
20
+
@@ -6,15 +6,16 @@ module XID
6
6
  true
7
7
  end
8
8
 
9
- # From the PostgreSQL manual: http://www.postgresql.org/docs/9.1/static/functions-info.html#FUNCTIONS-TXID-SNAPSHOT
9
+ # From the PostgreSQL manual:
10
+ # http://www.postgresql.org/docs/9.1/static/functions-info.html#FUNCTIONS-TXID-SNAPSHOT
10
11
  #
11
12
  # The internal transaction ID type (xid) is 32 bits wide and wraps around every
12
13
  # 4 billion transactions. However, these functions export a 64-bit format that
13
14
  # is extended with an "epoch" counter so it will not wrap around during the
14
15
  # life of an installation.
15
16
  #
16
- def transaction_id
17
- select_value('SELECT txid_current()').to_i
17
+ def select_transaction_id
18
+ select_value('SELECT txid_current()')
18
19
  end
19
20
 
20
21
  end
@@ -0,0 +1,17 @@
1
+ require 'uuidtools'
2
+
3
+ module XID
4
+ module ConnectionAdapters
5
+ module SyntheticAdapter
6
+
7
+ def supports_transaction_id?
8
+ true
9
+ end
10
+
11
+ def select_transaction_id
12
+ UUIDTools::UUID.random_create.to_s
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module XID
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -4,14 +4,16 @@ require 'active_record'
4
4
  require 'xid'
5
5
 
6
6
  module SpecHelpers
7
- def connect_with_adapter(adapter_name)
7
+ def connect_with_adapter(adapter_name, options={})
8
8
  before(:all) do
9
- ActiveRecord::Base.establish_connection({:adapter => adapter_name, :database => 'activerecord_unittest'})
9
+ ActiveRecord::Base.establish_connection({:adapter => adapter_name, :database => 'activerecord_unittest'}.merge(options))
10
10
  require "xid/connection_adapters/#{adapter_name}_adapter"
11
11
  end
12
12
  end
13
13
  end
14
14
 
15
+ Dir["./spec/support/**/*.rb"].each { |f| require f }
16
+
15
17
  RSpec.configure do |config|
16
18
  config.treat_symbols_as_metadata_keys_with_true_values = true
17
19
  config.run_all_when_everything_filtered = true
@@ -0,0 +1,31 @@
1
+ shared_examples "transaction ID supported behaviour" do
2
+ let(:adapter) { ActiveRecord::Base.connection }
3
+
4
+ describe "#supports_transaction_id?" do
5
+ it "should respond false to supports_transaction_id?" do
6
+ adapter.supports_transaction_id?.should be_true
7
+ end
8
+ end
9
+
10
+ describe "#transaction_id" do
11
+ it "should return a string" do
12
+ ActiveRecord::Base.transaction do
13
+ adapter.transaction_id.tap do |tid|
14
+ tid.should_not be_blank
15
+ tid.should be_kind_of(String)
16
+ end
17
+ end
18
+ end
19
+
20
+ it "should only return transaction id within an explicit transaction" do
21
+ adapter.transaction_id.should be_nil
22
+
23
+ ActiveRecord::Base.transaction do
24
+ adapter.transaction_id.should_not be_nil
25
+ end
26
+
27
+ adapter.transaction_id.should be_nil
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'XID::ConnectionAdapters::Mysql2Adapter' do
4
+ connect_with_adapter 'mysql2', :username => 'rails'
5
+
6
+ include_examples "transaction ID supported behaviour"
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'XID::ConnectionAdapters::MysqlAdapter' do
4
+ connect_with_adapter 'mysql', :username => 'rails'
5
+
6
+ include_examples "transaction ID supported behaviour"
7
+ end
@@ -0,0 +1,6 @@
1
+ describe 'XID::ConnectionAdapters::OracleEnhancedAdapter' do
2
+ # TODO: little help. I got no Oracle.
3
+ # connect_with_adapter 'oracle_enhanced'
4
+
5
+ # include_examples "transaction ID supported behaviour"
6
+ end
@@ -3,31 +3,5 @@ require 'spec_helper'
3
3
  describe 'XID::ConnectionAdapters::PostgreSQLAdapter' do
4
4
  connect_with_adapter 'postgresql'
5
5
 
6
- let(:adapter) { ActiveRecord::Base.connection }
7
-
8
- describe "#supports_transaction_id?" do
9
- it "should respond false to supports_transaction_id?" do
10
- adapter.supports_transaction_id?.should be_true
11
- end
12
- end
13
-
14
- describe "#transaction_id" do
15
- it "should return number" do
16
- adapter.transaction_id.should be_kind_of(Fixnum)
17
- end
18
-
19
- it "should return a different id within an explicit transaction" do
20
- tids = []
21
- tids << adapter.transaction_id
22
-
23
- ActiveRecord::Base.transaction do
24
- tids << adapter.transaction_id
25
- end
26
-
27
- tids << adapter.transaction_id
28
-
29
- tids.uniq.size.should eq 3
30
- end
31
-
32
- end
6
+ include_examples "transaction ID supported behaviour"
33
7
  end
@@ -14,4 +14,5 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "xid"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = XID::VERSION
17
+ gem.add_runtime_dependency('uuidtools', ["~> 2.1.3"])
17
18
  end
metadata CHANGED
@@ -1,34 +1,39 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: xid
3
- version: !ruby/object:Gem::Version
4
- hash: 27
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 2
10
- version: 0.0.2
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Adam Meehan
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-10-05 00:00:00 +10:00
19
- default_executable:
20
- dependencies: []
21
-
12
+ date: 2012-10-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: uuidtools
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.1.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.1.3
22
30
  description: Adds ability to ActiveRecord to retrieve the current transaction ID
23
- email:
31
+ email:
24
32
  - adam.meehan@gmail.com
25
33
  executables: []
26
-
27
34
  extensions: []
28
-
29
35
  extra_rdoc_files: []
30
-
31
- files:
36
+ files:
32
37
  - .gitignore
33
38
  - .rspec
34
39
  - Gemfile
@@ -37,48 +42,50 @@ files:
37
42
  - Rakefile
38
43
  - lib/xid.rb
39
44
  - lib/xid/connection_adapters/abstract_adapter.rb
45
+ - lib/xid/connection_adapters/mysql2_adapter.rb
46
+ - lib/xid/connection_adapters/mysql_adapter.rb
47
+ - lib/xid/connection_adapters/oracle_enhanced_adapter.rb
40
48
  - lib/xid/connection_adapters/postgresql_adapter.rb
49
+ - lib/xid/connection_adapters/synthetic_adapter.rb
41
50
  - lib/xid/railtie.rb
42
51
  - lib/xid/version.rb
43
52
  - spec/spec_helper.rb
53
+ - spec/support/transaction_id_specs.rb
44
54
  - spec/xid/connection_adapters/abstract_adapter_spec.rb
55
+ - spec/xid/connection_adapters/mysql2_adapter_spec.rb
56
+ - spec/xid/connection_adapters/mysql_adapter_spec.rb
57
+ - spec/xid/connection_adapters/oracle_enhanced_adapter_spec.rb
45
58
  - spec/xid/connection_adapters/postgresql_adapter_spec.rb
46
59
  - xid.gemspec
47
- has_rdoc: true
48
60
  homepage: https://github.com/adzap/xid
49
61
  licenses: []
50
-
51
62
  post_install_message:
52
63
  rdoc_options: []
53
-
54
- require_paths:
64
+ require_paths:
55
65
  - lib
56
- required_ruby_version: !ruby/object:Gem::Requirement
66
+ required_ruby_version: !ruby/object:Gem::Requirement
57
67
  none: false
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 3
62
- segments:
63
- - 0
64
- version: "0"
65
- required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
73
  none: false
67
- requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- hash: 3
71
- segments:
72
- - 0
73
- version: "0"
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
74
78
  requirements: []
75
-
76
79
  rubyforge_project:
77
- rubygems_version: 1.5.2
80
+ rubygems_version: 1.8.24
78
81
  signing_key:
79
82
  specification_version: 3
80
83
  summary: Adds ability to ActiveRecord to retrieve the current transaction ID
81
- test_files:
84
+ test_files:
82
85
  - spec/spec_helper.rb
86
+ - spec/support/transaction_id_specs.rb
83
87
  - spec/xid/connection_adapters/abstract_adapter_spec.rb
88
+ - spec/xid/connection_adapters/mysql2_adapter_spec.rb
89
+ - spec/xid/connection_adapters/mysql_adapter_spec.rb
90
+ - spec/xid/connection_adapters/oracle_enhanced_adapter_spec.rb
84
91
  - spec/xid/connection_adapters/postgresql_adapter_spec.rb