Rename all OPDS-prefixed models to generic names (Server, Feed, Entry, Link, StreamLink), expand the ServerSoftware interface to cover all server interactions, and implement a full Kavita REST API client that replaces the OPDS delegation. - Rename OPDS* models to generic names across ~60 files - Add database migrations 13 (opds_id → entry_id) and 14 (unify credentials) - Create OPDSServerSoftware wrapping existing OPDS services - Create KavitaApiClient for direct Kavita REST API calls - Create KavitaFeedMapper to convert Kavita JSON to Feed/Entry models - Rewrite KavitaServerSoftware to use native API (no OPDS delegation) - Unify server credentials (remove softwareUsername/softwarePassword) - Simplify add/edit server UI to single auth section - Add test connection button to server add/edit screens - Add progress indicator to PublicationCard using local and server data - Eliminate softwareType branching in reader screens - Add EntryProgress and fetchEntryProgress to ServerSoftware interface - Fix Entry.acquisitionLink crash on empty links - Add 59 new tests covering models, services, and providers
104 lines
2.7 KiB
Dart
104 lines
2.7 KiB
Dart
import 'package:sqflite/sqflite.dart';
|
|
import 'package:worldhopper/database/database.dart';
|
|
import 'package:worldhopper/database/tables/servers_table.dart';
|
|
import 'package:worldhopper/models/server.dart';
|
|
|
|
/// Repository for managing OPDS server data
|
|
class ServerRepository {
|
|
final DatabaseHelper _dbHelper;
|
|
|
|
ServerRepository({DatabaseHelper? dbHelper})
|
|
: _dbHelper = dbHelper ?? DatabaseHelper.instance;
|
|
|
|
/// Get database instance
|
|
Future<Database> get _db async => await _dbHelper.database;
|
|
|
|
/// Get all servers ordered by name
|
|
Future<List<Server>> getAllServers() async {
|
|
final db = await _db;
|
|
final List<Map<String, dynamic>> maps = await db.query(
|
|
ServersTable.tableName,
|
|
orderBy: 'name ASC',
|
|
);
|
|
|
|
return List.generate(maps.length, (i) {
|
|
return Server.fromDatabase(maps[i]);
|
|
});
|
|
}
|
|
|
|
/// Get a server by ID
|
|
Future<Server?> getServer(String id) async {
|
|
final db = await _db;
|
|
final List<Map<String, dynamic>> maps = await db.query(
|
|
ServersTable.tableName,
|
|
where: 'id = ?',
|
|
whereArgs: [id],
|
|
);
|
|
|
|
if (maps.isEmpty) return null;
|
|
return Server.fromDatabase(maps.first);
|
|
}
|
|
|
|
/// Add a new server
|
|
Future<void> addServer(Server server) async {
|
|
final db = await _db;
|
|
await db.insert(
|
|
ServersTable.tableName,
|
|
server.toDatabase(),
|
|
conflictAlgorithm: ConflictAlgorithm.replace,
|
|
);
|
|
}
|
|
|
|
/// Update an existing server
|
|
Future<void> updateServer(Server server) async {
|
|
final db = await _db;
|
|
await db.update(
|
|
ServersTable.tableName,
|
|
server.toDatabase(),
|
|
where: 'id = ?',
|
|
whereArgs: [server.id],
|
|
);
|
|
}
|
|
|
|
/// Delete a server by ID
|
|
Future<void> deleteServer(String id) async {
|
|
final db = await _db;
|
|
await db.delete(
|
|
ServersTable.tableName,
|
|
where: 'id = ?',
|
|
whereArgs: [id],
|
|
);
|
|
}
|
|
|
|
/// Update the last synced timestamp for a server
|
|
Future<void> updateLastSynced(String id, DateTime timestamp) async {
|
|
final db = await _db;
|
|
await db.update(
|
|
ServersTable.tableName,
|
|
{'last_synced_at': timestamp.millisecondsSinceEpoch},
|
|
where: 'id = ?',
|
|
whereArgs: [id],
|
|
);
|
|
}
|
|
|
|
/// Check if a server with the given URL already exists
|
|
Future<bool> serverExists(String url) async {
|
|
final db = await _db;
|
|
final List<Map<String, dynamic>> maps = await db.query(
|
|
ServersTable.tableName,
|
|
where: 'url = ?',
|
|
whereArgs: [url],
|
|
);
|
|
|
|
return maps.isNotEmpty;
|
|
}
|
|
|
|
/// Get server count
|
|
Future<int> getServerCount() async {
|
|
final db = await _db;
|
|
final result = await db.rawQuery(
|
|
'SELECT COUNT(*) as count FROM ${ServersTable.tableName}',
|
|
);
|
|
return Sqflite.firstIntValue(result) ?? 0;
|
|
}
|
|
}
|