mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-16 12:39:39 +02:00
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>
67 lines
1.7 KiB
TypeScript
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;
|
|
}
|
|
}
|