102 lines
2.8 KiB
Dart
102 lines
2.8 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:postgres/postgres.dart';
|
|
|
|
import 'trading_config.dart';
|
|
|
|
/// Loads and merges [trading_config_templates] with [user_trading_config].
|
|
class TradingConfigDb {
|
|
TradingConfigDb(this._connection);
|
|
|
|
final Connection _connection;
|
|
|
|
Future<EffectiveTradingConfig?> resolveEffectiveConfig(String firebaseUid) async {
|
|
final Result result = await _connection.execute(
|
|
Sql.named(
|
|
'''
|
|
SELECT utc.template_name, utc.config, utc.enabled
|
|
FROM user_trading_config utc
|
|
WHERE utc.firebase_uid = @uid
|
|
''',
|
|
),
|
|
parameters: <String, dynamic>{'uid': firebaseUid},
|
|
);
|
|
if (result.isEmpty) {
|
|
return null;
|
|
}
|
|
|
|
final ResultRow row = result.first;
|
|
final String? templateName = row[0] as String?;
|
|
final Map<String, dynamic> userConfig = _readJsonMap(row[1]);
|
|
final bool userEnabled = row[2]! as bool;
|
|
|
|
Map<String, dynamic> merged = userConfig;
|
|
if (templateName != null && templateName.isNotEmpty) {
|
|
final Map<String, dynamic>? templateConfig =
|
|
await _loadTemplateConfig(templateName);
|
|
if (templateConfig != null) {
|
|
merged = EffectiveTradingConfig.mergeJson(templateConfig, userConfig);
|
|
}
|
|
}
|
|
|
|
return EffectiveTradingConfig.fromJson(
|
|
merged,
|
|
templateName: templateName,
|
|
userEnabled: userEnabled,
|
|
);
|
|
}
|
|
|
|
Future<void> upsertUserConfig({
|
|
required String firebaseUid,
|
|
String? templateName,
|
|
Map<String, dynamic> config = const <String, dynamic>{},
|
|
bool enabled = false,
|
|
}) async {
|
|
await _connection.execute(
|
|
Sql.named(
|
|
'''
|
|
INSERT INTO user_trading_config (firebase_uid, template_name, config, enabled)
|
|
VALUES (@uid, @template_name, @config::jsonb, @enabled)
|
|
ON CONFLICT (firebase_uid) DO UPDATE SET
|
|
template_name = EXCLUDED.template_name,
|
|
config = EXCLUDED.config,
|
|
enabled = EXCLUDED.enabled,
|
|
updated_at = now()
|
|
''',
|
|
),
|
|
parameters: <String, dynamic>{
|
|
'uid': firebaseUid,
|
|
'template_name': templateName,
|
|
'config': jsonEncode(config),
|
|
'enabled': enabled,
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<Map<String, dynamic>?> _loadTemplateConfig(String name) async {
|
|
final Result result = await _connection.execute(
|
|
Sql.named(
|
|
'SELECT config FROM trading_config_templates WHERE name = @name',
|
|
),
|
|
parameters: <String, dynamic>{'name': name},
|
|
);
|
|
if (result.isEmpty) {
|
|
return null;
|
|
}
|
|
return _readJsonMap(result.first[0]);
|
|
}
|
|
|
|
Map<String, dynamic> _readJsonMap(Object? value) {
|
|
if (value is Map<String, dynamic>) {
|
|
return value;
|
|
}
|
|
if (value is Map) {
|
|
return Map<String, dynamic>.from(value);
|
|
}
|
|
if (value == null) {
|
|
return <String, dynamic>{};
|
|
}
|
|
return jsonDecode(value.toString()) as Map<String, dynamic>;
|
|
}
|
|
}
|