-
-
Notifications
You must be signed in to change notification settings - Fork 41
set up Drift database with local data models #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 6 commits
c4e036a
103bb0a
5cb6421
2b3be43
6ecd380
f2360ba
8e4a555
646a438
05119f7
e308066
f463fbf
27d9708
8161cfb
423e2a4
6c4f888
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import 'dart:io'; | ||
| import 'package:drift/drift.dart'; | ||
| import 'package:drift/native.dart'; | ||
| import 'package:path/path.dart' as p; | ||
| import 'package:path_provider/path_provider.dart'; | ||
| import 'package:zplit/core/database/daos/balances_dao.dart'; | ||
|
|
||
| import 'package:zplit/core/database/daos/groups_dao.dart'; | ||
| import 'package:zplit/core/database/daos/transactions_dao.dart'; | ||
| import 'package:zplit/core/database/daos/users_dao.dart'; | ||
|
|
||
| import 'package:zplit/core/database/tables/groups_table.dart'; | ||
|
|
||
| import 'tables/users_table.dart'; | ||
| import 'tables/transactions_table.dart'; | ||
| import 'tables/balances_table.dart'; | ||
|
|
||
| import 'package:uuid/uuid.dart'; | ||
|
|
||
| part 'app_database.g.dart'; | ||
|
|
||
| const _uuid = Uuid(); | ||
|
|
||
| @DriftDatabase( | ||
| tables: [UsersTable, TransactionsTable, BalancesTable, GroupsTable], | ||
| daos: [TransactionsDao, GroupsDao, UsersDao, BalancesDao], | ||
| ) | ||
| class AppDatabase extends _$AppDatabase { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SQLite doesn't enforce foreign keys by default, so the .references() in transactions and balances are currently non-functional |
||
| AppDatabase() : super(_openConnection()); | ||
| AppDatabase.forTesting(QueryExecutor executor) : super(executor); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be AppDatabase.forTesting(super.executor); instead of AppDatabase.forTesting(QueryExecutor executor) : super(executor); |
||
|
|
||
| @override | ||
| int get schemaVersion => 1; | ||
| @override | ||
| MigrationStrategy get migration => MigrationStrategy( | ||
| beforeOpen: (details) async { | ||
| await customStatement('PRAGMA foreign_keys = ON;'); | ||
| }, | ||
| ); | ||
| } | ||
|
|
||
| LazyDatabase _openConnection() { | ||
| return LazyDatabase(() async { | ||
| final dir = await getApplicationDocumentsDirectory(); | ||
| final file = File(p.join(dir.path, 'zplit.sqlite')); | ||
| return NativeDatabase.createInBackground(file); | ||
| }); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import 'package:drift/drift.dart'; | ||
| import 'package:zplit/core/database/tables/balances_table.dart'; | ||
| import 'package:zplit/core/database/app_database.dart'; | ||
|
|
||
| part 'balances_dao.g.dart'; | ||
|
|
||
| @DriftAccessor(tables: [BalancesTable]) | ||
| class BalancesDao extends DatabaseAccessor<AppDatabase> | ||
| with _$BalancesDaoMixin { | ||
| BalancesDao(super.db); | ||
|
|
||
| Future<List<BalancesTableData>> getAll() { | ||
| return select(balancesTable).get(); | ||
| } | ||
|
|
||
| Future<BalancesTableData?> getByPublicKey(String userPublicKey) { | ||
| final query = select(balancesTable); | ||
| query.where((t) => t.userPublicKey.equals(userPublicKey)); | ||
| return query.getSingleOrNull(); | ||
| } | ||
|
|
||
| // we can just use upsert for update and insert | ||
| Future<void> upsert(BalancesTableCompanion balance) { | ||
| return into(balancesTable).insertOnConflictUpdate(balance); | ||
| } | ||
|
|
||
| Future<int> deleteBalances(String userPublicKey) { | ||
| final query = delete(balancesTable); | ||
| query.where((t) => t.userPublicKey.equals(userPublicKey)); | ||
| return query.go(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import 'package:drift/drift.dart'; | ||
| import 'package:zplit/core/database/tables/groups_table.dart'; | ||
| import 'package:zplit/core/database/app_database.dart'; | ||
|
|
||
| part 'groups_dao.g.dart'; | ||
|
|
||
| @DriftAccessor(tables: [GroupsTable]) | ||
| class GroupsDao extends DatabaseAccessor<AppDatabase> with _$GroupsDaoMixin { | ||
| GroupsDao(super.db); | ||
|
|
||
| Future<List<GroupsTableData>> getAll() { | ||
| return select(groupsTable).get(); | ||
| } | ||
|
|
||
| Future<GroupsTableData?> getById(String id) { | ||
| final query = select(groupsTable); | ||
| query.where((t) => t.id.equals(id)); | ||
| return query.getSingleOrNull(); | ||
| } | ||
|
|
||
| Future<void> upsert(GroupsTableCompanion group) { | ||
| return into(groupsTable).insertOnConflictUpdate(group); | ||
| } | ||
|
|
||
| Future<int> deletegroup(String id) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use lower camel case |
||
| final query = delete(groupsTable); | ||
| query.where((t) => t.id.equals(id)); | ||
| return query.go(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import 'package:drift/drift.dart'; | ||
| import 'package:zplit/core/database/tables/transactions_table.dart'; | ||
| import 'package:zplit/core/database/app_database.dart'; | ||
|
|
||
| part 'transactions_dao.g.dart'; | ||
|
|
||
| @DriftAccessor(tables: [TransactionsTable]) | ||
| class TransactionsDao extends DatabaseAccessor<AppDatabase> | ||
| with _$TransactionsDaoMixin { | ||
| TransactionsDao(super.db); | ||
|
|
||
| Future<List<TransactionsTableData>> getAll() { | ||
| return select(transactionsTable).get(); | ||
| } | ||
|
|
||
| Future<TransactionsTableData?> getById(String id) { | ||
| final query = select(transactionsTable); | ||
| query.where((t) => t.id.equals(id)); | ||
| return query.getSingleOrNull(); | ||
| } | ||
|
|
||
| Future<int> insert(TransactionsTableCompanion transaction) { | ||
| return into(transactionsTable).insert(transaction); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import 'package:drift/drift.dart'; | ||
| import 'package:zplit/core/database/tables/users_table.dart'; | ||
| import 'package:zplit/core/database/app_database.dart'; | ||
|
|
||
| part 'users_dao.g.dart'; | ||
|
|
||
| @DriftAccessor(tables: [UsersTable]) | ||
| class UsersDao extends DatabaseAccessor<AppDatabase> with _$UsersDaoMixin { | ||
| UsersDao(super.db); | ||
|
|
||
| Future<List<UsersTableData>> getAll() { | ||
| return select(usersTable).get(); | ||
| } | ||
|
|
||
| Future<UsersTableData?> getByPublicKey(String publicKey) { | ||
| final query = select(usersTable); | ||
| query.where((t) => t.publicKey.equals(publicKey)); | ||
| return query.getSingleOrNull(); | ||
| } | ||
|
|
||
| Future<void> upsert(UsersTableCompanion user) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use lower camel case
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. upsert is already in lower camel case could you clarify what you'd like changed here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this was marked by mistake |
||
| return into(usersTable).insertOnConflictUpdate(user); | ||
| } | ||
|
|
||
| Future<int> deleteUser(String publicKey) { | ||
| final query = delete(usersTable); | ||
| query.where((t) => t.publicKey.equals(publicKey)); | ||
| return query.go(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import 'package:drift/drift.dart'; | ||
| import 'package:zplit/core/database/tables/users_table.dart'; | ||
|
|
||
| class BalancesTable extends Table { | ||
| TextColumn get userPublicKey => text().references(UsersTable, #publicKey)(); | ||
| IntColumn get netAmount => integer()(); | ||
| TextColumn get signed => text().nullable()(); | ||
| DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)(); | ||
|
|
||
| @override | ||
| String get tableName => 'balances'; | ||
|
|
||
| @override | ||
| Set<Column> get primaryKey => {userPublicKey}; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import 'package:drift/drift.dart'; | ||
| import 'package:uuid/uuid.dart'; | ||
|
|
||
| const _uuid = Uuid(); | ||
|
|
||
| class GroupsTable extends Table { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maintain a reference for transaction table to access the transactions in groups, also using a simple FK here will not be a good approach since one group can have multiple transactions |
||
| TextColumn get id => text().clientDefault(() => _uuid.v4())(); | ||
| TextColumn get name => text()(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's still just a string relabeled as set, so no dupe protection ("abc,def,abc" is allowed), no FK integrity (foreign keys can't reach inside a CSV, so the PRAGMA foreign_keys = ON doesn't protect membership), and "which groups is user X in?" are still unindexed and gets false-matches on substrings like (alice matches alice99). Standard fix is a join table, one row per membership, but you can look for better solution as well |
||
| // storing member public keys as a set (comma separated string) | ||
| TextColumn get users => text().withDefault(const Constant(''))(); | ||
| TextColumn get description => text().nullable()(); | ||
|
|
||
| @override | ||
| String get tableName => 'groups'; | ||
|
|
||
| @override | ||
| Set<Column> get primaryKey => {id}; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| import 'package:drift/drift.dart'; | ||
| import 'package:zplit/core/database/tables/users_table.dart'; | ||
|
|
||
| enum TransactionStatus { unsigned, partiallySigned, signed } | ||
|
|
||
| class TransactionsTable extends Table { | ||
| TextColumn get id => text()(); | ||
| TextColumn get fromUserPublicKey => | ||
| text().references(UsersTable, #publicKey)(); | ||
| TextColumn get toUserPublicKey => text().references(UsersTable, #publicKey)(); | ||
| Int64Column get amount => int64()(); | ||
| TextColumn get description => text().nullable()(); | ||
| TextColumn get tag => text().nullable()(); | ||
| TextColumn get status => textEnum<TransactionStatus>()(); | ||
| DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); | ||
| TextColumn get senderSignature => text().nullable()(); | ||
| TextColumn get receiverSignature => text().nullable()(); | ||
|
|
||
| @override | ||
| String get tableName => 'transactions'; | ||
|
|
||
| @override | ||
| Set<Column> get primaryKey => {id}; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import 'package:drift/drift.dart'; | ||
|
|
||
| class UsersTable extends Table { | ||
| TextColumn get publicKey => text()(); | ||
| TextColumn get displayName => text()(); | ||
| TextColumn get cryptoAddress => text().nullable()(); | ||
| TextColumn get profilePicture => text().nullable()(); | ||
|
|
||
| @override | ||
| String get tableName => 'users'; | ||
|
|
||
| @override | ||
| Set<Column> get primaryKey => {publicKey}; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scope (issue #47) lists 5 tables it's missing WalletDetailsTable
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually i discussed with the mentors and turns out we no longer need that table and i also modified the initial issue template
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay