Line data Source code
1 : import 'dart:async';
2 :
3 : import 'package:drift/drift.dart';
4 : import 'package:injectable/injectable.dart';
5 : import 'package:logging/logging.dart';
6 : import 'package:network_tools/network_tools.dart';
7 : import 'package:network_tools/src/database/database_service.dart';
8 : import 'package:network_tools/src/database/drift_database.dart';
9 : import 'package:network_tools/src/device_info/arp_table_helper.dart';
10 : import 'package:network_tools/src/repository/repository.dart';
11 :
12 : @Injectable(as: Repository<ARPData>)
13 : class ARPRepository implements Repository<ARPData> {
14 2 : const ARPRepository(this._database);
15 :
16 6 : static final arpDriftLogger = Logger("arp-drift-logger");
17 : final DatabaseService<AppDatabase> _database;
18 :
19 2 : @override
20 : Future<void> build() async {
21 4 : final database = await _database.open();
22 2 : final oldEntries = await this.entries();
23 2 : if (oldEntries.isNotEmpty) {
24 4 : arpDriftLogger.fine("Skipping ARP table build, old entries found");
25 : return;
26 : }
27 4 : arpDriftLogger.fine("Building ARP table...");
28 4 : final entries = (await ARPTableHelper().buildTable())
29 2 : .map(
30 4 : (e) => ARPDriftCompanion.insert(
31 2 : iPAddress: e.iPAddress,
32 2 : macAddress: e.macAddress,
33 2 : hostname: e.hostname,
34 2 : interfaceName: e.interfaceName,
35 2 : interfaceType: e.interfaceType,
36 2 : createdAt: DateTime.now(),
37 : ),
38 : )
39 2 : .toList();
40 2 : if (entries.isNotEmpty) {
41 4 : await database!.batch((batch) {
42 4 : batch.insertAll(database.aRPDrift, entries);
43 : });
44 8 : arpDriftLogger.fine("ARP table built with ${entries.length} entries");
45 : }
46 : }
47 :
48 0 : @override
49 : Future<void> close() async {
50 0 : final database = await _database.open();
51 0 : database!.close();
52 : }
53 :
54 1 : Future<List<ARPDriftData>> _fullEntries() async {
55 2 : final database = await _database.open();
56 1 : final records = await (database!.select(
57 1 : database.aRPDrift,
58 6 : )..orderBy([(t) => OrderingTerm(expression: t.id)])).get();
59 :
60 1 : return records.toList();
61 : }
62 :
63 2 : @override
64 : Future<List<String>> entries() async {
65 4 : final database = await _database.open();
66 2 : final records = await (database!.select(
67 2 : database.aRPDrift,
68 12 : )..orderBy([(t) => OrderingTerm(expression: t.id)])).get();
69 :
70 8 : return records.map((e) => e.iPAddress).toList();
71 : }
72 :
73 2 : @override
74 : Future<ARPData?> entryFor(String address) async {
75 4 : final database = await _database.open();
76 2 : final records = await (database!.select(
77 2 : database.aRPDrift,
78 10 : )..where((t) => t.iPAddress.equals(address))).get();
79 2 : if (records.isNotEmpty) {
80 3 : arpDriftLogger.fine("Found ARP entry for address: $address");
81 2 : return ARPData.fromDriftData(records.first);
82 : }
83 6 : arpDriftLogger.fine("No ARP entry found for address: $address");
84 : return null;
85 : }
86 :
87 1 : @override
88 : Future<bool> clear() async {
89 2 : final database = await _database.open();
90 1 : final oldEnteries = await _fullEntries();
91 1 : if (oldEnteries.isNotEmpty) {
92 2 : arpDriftLogger.fine("Skipping ARP table build, old entries found");
93 : bool hasOldEntries = false;
94 2 : for (final entry in oldEnteries) {
95 : // Delete records older than 1 hour
96 2 : if (entry.createdAt.isBefore(
97 2 : DateTime.now().subtract(const Duration(hours: 1)),
98 : )) {
99 : hasOldEntries = true;
100 : break;
101 : }
102 : }
103 : if (hasOldEntries) {
104 : //Delete entire table data
105 3 : await database!.delete(database.aRPDrift).go();
106 2 : arpDriftLogger.fine("Deleting all ARP entries older than 1 hour");
107 : }
108 : return true;
109 : }
110 : return false;
111 : }
112 : }
|