cyberhybridhub/server/lib/trading/trading_config_db.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>;
}
}