115 lines
3.4 KiB
Dart
115 lines
3.4 KiB
Dart
import 'dart:io' show Platform, Directory;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:path/path.dart' as path;
|
|
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
|
|
|
const settingsDir = '.journaler';
|
|
const dbFileName = 'journaler.db';
|
|
|
|
class DB {
|
|
static late Database db;
|
|
|
|
static const String _schema = '''
|
|
CREATE TABLE IF NOT EXISTS notes (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
date TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
content TEXT NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_notes_date ON notes (date);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_notes_date_unique ON notes (date);
|
|
-- Todos are "static", we are only interested in the latest entry
|
|
-- ie. they're not really a list but instead a string
|
|
-- But we will also keep a history of all todos
|
|
-- Because we might as well
|
|
CREATE TABLE IF NOT EXISTS scratches (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
date TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
content TEXT NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_scratches_date ON scratches (date);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_scratches_date_unique ON scratches (date);
|
|
|
|
CREATE TABLE IF NOT EXISTS settings (
|
|
key TEXT PRIMARY KEY NOT NULL,
|
|
value TEXT NOT NULL
|
|
);
|
|
''';
|
|
|
|
static Future<String> _getDatabasePath() async {
|
|
debugPrint('Attempting to get database path...');
|
|
if (Platform.isWindows || Platform.isLinux) {
|
|
// Get user's home directory
|
|
final home =
|
|
Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'];
|
|
if (home == null) {
|
|
throw Exception('Could not find home directory');
|
|
}
|
|
debugPrint('Home directory found: home');
|
|
|
|
final dbDir = Directory(path.join(home, settingsDir));
|
|
if (!await dbDir.exists()) {
|
|
await dbDir.create(recursive: true);
|
|
debugPrint('$settingsDir directory created');
|
|
} else {
|
|
debugPrint('$settingsDir directory already exists');
|
|
}
|
|
|
|
return path.join(dbDir.path, dbFileName);
|
|
} else {
|
|
// Default path for other platforms
|
|
final databasesPath = await databaseFactoryFfi.getDatabasesPath();
|
|
debugPrint('Using default databases path: databasesPath');
|
|
return path.join(databasesPath, dbFileName);
|
|
}
|
|
}
|
|
|
|
static Future<void> init() async {
|
|
debugPrint('Starting database initialization...');
|
|
sqfliteFfiInit();
|
|
|
|
final dbPath = await _getDatabasePath();
|
|
debugPrint('Database path: dbPath');
|
|
|
|
try {
|
|
db = await databaseFactoryFfi.openDatabase(
|
|
dbPath,
|
|
options: OpenDatabaseOptions(
|
|
version: 1,
|
|
onCreate: (db, version) async {
|
|
debugPrint('Creating database schema...');
|
|
await db.execute(_schema);
|
|
debugPrint('Database schema created successfully');
|
|
},
|
|
),
|
|
);
|
|
debugPrint('Database opened and initialized');
|
|
} catch (e) {
|
|
debugPrint('Failed to initialize database: e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Settings Management
|
|
static Future<String?> getSetting(String key) async {
|
|
final List<Map<String, dynamic>> maps = await db.query(
|
|
'settings',
|
|
columns: ['value'],
|
|
where: 'key = ?',
|
|
whereArgs: [key],
|
|
);
|
|
if (maps.isNotEmpty) {
|
|
return maps.first['value'] as String?;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
static Future<void> setSetting(String key, String value) async {
|
|
await db.insert(
|
|
'settings',
|
|
{'key': key, 'value': value},
|
|
conflictAlgorithm: ConflictAlgorithm.replace,
|
|
);
|
|
debugPrint("Setting updated: $key = $value");
|
|
}
|
|
}
|