From 369d62ddcde758ab774701367da3b343d2d0f6f7 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Fri, 10 Apr 2020 09:38:20 +0200
Subject: [PATCH] WIP: Functions to transerfer data between databases

---
 inc/lektor/database.h   |  4 +-
 inc/lektor/macro.h      |  9 ++---
 src/commands.c          | 20 ++++-----
 src/database/open.c     |  3 +-
 src/database/playlist.c | 89 ++++++++++++++++++++++++++++++++++++-----
 5 files changed, 96 insertions(+), 29 deletions(-)

diff --git a/inc/lektor/database.h b/inc/lektor/database.h
index ea4d079b..dbd58d75 100644
--- a/inc/lektor/database.h
+++ b/inc/lektor/database.h
@@ -125,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
index 65447285..faa7c53e 100644
--- a/inc/lektor/macro.h
+++ b/inc/lektor/macro.h
@@ -1,16 +1,15 @@
 #pragma once
 
-#ifndef __FUNCTION__
-#define __FUNCTION__ __func__
-#endif /* __FUNCTION__ */
-
 #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", \
-                __FUNCTION__, sqlite3_errmsg(db));                  \
+                __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 */
diff --git a/src/commands.c b/src/commands.c
index 32565f6f..3ac24119 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -874,11 +874,11 @@ command_plt_export(sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], long long int
     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_plt_export(db, args[0], args[1])) {
+    //     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
+    //     return true;
+    // } else
+    //     return false;
 }
 
 bool
@@ -887,11 +887,11 @@ command_plt_import(sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], long long int
     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_plt_import(db, args[0], args[1])) {
+    //     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
+    //     return true;
+    // } else
+    //     return false;
 }
 
 bool
diff --git a/src/database/open.c b/src/database/open.c
index 0e93589d..2797b6bf 100644
--- a/src/database/open.c
+++ b/src/database/open.c
@@ -1,13 +1,12 @@
 #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>
 
-#define PROTECTED_DATABASE "disk"
-
 /* Some notes:
    - There's one and only row.
    - `paused` 0 = play, 1 = paused
diff --git a/src/database/playlist.c b/src/database/playlist.c
index 8093c627..9616ba1d 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
-- 
GitLab