@@ -29,8 +29,8 @@ class Temporal(object):
2929 Or `pg_tmp` can decorate a method or function.
3030 """
3131
32- #: Format the cluster directory name.
33- cluster_dirname = 'pg_tmp_{0}_{1}' .format
32+ format_sandbox_id = staticmethod (( 'sandbox{0}_{1}' ). format )
33+ cluster_dirname = staticmethod (( 'pg_tmp_{0}_{1}' ) .format )
3434 cluster = None
3535
3636 _init_pid_ = None
@@ -91,7 +91,7 @@ def init(self,
9191 "environment variable to the `pg_config` path"
9292 }
9393 ):
94- if self .cluster is not None :
94+ if self .cluster is not None or 'PGTEST' in os . environ :
9595 return
9696 ##
9797 # Hasn't been created yet, but doesn't matter.
@@ -156,7 +156,7 @@ def init(self,
156156 unix_socket_directories = cluster .data_directory ,
157157 ))
158158
159- # Start it up .
159+ # Start the database cluster .
160160 with open (self .logfile , 'w' ) as lfo :
161161 cluster .start (logfile = lfo )
162162 cluster .wait_until_started ()
@@ -165,18 +165,23 @@ def init(self,
165165 c = cluster .connection (user = 'test' , database = 'template1' ,)
166166 with c :
167167 c .execute ('create database test' )
168- # It's ready.
169168 self .cluster = cluster
170169
171170 def push (self ):
172- c = self .cluster .connection (user = 'test' )
173- c .connect ()
171+ if 'PGTEST' in os .environ :
172+ from . import open as pg_open
173+ c = pg_open (os .environ ['PGTEST' ]) # Ignoring PGINSTALLATION.
174+ else :
175+ c = self .cluster .connection (user = 'test' )
176+ c .connect ()
177+
174178 extras = []
179+ sbid = self .format_sandbox_id (os .getpid (), self .sandbox_id + 1 )
175180
176- def new_pg_tmp_connection (l = extras , c = c , sbid = 'sandbox' + str ( self . sandbox_id + 1 ) ):
181+ def new_pg_tmp_connection (l = extras , clone = c . clone , sbid = sbid ):
177182 # Used to create a new connection that will be closed
178183 # when the context stack is popped along with 'db'.
179- l .append (c . clone ())
184+ l .append (clone ())
180185 l [- 1 ].settings ['search_path' ] = str (sbid ) + ',' + l [- 1 ].settings ['search_path' ]
181186 return l [- 1 ]
182187
@@ -205,7 +210,7 @@ def new_pg_tmp_connection(l = extras, c = c, sbid = 'sandbox' + str(self.sandbox
205210 builtins .__dict__ .update (local_builtins )
206211 self .sandbox_id += 1
207212
208- def pop (self , exc , drop_schema = 'DROP SCHEMA sandbox {0} CASCADE' .format ):
213+ def pop (self , exc , drop_schema = ( 'DROP SCHEMA {0} CASCADE' ) .format ):
209214 local_builtins , extras = self .builtins_stack .pop ()
210215 self .sandbox_id -= 1
211216
@@ -235,32 +240,36 @@ def pop(self, exc, drop_schema = 'DROP SCHEMA sandbox{0} CASCADE'.format):
235240
236241 # Interrupted and closed all the other connections at this level;
237242 # now remove the sandbox schema.
238- c = self . cluster . connection ( user = 'test' )
239- with c :
243+ xdb = local_builtins [ 'db' ]
244+ with xdb . clone () as c :
240245 # Use a new connection so that the state of
241246 # the context connection will not have to be
242247 # contended with.
243- c .execute (drop_schema (self .sandbox_id + 1 ))
248+ c .execute (drop_schema (self .format_sandbox_id ( os . getpid (), self . sandbox_id + 1 ) ))
244249 else :
245- # interrupt
250+ # interrupt exception; avoid waiting for close
246251 pass
247252
253+ def _init_c (self , cxn ):
254+ cxn .connect ()
255+ sb = self .format_sandbox_id (os .getpid (), self .sandbox_id )
256+ cxn .execute ('CREATE SCHEMA ' + sb )
257+ cxn .settings ['search_path' ] = ',' .join ((sb , cxn .settings ['search_path' ]))
258+
248259 def __enter__ (self ):
249260 if self .cluster is None :
250261 self .init ()
262+
251263 self .push ()
252264 try :
253- db .connect ()
254- db .execute ('CREATE SCHEMA sandbox' + str (self .sandbox_id ))
255- db .settings ['search_path' ] = 'sandbox' + str (self .sandbox_id ) + ',' + db .settings ['search_path' ]
265+ self ._init_c (builtins .db )
256266 except Exception as e :
257267 # failed to initialize sandbox schema; pop it.
258268 self .pop (e )
259269 raise
260270
261271 def __exit__ (self , exc , val , tb ):
262- if self .cluster is not None :
263- self .pop (val )
272+ self .pop (val )
264273
265- #: The process' temporary cluster.
274+ #: The process' temporary cluster or connection source .
266275pg_tmp = Temporal ()
0 commit comments