import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart' as p; import '../models/track.dart'; /// SQLite adatbázis-réteg a nyomvonalakhoz. /// Singleton — [TrackDatabase.instance]-on keresztül érhető el. class TrackDatabase { TrackDatabase._(); static final instance = TrackDatabase._(); static Database? _db; Future get database async { _db ??= await _open(); return _db!; } Future _open() async { final dbPath = p.join(await getDatabasesPath(), 'tracks.db'); return openDatabase( dbPath, version: 1, onCreate: _onCreate, ); } Future _onCreate(Database db, int version) async { await db.execute(''' CREATE TABLE tracks ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, start_time TEXT NOT NULL, end_time TEXT, status TEXT NOT NULL DEFAULT 'recording', source TEXT NOT NULL DEFAULT 'Telefon GPS', distance_meters REAL NOT NULL DEFAULT 0, point_count INTEGER NOT NULL DEFAULT 0 ) '''); await db.execute(''' CREATE TABLE track_points ( id INTEGER PRIMARY KEY AUTOINCREMENT, track_id INTEGER NOT NULL REFERENCES tracks(id) ON DELETE CASCADE, latitude REAL NOT NULL, longitude REAL NOT NULL, altitude REAL, accuracy REAL, speed REAL, heading REAL, timestamp TEXT NOT NULL ) '''); await db.execute( 'CREATE INDEX idx_tp_track ON track_points(track_id, timestamp)'); } // ─── Tracks CRUD ─────────────────────────────────────────────────────────── Future insertTrack(Track track) async { final db = await database; return db.insert('tracks', track.toMap()); } Future updateTrack(Track track) async { final db = await database; await db.update('tracks', track.toMap(), where: 'id = ?', whereArgs: [track.id]); } Future deleteTrack(int id) async { final db = await database; await db.delete('tracks', where: 'id = ?', whereArgs: [id]); } Future> listTracks() async { final db = await database; final rows = await db.query('tracks', orderBy: 'start_time DESC'); return rows.map(Track.fromMap).toList(); } Future getTrack(int id) async { final db = await database; final rows = await db.query('tracks', where: 'id = ?', whereArgs: [id], limit: 1); return rows.isEmpty ? null : Track.fromMap(rows.first); } // ─── TrackPoints ─────────────────────────────────────────────────────────── /// Egyetlen pont hozzáadása + track statisztikák atomi frissítése. Future addPoint(TrackPoint point, double newDistance) async { final db = await database; await db.transaction((txn) async { await txn.insert('track_points', point.toMap()); await txn.rawUpdate(''' UPDATE tracks SET distance_meters = ?, point_count = point_count + 1 WHERE id = ? ''', [newDistance, point.trackId]); }); } Future> getPoints(int trackId) async { final db = await database; final rows = await db.query( 'track_points', where: 'track_id = ?', whereArgs: [trackId], orderBy: 'timestamp ASC', ); return rows.map(TrackPoint.fromMap).toList(); } /// Csak a koordinátákat adja vissza — a térkép polyline-hoz elég. Future> getLatLons(int trackId) async { final db = await database; final rows = await db.query( 'track_points', columns: ['latitude', 'longitude'], where: 'track_id = ?', whereArgs: [trackId], orderBy: 'timestamp ASC', ); return rows .map((r) => (lat: r['latitude'] as double, lon: r['longitude'] as double)) .toList(); } }