Initial commit: IBKRTrader
.NET WinForms-Anwendung (Core, Modules/CongressTrading, UI). Enthaelt .gitignore und settings.example.json als Konfigurationsvorlage. Echte settings.json mit Zugangsdaten ist bewusst ausgeschlossen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
using IBKRTrader.Core.Database;
|
||||
using IBKRTrader.Core.Logging;
|
||||
|
||||
namespace IBKRTrader.Modules.CongressTrading.Database;
|
||||
|
||||
/// <summary>
|
||||
/// Legt die ct_xxx-Tabellen idempotent an.
|
||||
/// Namensschema: ct_{tabellenname} gemäß Architekturregeln.
|
||||
/// </summary>
|
||||
public class CongressMigrations
|
||||
{
|
||||
private readonly DatabaseService _db;
|
||||
private readonly LoggingService _logger;
|
||||
|
||||
public CongressMigrations(DatabaseService db, LoggingService logger)
|
||||
{
|
||||
_db = db;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task RunAsync()
|
||||
{
|
||||
_logger.Info("CT", "Starte CongressTrading-Datenbankmigrationen...");
|
||||
await CreateCongressMemberTableAsync();
|
||||
await CreateCongressTradeTableAsync();
|
||||
_logger.Info("CT", "CongressTrading-Migrationen abgeschlossen.");
|
||||
}
|
||||
|
||||
private Task CreateCongressMemberTableAsync() => _db.ExecuteAsync(@"
|
||||
CREATE TABLE IF NOT EXISTS `ct_congressMember` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
`bio_id` VARCHAR(20) NOT NULL UNIQUE,
|
||||
`name` VARCHAR(200),
|
||||
`party` VARCHAR(50),
|
||||
`state` VARCHAR(50),
|
||||
`chamber` VARCHAR(10),
|
||||
`profile_url` VARCHAR(500),
|
||||
`first_seen` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`last_updated` DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX `idx_bio_id` (`bio_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||
|
||||
private async Task CreateCongressTradeTableAsync()
|
||||
{
|
||||
// Tabelle anlegen
|
||||
await _db.ExecuteAsync(@"
|
||||
CREATE TABLE IF NOT EXISTS `ct_trade` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
`trade_id` VARCHAR(20) NOT NULL UNIQUE,
|
||||
`member_bio_id` VARCHAR(20) NOT NULL,
|
||||
`issuer_name` VARCHAR(500),
|
||||
`issuer_id` VARCHAR(20),
|
||||
`ticker` VARCHAR(20),
|
||||
`trade_type` VARCHAR(50),
|
||||
`chamber` VARCHAR(20),
|
||||
`owner` VARCHAR(50),
|
||||
`value` DECIMAL(18,2),
|
||||
`size_range_low` BIGINT,
|
||||
`size_range_high` BIGINT,
|
||||
`trade_date` DATE,
|
||||
`published_date` DATE,
|
||||
`detail_url` VARCHAR(500),
|
||||
`details_fetched` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`scraped_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX `idx_member` (`member_bio_id`),
|
||||
INDEX `idx_trade_date` (`trade_date`),
|
||||
INDEX `idx_ticker` (`ticker`),
|
||||
INDEX `idx_details` (`details_fetched`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
|
||||
|
||||
// Idempotente Spalten-Migrationen (für bestehende DBs)
|
||||
await _db.ExecuteAsync("ALTER TABLE `ct_trade` ADD COLUMN IF NOT EXISTS `details_fetched` TINYINT(1) NOT NULL DEFAULT 1;");
|
||||
await _db.ExecuteAsync("ALTER TABLE `ct_trade` ADD COLUMN IF NOT EXISTS `chamber` VARCHAR(20);");
|
||||
await _db.ExecuteAsync("ALTER TABLE `ct_trade` ADD COLUMN IF NOT EXISTS `owner` VARCHAR(50);");
|
||||
await _db.ExecuteAsync("ALTER TABLE `ct_trade` ADD COLUMN IF NOT EXISTS `value` DECIMAL(18,2);");
|
||||
await _db.ExecuteAsync("ALTER TABLE `ct_trade` ADD INDEX IF NOT EXISTS `idx_details` (`details_fetched`);");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user