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 ADDED
@@ -0,0 +1,2 @@
1
+ *.gemspec
2
+ pkg/
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
@@ -0,0 +1,7 @@
1
+ class NestedTransactionConfig < Rails::Railtie
2
+ railtie_name :dm_nested_transactions
3
+
4
+ config.after_initialize do
5
+ repository.adapter.extend(DataMapper::NestedTransactions)
6
+ end
7
+ end
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
+