managarten/apps-archived/mukke/apps/mobile/services/database.ts
Till JS 7a56699d45 feat(mukke): rename LightWrite to Mukke and add music library, player, playlists
Combines LightWrite (beat/lyrics editor) and Mukke (iOS music player) into
a single web-based music workspace app. Archives the old Mukke mobile app.

- Rename: @lightwrite/* → @mukke/*, all branding, configs, Dockerfiles
- New DB schemas: songs, playlists, playlist_songs + songId FK on projects
- New backend modules: SongModule, PlaylistModule, LibraryModule
- New web: app shell with sidebar, library (songs/albums/artists/genres),
  web player (queue/shuffle/repeat/MediaSession), playlists, search,
  upload, dashboard, album/artist/genre detail pages
- Auth: add forgot-password + reset-password pages, extend auth store
- Tests: 40 backend unit tests (song, playlist, library services)
- Config: env generation, MinIO bucket, docker-compose prod, cloudflare
- Docs: update CLAUDE.md, auth guidelines with SvelteKit checklist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:55:56 +01:00

67 lines
1.7 KiB
TypeScript

import * as SQLite from 'expo-sqlite';
let db: SQLite.SQLiteDatabase | null = null;
export async function getDatabase(): Promise<SQLite.SQLiteDatabase> {
if (db) return db;
db = await SQLite.openDatabaseAsync('mukke.db');
await initializeDatabase(db);
return db;
}
async function initializeDatabase(database: SQLite.SQLiteDatabase): Promise<void> {
await database.execAsync(`
PRAGMA journal_mode = WAL;
PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS songs (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
artist TEXT,
album TEXT,
albumArtist TEXT,
genre TEXT,
trackNumber INTEGER,
discNumber INTEGER,
year INTEGER,
duration REAL,
filePath TEXT NOT NULL,
fileSize INTEGER,
coverArtPath TEXT,
addedAt TEXT NOT NULL,
lastPlayedAt TEXT,
playCount INTEGER DEFAULT 0,
favorite INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS playlists (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
coverArtPath TEXT,
createdAt TEXT NOT NULL,
updatedAt TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS playlist_songs (
id TEXT PRIMARY KEY,
playlistId TEXT NOT NULL REFERENCES playlists(id) ON DELETE CASCADE,
songId TEXT NOT NULL REFERENCES songs(id) ON DELETE CASCADE,
sortOrder INTEGER NOT NULL,
addedAt TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_songs_artist ON songs(artist);
CREATE INDEX IF NOT EXISTS idx_songs_album ON songs(album);
CREATE INDEX IF NOT EXISTS idx_songs_genre ON songs(genre);
CREATE INDEX IF NOT EXISTS idx_songs_favorite ON songs(favorite);
CREATE INDEX IF NOT EXISTS idx_playlist_songs_playlist ON playlist_songs(playlistId);
`);
}
export async function closeDatabase(): Promise<void> {
if (db) {
await db.closeAsync();
db = null;
}
}