flounder 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d5865e63fb12cfb93c2514d412f9640e00383072
4
- data.tar.gz: 09a4d7dfab77ccea44f7b7c0f0fb9f8212e9d909
3
+ metadata.gz: a2a4bab6f9430ad7169aafe13673bb79debf2d1a
4
+ data.tar.gz: ddaa62449b7848ba338f79e48c22eab8d95da823
5
5
  SHA512:
6
- metadata.gz: 61fe664adec772a796f5136ecba197754aefb6656a9a2839dbddbea8ff4ef1b5331d2e2df023df299ff4365b2d7dfbe2ebdac0ab87eeb9713c53850f89220370
7
- data.tar.gz: c711c60ddee3a053ed91ef745773b3b4febb87edb5965028e8d0ff0ef1e17d2857b32d631f6855ac316249572b48228712c80f7483d9ed9a23efb4128c3b3729
6
+ metadata.gz: ef55ee6011bb3a31c99161529775800e347691a93b39b685eb6561c7ad0364a2f1b37d03e8c4236dd99e32d63cfd656900aed69404ffe2143e846dafaac34f91
7
+ data.tar.gz: c86cfee4eb453d63af98b23da4a5faeaad3292a3023b983631c159c53ad7bb7037eacd3cc2a8c341b73e0144f79db3166d9377eea5ac0bf10b1f34182f93fad4
data/HISTORY CHANGED
@@ -15,4 +15,5 @@
15
15
  0.9.3
16
16
  + DELETE FROM - entity#delete
17
17
 
18
-
18
+ 0.9.4
19
+ + nested transactions
data/flounder.gemspec CHANGED
@@ -2,21 +2,26 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "flounder"
5
- s.version = '0.9.3'
5
+ s.version = '0.9.4'
6
6
  s.summary = "Flounder is a way to write SQL simply in Ruby. It deals with everything BUT object relational mapping. "
7
7
  s.email = "kaspar.schiess@technologyastronauts.ch"
8
8
  s.homepage = "https://bitbucket.org/technologyastronauts/oss_flounder"
9
9
  s.authors = ['Kaspar Schiess', 'Florian Hanke']
10
10
 
11
- # s.description = <<-EOF
12
- # EOF
11
+ s.description = <<-EOF
12
+ Flounder is the missing piece between the database and your Ruby code. It
13
+ allows very simple access to database tables without going all the way to
14
+ begin an object mapper.
15
+ EOF
13
16
 
14
17
  s.add_runtime_dependency 'arel', '~> 5', '> 5.0.1'
15
- s.add_runtime_dependency 'pg', '> 0.17'
18
+ s.add_runtime_dependency 'pg', '~> 0.17'
16
19
  s.add_runtime_dependency 'hashie', '~> 3', '>= 3.2'
17
20
  s.add_runtime_dependency 'connection_pool', '~> 2'
18
21
 
19
22
  s.files = Dir['**/*']
20
23
  s.test_files = Dir['qed/**/*']
21
24
  s.require_paths = ["lib"]
25
+
26
+ s.licenses = 'MIT'
22
27
  end
@@ -3,10 +3,6 @@ require 'forwardable'
3
3
  require 'logger'
4
4
 
5
5
  module Flounder
6
- # Raised when an entity name cannot be found in this domain.
7
- class NoSuchEntity < StandardError
8
- end
9
-
10
6
  class Domain
11
7
  # A device that discards all logging made to it. This is used to be silent
12
8
  # by default while still allowing the logging of all queries.
@@ -29,8 +25,11 @@ module Flounder
29
25
  @oids_entity_map = {}
30
26
 
31
27
  @logger = Logger.new(NilDevice.new)
28
+
29
+ @savepoints = Hash.new(0)
32
30
  end
33
31
 
32
+ attr_reader :savepoints
34
33
  attr_reader :connection_pool
35
34
  attr_accessor :logger
36
35
 
@@ -39,8 +38,12 @@ module Flounder
39
38
 
40
39
  def transaction &block
41
40
  with_connection do |conn|
42
- conn.transaction do
43
- block.call(conn)
41
+ if in_transaction?(conn)
42
+ savepoint(conn) { block.call(conn) }
43
+ else
44
+ conn.transaction do
45
+ savepoint(conn) { block.call(conn) }
46
+ end
44
47
  end
45
48
  end
46
49
  end
@@ -89,6 +92,38 @@ module Flounder
89
92
  end
90
93
 
91
94
  private
95
+ def sp_count connection
96
+ savepoints[connection.object_id]
97
+ end
98
+ def inc_sp connection
99
+ savepoints[connection.object_id] += 1
100
+ end
101
+ def dec_sp connection
102
+ savepoints[connection.object_id] -= 1
103
+ if savepoints[connection.object_id] < 0
104
+ fail "ASSERTION FAILURE: Savepoint count cannot drop below zero!"
105
+ end
106
+
107
+ nil
108
+ end
109
+ def in_transaction? connection
110
+ sp_count(connection) > 0
111
+ end
112
+ def savepoint connection, &block
113
+ sp_number = inc_sp(connection)
114
+ sp_name = "s#{sp_number}"
115
+
116
+ connection.exec("SAVEPOINT #{sp_name};")
117
+ begin
118
+ yield
119
+ rescue Exception
120
+ connection.exec("ROLLBACK TO SAVEPOINT #{sp_name};")
121
+ raise
122
+ ensure
123
+ dec_sp(connection)
124
+ end
125
+ end
126
+
92
127
  def table_oid table_name
93
128
  connection_pool.with_connection do |conn|
94
129
  # TBD
@@ -1,6 +1,9 @@
1
1
 
2
2
 
3
3
  module Flounder
4
+ # Raised when an entity name cannot be found in this domain.
5
+ class NoSuchEntity < StandardError; end
6
+
4
7
  # Indicates a field reference in a chain method that cannot be resolved
5
8
  # to a real field on the underlying relation.
6
9
  #
@@ -4,26 +4,36 @@ Transactions are supported on the domain and on entities. Since you need to make
4
4
 
5
5
  ~~~ruby
6
6
  expect RuntimeError do
7
- domain.with_connection do |conn|
8
- conn.transaction do
9
- posts.update(title: 'A single title for everyone').kick(conn)
10
- fail 'rollback'
11
- end
7
+ domain.transaction do |conn|
8
+ posts.update(title: 'A single title for everyone').kick(conn)
9
+ fail 'rollback'
12
10
  end
13
11
  end
14
12
 
15
13
  posts.first.title.assert != 'A single title for everyone'
16
14
  ~~~
17
15
 
18
- The same works on any entity from the domain. Please note that there is a shortcut for getting at a transaction.
16
+ The same works on any entity from the domain.
19
17
 
20
18
  ~~~ruby
21
- domain.transaction do |conn|
19
+ posts.transaction do |conn|
22
20
  posts.all(conn)
23
21
  end
22
+ ~~~
24
23
 
25
- posts.transaction do |conn|
26
- posts.all(conn)
24
+ Domain transactions can be nested. Internally, this is realized using PostgreSQL savepoints.
25
+
26
+ ~~~ruby
27
+ domain.transaction do |connection|
28
+ begin
29
+ domain.transaction do |conn|
30
+ posts.update(title: 'A single title for everyone').kick(conn)
31
+ fail 'rollback'
32
+ end
33
+ rescue RuntimeError
34
+ end
35
+
36
+ posts.first.title.assert != 'A single title for everyone'
27
37
  end
28
38
  ~~~
29
39
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flounder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaspar Schiess
@@ -35,14 +35,14 @@ dependencies:
35
35
  name: pg
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">"
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.17'
41
41
  type: :runtime
42
42
  prerelease: false
43
43
  version_requirements: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">"
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0.17'
48
48
  - !ruby/object:Gem::Dependency
@@ -79,7 +79,9 @@ dependencies:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '2'
82
- description:
82
+ description: " Flounder is the missing piece between the database and your Ruby
83
+ code. It \n allows very simple access to database tables without going all the
84
+ way to\n begin an object mapper. \n"
83
85
  email: kaspar.schiess@technologyastronauts.ch
84
86
  executables: []
85
87
  extensions: []
@@ -90,8 +92,6 @@ files:
90
92
  - HISTORY
91
93
  - LICENSE
92
94
  - README
93
- - flounder-0.9.1.gem
94
- - flounder-0.9.2.gem
95
95
  - flounder.gemspec
96
96
  - lib/flounder.rb
97
97
  - lib/flounder/connection.rb
@@ -128,7 +128,8 @@ files:
128
128
  - qed/selects.md
129
129
  - qed/updates.md
130
130
  homepage: https://bitbucket.org/technologyastronauts/oss_flounder
131
- licenses: []
131
+ licenses:
132
+ - MIT
132
133
  metadata: {}
133
134
  post_install_message:
134
135
  rdoc_options: []
data/flounder-0.9.1.gem DELETED
Binary file
data/flounder-0.9.2.gem DELETED
Binary file