@@ -194,3 +194,106 @@ describe "pgmoon.pool", ->
194194 it " has NULL constant" , ->
195195 pool = PostgresPool {}
196196 assert . truthy pool. NULL
197+
198+ describe " reserve and release" , ->
199+ before_each ->
200+ pool = PostgresPool { database : DB , user : USER , password : PASSWORD , host : HOST , port : PORT }
201+ assert pool\ connect!
202+
203+ after_each ->
204+ pool\ disconnect!
205+
206+ it " reserves and releases a connection for transaction" , ->
207+ pg = assert pool\ reserve!
208+ assert . truthy pg. reserved
209+ assert . same 1 , pool\ pool_size!
210+
211+ assert pg\ query " BEGIN"
212+ assert . same " T" , pg. transaction_status
213+
214+ assert pg\ query " SELECT 1"
215+ assert pg\ query " COMMIT"
216+ assert . same " I" , pg. transaction_status
217+
218+ assert pool\ release pg
219+ assert . falsy pg. reserved
220+
221+ it " reserved connection is not reused by pool:query" , ->
222+ pg = assert pool\ reserve!
223+
224+ -- pool:query should create a new connection since first is reserved
225+ assert pool\ query " SELECT 1"
226+ assert . same 2 , pool\ pool_size!
227+
228+ assert pool\ release pg
229+
230+ it " auto-rollback on release when in transaction (T state)" , ->
231+ pg = assert pool\ reserve!
232+
233+ assert pg\ query " BEGIN"
234+ assert . same " T" , pg. transaction_status
235+
236+ -- Release without committing
237+ assert pool\ release pg
238+ assert . falsy pg. reserved
239+ assert . same " I" , pg. transaction_status
240+
241+ it " auto-rollback on release when in error state (E state)" , ->
242+ pg = assert pool\ reserve!
243+
244+ assert pg\ query " BEGIN"
245+ -- Cause an error
246+ res, err = pg\ query " SELECT * FROM nonexistent_table_xyz"
247+ assert . is_nil res
248+ assert . same " E" , pg. transaction_status
249+
250+ -- Release should auto-rollback and recover
251+ assert pool\ release pg
252+ assert . falsy pg. reserved
253+ assert . same " I" , pg. transaction_status
254+
255+ it " respects max_pool_size when reserving" , ->
256+ pool\ disconnect!
257+ pool = PostgresPool {
258+ database : DB , user : USER , password : PASSWORD , host : HOST , port : PORT
259+ max_pool_size : 2
260+ }
261+ assert pool\ connect!
262+
263+ pg1 = assert pool\ reserve!
264+ pg2 = assert pool\ reserve!
265+ assert . same 2 , pool\ pool_size!
266+
267+ res, err = pool\ reserve!
268+ assert . is_nil res
269+ assert . same " pool exhausted, max_pool_size reached" , err
270+
271+ pool\ release pg1
272+ pool\ release pg2
273+
274+ it " errors when releasing connection not from this pool" , ->
275+ other_pool = PostgresPool { database : DB , user : USER , password : PASSWORD , host : HOST , port : PORT }
276+ assert other_pool\ connect!
277+
278+ pg = assert other_pool\ reserve!
279+
280+ res, err = pool\ release pg
281+ assert . is_nil res
282+ assert . same " connection not from this pool" , err
283+
284+ other_pool\ release pg
285+ other_pool\ disconnect!
286+
287+ it " errors when releasing connection that is not reserved" , ->
288+ pg = pool. pool[ 1 ]
289+ assert . falsy pg. reserved
290+
291+ res, err = pool\ release pg
292+ assert . is_nil res
293+ assert . same " connection not reserved" , err
294+
295+ it " reserve returns error when not connected" , ->
296+ pool\ disconnect!
297+ res, err = pool\ reserve!
298+ assert . is_nil res
299+ assert . same " not connected" , err
0 commit comments