From 5b940b28985a41d90e417985f9c9c5df7aacdeea Mon Sep 17 00:00:00 2001 From: Milan Pavlik Date: Tue, 31 May 2022 09:21:46 +0200 Subject: [PATCH 1/2] [usage] Add db.Project model in golang --- components/usage/go.mod | 1 + components/usage/go.sum | 1 + components/usage/pkg/db/project.go | 38 +++++++++++++ components/usage/pkg/db/project_test.go | 73 +++++++++++++++++++++++++ components/usage/pkg/db/workspace.go | 6 +- 5 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 components/usage/pkg/db/project.go create mode 100644 components/usage/pkg/db/project_test.go diff --git a/components/usage/go.mod b/components/usage/go.mod index ab59b0781aa252..7150930373222d 100644 --- a/components/usage/go.mod +++ b/components/usage/go.mod @@ -57,6 +57,7 @@ replace k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.23.5 / require ( github.com/gitpod-io/gitpod/common-go v0.0.0-00010101000000-000000000000 github.com/go-sql-driver/mysql v1.6.0 + github.com/google/uuid v1.1.2 github.com/relvacode/iso8601 v1.1.0 github.com/spf13/cobra v1.4.0 github.com/stretchr/testify v1.7.0 diff --git a/components/usage/go.sum b/components/usage/go.sum index 79748a3221cd35..1866f9b842aed6 100644 --- a/components/usage/go.sum +++ b/components/usage/go.sum @@ -151,6 +151,7 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= diff --git a/components/usage/pkg/db/project.go b/components/usage/pkg/db/project.go new file mode 100644 index 00000000000000..41b1a4eac7821c --- /dev/null +++ b/components/usage/pkg/db/project.go @@ -0,0 +1,38 @@ +// Copyright (c) 2022 Gitpod GmbH. All rights reserved. +// Licensed under the GNU Affero General Public License (AGPL). +// See License-AGPL.txt in the project root for license information. + +package db + +import ( + "database/sql" + "github.com/google/uuid" + "gorm.io/datatypes" + "time" +) + +type Project struct { + ID uuid.UUID `gorm:"primary_key;column:id;type:char;size:36;" json:"id"` + Name string `gorm:"column:name;type:varchar;size:255;" json:"name"` + CloneURL string `gorm:"column:cloneUrl;type:varchar;size:255;" json:"cloneUrl"` + Slug sql.NullString `gorm:"column:slug;type:varchar;size:255;" json:"slug"` + Settings datatypes.JSON `gorm:"column:settings;type:text;size:65535;" json:"settings"` + + AppInstallationID string `gorm:"column:appInstallationId;type:varchar;size:255;" json:"appInstallationId"` + + CreationTime VarcharTime `gorm:"column:creationTime;type:varchar;size:255;" json:"creationTime"` + LastModified time.Time `gorm:"column:_lastModified;type:timestamp;default:CURRENT_TIMESTAMP(6);" json:"_lastModified"` + + TeamID sql.NullString `gorm:"column:teamId;type:char;size:36;" json:"teamId"` + UserID sql.NullString `gorm:"column:userId;type:char;size:36;" json:"userId"` + + MarkedDeleted bool `gorm:"column:markedDeleted;type:tinyint;default:0;" json:"markedDeleted"` + + // deleted is reserved for use by db-sync + _ int32 `gorm:"column:deleted;type:tinyint;default:0;" json:"deleted"` +} + +// TableName sets the insert table name for this struct type +func (d *Project) TableName() string { + return "d_b_project" +} diff --git a/components/usage/pkg/db/project_test.go b/components/usage/pkg/db/project_test.go new file mode 100644 index 00000000000000..86b51eb80f8fa2 --- /dev/null +++ b/components/usage/pkg/db/project_test.go @@ -0,0 +1,73 @@ +// Copyright (c) 2022 Gitpod GmbH. All rights reserved. +// Licensed under the GNU Affero General Public License (AGPL). +// See License-AGPL.txt in the project root for license information. + +package db_test + +import ( + "fmt" + "github.com/gitpod-io/gitpod/usage/pkg/db" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "gorm.io/gorm" + "strings" + "testing" +) + +var projectJSON = map[string]interface{}{ + "id": "49b5d309-bb95-4a79-846c-e3cf42c0d591", + "cloneUrl": "https://github.com/gptest1/gptest1-repo1-private.git", + "teamId": "0e433063-1358-4892-9ed2-68e273d17d07", + "appInstallationId": "20446411", + "creationTime": "2021-11-01T19:36:07.532Z", + "deleted": 0, + "_lastModified": "2021-11-02 10:49:12.473658", + "name": "gptest1-repo1-private", + "config": "{\".gitpod.yml\":\"tasks:\\n - init: |\\n echo 'TODO: build project'\\n command: |\\n echo 'TODO: start app'\"}", + "markedDeleted": 1, + "userId": nil, + "slug": "gptest1-repo1-private", + "settings": nil, +} + +func TestProject_ReadExistingRecords(t *testing.T) { + conn := db.ConnectForTests(t) + + id := insertRawProject(t, conn, projectJSON) + + project := db.Project{ID: id} + tx := conn.First(&project) + require.NoError(t, tx.Error) + + require.Equal(t, id, project.ID) + require.Equal(t, projectJSON["teamId"], project.TeamID.String) + require.Equal(t, stringToVarchar(t, "2021-11-01T19:36:07.532Z"), project.CreationTime) +} + +func insertRawProject(t *testing.T, conn *gorm.DB, obj map[string]interface{}) uuid.UUID { + columns := []string{ + "id", "cloneUrl", "teamId", "appInstallationId", "creationTime", "deleted", "_lastModified", "name", "config", "markedDeleted", "userId", "slug", "settings", + } + statement := fmt.Sprintf(`INSERT INTO d_b_project (%s) VALUES ?;`, strings.Join(columns, ", ")) + id := uuid.MustParse(obj["id"].(string)) + + var values []interface{} + for _, col := range columns { + val, ok := obj[col] + if !ok { + values = append(values, "null") + } else { + values = append(values, val) + } + } + + tx := conn.Exec(statement, values) + require.NoError(t, tx.Error) + + t.Cleanup(func() { + tx = conn.Delete(&db.Project{ID: id}) + require.NoError(t, tx.Error) + }) + + return id +} diff --git a/components/usage/pkg/db/workspace.go b/components/usage/pkg/db/workspace.go index fb393d871b16f0..fa5bafe720854d 100644 --- a/components/usage/pkg/db/workspace.go +++ b/components/usage/pkg/db/workspace.go @@ -33,11 +33,11 @@ type Workspace struct { SoftDeletedTime VarcharTime `gorm:"column:softDeletedTime;type:varchar;size:255;" json:"softDeletedTime"` ContentDeletedTime VarcharTime `gorm:"column:contentDeletedTime;type:varchar;size:255;" json:"contentDeletedTime"` - Archived int32 `gorm:"column:archived;type:tinyint;default:0;" json:"archived"` - Shareable int32 `gorm:"column:shareable;type:tinyint;default:0;" json:"shareable"` + Archived bool `gorm:"column:archived;type:tinyint;default:0;" json:"archived"` + Shareable bool `gorm:"column:shareable;type:tinyint;default:0;" json:"shareable"` SoftDeleted sql.NullString `gorm:"column:softDeleted;type:char;size:4;" json:"softDeleted"` - Pinned int32 `gorm:"column:pinned;type:tinyint;default:0;" json:"pinned"` + Pinned bool `gorm:"column:pinned;type:tinyint;default:0;" json:"pinned"` // deleted is reserved for use by db-sync _ int32 `gorm:"column:deleted;type:tinyint;default:0;" json:"deleted"` From e84166f7b03d34bfdced98a882b6893d2a1bd632 Mon Sep 17 00:00:00 2001 From: Milan Pavlik Date: Thu, 2 Jun 2022 13:36:52 +0200 Subject: [PATCH 2/2] Update components/usage/pkg/db/project.go Co-authored-by: Jan Keromnes --- components/usage/pkg/db/project.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/usage/pkg/db/project.go b/components/usage/pkg/db/project.go index 41b1a4eac7821c..dfabf3996778f9 100644 --- a/components/usage/pkg/db/project.go +++ b/components/usage/pkg/db/project.go @@ -29,7 +29,7 @@ type Project struct { MarkedDeleted bool `gorm:"column:markedDeleted;type:tinyint;default:0;" json:"markedDeleted"` // deleted is reserved for use by db-sync - _ int32 `gorm:"column:deleted;type:tinyint;default:0;" json:"deleted"` + _ bool `gorm:"column:deleted;type:tinyint;default:0;" json:"deleted"` } // TableName sets the insert table name for this struct type