Skip to content

Commit

Permalink
fixed migration system
Browse files Browse the repository at this point in the history
  • Loading branch information
0PandaDEV committed Aug 4, 2024
1 parent 6f64a4d commit d86618f
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 97 deletions.
2 changes: 1 addition & 1 deletion assets/styles/components/library.scss
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,4 @@
width: 32px;
height: 32px;
}
}
}
10 changes: 5 additions & 5 deletions components/Titlebar.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup>
import { getCurrent } from "@tauri-apps/api/window";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { platform } from '@tauri-apps/plugin-os';
const isMaximized = ref(false);
onMounted(async () => {
const currentWindow = await getCurrent();
const currentWindow = await getCurrentWindow();
isMaximized.value = await currentWindow.isMaximized();
if (await platform() == 'macos') {
Expand All @@ -24,14 +24,14 @@ onMounted(async () => {
<div class="titlebar">
<div class="drag-region" data-tauri-drag-region></div>
<div class="window-controls" id="window-controls">
<button class="button minimize" @click="async () => getCurrent().minimize()">
<button class="button minimize" @click="async () => getCurrentWindow().minimize()">
<img src="/minimize.svg" alt="minimize">
</button>
<button class="button maximize" @click="async () => getCurrent().toggleMaximize()">
<button class="button maximize" @click="async () => getCurrentWindow().toggleMaximize()">
<img v-if="!isMaximized" src="/maximize.svg" alt="maximize">
<img v-else src="/restore.svg" alt="restore">
</button>
<button class="button close" @click="() => getCurrent().close()">
<button class="button close" @click="() => getCurrentWindow().close()">
<img src="/close.svg" alt="close">
</button>
</div>
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ tauri-plugin-updater = "2.0.0-rc.0"
tauri-plugin-global-shortcut = "2.0.0-rc.0"
tauri-plugin-sql = {version = "2.0.0-rc.0", features = ["sqlite"] }
tauri-plugin-prevent-default = "0.3"
sqlx = { version = "0.8", features = ["runtime-tokio", "tls-native-tls", "sqlite"] }
serde_json = "1.0"
serde = "1.0"
lazy_static = "1.4"
Expand Down
168 changes: 152 additions & 16 deletions src-tauri/src/db/migration.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,53 @@
use crate::utils::commands;
use regex::Regex;
use serde_json::Value;
use sqlx::sqlite::SqlitePoolOptions;
use std::fs;
use regex::Regex;
use crate::utils::commands;
use std::path::PathBuf;
use tauri_plugin_sql::{Migration, MigrationKind};

pub async fn insert_data(app_data_dir: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
std::fs::create_dir_all(&app_data_dir)?;

let db_path = app_data_dir.join("data.db");
let db_url = format!("sqlite:{}", db_path.to_str().unwrap());

let pool = SqlitePoolOptions::new()
.max_connections(5)
.connect(&db_url)
.await?;

let count: (i64,) = sqlx::query_as("SELECT COUNT(*) FROM songs")
.fetch_one(&pool)
.await?;

if count.0 > 0 {
return Ok(());
}

let songs_sql = generate_songs_insert_sql();
for statement in songs_sql.split(';') {
if !statement.trim().is_empty() {
sqlx::query(statement).execute(&pool).await?;
}
}

let playlists_sql = generate_playlists_insert_sql();
for statement in playlists_sql.split(';') {
if !statement.trim().is_empty() {
sqlx::query(statement).execute(&pool).await?;
}
}

let settings_sql = generate_settings_insert_sql();
for statement in settings_sql.split(';') {
if !statement.trim().is_empty() {
sqlx::query(statement).execute(&pool).await?;
}
}

Ok(())
}

pub fn generate_songs_insert_sql() -> String {
let path = commands::get_music_path().join("songs.json");
Expand All @@ -14,13 +60,31 @@ pub fn generate_songs_insert_sql() -> String {
let mut inserts = Vec::new();
if let Some(songs) = json["songs"].as_object() {
for (id, song) in songs {
let title = song["title"].as_str().unwrap_or_default().replace("'", "''");
let artist = song["artist"].as_str().unwrap_or_default().replace("'", "''");
let title = song["title"]
.as_str()
.unwrap_or_default()
.replace("'", "''");
let artist = song["artist"]
.as_str()
.unwrap_or_default()
.replace("'", "''");
let length = song["length"].as_i64().unwrap_or_default();
let cover = song["cover"].as_str().unwrap_or_default().replace("'", "''");
let cover = Regex::new(r"^https?://[^/]+").unwrap().replace(&cover, "").to_string();
let date_added = song["date_added"].as_str().unwrap_or_default().replace("'", "''");
let last_played = song["lastPlayed"].as_str().unwrap_or_default().replace("'", "''");
let cover = song["cover"]
.as_str()
.unwrap_or_default()
.replace("'", "''");
let cover = Regex::new(r"^https?://[^/]+")
.unwrap()
.replace(&cover, "")
.to_string();
let date_added = song["date_added"]
.as_str()
.unwrap_or_default()
.replace("'", "''");
let last_played = song["lastPlayed"]
.as_str()
.unwrap_or_default()
.replace("'", "''");

inserts.push(format!(
"INSERT INTO songs (id, title, artist, length, cover, date_added, last_played) VALUES ('{}', '{}', '{}', {}, '{}', '{}', '{}');",
Expand All @@ -43,11 +107,27 @@ pub fn generate_playlists_insert_sql() -> String {
let mut inserts = Vec::new();
if let Some(playlists) = json["playlists"].as_object() {
for (id, playlist) in playlists {
let name = playlist["name"].as_str().unwrap_or_default().replace("'", "''");
let date = playlist["date"].as_str().unwrap_or_default().replace("'", "''");
let cover = playlist["cover"].as_str().unwrap_or_default().replace("'", "''");
let song_ids = playlist["songs"].as_array()
.map(|songs| songs.iter().filter_map(|s| s.as_str()).collect::<Vec<_>>().join(","))
let name = playlist["name"]
.as_str()
.unwrap_or_default()
.replace("'", "''");
let date = playlist["date"]
.as_str()
.unwrap_or_default()
.replace("'", "''");
let cover = playlist["cover"]
.as_str()
.unwrap_or_default()
.replace("'", "''");
let song_ids = playlist["songs"]
.as_array()
.map(|songs| {
songs
.iter()
.filter_map(|s| s.as_str())
.collect::<Vec<_>>()
.join(",")
})
.unwrap_or_default();

inserts.push(format!(
Expand All @@ -71,7 +151,9 @@ fn load_settings_json() -> Option<Value> {

pub fn generate_settings_insert_sql() -> String {
if let Some(json) = load_settings_json() {
let player_settings = json["playerSettings"].as_object().expect("Expected 'playerSettings' to be an object");
let player_settings = json["playerSettings"]
.as_object()
.expect("Expected 'playerSettings' to be an object");

let mut inserts = Vec::new();
let mut eq_settings = serde_json::Map::new();
Expand All @@ -85,7 +167,7 @@ pub fn generate_settings_insert_sql() -> String {
}
} else {
let value_str = match value {
Value::String(s) => s.replace("'", "''"),
Value::String(s) => s.replace("'", "''"),
_ => value.to_string().replace("'", "''"),
};
inserts.push(format!(
Expand All @@ -96,7 +178,9 @@ pub fn generate_settings_insert_sql() -> String {
}

if !eq_settings.is_empty() {
let eq_json = serde_json::to_string(&eq_settings).unwrap().replace("'", "''");
let eq_json = serde_json::to_string(&eq_settings)
.unwrap()
.replace("'", "''");
inserts.push(format!(
"INSERT INTO settings (key, value) VALUES ('eq', '{}');",
eq_json
Expand All @@ -108,3 +192,55 @@ pub fn generate_settings_insert_sql() -> String {
String::new()
}
}
pub fn load_migrations() -> Vec<Migration> {
let migration_v1 = r#"
CREATE TABLE IF NOT EXISTS songs (
id TEXT PRIMARY KEY,
title TEXT,
artist TEXT,
length INTEGER,
cover TEXT,
date_added TEXT,
last_played TEXT
);
CREATE TABLE IF NOT EXISTS playlists (
id TEXT PRIMARY KEY,
name TEXT,
date TEXT,
cover TEXT,
songs TEXT
);
"#;
let migration_v2 = r#"
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT
);
"#;

let migration_v3 = r#"
INSERT INTO settings (key, value) VALUES ('apiURL', 'https://pipedapi.wireway.ch');
INSERT INTO settings (key, value) VALUES ('volume', '50');
"#;

vec![
Migration {
version: 1,
description: "create_songs_and_playlists_tables",
sql: migration_v1,
kind: MigrationKind::Up,
},
Migration {
version: 2,
description: "create_settings_table",
sql: migration_v2,
kind: MigrationKind::Up,
},
Migration {
version: 3,
description: "insert_default_apiURL",
sql: migration_v3,
kind: MigrationKind::Up,
},
]
}
Loading

0 comments on commit d86618f

Please sign in to comment.