From 796a4c60b9d7cdfdfe7496b63c5d346ece46fc69 Mon Sep 17 00:00:00 2001 From: Alex-Monahan Date: Thu, 24 Oct 2024 14:21:52 -0700 Subject: [PATCH 1/2] Delete sheet1 content before writing --- src/gsheets_copy.cpp | 9 ++++++--- src/gsheets_requests.cpp | 25 +++++++++++++++++++++++++ src/include/gsheets_requests.hpp | 3 +++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/gsheets_copy.cpp b/src/gsheets_copy.cpp index 566ae31..38bf147 100644 --- a/src/gsheets_copy.cpp +++ b/src/gsheets_copy.cpp @@ -72,6 +72,10 @@ namespace duckdb std::string sheet_id = extract_sheet_id(file_path); std::string sheet_name = "Sheet1"; // TODO: make this configurable + // If writing, clear out the entire sheet first. + // Do this here in the initialization so that it only happens once + std::string response = delete_sheet_data(sheet_id, token, sheet_name); + return make_uniq(context, sheet_id, token, sheet_name); } @@ -92,6 +96,8 @@ namespace duckdb sheet_data["range"] = "Sheet1"; sheet_data["majorDimension"] = "ROWS"; + // TODO: Add column headers + vector> values; for (idx_t r = 0; r < input.size(); r++) { @@ -129,9 +135,6 @@ namespace duckdb // Make the API call to write data to the Google Sheet // Today, this is only append. - // To overwrite, need to detect if we are the first data chunk and clear out the sheet. - // Is there a way to force that to happen only once, even in the presence of multithreading? - // Maybe this? https://github.com/duckdb/duckdb/pull/7368 std::string response = fetch_sheet_data(gstate.sheet_id, gstate.token, gstate.sheet_name, HttpMethod::POST, request_body); // Check for errors in the response diff --git a/src/gsheets_requests.cpp b/src/gsheets_requests.cpp index d1549de..b980460 100644 --- a/src/gsheets_requests.cpp +++ b/src/gsheets_requests.cpp @@ -102,4 +102,29 @@ namespace duckdb return perform_https_request(host, path, token, method, body); } + + std::string delete_sheet_data(const std::string &sheet_id, const std::string &token, const std::string &sheet_name) + { + std::string host = "sheets.googleapis.com"; + std::string path = "/v4/spreadsheets/" + sheet_id + ":batchUpdate"; + + // TODO: Either pass in the sheetId (parsed from the URL) + // or build another method to ping the GSheets API to convert from sheet_name to sheetId in some way + std::string body = R"( + { + "requests": [ + { + "updateCells": { + "range": { + "sheetId": 0 + }, + "fields": "userEnteredValue" + } + } + ] + } + )"; + + return perform_https_request(host, path, token, HttpMethod::POST, body); + } } diff --git a/src/include/gsheets_requests.hpp b/src/include/gsheets_requests.hpp index 9476f1a..4e6ec4a 100644 --- a/src/include/gsheets_requests.hpp +++ b/src/include/gsheets_requests.hpp @@ -14,4 +14,7 @@ std::string perform_https_request(const std::string& host, const std::string& pa HttpMethod method = HttpMethod::GET, const std::string& body = "", const std::string& content_type = "application/json"); std::string fetch_sheet_data(const std::string& sheet_id, const std::string& token, const std::string& sheet_name, HttpMethod method = HttpMethod::GET, const std::string& body = ""); + +std::string delete_sheet_data(const std::string& sheet_id, const std::string& token, const std::string& sheet_name); + } \ No newline at end of file From 1423e404b4a85edd385d046ac3bbddc0ae73f12b Mon Sep 17 00:00:00 2001 From: Alex-Monahan Date: Thu, 24 Oct 2024 14:37:53 -0700 Subject: [PATCH 2/2] Use :clear API so sheet_name can be used --- src/gsheets_requests.cpp | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/gsheets_requests.cpp b/src/gsheets_requests.cpp index b980460..ec21e59 100644 --- a/src/gsheets_requests.cpp +++ b/src/gsheets_requests.cpp @@ -3,7 +3,6 @@ #include #include #include - namespace duckdb { @@ -106,25 +105,8 @@ namespace duckdb std::string delete_sheet_data(const std::string &sheet_id, const std::string &token, const std::string &sheet_name) { std::string host = "sheets.googleapis.com"; - std::string path = "/v4/spreadsheets/" + sheet_id + ":batchUpdate"; - - // TODO: Either pass in the sheetId (parsed from the URL) - // or build another method to ping the GSheets API to convert from sheet_name to sheetId in some way - std::string body = R"( - { - "requests": [ - { - "updateCells": { - "range": { - "sheetId": 0 - }, - "fields": "userEnteredValue" - } - } - ] - } - )"; - - return perform_https_request(host, path, token, HttpMethod::POST, body); + std::string path = "/v4/spreadsheets/" + sheet_id + "/values/" + sheet_name + ":clear"; + + return perform_https_request(host, path, token, HttpMethod::POST, "{}"); } }