@@ -3,7 +3,8 @@ abstract class Avram::Database
3
3
4
4
@@db : DB ::Database ? = nil
5
5
@@lock = Mutex .new
6
- class_getter transactions = {} of FiberId => DB ::Transaction
6
+ class_getter connections = {} of FiberId => DB ::Connection
7
+ class_property lock_id : UInt64 ?
7
8
8
9
macro inherited
9
10
Habitat .create do
@@ -24,6 +25,16 @@ abstract class Avram::Database
24
25
% }
25
26
end
26
27
28
+ def self.setup_connection (& block : DB ::Connection - > Nil )
29
+ new.db.setup_connection do |conn |
30
+ block.call conn
31
+ end
32
+ end
33
+
34
+ def self.verify_connection
35
+ new.connection.open.close
36
+ end
37
+
27
38
# Rollback the current transaction
28
39
def self.rollback
29
40
new.rollback
@@ -142,28 +153,36 @@ abstract class Avram::Database
142
153
143
154
# :nodoc:
144
155
def run
145
- yield current_transaction.try( & .connection) || db
156
+ yield current_connection || db
146
157
end
147
158
148
159
# :nodoc:
149
160
def listen (* channels : String , & block : PQ ::Notification - > ) : Nil
150
161
connection.connect_listen(* channels, & block)
151
162
end
152
163
153
- private def connection : Avram ::Connection
164
+ protected def connection : Avram ::Connection
154
165
Avram ::Connection .new(url, database_class: self .class)
155
166
end
156
167
157
- private def db : DB ::Database
168
+ protected def db : DB ::Database
158
169
@@db ||= @@lock .synchronize do
159
170
# check @@db again because a previous request could have set it after
160
171
# the first time it was checked
161
172
@@db || connection.open
162
173
end
163
174
end
164
175
176
+ private def current_connection : DB ::Connection
177
+ connections[object_id] ||= db.checkout
178
+ end
179
+
180
+ private def object_id : UInt64
181
+ self .class.lock_id || Fiber .current.object_id
182
+ end
183
+
165
184
private def current_transaction : DB ::Transaction ?
166
- transactions[ Fiber .current.object_id] ?
185
+ current_connection._avram_stack.last ?
167
186
end
168
187
169
188
protected def truncate
@@ -180,7 +199,7 @@ abstract class Avram::Database
180
199
181
200
# :nodoc:
182
201
def transaction : Bool
183
- if current_transaction
202
+ if current_transaction.try( & ._avram_joinable?)
184
203
yield
185
204
true
186
205
else
@@ -190,20 +209,23 @@ abstract class Avram::Database
190
209
end
191
210
end
192
211
193
- private def transactions
194
- self .class.transactions
212
+ private def connections
213
+ self .class.connections
195
214
end
196
215
197
216
private def wrap_in_transaction
198
- db.transaction do |tx |
199
- transactions[Fiber .current.object_id] ||= tx
217
+ (current_transaction || current_connection).transaction do
200
218
yield
201
219
end
202
220
true
203
221
rescue e : Avram ::Rollback
204
222
false
205
223
ensure
206
- transactions.delete(Fiber .current.object_id)
224
+ # TODO: not sure of this
225
+ if current_connection._avram_in_transaction?
226
+ current_connection.release
227
+ connections.delete(object_id)
228
+ end
207
229
end
208
230
209
231
class DatabaseCleaner
0 commit comments