diff --git a/src/api/sqliteConnector.cpp b/src/api/sqliteConnector.cpp index 3c33bca..deabb43 100644 --- a/src/api/sqliteConnector.cpp +++ b/src/api/sqliteConnector.cpp @@ -37,32 +37,78 @@ bool SqliteConnector::open() return false; } - rs = sqlite3_exec(_db, "CREATE TABLE IF NOT EXISTS metadata (title VARCHAR, localPath VARCHAR, size VARCHAR, fileType VARCHAR, lasteditDate VARCHAR, type INT, state INT, etag VARCHAR, path VARCHAR, parentPath VARCHAR, key VARCHAR, PRIMARY KEY (key))", NULL, 0, NULL); + rs = sqlite3_exec(_db, "CREATE TABLE IF NOT EXISTS metadata (title VARCHAR, localPath VARCHAR, size VARCHAR, fileType VARCHAR, lasteditDate VARCHAR, type INT, state INT, etag VARCHAR, path VARCHAR PRIMARY KEY, parentPath VARCHAR)", NULL, 0, NULL); return true; } -string SqliteConnector::getEtag(string path) +string SqliteConnector::getEtag(const string &path) { open(); int rs; sqlite3_stmt *stmt = 0; std::vector items; + string etag = "not found"; rs = sqlite3_prepare_v2(_db, "SELECT etag FROM 'metadata' WHERE path = ? LIMIT 1;", -1, &stmt, 0); rs = sqlite3_bind_text(stmt, 1, path.c_str(), path.length(), NULL); - //TODO erase while while (sqlite3_step(stmt) == SQLITE_ROW) { - path = reinterpret_cast(sqlite3_column_text(stmt, 0)); + etag = reinterpret_cast(sqlite3_column_text(stmt, 0)); } sqlite3_finalize(stmt); sqlite3_close(_db); - return path; + return etag; +} + +FileState SqliteConnector::getState(const string &path) +{ + open(); + + int rs; + sqlite3_stmt *stmt = 0; + std::vector items; + FileState state = FileState::ICLOUD; + + rs = sqlite3_prepare_v2(_db, "SELECT state FROM 'metadata' WHERE path = ? LIMIT 1;", -1, &stmt, 0); + rs = sqlite3_bind_text(stmt, 1, path.c_str(), path.length(), NULL); + + while (sqlite3_step(stmt) == SQLITE_ROW) + { + state = static_cast(sqlite3_column_int(stmt,0)); + } + + sqlite3_finalize(stmt); + sqlite3_close(_db); + return state; +} + +bool SqliteConnector::updateState(const string &path, FileState state) +{ + open(); + int rs; + sqlite3_stmt *stmt = 0; + + rs = sqlite3_prepare_v2(_db, "UPDATE 'metadata' SET state=? WHERE path=?", -1, &stmt, 0); + rs = sqlite3_bind_int(stmt, 1, state); + rs = sqlite3_bind_text(stmt, 2, path.c_str(), path.length(), NULL); + rs = sqlite3_step(stmt); + + if (rs != SQLITE_DONE) + { + Log::writeErrorLog(sqlite3_errmsg(_db) + std::string(" (Error Code: ") + std::to_string(rs) + ")"); + } + rs = sqlite3_clear_bindings(stmt); + rs = sqlite3_reset(stmt); + + sqlite3_finalize(stmt); + sqlite3_close(_db); + + return true; } std::vector SqliteConnector::getItemsChildren(const string &parentPath) @@ -73,35 +119,25 @@ std::vector SqliteConnector::getItemsChildren(const string &parentPa sqlite3_stmt *stmt = 0; std::vector items; - - rs = sqlite3_prepare_v2(_db, "SELECT title, localPath, path, size, etag, fileType, lastEditDate, type, state FROM 'metadata' WHERE parentPath = ?;", -1, &stmt, 0); + rs = sqlite3_prepare_v2(_db, "SELECT title, localPath, path, size, etag, fileType, lastEditDate, type, state FROM 'metadata' WHERE path=? OR parentPath=? ORDER BY parentPath;", -1, &stmt, 0); rs = sqlite3_bind_text(stmt, 1, parentPath.c_str(), parentPath.length(), NULL); + rs = sqlite3_bind_text(stmt, 2, parentPath.c_str(), parentPath.length(), NULL); while (sqlite3_step(stmt) == SQLITE_ROW) { + WebDAVItem temp; - WebDAVItem temp; - - temp.title = reinterpret_cast(sqlite3_column_text(stmt, 0)); - temp.localPath = reinterpret_cast(sqlite3_column_text(stmt, 1)); - temp.path = reinterpret_cast(sqlite3_column_text(stmt, 2)); - temp.size = reinterpret_cast(sqlite3_column_text(stmt, 3)); - temp.etag = reinterpret_cast(sqlite3_column_text(stmt, 4)); - temp.fileType = reinterpret_cast(sqlite3_column_text(stmt, 5)); - temp.lastEditDate = reinterpret_cast(sqlite3_column_text(stmt, 6)); - temp.type = static_cast(sqlite3_column_int(stmt,7)); - temp.state = static_cast(sqlite3_column_int(stmt,8)); - - items.push_back(temp); - // - //TODO also for folders - /* - if (iv_access(tempItem.localPath.c_str(), W_OK) != 0) - tempItem.state = FileState::ICLOUD; - else - tempItem.state = FileState::ISYNCED; - */ + temp.title = reinterpret_cast(sqlite3_column_text(stmt, 0)); + temp.localPath = reinterpret_cast(sqlite3_column_text(stmt, 1)); + temp.path = reinterpret_cast(sqlite3_column_text(stmt, 2)); + temp.size = reinterpret_cast(sqlite3_column_text(stmt, 3)); + temp.etag = reinterpret_cast(sqlite3_column_text(stmt, 4)); + temp.fileType = reinterpret_cast(sqlite3_column_text(stmt, 5)); + temp.lastEditDate = reinterpret_cast(sqlite3_column_text(stmt, 6)); + temp.type = static_cast(sqlite3_column_int(stmt,7)); + temp.state = static_cast(sqlite3_column_int(stmt,8)); + items.push_back(temp); } sqlite3_finalize(stmt); @@ -114,7 +150,6 @@ void SqliteConnector::deleteChildren(const string &parentPath) open(); int rs; sqlite3_stmt *stmt = 0; - Log::writeInfoLog(parentPath); rs = sqlite3_prepare_v2(_db, "DELETE FROM 'metadata' WHERE parentPath like ?", -1, &stmt, 0); rs = sqlite3_bind_text(stmt, 1, parentPath.c_str(), parentPath.length(), NULL); @@ -128,14 +163,10 @@ void SqliteConnector::deleteChildren(const string &parentPath) } -//TODO for folder write to all below folder or do singles? -// void SqliteConnector::updateState(const WebDAVItem - bool SqliteConnector::saveItemsChildren(const std::vector &items) { open(); int rs; - string key; sqlite3_stmt *stmt = 0; string parent = items.at(0).path; @@ -144,13 +175,10 @@ bool SqliteConnector::saveItemsChildren(const std::vector &items) //rs = sqlite3_prepare_v2(_db, "INSERT INTO 'metadata' (title, localPath, path, size, parentPath, etag, fileType, lastEditDate, type, state, key) VALUES (?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(key) DO UPDATE SET etag=?, size=?, lastEditDate=? WHERE metadata.etag <> ?;", -1, &stmt, 0); deleteChildren(parent); - - rs = sqlite3_prepare_v2(_db, "INSERT INTO 'metadata' (title, localPath, path, size, parentPath, etag, fileType, lastEditDate, type, state, key) VALUES (?,?,?,?,?,?,?,?,?,?,?);", -1, &stmt, 0); - rs = sqlite3_exec(_db, "BEGIN TRANSACTION;", NULL, NULL, NULL); - for (auto item : items) { - Log::writeInfoLog("item :" + item.title); + rs = sqlite3_prepare_v2(_db, "INSERT INTO 'metadata' (title, localPath, path, size, parentPath, etag, fileType, lastEditDate, type, state) VALUES (?,?,?,?,?,?,?,?,?,?);", -1, &stmt, 0); + rs = sqlite3_exec(_db, "BEGIN TRANSACTION;", NULL, NULL, NULL); rs = sqlite3_bind_text(stmt, 1, item.title.c_str(), item.title.length(), NULL); rs = sqlite3_bind_text(stmt, 2, item.localPath.c_str(), item.localPath.length(), NULL); rs = sqlite3_bind_text(stmt, 3, item.path.c_str(), item.path.length(), NULL); @@ -161,13 +189,27 @@ bool SqliteConnector::saveItemsChildren(const std::vector &items) rs = sqlite3_bind_text(stmt, 8, item.lastEditDate.c_str(), item.lastEditDate.length(), NULL); rs = sqlite3_bind_int(stmt, 9, item.type); rs = sqlite3_bind_int(stmt, 10, item.state); - key = parent + item.title; - rs = sqlite3_bind_text(stmt, 11, key.c_str(),key.length(),NULL); rs = sqlite3_step(stmt); if (rs == SQLITE_CONSTRAINT) { - Log::writeInfoLog("item exists already: " + item.path); + rs = sqlite3_clear_bindings(stmt); + rs = sqlite3_reset(stmt); + + rs = sqlite3_prepare_v2(_db, "UPDATE 'metadata' SET state=?, etag=?, lastEditDate=?, size=? WHERE path=?", -1, &stmt, 0); + rs = sqlite3_bind_int(stmt, 1, item.state); + rs = sqlite3_bind_text(stmt, 2, item.etag.c_str(), item.etag.length(), NULL); + rs = sqlite3_bind_text(stmt, 3, item.lastEditDate.c_str(), item.lastEditDate.length(), NULL); + rs = sqlite3_bind_text(stmt, 4, item.size.c_str(), item.size.length(), NULL); + rs = sqlite3_bind_text(stmt, 5, item.path.c_str(), item.path.length(), NULL); + rs = sqlite3_step(stmt); + + if (rs != SQLITE_DONE) + { + Log::writeErrorLog(sqlite3_errmsg(_db) + std::string(" (Error Code: ") + std::to_string(rs) + ")"); + } + rs = sqlite3_clear_bindings(stmt); + rs = sqlite3_reset(stmt); } else if (rs != SQLITE_DONE) { diff --git a/src/api/sqliteConnector.h b/src/api/sqliteConnector.h index a65d0ca..354a822 100644 --- a/src/api/sqliteConnector.h +++ b/src/api/sqliteConnector.h @@ -28,7 +28,11 @@ public: bool open(); - std::string getEtag(std::string path); + std::string getEtag(const std::string &path); + + FileState getState(const std::string &path); + + bool updateState(const std::string &path, FileState state); std::vector getItemsChildren(const std::string &parenthPath);