import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:sqflite/sqflite.dart'; const String logTable = 'logs'; const String idColumn = '_id'; const String levelColumn = 'level'; const String messageColumn = 'message'; const String timestampColumn = 'timestamp'; const String dbPath = 'logs.db'; enum LogLevels { debug, info, warning, error } class Log { int? id; late LogLevels level; late String message; DateTime timestamp = DateTime.now(); Map toMap() { var map = { idColumn: id, levelColumn: level.index, messageColumn: message, timestampColumn: timestamp.millisecondsSinceEpoch, }; return map; } Log(this.message, this.level); Log.fromMap(Map map) { id = map[idColumn] as int; level = LogLevels.values.elementAt(map[levelColumn] as int); message = map[messageColumn] as String; timestamp = DateTime.fromMillisecondsSinceEpoch( map[timestampColumn] as int, ); } @override String toString() { return '${timestamp.toString()}: ${level.name}: $message'; } } class LogsProvider { LogsProvider({bool runDefaultClear = true}) { clear(before: DateTime.now().subtract(const Duration(days: 7))); } Database? db; Future getDB() async { db ??= await openDatabase( dbPath, version: 1, onCreate: (Database db, int version) async { await db.execute(''' create table if not exists $logTable ( $idColumn integer primary key autoincrement, $levelColumn integer not null, $messageColumn text not null, $timestampColumn integer not null) '''); }, ); return db!; } Future add(String message, {LogLevels level = LogLevels.info}) async { Log l = Log(message, level); l.id = await (await getDB()).insert(logTable, l.toMap()); if (kDebugMode) { print(l); } return l; } Future> get({DateTime? before, DateTime? after}) async { var where = getWhereDates(before: before, after: after); return (await (await getDB()).query( logTable, where: where.key, whereArgs: where.value, )).map((e) => Log.fromMap(e)).toList(); } Future clear({DateTime? before, DateTime? after}) async { var where = getWhereDates(before: before, after: after); var res = await (await getDB()).delete( logTable, where: where.key, whereArgs: where.value, ); if (res > 0) { add( plural( 'clearedNLogsBeforeXAfterY', res, namedArgs: {'before': before.toString(), 'after': after.toString()}, name: 'n', ), ); } return res; } } MapEntry?> getWhereDates({ DateTime? before, DateTime? after, }) { List where = []; List whereArgs = []; if (before != null) { where.add('$timestampColumn < ?'); whereArgs.add(before.millisecondsSinceEpoch); } if (after != null) { where.add('$timestampColumn > ?'); whereArgs.add(after.millisecondsSinceEpoch); } return whereArgs.isEmpty ? const MapEntry(null, null) : MapEntry(where.join(' and '), whereArgs); }