dm-nested-transactions 0.0.1
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/.gitignore +2 -0
- data/README +12 -0
- data/Rakefile +13 -0
- data/VERSION +1 -0
- data/lib/dm-nested-transactions.rb +85 -0
- data/rails/init.rb +7 -0
- metadata +67 -0
data/.gitignore
ADDED
data/README
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
dm-nested-transactions
|
2
|
+
----------------------
|
3
|
+
|
4
|
+
Adds nested transaction support to DataMapper. Only tested with Postgres, and it's a bit of a hack, so use at your own risk!
|
5
|
+
|
6
|
+
Install:
|
7
|
+
gem install dm-nested-transactions
|
8
|
+
|
9
|
+
Usage:
|
10
|
+
repository.adapter.extend(DataMapper::NestedTransactinos)
|
11
|
+
|
12
|
+
There's a rails/init.rb file that automatically does the above for you.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "dm-nested-transactions"
|
5
|
+
gemspec.summary = "Adds nested transaction support to DM"
|
6
|
+
gemspec.description = "Only tested with Postgres, and it's a bit of a hack, so use at your own risk!"
|
7
|
+
gemspec.email = "contact@rhnh.net"
|
8
|
+
gemspec.homepage = "http://github.com/xaviershay/dm-nested-transactions"
|
9
|
+
gemspec.authors = ["Xavier Shay"]
|
10
|
+
end
|
11
|
+
rescue LoadError
|
12
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
13
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Hacks to get nested transactions in Postgres
|
2
|
+
# Not extensively tested, more a proof of concept
|
3
|
+
#
|
4
|
+
# It re-opens the existing Transaction class to add a check for whether
|
5
|
+
# we need a nested transaction or not, and adds a new NestedTransaction
|
6
|
+
# transaction primitive that issues savepoint commands rather than begin/commit.
|
7
|
+
|
8
|
+
module DataMapper
|
9
|
+
module Resource
|
10
|
+
def transaction(&block)
|
11
|
+
self.class.transaction(&block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Transaction
|
16
|
+
# Overridden to allow nested transactions
|
17
|
+
def connect_adapter(adapter)
|
18
|
+
if @transaction_primitives.key?(adapter)
|
19
|
+
raise "Already a primitive for adapter #{adapter}"
|
20
|
+
end
|
21
|
+
|
22
|
+
primitive = if adapter.current_transaction
|
23
|
+
adapter.nested_transaction_primitive
|
24
|
+
else
|
25
|
+
adapter.transaction_primitive
|
26
|
+
end
|
27
|
+
|
28
|
+
@transaction_primitives[adapter] = validate_primitive(primitive)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module NestedTransactions
|
33
|
+
def nested_transaction_primitive
|
34
|
+
DataObjects::NestedTransaction.create_for_uri(normalized_uri, current_connection)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module DataObjects
|
40
|
+
class NestedTransaction < Transaction
|
41
|
+
|
42
|
+
# The host name. Note, this relies on the host name being configured
|
43
|
+
# and resolvable using DNS
|
44
|
+
HOST = "#{Socket::gethostbyname(Socket::gethostname)[0]}" rescue "localhost"
|
45
|
+
@@counter = 0
|
46
|
+
|
47
|
+
# The connection object for this transaction - must have already had
|
48
|
+
# a transaction begun on it
|
49
|
+
attr_reader :connection
|
50
|
+
# A unique ID for this transaction
|
51
|
+
attr_reader :id
|
52
|
+
|
53
|
+
def self.create_for_uri(uri, connection)
|
54
|
+
uri = uri.is_a?(String) ? URI::parse(uri) : uri
|
55
|
+
DataObjects::NestedTransaction.new(uri, connection)
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Creates a NestedTransaction bound to an existing connection
|
60
|
+
#
|
61
|
+
def initialize(uri, connection)
|
62
|
+
@connection = connection
|
63
|
+
@id = Digest::SHA256.hexdigest("#{HOST}:#{$$}:#{Time.now.to_f}:nested:#{@@counter += 1}")
|
64
|
+
end
|
65
|
+
|
66
|
+
def close
|
67
|
+
end
|
68
|
+
|
69
|
+
def begin
|
70
|
+
cmd = "SAVEPOINT \"#{@id}\""
|
71
|
+
connection.create_command(cmd).execute_non_query
|
72
|
+
end
|
73
|
+
|
74
|
+
def commit
|
75
|
+
cmd = "RELEASE SAVEPOINT \"#{@id}\""
|
76
|
+
connection.create_command(cmd).execute_non_query
|
77
|
+
end
|
78
|
+
|
79
|
+
def rollback
|
80
|
+
cmd = "ROLLBACK TO SAVEPOINT \"#{@id}\""
|
81
|
+
connection.create_command(cmd).execute_non_query
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
data/rails/init.rb
ADDED
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dm-nested-transactions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Xavier Shay
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-09 00:00:00 +13:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Only tested with Postgres, and it's a bit of a hack, so use at your own risk!
|
22
|
+
email: contact@rhnh.net
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files:
|
28
|
+
- README
|
29
|
+
files:
|
30
|
+
- .gitignore
|
31
|
+
- README
|
32
|
+
- Rakefile
|
33
|
+
- VERSION
|
34
|
+
- lib/dm-nested-transactions.rb
|
35
|
+
- rails/init.rb
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/xaviershay/dm-nested-transactions
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options:
|
42
|
+
- --charset=UTF-8
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
segments:
|
50
|
+
- 0
|
51
|
+
version: "0"
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.3.6
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: Adds nested transaction support to DM
|
66
|
+
test_files: []
|
67
|
+
|