diff --git a/internal/google/sheets/models.go b/internal/google/sheets/models.go index f7bb5b0..5595685 100644 --- a/internal/google/sheets/models.go +++ b/internal/google/sheets/models.go @@ -2,7 +2,6 @@ package sheets import ( "fmt" - "strconv" "strings" ) @@ -134,12 +133,14 @@ func (r rawQueryRowsResult) convertRawValue(cellIdx int, cell rawQueryRowsResult col := r.Table.Cols[cellIdx] switch col.Type { case "boolean": - return cell.Raw == "true", nil + return strings.ToLower(cell.Raw) == "true", nil case "number": if strings.Contains(cell.Raw, ".") { - return strconv.ParseFloat(cell.Raw, 64) + return cell.Value, nil + } else { + val := cell.Value.(float64) + return int64(val), nil } - return strconv.ParseInt(cell.Raw, 10, 64) case "string": // `string` type does not have the raw value return cell.Value, nil diff --git a/internal/google/sheets/models_test.go b/internal/google/sheets/models_test.go index ece4963..ae2bde7 100644 --- a/internal/google/sheets/models_test.go +++ b/internal/google/sheets/models_test.go @@ -87,18 +87,28 @@ func TestRawQueryRowsResult_toQueryRowsResult(t *testing.T) { Cols: []rawQueryRowsResultColumn{ {ID: "A", Type: "number"}, {ID: "B", Type: "string"}, + {ID: "C", Type: "boolean"}, }, Rows: []rawQueryRowsResultRow{ { []rawQueryRowsResultCell{ - {Value: 123, Raw: "123"}, + {Value: 123.0, Raw: "123"}, {Value: "blah", Raw: "blah"}, + {Value: "true", Raw: "blah"}, }, }, { []rawQueryRowsResultCell{ - {Value: 456, Raw: "456"}, + {Value: 456.0, Raw: "456"}, {Value: "blah2", Raw: "blah2"}, + {Value: "FALSE", Raw: "blah"}, + }, + }, + { + []rawQueryRowsResultCell{ + {Value: 123.1, Raw: "123.1"}, + {Value: "blah", Raw: "blah"}, + {Value: "TRUE", Raw: "blah"}, }, }, }, @@ -107,8 +117,9 @@ func TestRawQueryRowsResult_toQueryRowsResult(t *testing.T) { expected := QueryRowsResult{ Rows: [][]interface{}{ - {int64(123), "blah"}, - {int64(456), "blah2"}, + {int64(123), "blah", true}, + {int64(456), "blah2", false}, + {123.1, "blah", true}, }, } diff --git a/row.go b/row.go index 9f33cdf..5c45837 100644 --- a/row.go +++ b/row.go @@ -30,13 +30,11 @@ func (c GoogleSheetRowStoreConfig) validate() error { // GoogleSheetRowStore encapsulates row store functionality on top of a Google Sheet. type GoogleSheetRowStore struct { - wrapper sheetsWrapper - spreadsheetID string - sheetName string - scratchpadSheetName string - scratchpadLocation sheets.A1Range - colsMapping colsMapping - config GoogleSheetRowStoreConfig + wrapper sheetsWrapper + spreadsheetID string + sheetName string + colsMapping colsMapping + config GoogleSheetRowStoreConfig } // Select specifies which columns to return from the Google Sheet when querying and the output variable @@ -105,9 +103,8 @@ func (s *GoogleSheetRowStore) Count() *GoogleSheetCountStmt { } // Close cleans up all held resources like the scratchpad cell booked for this specific GoogleSheetRowStore instance. -func (s *GoogleSheetRowStore) Close(ctx context.Context) error { - _, err := s.wrapper.Clear(ctx, s.spreadsheetID, []string{s.scratchpadLocation.Original}) - return err +func (s *GoogleSheetRowStore) Close(_ context.Context) error { + return nil } func (s *GoogleSheetRowStore) ensureHeaders() error { @@ -156,30 +153,19 @@ func NewGoogleSheetRowStore( } config = injectTimestampCol(config) - scratchpadSheetName := sheetName + scratchpadSheetNameSuffix store := &GoogleSheetRowStore{ - wrapper: wrapper, - spreadsheetID: spreadsheetID, - sheetName: sheetName, - scratchpadSheetName: scratchpadSheetName, - colsMapping: generateColumnMapping(config.Columns), - config: config, + wrapper: wrapper, + spreadsheetID: spreadsheetID, + sheetName: sheetName, + colsMapping: generateColumnMapping(config.Columns), + config: config, } _ = ensureSheets(store.wrapper, store.spreadsheetID, store.sheetName) - _ = ensureSheets(store.wrapper, store.spreadsheetID, store.scratchpadSheetName) - if err := store.ensureHeaders(); err != nil { panic(fmt.Errorf("error checking headers: %w", err)) } - - scratchpadLocation, err := findScratchpadLocation(store.wrapper, store.spreadsheetID, store.scratchpadSheetName) - if err != nil { - panic(fmt.Errorf("error finding a scratchpad location in sheet %s: %w", store.scratchpadSheetName, err)) - } - store.scratchpadLocation = scratchpadLocation - return store } diff --git a/row_test.go b/row_test.go index a76e063..fc138c8 100644 --- a/row_test.go +++ b/row_test.go @@ -34,7 +34,7 @@ func TestGoogleSheetRowStore_Integration(t *testing.T) { GoogleSheetRowStoreConfig{Columns: []string{"name", "age", "dob"}}, ) defer func() { - deleteSheet(t, db.wrapper, spreadsheetID, []string{db.sheetName, db.scratchpadSheetName}) + deleteSheet(t, db.wrapper, spreadsheetID, []string{db.sheetName}) _ = db.Close(context.Background()) }() diff --git a/stmt.go b/stmt.go index ad66545..ff2cddc 100644 --- a/stmt.go +++ b/stmt.go @@ -549,36 +549,24 @@ func (s *GoogleSheetCountStmt) Exec(ctx context.Context) (uint64, error) { return 0, err } - formula := fmt.Sprintf( - rwoCountQueryTemplate, - getA1Range(s.store.sheetName, defaultRowFullTableRange), - selectStmt, - ) - - result, err := s.store.wrapper.UpdateRows( - ctx, - s.store.spreadsheetID, - s.store.scratchpadLocation.Original, - [][]interface{}{{formula}}, - ) + result, err := s.store.wrapper.QueryRows(ctx, s.store.spreadsheetID, s.store.sheetName, selectStmt, true) if err != nil { return 0, err } - if len(result.UpdatedValues) == 0 || len(result.UpdatedValues[0]) == 0 { - return 0, fmt.Errorf("error retrieving row indices to delete: %+v", result) - } - raw := result.UpdatedValues[0][0].(string) - if raw == naValue || raw == errorValue || raw == "" { - return 0, fmt.Errorf("error retrieving row indices to delete: %s", raw) + if len(result.Rows) != 1 || len(result.Rows[0]) != 1 { + return 0, errors.New("") } - return strconv.ParseUint(raw, 10, 64) + + count := result.Rows[0][0].(int64) + return uint64(count), nil } func newGoogleSheetCountStmt(store *GoogleSheetRowStore) *GoogleSheetCountStmt { + countClause := fmt.Sprintf("COUNT(%s)", rowIdxCol) return &GoogleSheetCountStmt{ store: store, - queryBuilder: newQueryBuilder(store.colsMapping.NameMap(), []string{rowIdxCol}), + queryBuilder: newQueryBuilder(store.colsMapping.NameMap(), []string{countClause}), } }