204 def close(self): |
204 def close(self): |
205 if self.cnx: |
205 if self.cnx: |
206 self.cnx.close() |
206 self.cnx.close() |
207 self.cnx = None |
207 self.cnx = None |
208 |
208 |
209 def create_eid(self, _session): |
209 def create_eid(self, _session, count=1): |
210 # lock needed to prevent 'Connection is busy with results for another |
210 # lock needed to prevent 'Connection is busy with results for another |
211 # command (0)' errors with SQLServer |
211 # command (0)' errors with SQLServer |
|
212 assert count > 0 |
212 with self.lock: |
213 with self.lock: |
213 return self._create_eid() # pylint: disable=E1102 |
214 return self._create_eid(count) |
214 |
215 |
215 def _create_eid(self): # pylint: disable=E0202 |
216 def _create_eid(self, count): |
216 # internal function doing the eid creation without locking. |
217 # internal function doing the eid creation without locking. |
217 # needed for the recursive handling of disconnections (otherwise we |
218 # needed for the recursive handling of disconnections (otherwise we |
218 # deadlock on self._eid_cnx_lock |
219 # deadlock on self._eid_cnx_lock |
219 source = self.source |
220 source = self.source |
220 if self.cnx is None: |
221 if self.cnx is None: |
221 self.cnx = source.get_connection() |
222 self.cnx = source.get_connection() |
222 cnx = self.cnx |
223 cnx = self.cnx |
223 try: |
224 try: |
224 cursor = cnx.cursor() |
225 cursor = cnx.cursor() |
225 for sql in source.dbhelper.sqls_increment_sequence('entities_id_seq'): |
226 for sql in source.dbhelper.sqls_increment_numrange('entities_id_seq', count): |
226 cursor.execute(sql) |
227 cursor.execute(sql) |
227 eid = cursor.fetchone()[0] |
228 eid = cursor.fetchone()[0] |
228 except (source.OperationalError, source.InterfaceError): |
229 except (source.OperationalError, source.InterfaceError): |
229 # FIXME: better detection of deconnection pb |
230 # FIXME: better detection of deconnection pb |
230 source.warning("trying to reconnect create eid connection") |
231 source.warning("trying to reconnect create eid connection") |
231 self.cnx = None |
232 self.cnx = None |
232 return self._create_eid() # pylint: disable=E1102 |
233 return self._create_eid(count) |
233 except source.DbapiError as exc: |
234 except source.DbapiError as exc: |
234 # We get this one with pyodbc and SQL Server when connection was reset |
235 # We get this one with pyodbc and SQL Server when connection was reset |
235 if exc.args[0] == '08S01': |
236 if exc.args[0] == '08S01': |
236 source.warning("trying to reconnect create eid connection") |
237 source.warning("trying to reconnect create eid connection") |
237 self.cnx = None |
238 self.cnx = None |
238 return self._create_eid() # pylint: disable=E1102 |
239 return self._create_eid(count) |
239 else: |
240 else: |
240 raise |
241 raise |
241 except Exception: # WTF? |
242 except Exception: # WTF? |
242 cnx.rollback() |
243 cnx.rollback() |
243 self.cnx = None |
244 self.cnx = None |
256 self.lock = Lock() |
257 self.lock = Lock() |
257 |
258 |
258 def close(self): |
259 def close(self): |
259 pass |
260 pass |
260 |
261 |
261 def create_eid(self, session): |
262 def create_eid(self, session, count=1): |
|
263 assert count > 0 |
262 source = self.source |
264 source = self.source |
263 with self.lock: |
265 with self.lock: |
264 for sql in source.dbhelper.sqls_increment_sequence('entities_id_seq'): |
266 for sql in source.dbhelper.sqls_increment_numrange('entities_id_seq', count): |
265 cursor = source.doexec(session, sql) |
267 cursor = source.doexec(session, sql) |
266 return cursor.fetchone()[0] |
268 return cursor.fetchone()[0] |
267 |
269 |
268 |
270 |
269 class NativeSQLSource(SQLAdapterMixIn, AbstractSource): |
271 class NativeSQLSource(SQLAdapterMixIn, AbstractSource): |
1419 CREATE INDEX tx_relation_actions_txa_action_idx ON tx_relation_actions(txa_action);; |
1421 CREATE INDEX tx_relation_actions_txa_action_idx ON tx_relation_actions(txa_action);; |
1420 CREATE INDEX tx_relation_actions_txa_public_idx ON tx_relation_actions(txa_public);; |
1422 CREATE INDEX tx_relation_actions_txa_public_idx ON tx_relation_actions(txa_public);; |
1421 CREATE INDEX tx_relation_actions_eid_from_idx ON tx_relation_actions(eid_from);; |
1423 CREATE INDEX tx_relation_actions_eid_from_idx ON tx_relation_actions(eid_from);; |
1422 CREATE INDEX tx_relation_actions_eid_to_idx ON tx_relation_actions(eid_to);; |
1424 CREATE INDEX tx_relation_actions_eid_to_idx ON tx_relation_actions(eid_to);; |
1423 CREATE INDEX tx_relation_actions_tx_uuid_idx ON tx_relation_actions(tx_uuid);; |
1425 CREATE INDEX tx_relation_actions_tx_uuid_idx ON tx_relation_actions(tx_uuid);; |
1424 """ % (helper.sql_create_sequence('entities_id_seq').replace(';', ';;'), |
1426 """ % (helper.sql_create_numrange('entities_id_seq').replace(';', ';;'), |
1425 typemap['Datetime'], |
1427 typemap['Datetime'], |
1426 typemap['Boolean'], typemap['Bytes'], typemap['Boolean']) |
1428 typemap['Boolean'], typemap['Bytes'], typemap['Boolean']) |
1427 if helper.backend_name == 'sqlite': |
1429 if helper.backend_name == 'sqlite': |
1428 # sqlite support the ON DELETE CASCADE syntax but do nothing |
1430 # sqlite support the ON DELETE CASCADE syntax but do nothing |
1429 schema += ''' |
1431 schema += ''' |
1443 %s |
1445 %s |
1444 DROP TABLE entities; |
1446 DROP TABLE entities; |
1445 DROP TABLE tx_entity_actions; |
1447 DROP TABLE tx_entity_actions; |
1446 DROP TABLE tx_relation_actions; |
1448 DROP TABLE tx_relation_actions; |
1447 DROP TABLE transactions; |
1449 DROP TABLE transactions; |
1448 """ % helper.sql_drop_sequence('entities_id_seq') |
1450 """ % helper.sql_drop_numrange('entities_id_seq') |
1449 |
1451 |
1450 |
1452 |
1451 def grant_schema(user, set_owner=True): |
1453 def grant_schema(user, set_owner=True): |
1452 result = '' |
1454 result = '' |
1453 for table in ('entities', 'entities_id_seq', |
1455 for table in ('entities', 'entities_id_seq', |