79 lines
2.2 KiB
Dart
79 lines
2.2 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:postgres/postgres.dart';
|
|
|
|
import 'question_source_preferences.dart';
|
|
|
|
class QuestionSourcePreferencesDb {
|
|
QuestionSourcePreferencesDb(this._connection);
|
|
|
|
final Connection _connection;
|
|
|
|
Future<List<ResolvedQuestionSourcePreference>> getResolved(
|
|
String firebaseUid,
|
|
) async {
|
|
final List<Map<String, dynamic>>? stored = await _readStored(firebaseUid);
|
|
return QuestionSourcePreferences.mergeStored(stored);
|
|
}
|
|
|
|
Future<bool> isSourceEnabled(String firebaseUid, String sourceId) async {
|
|
final List<ResolvedQuestionSourcePreference> resolved =
|
|
await getResolved(firebaseUid);
|
|
return QuestionSourcePreferences.isEnabled(resolved, sourceId);
|
|
}
|
|
|
|
Future<List<ResolvedQuestionSourcePreference>> save(
|
|
String firebaseUid,
|
|
List<Map<String, dynamic>> stored,
|
|
) async {
|
|
final DateTime updatedAt = DateTime.now().toUtc();
|
|
await _connection.execute(
|
|
Sql.named(
|
|
'''
|
|
INSERT INTO users (firebase_uid, question_source_preferences, updated_at)
|
|
VALUES (@uid, @preferences::jsonb, @updated_at)
|
|
ON CONFLICT (firebase_uid) DO UPDATE SET
|
|
question_source_preferences = EXCLUDED.question_source_preferences,
|
|
updated_at = EXCLUDED.updated_at
|
|
''',
|
|
),
|
|
parameters: <String, dynamic>{
|
|
'uid': firebaseUid,
|
|
'preferences': jsonEncode(stored),
|
|
'updated_at': updatedAt,
|
|
},
|
|
);
|
|
return QuestionSourcePreferences.mergeStored(stored);
|
|
}
|
|
|
|
Future<List<Map<String, dynamic>>?> _readStored(String firebaseUid) async {
|
|
final Result result = await _connection.execute(
|
|
Sql.named(
|
|
'''
|
|
SELECT question_source_preferences
|
|
FROM users
|
|
WHERE firebase_uid = @uid
|
|
''',
|
|
),
|
|
parameters: <String, dynamic>{'uid': firebaseUid},
|
|
);
|
|
if (result.isEmpty) {
|
|
return null;
|
|
}
|
|
final Object? value = result.first[0];
|
|
if (value == null) {
|
|
return null;
|
|
}
|
|
if (value is List<dynamic>) {
|
|
return value.cast<Map<String, dynamic>>();
|
|
}
|
|
if (value is String) {
|
|
final Object? decoded = jsonDecode(value);
|
|
if (decoded is List<dynamic>) {
|
|
return decoded.cast<Map<String, dynamic>>();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|