Simplified connection API
This commit is contained in:
parent
729bf7a653
commit
bd537b8134
8 changed files with 79 additions and 120 deletions
|
@ -48,9 +48,7 @@ fn get_auth_secret<T>(db: &T) -> Result<String>
|
||||||
{
|
{
|
||||||
use self::misc_settings::dsl::*;
|
use self::misc_settings::dsl::*;
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
let misc: MiscSettings = misc_settings.get_result(connection.deref())?;
|
||||||
let connection = connection.deref();
|
|
||||||
let misc: MiscSettings = misc_settings.get_result(connection)?;
|
|
||||||
Ok(misc.auth_secret.to_owned())
|
Ok(misc.auth_secret.to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,6 @@ pub fn read<T>(db: &T) -> Result<Config>
|
||||||
use self::ddns_config::dsl::*;
|
use self::ddns_config::dsl::*;
|
||||||
|
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
|
|
||||||
let mut config = Config {
|
let mut config = Config {
|
||||||
album_art_pattern: None,
|
album_art_pattern: None,
|
||||||
|
@ -91,18 +89,18 @@ pub fn read<T>(db: &T) -> Result<Config>
|
||||||
|
|
||||||
let (art_pattern, sleep_duration) = misc_settings
|
let (art_pattern, sleep_duration) = misc_settings
|
||||||
.select((index_album_art_pattern, index_sleep_duration_seconds))
|
.select((index_album_art_pattern, index_sleep_duration_seconds))
|
||||||
.get_result(connection)?;
|
.get_result(connection.deref())?;
|
||||||
config.album_art_pattern = Some(art_pattern);
|
config.album_art_pattern = Some(art_pattern);
|
||||||
config.reindex_every_n_seconds = Some(sleep_duration);
|
config.reindex_every_n_seconds = Some(sleep_duration);
|
||||||
|
|
||||||
let mount_dirs = mount_points
|
let mount_dirs = mount_points
|
||||||
.select((source, name))
|
.select((source, name))
|
||||||
.get_results(connection)?;
|
.get_results(connection.deref())?;
|
||||||
config.mount_dirs = Some(mount_dirs);
|
config.mount_dirs = Some(mount_dirs);
|
||||||
|
|
||||||
let found_users: Vec<(String, i32)> = users::table
|
let found_users: Vec<(String, i32)> = users::table
|
||||||
.select((users::columns::name, users::columns::admin))
|
.select((users::columns::name, users::columns::admin))
|
||||||
.get_results(connection)?;
|
.get_results(connection.deref())?;
|
||||||
config.users = Some(found_users
|
config.users = Some(found_users
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(n, a)| {
|
.map(|(n, a)| {
|
||||||
|
@ -116,7 +114,7 @@ pub fn read<T>(db: &T) -> Result<Config>
|
||||||
|
|
||||||
let ydns = ddns_config
|
let ydns = ddns_config
|
||||||
.select((host, username, password))
|
.select((host, username, password))
|
||||||
.get_result(connection)?;
|
.get_result(connection.deref())?;
|
||||||
config.ydns = Some(ydns);
|
config.ydns = Some(ydns);
|
||||||
|
|
||||||
Ok(config)
|
Ok(config)
|
||||||
|
@ -127,14 +125,13 @@ fn reset<T>(db: &T) -> Result<()>
|
||||||
{
|
{
|
||||||
use self::ddns_config::dsl::*;
|
use self::ddns_config::dsl::*;
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
|
|
||||||
diesel::delete(mount_points::table).execute(connection)?;
|
diesel::delete(mount_points::table)
|
||||||
diesel::delete(users::table).execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
|
diesel::delete(users::table).execute(connection.deref())?;
|
||||||
diesel::update(ddns_config)
|
diesel::update(ddns_config)
|
||||||
.set((host.eq(""), username.eq(""), password.eq("")))
|
.set((host.eq(""), username.eq(""), password.eq("")))
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -150,20 +147,19 @@ pub fn amend<T>(db: &T, new_config: &Config) -> Result<()>
|
||||||
where T: ConnectionSource
|
where T: ConnectionSource
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
|
|
||||||
if let Some(ref mount_dirs) = new_config.mount_dirs {
|
if let Some(ref mount_dirs) = new_config.mount_dirs {
|
||||||
diesel::delete(mount_points::table).execute(connection)?;
|
diesel::delete(mount_points::table)
|
||||||
|
.execute(connection.deref())?;
|
||||||
diesel::insert(mount_dirs)
|
diesel::insert(mount_dirs)
|
||||||
.into(mount_points::table)
|
.into(mount_points::table)
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref config_users) = new_config.users {
|
if let Some(ref config_users) = new_config.users {
|
||||||
let old_usernames: Vec<String> = users::table
|
let old_usernames: Vec<String> = users::table
|
||||||
.select(users::name)
|
.select(users::name)
|
||||||
.get_results(connection)?;
|
.get_results(connection.deref())?;
|
||||||
|
|
||||||
// Delete users that are not in new list
|
// Delete users that are not in new list
|
||||||
// Delete users that have a new password
|
// Delete users that have a new password
|
||||||
|
@ -175,7 +171,7 @@ pub fn amend<T>(db: &T, new_config: &Config) -> Result<()>
|
||||||
})
|
})
|
||||||
.collect::<_>();
|
.collect::<_>();
|
||||||
diesel::delete(users::table.filter(users::name.eq_any(&delete_usernames)))
|
diesel::delete(users::table.filter(users::name.eq_any(&delete_usernames)))
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
|
|
||||||
// Insert users that have a new password
|
// Insert users that have a new password
|
||||||
let insert_users: Vec<&ConfigUser> = config_users
|
let insert_users: Vec<&ConfigUser> = config_users
|
||||||
|
@ -186,27 +182,27 @@ pub fn amend<T>(db: &T, new_config: &Config) -> Result<()>
|
||||||
let new_user = User::new(&config_user.name, &config_user.password, config_user.admin);
|
let new_user = User::new(&config_user.name, &config_user.password, config_user.admin);
|
||||||
diesel::insert(&new_user)
|
diesel::insert(&new_user)
|
||||||
.into(users::table)
|
.into(users::table)
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grant admin rights
|
// Grant admin rights
|
||||||
for ref user in config_users {
|
for ref user in config_users {
|
||||||
diesel::update(users::table.filter(users::name.eq(&user.name)))
|
diesel::update(users::table.filter(users::name.eq(&user.name)))
|
||||||
.set(users::admin.eq(user.admin as i32))
|
.set(users::admin.eq(user.admin as i32))
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sleep_duration) = new_config.reindex_every_n_seconds {
|
if let Some(sleep_duration) = new_config.reindex_every_n_seconds {
|
||||||
diesel::update(misc_settings::table)
|
diesel::update(misc_settings::table)
|
||||||
.set(misc_settings::index_sleep_duration_seconds.eq(sleep_duration as i32))
|
.set(misc_settings::index_sleep_duration_seconds.eq(sleep_duration as i32))
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref album_art_pattern) = new_config.album_art_pattern {
|
if let Some(ref album_art_pattern) = new_config.album_art_pattern {
|
||||||
diesel::update(misc_settings::table)
|
diesel::update(misc_settings::table)
|
||||||
.set(misc_settings::index_album_art_pattern.eq(album_art_pattern))
|
.set(misc_settings::index_album_art_pattern.eq(album_art_pattern))
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref ydns) = new_config.ydns {
|
if let Some(ref ydns) = new_config.ydns {
|
||||||
|
@ -215,7 +211,7 @@ pub fn amend<T>(db: &T, new_config: &Config) -> Result<()>
|
||||||
.set((host.eq(ydns.host.clone()),
|
.set((host.eq(ydns.host.clone()),
|
||||||
username.eq(ydns.username.clone()),
|
username.eq(ydns.username.clone()),
|
||||||
password.eq(ydns.password.clone())))
|
password.eq(ydns.password.clone())))
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -314,12 +310,10 @@ fn test_amend_preserve_password_hashes() {
|
||||||
|
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
initial_hash = users
|
initial_hash = users
|
||||||
.select(password_hash)
|
.select(password_hash)
|
||||||
.filter(name.eq("Teddy🐻"))
|
.filter(name.eq("Teddy🐻"))
|
||||||
.get_result(connection)
|
.get_result(connection.deref())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,12 +337,10 @@ fn test_amend_preserve_password_hashes() {
|
||||||
|
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
new_hash = users
|
new_hash = users
|
||||||
.select(password_hash)
|
.select(password_hash)
|
||||||
.filter(name.eq("Teddy🐻"))
|
.filter(name.eq("Teddy🐻"))
|
||||||
.get_result(connection)
|
.get_result(connection.deref())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,9 +369,10 @@ fn test_toggle_admin() {
|
||||||
|
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
let is_admin: i32 = users
|
||||||
let connection = connection.deref();
|
.select(admin)
|
||||||
let is_admin: i32 = users.select(admin).get_result(connection).unwrap();
|
.get_result(connection.deref())
|
||||||
|
.unwrap();
|
||||||
assert_eq!(is_admin, 1);
|
assert_eq!(is_admin, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,9 +391,10 @@ fn test_toggle_admin() {
|
||||||
|
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
let is_admin: i32 = users
|
||||||
let connection = connection.deref();
|
.select(admin)
|
||||||
let is_admin: i32 = users.select(admin).get_result(connection).unwrap();
|
.get_result(connection.deref())
|
||||||
|
.unwrap();
|
||||||
assert_eq!(is_admin, 0);
|
assert_eq!(is_admin, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use diesel::prelude::*;
|
||||||
use diesel::sqlite::SqliteConnection;
|
use diesel::sqlite::SqliteConnection;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
|
|
||||||
use errors::*;
|
use errors::*;
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@ const DB_MIGRATIONS_PATH: &'static str = "src/db/migrations";
|
||||||
embed_migrations!("src/db/migrations");
|
embed_migrations!("src/db/migrations");
|
||||||
|
|
||||||
pub trait ConnectionSource {
|
pub trait ConnectionSource {
|
||||||
fn get_connection(&self) -> Arc<Mutex<SqliteConnection>>;
|
fn get_connection(&self) -> MutexGuard<SqliteConnection>;
|
||||||
|
fn get_connection_mutex(&self) -> Arc<Mutex<SqliteConnection>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DB {
|
pub struct DB {
|
||||||
|
@ -66,7 +67,11 @@ impl DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectionSource for DB {
|
impl ConnectionSource for DB {
|
||||||
fn get_connection(&self) -> Arc<Mutex<SqliteConnection>> {
|
fn get_connection(&self) -> MutexGuard<SqliteConnection> {
|
||||||
|
self.connection.lock().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_connection_mutex(&self) -> Arc<Mutex<SqliteConnection>> {
|
||||||
self.connection.clone()
|
self.connection.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,9 @@ impl DDNSConfigSource for DB {
|
||||||
fn get_ddns_config(&self) -> errors::Result<DDNSConfig> {
|
fn get_ddns_config(&self) -> errors::Result<DDNSConfig> {
|
||||||
use self::ddns_config::dsl::*;
|
use self::ddns_config::dsl::*;
|
||||||
let connection = self.get_connection();
|
let connection = self.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
Ok(ddns_config
|
Ok(ddns_config
|
||||||
.select((host, username, password))
|
.select((host, username, password))
|
||||||
.get_result(connection)?)
|
.get_result(connection.deref())?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
63
src/index.rs
63
src/index.rs
|
@ -295,9 +295,9 @@ fn clean<T>(db: &T) -> Result<()>
|
||||||
let all_songs: Vec<String>;
|
let all_songs: Vec<String>;
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
all_songs = songs::table
|
||||||
let connection = connection.deref();
|
.select(songs::path)
|
||||||
all_songs = songs::table.select(songs::path).load(connection)?;
|
.load(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let missing_songs = all_songs
|
let missing_songs = all_songs
|
||||||
|
@ -310,11 +310,9 @@ fn clean<T>(db: &T) -> Result<()>
|
||||||
|
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
for chunk in missing_songs[..].chunks(INDEX_BUILDING_CLEAN_BUFFER_SIZE) {
|
for chunk in missing_songs[..].chunks(INDEX_BUILDING_CLEAN_BUFFER_SIZE) {
|
||||||
diesel::delete(songs::table.filter(songs::path.eq_any(chunk)))
|
diesel::delete(songs::table.filter(songs::path.eq_any(chunk)))
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -324,11 +322,9 @@ fn clean<T>(db: &T) -> Result<()>
|
||||||
let all_directories: Vec<String>;
|
let all_directories: Vec<String>;
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
all_directories = directories::table
|
all_directories = directories::table
|
||||||
.select(directories::path)
|
.select(directories::path)
|
||||||
.load(connection)?;
|
.load(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let missing_directories = all_directories
|
let missing_directories = all_directories
|
||||||
|
@ -341,11 +337,9 @@ fn clean<T>(db: &T) -> Result<()>
|
||||||
|
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
for chunk in missing_directories[..].chunks(INDEX_BUILDING_CLEAN_BUFFER_SIZE) {
|
for chunk in missing_directories[..].chunks(INDEX_BUILDING_CLEAN_BUFFER_SIZE) {
|
||||||
diesel::delete(directories::table.filter(directories::path.eq_any(chunk)))
|
diesel::delete(directories::table.filter(directories::path.eq_any(chunk)))
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,17 +352,16 @@ fn populate<T>(db: &T) -> Result<()>
|
||||||
{
|
{
|
||||||
let vfs = db.get_vfs()?;
|
let vfs = db.get_vfs()?;
|
||||||
let mount_points = vfs.get_mount_points();
|
let mount_points = vfs.get_mount_points();
|
||||||
let connection = db.get_connection();
|
|
||||||
|
|
||||||
let album_art_pattern;
|
let album_art_pattern;
|
||||||
{
|
{
|
||||||
let connection = connection.lock().unwrap();
|
let connection = db.get_connection();
|
||||||
let connection = connection.deref();
|
let settings: MiscSettings = misc_settings::table.get_result(connection.deref())?;
|
||||||
let settings: MiscSettings = misc_settings::table.get_result(connection)?;
|
|
||||||
album_art_pattern = Regex::new(&settings.index_album_art_pattern)?;
|
album_art_pattern = Regex::new(&settings.index_album_art_pattern)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut builder = IndexBuilder::new(&connection, album_art_pattern)?;
|
let connection_mutex = db.get_connection_mutex();
|
||||||
|
let mut builder = IndexBuilder::new(connection_mutex.deref(), album_art_pattern)?;
|
||||||
for (_, target) in mount_points {
|
for (_, target) in mount_points {
|
||||||
builder.populate_directory(None, target.as_path())?;
|
builder.populate_directory(None, target.as_path())?;
|
||||||
}
|
}
|
||||||
|
@ -433,10 +426,8 @@ pub fn self_trigger<T>(db: &T, command_buffer: Arc<Mutex<Sender<Command>>>)
|
||||||
let sleep_duration;
|
let sleep_duration;
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
let settings: Result<MiscSettings> = misc_settings::table
|
let settings: Result<MiscSettings> = misc_settings::table
|
||||||
.get_result(connection)
|
.get_result(connection.deref())
|
||||||
.map_err(|e| e.into());
|
.map_err(|e| e.into());
|
||||||
if let Err(ref e) = settings {
|
if let Err(ref e) = settings {
|
||||||
println!("Could not retrieve index sleep duration: {}", e);
|
println!("Could not retrieve index sleep duration: {}", e);
|
||||||
|
@ -483,14 +474,12 @@ pub fn browse<T>(db: &T, virtual_path: &Path) -> Result<Vec<CollectionFile>>
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
let vfs = db.get_vfs()?;
|
let vfs = db.get_vfs()?;
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
|
|
||||||
if virtual_path.components().count() == 0 {
|
if virtual_path.components().count() == 0 {
|
||||||
// Browse top-level
|
// Browse top-level
|
||||||
let real_directories: Vec<Directory> = directories::table
|
let real_directories: Vec<Directory> = directories::table
|
||||||
.filter(directories::parent.is_null())
|
.filter(directories::parent.is_null())
|
||||||
.load(connection)?;
|
.load(connection.deref())?;
|
||||||
let virtual_directories = real_directories
|
let virtual_directories = real_directories
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|s| virtualize_directory(&vfs, s));
|
.filter_map(|s| virtualize_directory(&vfs, s));
|
||||||
|
@ -506,7 +495,7 @@ pub fn browse<T>(db: &T, virtual_path: &Path) -> Result<Vec<CollectionFile>>
|
||||||
let real_directories: Vec<Directory> = directories::table
|
let real_directories: Vec<Directory> = directories::table
|
||||||
.filter(directories::parent.eq(&real_path_string))
|
.filter(directories::parent.eq(&real_path_string))
|
||||||
.order(sql::<types::Bool>("path COLLATE NOCASE ASC"))
|
.order(sql::<types::Bool>("path COLLATE NOCASE ASC"))
|
||||||
.load(connection)?;
|
.load(connection.deref())?;
|
||||||
let virtual_directories = real_directories
|
let virtual_directories = real_directories
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|s| virtualize_directory(&vfs, s));
|
.filter_map(|s| virtualize_directory(&vfs, s));
|
||||||
|
@ -515,7 +504,7 @@ pub fn browse<T>(db: &T, virtual_path: &Path) -> Result<Vec<CollectionFile>>
|
||||||
let real_songs: Vec<Song> = songs::table
|
let real_songs: Vec<Song> = songs::table
|
||||||
.filter(songs::parent.eq(&real_path_string))
|
.filter(songs::parent.eq(&real_path_string))
|
||||||
.order(sql::<types::Bool>("path COLLATE NOCASE ASC"))
|
.order(sql::<types::Bool>("path COLLATE NOCASE ASC"))
|
||||||
.load(connection)?;
|
.load(connection.deref())?;
|
||||||
let virtual_songs = real_songs
|
let virtual_songs = real_songs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|s| virtualize_song(&vfs, s));
|
.filter_map(|s| virtualize_song(&vfs, s));
|
||||||
|
@ -531,11 +520,11 @@ pub fn flatten<T>(db: &T, virtual_path: &Path) -> Result<Vec<Song>>
|
||||||
use self::songs::dsl::*;
|
use self::songs::dsl::*;
|
||||||
let vfs = db.get_vfs()?;
|
let vfs = db.get_vfs()?;
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
let real_path = vfs.virtual_to_real(virtual_path)?;
|
let real_path = vfs.virtual_to_real(virtual_path)?;
|
||||||
let like_path = real_path.as_path().to_string_lossy().into_owned() + "%";
|
let like_path = real_path.as_path().to_string_lossy().into_owned() + "%";
|
||||||
let real_songs: Vec<Song> = songs.filter(path.like(&like_path)).load(connection)?;
|
let real_songs: Vec<Song> = songs
|
||||||
|
.filter(path.like(&like_path))
|
||||||
|
.load(connection.deref())?;
|
||||||
let virtual_songs = real_songs
|
let virtual_songs = real_songs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|s| virtualize_song(&vfs, s));
|
.filter_map(|s| virtualize_song(&vfs, s));
|
||||||
|
@ -548,13 +537,11 @@ pub fn get_random_albums<T>(db: &T, count: i64) -> Result<Vec<Directory>>
|
||||||
use self::directories::dsl::*;
|
use self::directories::dsl::*;
|
||||||
let vfs = db.get_vfs()?;
|
let vfs = db.get_vfs()?;
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
let real_directories = directories
|
let real_directories = directories
|
||||||
.filter(album.is_not_null())
|
.filter(album.is_not_null())
|
||||||
.limit(count)
|
.limit(count)
|
||||||
.order(random)
|
.order(random)
|
||||||
.load(connection)?;
|
.load(connection.deref())?;
|
||||||
let virtual_directories = real_directories
|
let virtual_directories = real_directories
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|s| virtualize_directory(&vfs, s));
|
.filter_map(|s| virtualize_directory(&vfs, s));
|
||||||
|
@ -567,13 +554,11 @@ pub fn get_recent_albums<T>(db: &T, count: i64) -> Result<Vec<Directory>>
|
||||||
use self::directories::dsl::*;
|
use self::directories::dsl::*;
|
||||||
let vfs = db.get_vfs()?;
|
let vfs = db.get_vfs()?;
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
let real_directories: Vec<Directory> = directories
|
let real_directories: Vec<Directory> = directories
|
||||||
.filter(album.is_not_null())
|
.filter(album.is_not_null())
|
||||||
.order(date_added.desc())
|
.order(date_added.desc())
|
||||||
.limit(count)
|
.limit(count)
|
||||||
.load(connection)?;
|
.load(connection.deref())?;
|
||||||
let virtual_directories = real_directories
|
let virtual_directories = real_directories
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|s| virtualize_directory(&vfs, s));
|
.filter_map(|s| virtualize_directory(&vfs, s));
|
||||||
|
@ -587,10 +572,8 @@ fn test_populate() {
|
||||||
update(&db).unwrap(); // Check that subsequent updates don't run into conflicts
|
update(&db).unwrap(); // Check that subsequent updates don't run into conflicts
|
||||||
|
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
let all_directories: Vec<Directory> = directories::table.load(connection.deref()).unwrap();
|
||||||
let connection = connection.deref();
|
let all_songs: Vec<Song> = songs::table.load(connection.deref()).unwrap();
|
||||||
let all_directories: Vec<Directory> = directories::table.load(connection).unwrap();
|
|
||||||
let all_songs: Vec<Song> = songs::table.load(connection).unwrap();
|
|
||||||
assert_eq!(all_directories.len(), 5);
|
assert_eq!(all_directories.len(), 5);
|
||||||
assert_eq!(all_songs.len(), 12);
|
assert_eq!(all_songs.len(), 12);
|
||||||
}
|
}
|
||||||
|
@ -613,11 +596,9 @@ fn test_metadata() {
|
||||||
update(&db).unwrap();
|
update(&db).unwrap();
|
||||||
|
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
let songs: Vec<Song> = songs::table
|
let songs: Vec<Song> = songs::table
|
||||||
.filter(songs::title.eq("シャーベット (Sherbet)"))
|
.filter(songs::title.eq("シャーベット (Sherbet)"))
|
||||||
.load(connection)
|
.load(connection.deref())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(songs.len(), 1);
|
assert_eq!(songs.len(), 1);
|
||||||
|
|
|
@ -52,8 +52,6 @@ fn list_playlists<T>(owner: &str, db: &T) -> Result<Vec<String>>
|
||||||
where T: ConnectionSource + VFSSource
|
where T: ConnectionSource + VFSSource
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
|
|
||||||
let user: User;
|
let user: User;
|
||||||
{
|
{
|
||||||
|
@ -61,14 +59,14 @@ fn list_playlists<T>(owner: &str, db: &T) -> Result<Vec<String>>
|
||||||
user = users
|
user = users
|
||||||
.filter(name.eq(owner))
|
.filter(name.eq(owner))
|
||||||
.select((id, name))
|
.select((id, name))
|
||||||
.first(connection)?;
|
.first(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
use self::playlists::dsl::*;
|
use self::playlists::dsl::*;
|
||||||
let found_playlists: Vec<String> = Playlist::belonging_to(&user)
|
let found_playlists: Vec<String> = Playlist::belonging_to(&user)
|
||||||
.select(name)
|
.select(name)
|
||||||
.load(connection)?;
|
.load(connection.deref())?;
|
||||||
Ok(found_playlists)
|
Ok(found_playlists)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,8 +81,6 @@ fn save_playlist<T>(name: &str, owner: &str, content: &Vec<String>, db: &T) -> R
|
||||||
|
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
|
|
||||||
// Find owner
|
// Find owner
|
||||||
{
|
{
|
||||||
|
@ -92,7 +88,7 @@ fn save_playlist<T>(name: &str, owner: &str, content: &Vec<String>, db: &T) -> R
|
||||||
user = users
|
user = users
|
||||||
.filter(name.eq(owner))
|
.filter(name.eq(owner))
|
||||||
.select((id, name))
|
.select((id, name))
|
||||||
.get_result(connection)?;
|
.get_result(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create playlist
|
// Create playlist
|
||||||
|
@ -102,19 +98,19 @@ fn save_playlist<T>(name: &str, owner: &str, content: &Vec<String>, db: &T) -> R
|
||||||
};
|
};
|
||||||
|
|
||||||
diesel::insert(&new_playlist)
|
diesel::insert(&new_playlist)
|
||||||
.into(playlists::table)
|
.into(playlists::table)
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
|
|
||||||
{
|
{
|
||||||
use self::playlists::dsl::*;
|
use self::playlists::dsl::*;
|
||||||
playlist = playlists
|
playlist = playlists
|
||||||
.filter(name.eq(name).and(owner.eq(user.id)))
|
.filter(name.eq(name).and(owner.eq(user.id)))
|
||||||
.get_result(connection)?;
|
.get_result(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete old content (if any)
|
// Delete old content (if any)
|
||||||
let old_songs = PlaylistSong::belonging_to(&playlist);
|
let old_songs = PlaylistSong::belonging_to(&playlist);
|
||||||
diesel::delete(old_songs).execute(connection)?;
|
diesel::delete(old_songs).execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert content
|
// Insert content
|
||||||
|
@ -136,12 +132,9 @@ fn save_playlist<T>(name: &str, owner: &str, content: &Vec<String>, db: &T) -> R
|
||||||
|
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
|
|
||||||
diesel::insert(&new_songs)
|
diesel::insert(&new_songs)
|
||||||
.into(playlist_songs::table)
|
.into(playlist_songs::table)
|
||||||
.execute(connection)?;
|
.execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -157,8 +150,6 @@ fn read_playlist<T>(playlist_name: &str, owner: &str, db: &T) -> Result<Vec<Song
|
||||||
|
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
|
|
||||||
// Find owner
|
// Find owner
|
||||||
{
|
{
|
||||||
|
@ -166,7 +157,7 @@ fn read_playlist<T>(playlist_name: &str, owner: &str, db: &T) -> Result<Vec<Song
|
||||||
user = users
|
user = users
|
||||||
.filter(name.eq(owner))
|
.filter(name.eq(owner))
|
||||||
.select((id, name))
|
.select((id, name))
|
||||||
.get_result(connection)?;
|
.get_result(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find playlist
|
// Find playlist
|
||||||
|
@ -174,13 +165,13 @@ fn read_playlist<T>(playlist_name: &str, owner: &str, db: &T) -> Result<Vec<Song
|
||||||
use self::playlists::dsl::*;
|
use self::playlists::dsl::*;
|
||||||
playlist = playlists
|
playlist = playlists
|
||||||
.filter(name.eq(playlist_name).and(owner.eq(user.id)))
|
.filter(name.eq(playlist_name).and(owner.eq(user.id)))
|
||||||
.get_result(connection)?;
|
.get_result(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find content
|
// Find content
|
||||||
playlist_songs = PlaylistSong::belonging_to(&playlist)
|
playlist_songs = PlaylistSong::belonging_to(&playlist)
|
||||||
.order(playlist_songs::columns::ordering)
|
.order(playlist_songs::columns::ordering)
|
||||||
.get_results(connection)?;
|
.get_results(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -191,8 +182,6 @@ fn delete_playlist<T>(playlist_name: &str, owner: &str, db: &T) -> Result<()>
|
||||||
where T: ConnectionSource + VFSSource
|
where T: ConnectionSource + VFSSource
|
||||||
{
|
{
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
|
|
||||||
let user: User;
|
let user: User;
|
||||||
{
|
{
|
||||||
|
@ -200,13 +189,13 @@ fn delete_playlist<T>(playlist_name: &str, owner: &str, db: &T) -> Result<()>
|
||||||
user = users
|
user = users
|
||||||
.filter(name.eq(owner))
|
.filter(name.eq(owner))
|
||||||
.select((id, name))
|
.select((id, name))
|
||||||
.first(connection)?;
|
.first(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
use self::playlists::dsl::*;
|
use self::playlists::dsl::*;
|
||||||
let q = Playlist::belonging_to(&user).filter(name.eq(playlist_name));
|
let q = Playlist::belonging_to(&user).filter(name.eq(playlist_name));
|
||||||
diesel::delete(q).execute(connection)?;
|
diesel::delete(q).execute(connection.deref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
14
src/user.rs
14
src/user.rs
|
@ -60,12 +60,10 @@ pub fn auth<T>(db: &T, username: &str, password: &str) -> Result<bool>
|
||||||
{
|
{
|
||||||
use db::users::dsl::*;
|
use db::users::dsl::*;
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
let user: QueryResult<User> = users
|
let user: QueryResult<User> = users
|
||||||
.select((name, password_salt, password_hash, admin))
|
.select((name, password_salt, password_hash, admin))
|
||||||
.filter(name.eq(username))
|
.filter(name.eq(username))
|
||||||
.get_result(connection);
|
.get_result(connection.deref());
|
||||||
match user {
|
match user {
|
||||||
Err(diesel::result::Error::NotFound) => Ok(false),
|
Err(diesel::result::Error::NotFound) => Ok(false),
|
||||||
Ok(u) => Ok(u.verify_password(password)),
|
Ok(u) => Ok(u.verify_password(password)),
|
||||||
|
@ -78,9 +76,9 @@ pub fn count<T>(db: &T) -> Result<i64>
|
||||||
{
|
{
|
||||||
use db::users::dsl::*;
|
use db::users::dsl::*;
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
Ok(users
|
||||||
let connection = connection.deref();
|
.select(expression::count(name))
|
||||||
Ok(users.select(expression::count(name)).first(connection)?)
|
.first(connection.deref())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_admin<T>(db: &T, username: &str) -> Result<bool>
|
pub fn is_admin<T>(db: &T, username: &str) -> Result<bool>
|
||||||
|
@ -88,11 +86,9 @@ pub fn is_admin<T>(db: &T, username: &str) -> Result<bool>
|
||||||
{
|
{
|
||||||
use db::users::dsl::*;
|
use db::users::dsl::*;
|
||||||
let connection = db.get_connection();
|
let connection = db.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
let is_admin: i32 = users
|
let is_admin: i32 = users
|
||||||
.filter(name.eq(username))
|
.filter(name.eq(username))
|
||||||
.select(admin)
|
.select(admin)
|
||||||
.get_result(connection)?;
|
.get_result(connection.deref())?;
|
||||||
Ok(is_admin != 0)
|
Ok(is_admin != 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,9 @@ impl VFSSource for DB {
|
||||||
use self::mount_points::dsl::*;
|
use self::mount_points::dsl::*;
|
||||||
let mut vfs = VFS::new();
|
let mut vfs = VFS::new();
|
||||||
let connection = self.get_connection();
|
let connection = self.get_connection();
|
||||||
let connection = connection.lock().unwrap();
|
|
||||||
let connection = connection.deref();
|
|
||||||
let points: Vec<MountPoint> = mount_points
|
let points: Vec<MountPoint> = mount_points
|
||||||
.select((source, name))
|
.select((source, name))
|
||||||
.get_results(connection)?;
|
.get_results(connection.deref())?;
|
||||||
for point in points {
|
for point in points {
|
||||||
vfs.mount(&Path::new(&point.source), &point.name)?;
|
vfs.mount(&Path::new(&point.source), &point.name)?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue