xid 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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