diff --git a/inc/lektor/database.h b/inc/lektor/database.h
index 303d8499032baad782b4f1355b3539902ac480c8..dbd58d75ccb24200c04c2caec39a6f7d22fcfabf 100644
--- a/inc/lektor/database.h
+++ b/inc/lektor/database.h
@@ -34,6 +34,8 @@ struct lkt_queue_state {
 /* Open correctly a database for lektor. */
 bool database_new(sqlite3 **db);
 bool database_open(sqlite3 *db, const char *dbpath);
+bool database_attach(sqlite3 *db, const char *name, const char *dbpath);
+bool database_detach(sqlite3 *db, const char *name);
 
 /* Get information on the queue and currently playing kara. */
 bool database_queue_state(sqlite3 *db, struct lkt_queue_state *res);
@@ -123,8 +125,8 @@ bool database_plt_remove_pos(sqlite3 *db, const char *name, int pos);
 bool database_plt_clear(sqlite3 *db, const char *name);
 bool database_plt_rename(sqlite3 *db, const char *old_name, const char *new_name);
 
-bool database_plt_export(sqlite3 *db, const char *name, const char *file);
-bool database_plt_import(sqlite3 *db, const char *name, const char *file);
+bool database_plt_export(sqlite3 *db, const char *name);
+bool database_plt_import(sqlite3 *db, const char *name);
 
 bool database_plt_add_uri(sqlite3 *db, const char *name, struct lkt_uri_t *uri);
 
diff --git a/inc/lektor/macro.h b/inc/lektor/macro.h
new file mode 100644
index 0000000000000000000000000000000000000000..faa7c53e097a36da8a1c61c6c7ded9122e4554c4
--- /dev/null
+++ b/inc/lektor/macro.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#define SQLITE_PREPARE(db, stmt, SQL, goto_label)                   \
+    if (sqlite3_prepare_v2(db, SQL, -1, &stmt, 0) != SQLITE_OK) {   \
+        fprintf(stderr, " ! %s: Failed to prepare statement: %s\n", \
+                __func__, sqlite3_errmsg(db));                      \
+        goto goto_label;                                            \
+    }
+
+#define LKT_MAX_SQLITE_STATEMENT    1024
+#define PROTECTED_DATABASE          "disk"
+
+#ifndef MAX
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+#endif /* MAX */
+
+#ifndef MIN
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+#endif /* MIN */
diff --git a/src/commands.c b/src/commands.c
index 32565f6f04cce2add02f670400e3232a90ab97ff..64aa02c716aa9160fcba5363cc48a234358d5103 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -871,27 +871,49 @@ command_plt_rename(sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], long long int
 bool
 command_plt_export(sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], long long int *watch_mask_ptr)
 {
+    int ret = false;
+
     if (args == NULL || args[0] == NULL || args[1] == NULL)
         return false;
 
-    if (database_plt_export(db, args[0], args[1])) {
-        *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-        return true;
-    } else
-        return false;
+    if (!database_attach(db, args[0], args[1]))
+        goto error;
+
+    if (!database_plt_export(db, args[0]))
+        goto error;
+
+    if (!database_detach(db, args[0]))
+        goto error;
+
+    fprintf(stderr, " * Exported playlist %s with path '%s'\n", args[0], args[1]);
+    *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
+    ret = true;
+error:
+    return ret;
 }
 
 bool
 command_plt_import(sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], long long int *watch_mask_ptr)
 {
+    int ret = false;
+
     if (args == NULL || args[0] == NULL || args[1] == NULL)
         return false;
 
-    if (database_plt_import(db, args[0], args[1])) {
-        *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-        return true;
-    } else
-        return false;
+    if (!database_attach(db, args[0], args[1]))
+        goto error;
+
+    if (!database_plt_import(db, args[0]))
+        goto error;
+
+    if (!database_detach(db, args[0]))
+        goto error;
+
+    fprintf(stderr, " * Imported playlist %s with path '%s'\n", args[0], args[1]);
+    *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
+    ret = true;
+error:
+    return ret;
 }
 
 bool
diff --git a/src/database/open.c b/src/database/open.c
index b493bf2612155e06d2ec03e0222e73a92068c1b4..2797b6bfabe50f03f74fbf45829f569ea515b1c9 100644
--- a/src/database/open.c
+++ b/src/database/open.c
@@ -1,9 +1,11 @@
 #define _POSIX_C_SOURCE 200809L
 
 #include <lektor/database.h>
+#include <lektor/macro.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 
 /* Some notes:
    - There's one and only row.
@@ -87,6 +89,79 @@ err_not_init:
     return false;
 }
 
+static inline bool
+__attach(sqlite3 *db, const char *name, const char *path)
+{
+    static const char SQL_ATTACH_TEMPLATE[] = "ATTACH '%s' AS '%s';";
+    size_t len = strlen(path) + strlen(name) + (sizeof(SQL_ATTACH_TEMPLATE) / sizeof(char));
+    char *SQL_ATTACH = (char *) calloc(len, sizeof(char));
+    bool ret = false;
+    snprintf(SQL_ATTACH, len - 1, SQL_ATTACH_TEMPLATE, path, name);
+
+    if (SQLITE_OK != sqlite3_exec(db, SQL_ATTACH, 0, 0, 0)) {
+        fprintf(stderr, " * Failed to attach database named %s with path %s: %s\n",
+                name, path, sqlite3_errmsg(db));
+        goto err_no_attach;
+    }
+
+    fprintf(stderr, " * Attached database '%s' with path '%s'\n", name, path);
+    ret = true;
+err_no_attach:
+    free(SQL_ATTACH);
+    return ret;
+}
+
+static inline bool
+__detach(sqlite3 *db, const char *name)
+{
+    static const char SQL_DETACH_TEMPLATE[] = "DETACH '%s';\n";
+    size_t len = strlen(name) + (sizeof(SQL_DETACH_TEMPLATE) / sizeof(char));
+    char *SQL_DETACH = (char *) calloc(len, sizeof(char));
+    bool ret = false;
+    snprintf(SQL_DETACH, len - 1, SQL_DETACH_TEMPLATE, name);
+
+    if (SQLITE_OK != sqlite3_exec(db, SQL_DETACH, 0, 0, 0)) {
+        fprintf(stderr, " * Failed to detach database named %s: %s\n",
+                name, sqlite3_errmsg(db));
+        goto err_no_detach;
+    }
+
+    fprintf(stderr, " * Detached database '%s'\n", name);
+    ret = true;
+err_no_detach:
+    free(SQL_DETACH);
+    return ret;
+}
+
+static inline bool
+__is_attached(sqlite3 *db, const char *name)
+{
+    static const char *SQL_STMT = "SELECT name FROM pragma_database_list WHERE name = ?;\n";
+    sqlite3_stmt *stmt = 0;
+    int code = 0;
+    bool ret = false;
+
+    if (SQLITE_OK != sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0)) {
+        fprintf(stderr, " . __is_attached: Failed to prepare statement: %s\n",
+                sqlite3_errmsg(db));
+        goto error;
+    }
+
+    if (SQLITE_OK != sqlite3_bind_text(stmt, 1, name, -1, 0)) {
+        fprintf(stderr, " . __is_attached: Failed to bind name: %s\n",
+                sqlite3_errmsg(db));
+        goto error;
+    }
+
+    code = sqlite3_step(stmt);
+    if (code == SQLITE_ROW)
+        ret = true;
+
+error:
+    sqlite3_finalize(stmt);
+    return ret;
+}
+
 bool
 database_open(sqlite3 *db, const char *dbpath)
 {
@@ -95,20 +170,62 @@ database_open(sqlite3 *db, const char *dbpath)
         return false;
     }
 
-    static const char SQL_ATTACH_TEMPLATE[] = "ATTACH '%s' AS disk;";
-    size_t len = strlen(dbpath) + (sizeof(SQL_ATTACH_TEMPLATE) / sizeof(char));
-    char *SQL_ATTACH = (char *) calloc(len, sizeof(char));
-    snprintf(SQL_ATTACH, len - 1, SQL_ATTACH_TEMPLATE, dbpath);
+    return __attach(db, PROTECTED_DATABASE, dbpath);
+}
 
-    if (SQLITE_OK != sqlite3_exec(db, SQL_ATTACH, 0, 0, 0)) {
-        fprintf(stderr, " ! database_open: Failed to attach disk database %s: %s\n",
-                dbpath, sqlite3_errmsg(db));
-        goto err_no_attach;
+bool
+database_attach(sqlite3 *db, const char *name, const char *dbpath)
+{
+    if (!strcasecmp(PROTECTED_DATABASE, name)) {
+        fprintf(stderr, " ! database_attach: The database " PROTECTED_DATABASE
+                " is protected, can't attach a database with the same name\n");
+        return false;
+    }
+
+    if (is_sql_str_invalid(name)) {
+        fprintf(stderr, " ! database_attach: The database name %s is invalid\n", name);
+        return false;
     }
 
+    if (__is_attached(db, name)) {
+        fprintf(stderr, " ! database_detach: Database named %s is already attached\n", name);
+        return false;
+    }
+
+    if (!__attach(db, name, dbpath)) {
+        fprintf(stderr, " ! database_attach: Failed to attach database named '%s' with path '%s'\n",
+                name, dbpath);
+        return false;
+    }
+
+    fprintf(stderr, " * Database %s attached\n", name);
     return true;
+}
 
-err_no_attach:
-    free(SQL_ATTACH);
-    return false;
+bool
+database_detach(sqlite3 *db, const char *name)
+{
+    if (!strcasecmp(PROTECTED_DATABASE, name)) {
+        fprintf(stderr, " ! database_detach: The database " PROTECTED_DATABASE
+                " is protected, can't detach it\n");
+        return false;
+    }
+
+    if (is_sql_str_invalid(name)) {
+        fprintf(stderr, " ! database_detach: The database name %s is invalid\n", name);
+        return false;
+    }
+
+    if (!__is_attached(db, name)) {
+        fprintf(stderr, " ! database_detach: Database named %s is not attached\n", name);
+        return false;
+    }
+
+    if (!__detach(db, name)) {
+        fprintf(stderr, " ! database_detach: Failed to detach database named %s\n", name);
+        return false;
+    }
+
+    fprintf(stderr, " * Database %s detached\n", name);
+    return true;
 }
diff --git a/src/database/playlist.c b/src/database/playlist.c
index 8093c6277797b09531023e573672e28514c6a770..9616ba1d2754beb382753221a861aa9cefcece59 100644
--- a/src/database/playlist.c
+++ b/src/database/playlist.c
@@ -1,5 +1,13 @@
+#define _POSIX_C_SOURCE 200809L
+
 #include <lektor/database.h>
+#include <lektor/macro.h>
 #include <stdio.h>
+#include <strings.h>
+
+/* Find it in database/open.c */
+extern int
+is_sql_str_invalid(const char *str);
 
 bool
 database_plt_create(sqlite3 *db, const char *name)
@@ -163,21 +171,82 @@ error:
 }
 
 bool
-database_plt_export(sqlite3 *db, const char *name, const char *file)
+database_plt_export(sqlite3 *db, const char *name)
 {
-    (void) db;
-    (void) name;
-    (void) file;
-    return false;
+    static const char *SQL_SCHEM =
+        "CREATE TABLE IF NOT EXISTS %s.content"
+        "( kara_id INTEGER PRIMARY KEY NOT NULL CHECK(kara_id > 0) );";
+    char SQL_STMT[1024];
+    int code, ret = false;
+    sqlite3_stmt *stmt;
+
+    if (is_sql_str_invalid(name)) {
+        fprintf(stderr, " . database_plt_export: Name of playlist '%s' is invalid\n",
+                name);
+        goto error;
+    }
+
+    if (!strcasecmp(name, PROTECTED_DATABASE)) {
+        fprintf(stderr, " . database_plt_export: Name '" PROTECTED_DATABASE
+                "' is protected, you can't use it for a playlist name\n");
+        goto error;
+    }
+
+    snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_SCHEM, name);
+    SQL_STMT[LKT_MAX_SQLITE_STATEMENT - 1] = 0;
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
+    code = sqlite3_step(stmt);
+
+    if (code != SQLITE_DONE && code != SQLITE_OK) {
+        fprintf(stderr, " . database_plt_export: Failed to create schema: %s\n",
+                sqlite3_errmsg(db));
+        goto error;
+    }
+
+    ret = true;
+error:
+    sqlite3_finalize(stmt);
+    return ret;
 }
 
 bool
-database_plt_import(sqlite3 *db, const char *name, const char *file)
+database_plt_import(sqlite3 *db, const char *name)
 {
-    (void) db;
-    (void) name;
-    (void) file;
-    return false;
+    static const char *SQL_SCHEM =
+        "INSERT OR IGNORE INTO kara_playlist (kara_id, playlist_id)"
+        " SELECT %s.content.kara_id, ( SELECT id FROM playlist WHERE name = %s LIMIT 1 )"
+        " FROM %s.content;\n";
+    char SQL_STMT[1024];
+    int code, ret = false;
+    sqlite3_stmt *stmt;
+
+    if (is_sql_str_invalid(name)) {
+        fprintf(stderr, " . database_plt_import: Name of playlist '%s' is invalid\n",
+                name);
+        goto error;
+    }
+
+    if (!strcasecmp(name, PROTECTED_DATABASE)) {
+        fprintf(stderr, " . database_plt_import: Name '" PROTECTED_DATABASE
+                "' is protected, you can't use it for a playlist name\n");
+        goto error;
+    }
+
+    snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_SCHEM, name, name, name);
+    SQL_STMT[LKT_MAX_SQLITE_STATEMENT - 1] = 0;
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
+    code = sqlite3_step(stmt);
+
+    if (code != SQLITE_DONE && code != SQLITE_OK) {
+        fprintf(stderr, " . database_plt_import: Failed to import database: %s\n",
+                sqlite3_errmsg(db));
+        goto error;
+    }
+
+    ret = true;
+error:
+    sqlite3_finalize(stmt);
+    return ret;
 }
 
 bool
diff --git a/src/database/queue.c b/src/database/queue.c
index eb1d450949d3f9c51406d7517a97484937297d57..c45973de02d9901952c6ae6c9a0638f6077fe480 100644
--- a/src/database/queue.c
+++ b/src/database/queue.c
@@ -1,11 +1,12 @@
+#define _POSIX_C_SOURCE 200809L
+
 #include <lektor/database.h>
+#include <lektor/macro.h>
 
 #include <linux/limits.h>
 #include <stdio.h>
 #include <string.h>
 
-#define max(a, b) ((a) < (b) ? (b) : (a))
-
 /* Find in in database/open.c */
 extern int is_sql_str_invalid(const char *);
 
@@ -16,15 +17,11 @@ database_queue_state(sqlite3 *db, struct lkt_queue_state *res)
         "SELECT"
         "  volume, paused, random, repeat, single, current, duration, consume, "
         "  (SELECT COUNT(*) FROM queue) AS length "
-        "FROM queue_state";
+        "FROM queue_state;\n";
     sqlite3_stmt *stmt = 0;
     bool ret = false;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_state: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
 
     if (sqlite3_step(stmt) != SQLITE_ROW) {
         fprintf(stderr, " ! database_queue_state: queue_state has no row.\n");
@@ -66,12 +63,7 @@ database_queue_current_kara(sqlite3 *db, struct kara_metadata *res)
     sqlite3_stmt *stmt = 0;
     int code = -1;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_current_kara: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
-
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
     memset(res, 0, sizeof(struct kara_metadata));
     code = sqlite3_step(stmt);
 
@@ -116,12 +108,7 @@ queue_add_with_col_like_str(sqlite3 *db, const char *col, const char *val, int p
     sqlite3_stmt *stmt = NULL;
 
     snprintf(SQL, 1024, SQL_STMT, col);
-
-    if (sqlite3_prepare_v2(db, SQL, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! queue_add_with_col_like_str: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
+    SQLITE_PREPARE(db, stmt, SQL, error);
 
     if (sqlite3_bind_int(stmt, 1, priority) != SQLITE_OK ||
         sqlite3_bind_text(stmt, 2, val, -1, 0) != SQLITE_OK) {
@@ -178,12 +165,7 @@ queue_insert_with_col_like_str(sqlite3 *db, const char *col, const char *val, in
     sqlite3_stmt *stmt = NULL;
 
     snprintf(SQL, 1024, SQL_STMT, col);
-
-    if (sqlite3_prepare_v2(db, SQL, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! queue_insert_with_col_like_str: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
+    SQLITE_PREPARE(db, stmt, SQL, error);
 
     if (sqlite3_bind_int(stmt, 1, pos) != SQLITE_OK ||
         sqlite3_bind_text(stmt, 2, val, -1, 0) != SQLITE_OK) {
@@ -230,11 +212,7 @@ database_queue_add_plt(sqlite3 *db, const char *plt_name, int priority)
     bool status = false;
     sqlite3_stmt *stmt = NULL;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_add_plt: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
 
     if (sqlite3_bind_int(stmt, 1, priority) != SQLITE_OK ||
         sqlite3_bind_text(stmt, 2, plt_name, -1, 0) != SQLITE_OK) {
@@ -328,8 +306,7 @@ database_queue_add_id(sqlite3 *db, int id, int priority)
     bool status = false;
     sqlite3_stmt *stmt = NULL;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK)
-        goto error;
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
 
     if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK ||
         sqlite3_bind_int(stmt, 2, priority) != SQLITE_OK)
@@ -399,16 +376,12 @@ database_queue_next(sqlite3 *db, char filepath[PATH_MAX])
     int code = SQLITE_OK, id;
     sqlite3_stmt *stmt = NULL;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_next: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
 
     code = sqlite3_step(stmt);
 
     if (code == SQLITE_ROW) {
-        id = max(1, sqlite3_column_int(stmt, 1));
+        id = MAX(1, sqlite3_column_int(stmt, 1));
         snprintf(SQL_UPDATE, PATH_MAX, "UPDATE queue_state SET current = %d;", id);
 
         if (filepath != NULL)
@@ -473,16 +446,11 @@ database_queue_prev(sqlite3 *db, char filepath[PATH_MAX])
     int code = SQLITE_OK, id;
     sqlite3_stmt *stmt = NULL;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_prev: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
-
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
     code = sqlite3_step(stmt);
 
     if (code == SQLITE_ROW) {
-        id = max(1, sqlite3_column_int(stmt, 1));
+        id = MAX(1, sqlite3_column_int(stmt, 1));
         snprintf(SQL_UPDATE, PATH_MAX, "UPDATE queue_state SET current = %d;", id);
 
         if (filepath != NULL)
@@ -566,11 +534,7 @@ database_queue_move(sqlite3 *db, int from, int to)
     bool ret = false;
     int code;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_move: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
 
     if (sqlite3_bind_int(stmt, 1, to) != SQLITE_OK ||
         sqlite3_bind_int(stmt, 2, to) != SQLITE_OK ||
@@ -603,11 +567,7 @@ database_queue_play(sqlite3 *db, int pos)
     bool ret = false;
     sqlite3_stmt *stmt = NULL;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_play: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
 
     if (sqlite3_bind_int(stmt, 1, pos) != SQLITE_OK) {
         fprintf(stderr, " ! database_queue_play: Failed to bind start position: %s\n",
@@ -683,12 +643,7 @@ database_queue_get_current_file(sqlite3 *db, char filepath[PATH_MAX])
     if (filepath == NULL)
         goto error;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_get_current_file: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
-
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
     code = sqlite3_step(stmt);
 
     if (code == SQLITE_ROW)
@@ -804,11 +759,7 @@ database_queue_list_abs(sqlite3 *db, unsigned int from, unsigned int to, void *a
     bool ret = false;
     sqlite3_stmt *stmt;
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_list: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
 
     if (sqlite3_bind_int(stmt, 1, from) != SQLITE_OK
         || sqlite3_bind_int(stmt, 2, to) != SQLITE_OK) {
@@ -866,11 +817,7 @@ database_queue_list_from(sqlite3 *db, unsigned int count, void *args,
 
     snprintf(SQL_STMT, stmt_len, SQL_TEMPLATE, count);
 
-    if (sqlite3_prepare_v2(db, SQL_STMT, -1, &stmt, 0) != SQLITE_OK) {
-        fprintf(stderr, " ! database_queue_list: Failed to prepare statement: %s\n",
-                sqlite3_errmsg(db));
-        goto error;
-    }
+    SQLITE_PREPARE(db, stmt, SQL_STMT, error);
 
     for (;;) {
         code = sqlite3_step(stmt);
diff --git a/src/main/lktadm.c b/src/main/lktadm.c
index 59681e77053fb04a661732e2b3ad409314e76199..17ea343bf50c1a216ede55c2e7f4987518e96a3c 100644
--- a/src/main/lktadm.c
+++ b/src/main/lktadm.c
@@ -80,10 +80,10 @@ main(int argc, char *argv[])
             goto end_populate;
         }
 
-    if (!database_open(db, db_path)) {
-        fprintf(stderr, " ! lkt_listen: Failed to open database\n");
-        return 1;
-    }
+        if (!database_open(db, db_path)) {
+            fprintf(stderr, " ! lkt_listen: Failed to open database\n");
+            return 1;
+        }
 
         database_update(db, kara_dir);
         sqlite3_close(db);
diff --git a/src/net/listen.c b/src/net/listen.c
index 8818ad900ad37e50552ff365d20f1bd37141cb0f..cade02db046d9f3d707a630feecfe0e5dda06667 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -212,6 +212,10 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd)
             err = ! command_plt_add(srv->db, cmd.args, &srv->mpd_idle_events);
         else if (!strcmp(cmd.name, "rm") && cmd.args[0] != NULL && cmd.args[1] == NULL)
             err = ! command_plt_remove(srv->db, cmd.args, &srv->mpd_idle_events);
+        else if (!strcmp(cmd.name, "save"))
+            err = ! command_plt_export(srv->db, cmd.args, &srv->mpd_idle_events);
+        else if (!strcmp(cmd.name, "__import"))
+            err = ! command_plt_import(srv->db, cmd.args, &srv->mpd_idle_events);
 
         else if (!strcmp(cmd.name, "random"))
             err = !command_set_playback_option(srv, c, lkt_playback_option_random, cmd.args);
@@ -736,6 +740,14 @@ lkt_listen(void)
         return 1;
     }
 
+    /* Finish to initialize. */
+
+    if (!database_config_get_text(srv.db, "database", "db_path", db_path, PATH_MAX)) {
+        fprintf(stderr, " ! lkt_listen: Failed to get database path\n");
+        goto end_free_strings;
+    }
+
+
     if (!database_open(srv.db, db_path)) {
         fprintf(stderr, " ! lkt_listen: Failed to open database\n");
         return 1;
@@ -748,11 +760,6 @@ lkt_listen(void)
         return 1;
     }
 
-    if (!database_config_get_text(srv.db, "database", "db_path", db_path, PATH_MAX)) {
-        fprintf(stderr, " ! lkt_listen: Failed to get database path\n");
-        goto end_free_strings;
-    }
-
     if (!database_config_get_text(srv.db, "database", "kara_dir", kara_dir, PATH_MAX)) {
         fprintf(stderr, " ! lkt_listen: Failed to get kara directory\n");
         goto end_free_strings;