Skip to content

Commit 8b52d96

Browse files
committed
Add connectors for resources
1 parent f7ae613 commit 8b52d96

File tree

14 files changed

+403
-255
lines changed

14 files changed

+403
-255
lines changed

api/lib/models/note/database.dart

Lines changed: 102 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,23 @@
11
import 'dart:async';
22

33
import 'package:collection/collection.dart';
4+
import 'package:flow_api/models/label/model.dart';
5+
import 'package:flow_api/models/note/label.dart';
46
import 'dart:typed_data';
57
import 'package:flow_api/models/note/service.dart';
68
import 'package:flow_api/services/database.dart';
79
import 'package:sqflite_common/sqlite_api.dart';
810

911
import 'model.dart';
1012

11-
abstract class NoteDatabaseConnector<T> extends NoteConnector<T>
12-
with TableService {
13-
String get tableName;
14-
String get connectedTableName;
15-
String get connectedIdName;
16-
17-
T decode(Map<String, dynamic> data);
18-
13+
abstract class NoteDatabaseConnector<T> extends DatabaseModelConnector
14+
implements NoteConnector<T> {
1915
@override
20-
Future<void> create(Database db) async {
21-
await db.execute("""
22-
CREATE TABLE IF NOT EXISTS $tableName (
23-
noteId BLOB(16) NOT NULL,
24-
$connectedIdName BLOB(16) NOT NULL,
25-
PRIMARY KEY ($connectedIdName, noteId),
26-
FOREIGN KEY ($connectedIdName) REFERENCES $connectedTableName(id) ON DELETE CASCADE,
27-
FOREIGN KEY (noteId) REFERENCES notes(id) ON DELETE CASCADE
28-
)
29-
""");
30-
}
31-
16+
String get itemIdName => 'noteId';
3217
@override
33-
Future<void> connect(Uint8List connectId, Uint8List noteId) async {
34-
if (await isNoteConnected(connectId, noteId)) return;
35-
await db?.insert(tableName, {
36-
'noteId': noteId,
37-
connectedIdName: connectId,
38-
});
39-
}
18+
String get itemTableName => 'notes';
4019

41-
@override
42-
Future<void> disconnect(Uint8List connectId, Uint8List noteId) async {
43-
await db?.delete(
44-
tableName,
45-
where: 'noteId = ? AND $connectedIdName = ?',
46-
whereArgs: [noteId, connectId],
47-
);
48-
}
20+
T decode(Map<String, dynamic> data);
4921

5022
@override
5123
Future<List<Note>> getNotes(Uint8List connectId,
@@ -88,16 +60,6 @@ abstract class NoteDatabaseConnector<T> extends NoteConnector<T>
8860
return result?.map(decode).toList() ?? [];
8961
}
9062

91-
@override
92-
Future<bool> isNoteConnected(Uint8List connectId, Uint8List noteId) async {
93-
final result = await db?.query(
94-
tableName,
95-
where: 'noteId = ? AND $connectedIdName = ?',
96-
whereArgs: [noteId, connectId],
97-
);
98-
return result?.isNotEmpty == true;
99-
}
100-
10163
@override
10264
Future<bool?> notesDone(Uint8List connectId) async {
10365
final result = await db?.rawQuery(
@@ -311,3 +273,98 @@ LIMIT 1;""",
311273
1;
312274
}
313275
}
276+
277+
class LabelNoteDatabaseConnector extends NoteDatabaseConnector<Label>
278+
implements LabelNoteConnector {
279+
@override
280+
String get connectedIdName => "labelId";
281+
282+
@override
283+
String get connectedTableName => "labels";
284+
285+
@override
286+
String get tableName => "labelNotes";
287+
288+
@override
289+
Future<List<Note>> getNotes(
290+
Uint8List connectId, {
291+
int offset = 0,
292+
int limit = 50,
293+
Uint8List? parent,
294+
Uint8List? notebook,
295+
Set<NoteStatus?> statuses = const {
296+
NoteStatus.todo,
297+
NoteStatus.inProgress,
298+
NoteStatus.done,
299+
null
300+
},
301+
String search = '',
302+
}) async {
303+
String? where;
304+
List<Object> whereArgs = [];
305+
if (search.isNotEmpty) {
306+
where = '(name LIKE ? OR description LIKE ?)';
307+
whereArgs = ['%$search%', '%$search%'];
308+
}
309+
if (parent != null) {
310+
if (parent.isNotEmpty) {
311+
where = where == null ? 'parentId = ?' : '$where AND parentId = ?';
312+
whereArgs.add(parent);
313+
} else {
314+
where =
315+
where == null ? 'parentId IS NULL' : '$where AND parentId IS NULL';
316+
}
317+
}
318+
if (notebook != null) {
319+
if (notebook.isNotEmpty) {
320+
where = where == null ? 'notebookId = ?' : '$where AND notebookId = ?';
321+
whereArgs.add(notebook);
322+
} else {
323+
where = where == null
324+
? 'notebookId IS NULL'
325+
: '$where AND notebookId IS NULL';
326+
}
327+
}
328+
var statusStatement =
329+
"status IN (${statuses.nonNulls.map((e) => "'${e.name}'").join(',')})";
330+
if (statuses.contains(null)) {
331+
statusStatement = "$statusStatement OR status IS NULL";
332+
}
333+
where =
334+
where == null ? '($statusStatement)' : '$where AND ($statusStatement)';
335+
final result = await db?.query(
336+
'$tableName JOIN notes ON notes.id = noteId',
337+
where: '$where AND $connectedIdName = ?',
338+
whereArgs: [...whereArgs, connectId],
339+
columns: [
340+
'notes.id AS noteid',
341+
'notes.name AS notename',
342+
'notes.description AS notedescription',
343+
'notes.status AS notestatus',
344+
'notes.priority AS notepriority',
345+
'notes.parentId AS noteparentId',
346+
],
347+
offset: offset,
348+
limit: limit,
349+
);
350+
return result
351+
?.map((e) => Map.fromEntries(e.entries
352+
.where((element) => element.key.startsWith('note'))
353+
.map((e) => MapEntry(e.key.substring('note'.length), e.value))))
354+
.map((e) {
355+
return Note.fromDatabase(e);
356+
}).toList() ??
357+
[];
358+
}
359+
360+
@override
361+
FutureOr<void> migrate(Database db, int version) async {
362+
if (version < 2) {
363+
await create(db);
364+
}
365+
return super.migrate(db, version);
366+
}
367+
368+
@override
369+
Label decode(Map<String, dynamic> data) => Label.fromDatabase(data);
370+
}

api/lib/models/note/label.dart

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ import 'dart:async';
33
import 'dart:typed_data';
44
import 'package:flow_api/models/label/model.dart';
55

6-
import 'package:flow_api/models/note/database.dart';
7-
import 'package:sqflite_common/sqlite_api.dart';
8-
96
import 'model.dart';
107
import 'service.dart';
118

@@ -26,98 +23,3 @@ abstract class LabelNoteConnector extends NoteConnector<Label> {
2623
String search = '',
2724
});
2825
}
29-
30-
class LabelNoteDatabaseConnector extends NoteDatabaseConnector<Label>
31-
implements LabelNoteConnector {
32-
@override
33-
String get connectedIdName => "labelId";
34-
35-
@override
36-
String get connectedTableName => "labels";
37-
38-
@override
39-
String get tableName => "labelNotes";
40-
41-
@override
42-
Future<List<Note>> getNotes(
43-
Uint8List connectId, {
44-
int offset = 0,
45-
int limit = 50,
46-
Uint8List? parent,
47-
Uint8List? notebook,
48-
Set<NoteStatus?> statuses = const {
49-
NoteStatus.todo,
50-
NoteStatus.inProgress,
51-
NoteStatus.done,
52-
null
53-
},
54-
String search = '',
55-
}) async {
56-
String? where;
57-
List<Object> whereArgs = [];
58-
if (search.isNotEmpty) {
59-
where = '(name LIKE ? OR description LIKE ?)';
60-
whereArgs = ['%$search%', '%$search%'];
61-
}
62-
if (parent != null) {
63-
if (parent.isNotEmpty) {
64-
where = where == null ? 'parentId = ?' : '$where AND parentId = ?';
65-
whereArgs.add(parent);
66-
} else {
67-
where =
68-
where == null ? 'parentId IS NULL' : '$where AND parentId IS NULL';
69-
}
70-
}
71-
if (notebook != null) {
72-
if (notebook.isNotEmpty) {
73-
where = where == null ? 'notebookId = ?' : '$where AND notebookId = ?';
74-
whereArgs.add(notebook);
75-
} else {
76-
where = where == null
77-
? 'notebookId IS NULL'
78-
: '$where AND notebookId IS NULL';
79-
}
80-
}
81-
var statusStatement =
82-
"status IN (${statuses.nonNulls.map((e) => "'${e.name}'").join(',')})";
83-
if (statuses.contains(null)) {
84-
statusStatement = "$statusStatement OR status IS NULL";
85-
}
86-
where =
87-
where == null ? '($statusStatement)' : '$where AND ($statusStatement)';
88-
final result = await db?.query(
89-
'$tableName JOIN notes ON notes.id = noteId',
90-
where: '$where AND $connectedIdName = ?',
91-
whereArgs: [...whereArgs, connectId],
92-
columns: [
93-
'notes.id AS noteid',
94-
'notes.name AS notename',
95-
'notes.description AS notedescription',
96-
'notes.status AS notestatus',
97-
'notes.priority AS notepriority',
98-
'notes.parentId AS noteparentId',
99-
],
100-
offset: offset,
101-
limit: limit,
102-
);
103-
return result
104-
?.map((e) => Map.fromEntries(e.entries
105-
.where((element) => element.key.startsWith('note'))
106-
.map((e) => MapEntry(e.key.substring('note'.length), e.value))))
107-
.map((e) {
108-
return Note.fromDatabase(e);
109-
}).toList() ??
110-
[];
111-
}
112-
113-
@override
114-
FutureOr<void> migrate(Database db, int version) async {
115-
if (version < 2) {
116-
await create(db);
117-
}
118-
return super.migrate(db, version);
119-
}
120-
121-
@override
122-
Label decode(Map<String, dynamic> data) => Label.fromDatabase(data);
123-
}

api/lib/models/note/service.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ abstract class NoteService extends ModelService {
4343
FutureOr<Notebook?> getNotebook(Uint8List id);
4444
}
4545

46-
abstract class NoteConnector<T> extends ModelService {
47-
FutureOr<void> connect(Uint8List connectId, Uint8List noteId);
48-
FutureOr<void> disconnect(Uint8List connectId, Uint8List noteId);
46+
abstract class NoteConnector<T> extends ModelConnector {
4947
FutureOr<List<Note>> getNotes(
5048
Uint8List connectId, {
5149
int offset = 0,
@@ -56,6 +54,5 @@ abstract class NoteConnector<T> extends ModelService {
5654
int offset = 0,
5755
int limit = 50,
5856
});
59-
FutureOr<bool> isNoteConnected(Uint8List connectId, Uint8List noteId);
6057
FutureOr<bool?> notesDone(Uint8List connectId);
6158
}

api/lib/models/resource/database.dart

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class ResourceDatabaseService extends ResourceService with TableService {
2323

2424
@override
2525
FutureOr<void> migrate(Database db, int version) async {
26-
if (version < 5) {
26+
if (version < 4) {
2727
await db.execute("ALTER TABLE places RENAME TO resources");
2828
}
2929
}
@@ -89,3 +89,53 @@ class ResourceDatabaseService extends ResourceService with TableService {
8989
await db?.delete('resources');
9090
}
9191
}
92+
93+
abstract class ResourceDatabaseConnector<T> extends DatabaseModelConnector
94+
implements ResourceConnector<T> {
95+
@override
96+
String get itemIdName => 'resourceId';
97+
@override
98+
String get itemTableName => 'resources';
99+
100+
T decode(Map<String, dynamic> data);
101+
102+
@override
103+
Future<List<Resource>> getResources(Uint8List connectId,
104+
{int offset = 0, int limit = 50}) async {
105+
final result = await db?.query(
106+
'$tableName JOIN resources ON resources.id = resourceId',
107+
where: '$connectedIdName = ?',
108+
whereArgs: [connectId],
109+
columns: [
110+
'resources.id AS resourceid',
111+
'resources.name AS resourcename',
112+
'resources.description AS resourcedescription',
113+
'resources.address AS resourceaddress',
114+
],
115+
offset: offset,
116+
limit: limit,
117+
);
118+
return result
119+
?.map((e) => Map.fromEntries(e.entries
120+
.where((element) => element.key.startsWith('resource'))
121+
.map((e) =>
122+
MapEntry(e.key.substring('resource'.length), e.value))))
123+
.map((e) {
124+
return Resource.fromDatabase(e);
125+
}).toList() ??
126+
[];
127+
}
128+
129+
@override
130+
Future<List<T>> getConnected(Uint8List noteId,
131+
{int offset = 0, int limit = 50}) async {
132+
final result = await db?.query(
133+
'$tableName JOIN resources ON resources.id = resourceId',
134+
where: 'noteId = ?',
135+
whereArgs: [noteId],
136+
offset: offset,
137+
limit: limit,
138+
);
139+
return result?.map(decode).toList() ?? [];
140+
}
141+
}

api/lib/models/resource/event.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import 'dart:async';
2+
3+
import 'package:flow_api/models/event/model.dart';
4+
import 'package:flow_api/models/resource/database.dart';
5+
import 'package:sqflite_common/sqlite_api.dart';
6+
7+
class EventResourceDatabaseConnector extends ResourceDatabaseConnector<Event> {
8+
@override
9+
String get connectedIdName => "eventId";
10+
11+
@override
12+
String get connectedTableName => "events";
13+
14+
@override
15+
String get tableName => "eventResources";
16+
17+
@override
18+
Event decode(Map<String, dynamic> data) => Event.fromDatabase(data);
19+
20+
@override
21+
Future<void> migrate(Database db, int version) async {
22+
if (version < 4) {
23+
await create(db);
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)