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 +2 -0
- data/README.md +14 -1
- data/lib/xid.rb +17 -2
- data/lib/xid/connection_adapters/abstract_adapter.rb +14 -1
- data/lib/xid/connection_adapters/mysql2_adapter.rb +20 -0
- data/lib/xid/connection_adapters/mysql_adapter.rb +19 -0
- data/lib/xid/connection_adapters/oracle_enhanced_adapter.rb +20 -0
- data/lib/xid/connection_adapters/postgresql_adapter.rb +4 -3
- data/lib/xid/connection_adapters/synthetic_adapter.rb +17 -0
- data/lib/xid/version.rb +1 -1
- data/spec/spec_helper.rb +4 -2
- data/spec/support/transaction_id_specs.rb +31 -0
- data/spec/xid/connection_adapters/mysql2_adapter_spec.rb +7 -0
- data/spec/xid/connection_adapters/mysql_adapter_spec.rb +7 -0
- data/spec/xid/connection_adapters/oracle_enhanced_adapter_spec.rb +6 -0
- data/spec/xid/connection_adapters/postgresql_adapter_spec.rb +1 -27
- data/xid.gemspec +1 -0
- metadata +49 -42
data/Gemfile
CHANGED
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
|
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
|
-
|
6
|
-
require "xid/connection_adapters/#{
|
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
|
-
|
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:
|
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
|
17
|
-
select_value('SELECT txid_current()')
|
17
|
+
def select_transaction_id
|
18
|
+
select_value('SELECT txid_current()')
|
18
19
|
end
|
19
20
|
|
20
21
|
end
|
data/lib/xid/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -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
|
@@ -3,31 +3,5 @@ require 'spec_helper'
|
|
3
3
|
describe 'XID::ConnectionAdapters::PostgreSQLAdapter' do
|
4
4
|
connect_with_adapter 'postgresql'
|
5
5
|
|
6
|
-
|
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
|
data/xid.gemspec
CHANGED
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
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
62
|
-
|
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
|
-
|
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.
|
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
|