| | 121 | class ConnectionPerThread(object): |
|---|
| | 122 | """A database connection factory which uses one connection per thread. |
|---|
| | 123 | |
|---|
| | 124 | This is useful for SQLite; from http://www.sqlite.org/c_interface.html: |
|---|
| | 125 | |
|---|
| | 126 | "If SQLite is compiled with the THREADSAFE preprocessor macro set |
|---|
| | 127 | to 1, then it is safe to use SQLite from two or more threads of |
|---|
| | 128 | the same process at the same time. But each thread should have |
|---|
| | 129 | its own sqlite* pointer returned from sqlite_open. It is never safe |
|---|
| | 130 | for two or more threads to access the same sqlite* pointer at the |
|---|
| | 131 | same time. |
|---|
| | 132 | |
|---|
| | 133 | In precompiled SQLite libraries available on the website, the Unix |
|---|
| | 134 | versions are compiled with THREADSAFE turned off but the windows |
|---|
| | 135 | versions are compiled with THREADSAFE turned on. If you need |
|---|
| | 136 | something different that this you will have to recompile." |
|---|
| | 137 | |
|---|
| | 138 | See also http://www.sqlite.org/faq.html#q8 |
|---|
| | 139 | """ |
|---|
| | 140 | |
|---|
| | 141 | def __init__(self, open, close, retry=5): |
|---|
| | 142 | self.open = open |
|---|
| | 143 | self.close = close |
|---|
| | 144 | self.retry = retry |
|---|
| | 145 | self.conns = {} |
|---|
| | 146 | |
|---|
| | 147 | def __call__(self): |
|---|
| | 148 | """Return the connection for the current thread.""" |
|---|
| | 149 | threadid = threading._get_ident() |
|---|
| | 150 | try: |
|---|
| | 151 | return self.conns[threadid] |
|---|
| | 152 | except KeyError: |
|---|
| | 153 | for i in xrange(self.retry): |
|---|
| | 154 | try: |
|---|
| | 155 | conn = self.open() |
|---|
| | 156 | self.conns[threadid] = conn |
|---|
| | 157 | return conn |
|---|
| | 158 | except errors.OutOfConnectionsError: |
|---|
| | 159 | conn = None |
|---|
| | 160 | time.sleep(i + 1) |
|---|
| | 161 | raise errors.OutOfConnectionsError() |
|---|
| | 162 | |
|---|
| | 163 | def shutdown(self): |
|---|
| | 164 | """Release all database connections.""" |
|---|
| | 165 | # Empty the conn map. |
|---|
| | 166 | while self.conns: |
|---|
| | 167 | threadid, conn = self.conns.popitem() |
|---|
| | 168 | self.close(conn) |
|---|
| | 169 | |
|---|
| | 170 | |
|---|