flounder 0.9.3 → 0.9.4

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.
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