Files
journaler/lib/db.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");
}
}