transactionTests method
dynamic
transactionTests()
Implementation
transactionTests() {
group('Transaction', () {
late Cursor cursor;
late Connection otherConnection;
setUp(() async {
connection = await connector.connect(_initDb);
otherConnection = await connector.connect();
cursor = await connection.cursor();
});
tearDown(() async {
await connection.close();
await otherConnection.close();
});
test('autocommit defaults to true', () {
expect(connection.autocommit, true);
});
test('autocommit can be set to false', () async {
expect(connection.autocommit, true);
await connection.setAutocommit(false);
expect(connection.autocommit, false);
});
test('autocommit is true after commit', () async {
expect(connection.autocommit, true);
await connection.setAutocommit(false);
await connection.commit();
expect(connection.autocommit, true);
});
test('autocommit is true after rollback', () async {
expect(connection.autocommit, true);
await connection.setAutocommit(false);
await connection.rollback();
expect(connection.autocommit, true);
});
test('closing connection rolls back open transactions', () async {});
group('on single collection', () {
test('single operation can be commited', () async {
final entity = {
"id": 1,
"name": "first!",
};
await connection.setAutocommit(false);
await cursor.execute(
Insert(userSchema, [entity]),
);
await connection.commit();
await cursor.execute(Query(from: userSchema));
var result = await cursor.fetchone();
expect(result, entity);
});
test('single operation can be rolled back', () async {
final entity = {
"id": 1,
"name": "first!",
};
await connection.setAutocommit(false);
await cursor.execute(
Insert(userSchema, [entity]),
);
await connection.rollback();
await cursor.execute(Query(from: userSchema));
var result = await cursor.fetchone();
expect(result, isNull);
});
test('multiple operations can be commited', () async {
final entity = {
"id": 1,
"name": "first!",
};
final entity2 = {
"id": 2,
"name": "second!",
};
await connection.setAutocommit(false);
await cursor.execute(
Insert(userSchema, [entity]),
);
await cursor.execute(
Insert(userSchema, [entity2]),
);
await connection.commit();
await cursor.execute(Query(from: userSchema));
var results = await cursor.fetchall();
expect(results, hasLength(2));
});
test('multiple operation can be rolled back', () async {
final entity = {
"id": 1,
"name": "first!",
};
final entity2 = {
"id": 2,
"name": "second!",
};
await connection.setAutocommit(false);
await cursor.execute(
Insert(userSchema, [entity]),
);
await cursor.execute(
Insert(userSchema, [entity2]),
);
await connection.rollback();
await cursor.execute(Query(from: userSchema));
var result = await cursor.fetchone();
expect(result, isNull);
});
test('read after write in transaction', () async {
final entity = {
"id": 1,
"name": "first!",
};
await connection.setAutocommit(false);
await cursor.execute(
Insert(userSchema, [entity]),
);
await cursor.execute(Query(from: userSchema));
final fromDb = await cursor.fetchone();
expect(fromDb, entity);
});
test('write in transaction are not visibile in other connections',
() async {
final entity = {
"id": 1,
"name": "first!",
};
await connection.setAutocommit(false);
await cursor.execute(
Insert(userSchema, [entity]),
);
final otherCursor = await otherConnection.cursor();
try {
await otherCursor.execute(Query(from: userSchema));
final result = await otherCursor.fetchall();
expect(result, isEmpty);
} on OperationalError {
// execute/fetchall could fail. If it does so raising OperationalError, it's ok.
// e.g. SQLite in memory takes this branch, while SQLite on file completes without
// exceptions.
// TODO: consider adding non-generic tests for specific behaviour in package:dbapi_sqlite
assert(true);
}
});
});
group('on multiple collections', () {
test('can read from multiple collections', () async {
final user = {
"id": 1,
"name": "first!",
};
final article = {
"id": 1,
"title": "A great article",
};
await cursor.execute(Insert(userSchema, [user]));
await cursor.execute(Insert(articleSchema, [article]));
await connection.setAutocommit(false);
await cursor.execute(Query(from: userSchema));
var dbUser = await cursor.fetchone();
await cursor.execute(Query(from: articleSchema));
var dbArticle = await cursor.fetchone();
await connection.commit();
expect(dbUser, user);
expect(dbArticle, article);
});
test('can write to multiple collections', () async {
final user = {
"id": 1,
"name": "first!",
};
final article = {
"id": 1,
"title": "A great article",
};
await connection.setAutocommit(false);
await cursor.execute(Insert(userSchema, [user]));
await cursor.execute(Insert(articleSchema, [article]));
await connection.commit();
await cursor.execute(Query(from: userSchema));
var dbUser = await cursor.fetchone();
await cursor.execute(Query(from: articleSchema));
var dbArticle = await cursor.fetchone();
expect(dbUser, user);
expect(dbArticle, article);
});
test('can rea and write to multiple collections', () async {
final user = {
"id": 1,
"name": "first!",
};
final article = {
"id": 1,
"title": "A great article",
};
await connection.setAutocommit(false);
await cursor.execute(Insert(userSchema, [user]));
await cursor.execute(Insert(articleSchema, [article]));
await cursor.execute(Query(from: userSchema));
var dbUser = await cursor.fetchone();
await cursor.execute(Query(from: articleSchema));
var dbArticle = await cursor.fetchone();
await connection.commit();
expect(dbUser, user);
expect(dbArticle, article);
});
});
}, skip: requireFeature(DatabaseFeature.transactions));
}