def _populate_results_table(source_conn: ConnectionPlus, target_conn: ConnectionPlus, source_table_name: str, target_table_name: str) -> None: """ Copy over all the entries of the results table """ get_data_query = f""" SELECT * FROM "{source_table_name}" """ source_cursor = source_conn.cursor() target_cursor = target_conn.cursor() for row in source_cursor.execute(get_data_query): column_names = ','.join(row.keys()[1:]) # the first key is "id" values = tuple(val for val in row[1:]) value_placeholders = sql_placeholder_string(len(values)) insert_data_query = f""" INSERT INTO "{target_table_name}" ({column_names}) values {value_placeholders} """ target_cursor.execute(insert_data_query, values)
def test_atomic_on_connection_plus_that_is_in_progress(in_transaction): sqlite_conn = sqlite3.connect(':memory:') conn_plus = ConnectionPlus(sqlite_conn) # explicitly set to True for testing purposes conn_plus.atomic_in_progress = True # implement parametrizing over connection's `in_transaction` attribute if in_transaction: conn_plus.cursor().execute('BEGIN') assert in_transaction is conn_plus.in_transaction isolation_level = conn_plus.isolation_level in_transaction = conn_plus.in_transaction with atomic(conn_plus) as atomic_conn: assert True is conn_plus.atomic_in_progress assert isolation_level == conn_plus.isolation_level assert in_transaction is conn_plus.in_transaction assert True is atomic_conn.atomic_in_progress assert isolation_level == atomic_conn.isolation_level assert in_transaction is atomic_conn.in_transaction assert True is conn_plus.atomic_in_progress assert isolation_level == conn_plus.isolation_level assert in_transaction is conn_plus.in_transaction assert True is atomic_conn.atomic_in_progress assert isolation_level == atomic_conn.isolation_level assert in_transaction is atomic_conn.in_transaction
def test_connection_plus(): sqlite_conn = sqlite3.connect(':memory:') conn_plus = ConnectionPlus(sqlite_conn) assert isinstance(conn_plus, ConnectionPlus) assert isinstance(conn_plus, sqlite3.Connection) assert False is conn_plus.atomic_in_progress match_str = re.escape('Attempted to create `ConnectionPlus` from a ' '`ConnectionPlus` object which is not allowed.') with pytest.raises(ValueError, match=match_str): ConnectionPlus(conn_plus)
def test_atomic_on_outmost_connection_that_is_in_transaction(): conn = ConnectionPlus(sqlite3.connect(':memory:')) conn.execute('BEGIN') assert True is conn.in_transaction match_str = re.escape('SQLite connection has uncommitted transactions. ' 'Please commit those before starting an atomic ' 'transaction.') with pytest.raises(RuntimeError, match=match_str): with atomic(conn): pass
def test_atomic(): sqlite_conn = sqlite3.connect(':memory:') match_str = re.escape('atomic context manager only accepts ConnectionPlus ' 'database connection objects.') with pytest.raises(ValueError, match=match_str): with atomic(sqlite_conn): pass conn_plus = ConnectionPlus(sqlite_conn) assert False is conn_plus.atomic_in_progress atomic_in_progress = conn_plus.atomic_in_progress isolation_level = conn_plus.isolation_level assert False is conn_plus.in_transaction with atomic(conn_plus) as atomic_conn: assert conn_plus_in_transaction(atomic_conn) assert conn_plus_in_transaction(conn_plus) assert isolation_level == conn_plus.isolation_level assert False is conn_plus.in_transaction assert atomic_in_progress is conn_plus.atomic_in_progress assert isolation_level == conn_plus.isolation_level assert False is atomic_conn.in_transaction assert atomic_in_progress is atomic_conn.atomic_in_progress
def test_make_connection_plus_from_connecton_plus(): conn = ConnectionPlus(sqlite3.connect(':memory:')) conn_plus = make_connection_plus_from(conn) assert isinstance(conn_plus, ConnectionPlus) assert conn.atomic_in_progress is conn_plus.atomic_in_progress assert conn_plus is conn
def test_two_nested_atomics(): sqlite_conn = sqlite3.connect(':memory:') conn_plus = ConnectionPlus(sqlite_conn) atomic_in_progress = conn_plus.atomic_in_progress isolation_level = conn_plus.isolation_level assert False is conn_plus.in_transaction with atomic(conn_plus) as atomic_conn_1: assert conn_plus_in_transaction(conn_plus) assert conn_plus_in_transaction(atomic_conn_1) with atomic(atomic_conn_1) as atomic_conn_2: assert conn_plus_in_transaction(conn_plus) assert conn_plus_in_transaction(atomic_conn_1) assert conn_plus_in_transaction(atomic_conn_2) assert conn_plus_in_transaction(conn_plus) assert conn_plus_in_transaction(atomic_conn_1) assert conn_plus_in_transaction(atomic_conn_2) assert conn_plus_is_idle(conn_plus, isolation_level) assert conn_plus_is_idle(atomic_conn_1, isolation_level) assert conn_plus_is_idle(atomic_conn_2, isolation_level) assert atomic_in_progress == conn_plus.atomic_in_progress assert atomic_in_progress == atomic_conn_1.atomic_in_progress assert atomic_in_progress == atomic_conn_2.atomic_in_progress
def path_to_dbfile(conn: ConnectionPlus) -> str: """ Return the path of the database file that the conn object is connected to """ cursor = conn.cursor() cursor.execute("PRAGMA database_list") row = cursor.fetchall()[0] return row[2]
def _rewrite_timestamps(target_conn: ConnectionPlus, target_run_id: int, correct_run_timestamp: float, correct_completed_timestamp: float) -> None: """ Update the timestamp to match the original one """ query = """ UPDATE runs SET run_timestamp = ? WHERE run_id = ? """ cursor = target_conn.cursor() cursor.execute(query, (correct_run_timestamp, target_run_id)) query = """ UPDATE runs SET completed_timestamp = ? WHERE run_id = ? """ cursor = target_conn.cursor() cursor.execute(query, (correct_completed_timestamp, target_run_id))
def test_atomic_transaction(tmp_path): """Test that atomic_transaction works for ConnectionPlus""" dbfile = str(tmp_path / 'temp.db') conn = ConnectionPlus(sqlite3.connect(dbfile)) ctrl_conn = sqlite3.connect(dbfile) sql_create_table = 'CREATE TABLE smth (name TEXT)' sql_table_exists = 'SELECT sql FROM sqlite_master WHERE TYPE = "table"' atomic_transaction(conn, sql_create_table) assert sql_create_table in ctrl_conn.execute( sql_table_exists).fetchall()[0]
def test_atomic_with_exception(): sqlite_conn = sqlite3.connect(':memory:') conn_plus = ConnectionPlus(sqlite_conn) sqlite_conn.execute('PRAGMA user_version(25)') sqlite_conn.commit() assert 25 == sqlite_conn.execute('PRAGMA user_version').fetchall()[0][0] with pytest.raises(RuntimeError, match="Rolling back due to unhandled exception") as e: with atomic(conn_plus) as atomic_conn: atomic_conn.execute('PRAGMA user_version(42)') raise Exception('intended exception') assert error_caused_by(e, 'intended exception') assert 25 == sqlite_conn.execute('PRAGMA user_version').fetchall()[0][0]