Skip to content

Commit 9f1b591

Browse files
committed
[usage] Add db.WorkspaceInstance model in golang
1 parent 45f1ca4 commit 9f1b591

File tree

5 files changed

+151
-17
lines changed

5 files changed

+151
-17
lines changed

components/usage/go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ require (
5858
github.com/gitpod-io/gitpod/common-go v0.0.0-00010101000000-000000000000
5959
github.com/go-sql-driver/mysql v1.6.0
6060
github.com/google/uuid v1.1.2
61+
github.com/google/uuid v1.1.2
62+
github.com/jackc/pgtype v1.10.0
6163
github.com/relvacode/iso8601 v1.1.0
6264
github.com/robfig/cron v1.2.0
6365
github.com/spf13/cobra v1.4.0
@@ -71,12 +73,14 @@ require (
7173
github.com/beorn7/perks v1.0.1 // indirect
7274
github.com/cespare/xxhash/v2 v2.1.2 // indirect
7375
github.com/davecgh/go-spew v1.1.1 // indirect
76+
github.com/gofrs/uuid v4.0.0+incompatible // indirect
7477
github.com/golang/protobuf v1.5.2 // indirect
7578
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
7679
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
7780
github.com/hashicorp/golang-lru v0.5.1 // indirect
7881
github.com/heptiolabs/healthcheck v0.0.0-20211123025425-613501dd5deb // indirect
7982
github.com/inconshreveable/mousetrap v1.0.0 // indirect
83+
github.com/jackc/pgio v1.0.0 // indirect
8084
github.com/jinzhu/inflection v1.0.0 // indirect
8185
github.com/jinzhu/now v1.1.4 // indirect
8286
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect

components/usage/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
9191
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
9292
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
9393
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
94+
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
9495
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
9596
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
9697
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -248,6 +249,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
248249
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
249250
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
250251
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
252+
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
251253
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
252254
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
253255
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package db
6+
7+
import (
8+
"database/sql"
9+
"github.com/google/uuid"
10+
"gorm.io/datatypes"
11+
"time"
12+
)
13+
14+
type WorkspaceInstance struct {
15+
ID uuid.UUID `gorm:"primary_key;column:id;type:char;size:36;" json:"id"`
16+
WorkspaceID string `gorm:"column:workspaceId;type:char;size:36;" json:"workspaceId"`
17+
Configuration datatypes.JSON `gorm:"column:configuration;type:text;size:65535;" json:"configuration"`
18+
Region string `gorm:"column:region;type:varchar;size:255;" json:"region"`
19+
ImageBuildInfo sql.NullString `gorm:"column:imageBuildInfo;type:text;size:65535;" json:"imageBuildInfo"`
20+
IdeURL string `gorm:"column:ideUrl;type:varchar;size:255;" json:"ideUrl"`
21+
WorkspaceBaseImage string `gorm:"column:workspaceBaseImage;type:varchar;size:255;" json:"workspaceBaseImage"`
22+
WorkspaceImage string `gorm:"column:workspaceImage;type:varchar;size:255;" json:"workspaceImage"`
23+
24+
CreationTime VarcharTime `gorm:"column:creationTime;type:varchar;size:255;" json:"creationTime"`
25+
StartedTime VarcharTime `gorm:"column:startedTime;type:varchar;size:255;" json:"startedTime"`
26+
DeployedTime VarcharTime `gorm:"column:deployedTime;type:varchar;size:255;" json:"deployedTime"`
27+
StoppedTime VarcharTime `gorm:"column:stoppedTime;type:varchar;size:255;" json:"stoppedTime"`
28+
LastModified time.Time `gorm:"column:_lastModified;type:timestamp;default:CURRENT_TIMESTAMP(6);" json:"_lastModified"`
29+
StoppingTime VarcharTime `gorm:"column:stoppingTime;type:varchar;size:255;" json:"stoppingTime"`
30+
31+
LastHeartbeat string `gorm:"column:lastHeartbeat;type:varchar;size:255;" json:"lastHeartbeat"`
32+
StatusOld sql.NullString `gorm:"column:status_old;type:varchar;size:255;" json:"status_old"`
33+
Status datatypes.JSON `gorm:"column:status;type:json;" json:"status"`
34+
Phase sql.NullString `gorm:"column:phase;type:char;size:32;" json:"phase"`
35+
PhasePersisted string `gorm:"column:phasePersisted;type:char;size:32;" json:"phasePersisted"`
36+
37+
// deleted is restricted for use by db-sync
38+
_ bool `gorm:"column:deleted;type:tinyint;default:0;" json:"deleted"`
39+
}
40+
41+
// TableName sets the insert table name for this struct type
42+
func (d *WorkspaceInstance) TableName() string {
43+
return "d_b_workspace_instance"
44+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package db_test
6+
7+
import (
8+
"fmt"
9+
"github.com/gitpod-io/gitpod/usage/pkg/db"
10+
"github.com/google/uuid"
11+
"github.com/stretchr/testify/require"
12+
"gorm.io/gorm"
13+
"strings"
14+
"testing"
15+
)
16+
17+
var workspaceInstanceJSON = map[string]interface{}{
18+
"id": "2f9a29bb-406e-4494-b592-c99f7fa0e793",
19+
"workspaceId": "gitpodio-ops-b8fqh3eylmr",
20+
"region": "eu03",
21+
"creationTime": "2022-05-31T15:22:57.192Z",
22+
"startedTime": "2022-05-31T15:24:04.336Z",
23+
"deployedTime": "",
24+
"stoppedTime": "2022-05-31T15:24:50.361Z",
25+
"lastHeartbeat": "",
26+
"ideUrl": "https://gitpodio-ops-b8fqh3eylmr.ws-eu03.gitpod-staging.com",
27+
"workspaceBaseImage": "",
28+
"workspaceImage": "eu.gcr.io/gitpod-dev/workspace-images:59e2c9722f56918c0e84f2640880fee0c19ac40471e968faaddcdcaebaf0df58",
29+
"status_old": nil,
30+
"_lastModified": "2022-05-31 15:24:50.373117",
31+
"status": "{\"repo\": {\"branch\": \"main\", \"latestCommit\": \"25d888e90dd21eb98be699c0b43556c153d667c9\", \"totalUntrackedFiles\": 0, \"totalUncommitedFiles\": 0, \"totalUnpushedCommits\": 0}, \"phase\": \"stopped\", \"nodeIp\": \"10.132.0.14\", \"message\": \"\", \"podName\": \"prebuild-2f9a29bb-406e-4494-b592-c99f7fa0e791\", \"timeout\": \"30m0s\", \"nodeName\": \"ws-eu03.gitpod-staging.com\", \"conditions\": {\"failed\": \"\", \"timeout\": \"\", \"deployed\": false, \"pullingImages\": false, \"stoppedByRequest\": false, \"headlessTaskFailed\": \"\"}, \"ownerToken\": \"4.MIXs2XurX1vMP7bTEryt9R9IbzGT_D\", \"exposedPorts\": []}",
32+
"phase": "stopped",
33+
"deleted": 0,
34+
"phasePersisted": "stopped",
35+
"configuration": "{\"ideImage\":\"eu.gcr.io/gitpod-core-dev/build/ide/code:commit-80d9b1ebfd826fd0db25320ba94d762b51887ada\",\"supervisorImage\":\"eu.gcr.io/gitpod-core-dev/build/supervisor:commit-1d4be665efdd1507f92b185afd112a7568d21a42\",\"ideConfig\":{\"useLatest\":false},\"featureFlags\":[\"registry_facade\",\"fixed_resources\"]}",
36+
"stoppingTime": "2022-05-31T15:24:39.657Z",
37+
"imageBuildInfo": nil,
38+
}
39+
40+
func TestWorkspaceInstance_ReadExistingRecords(t *testing.T) {
41+
conn := db.ConnectForTests(t)
42+
id := insertRawWorkspaceInstance(t, conn, workspaceInstanceJSON)
43+
44+
wsi := db.WorkspaceInstance{ID: id}
45+
tx := conn.First(&wsi)
46+
require.NoError(t, tx.Error)
47+
48+
require.Equal(t, id, wsi.ID)
49+
50+
require.True(t, wsi.StoppingTime.IsSet())
51+
require.Equal(t, stringToVarchar(t, workspaceInstanceJSON["stoppingTime"].(string)), wsi.StoppingTime)
52+
53+
require.True(t, wsi.StartedTime.IsSet())
54+
require.Equal(t, stringToVarchar(t, workspaceInstanceJSON["startedTime"].(string)), wsi.StartedTime)
55+
56+
require.False(t, wsi.DeployedTime.IsSet())
57+
58+
require.True(t, wsi.StoppedTime.IsSet())
59+
require.Equal(t, stringToVarchar(t, workspaceInstanceJSON["stoppedTime"].(string)), wsi.StoppedTime)
60+
61+
require.True(t, wsi.CreationTime.IsSet())
62+
require.Equal(t, stringToVarchar(t, workspaceInstanceJSON["creationTime"].(string)), wsi.CreationTime)
63+
64+
require.Equal(t, workspaceInstanceJSON["status"], wsi.Status.String())
65+
require.Equal(t, workspaceInstanceJSON["configuration"], wsi.Configuration.String())
66+
}
67+
68+
func insertRawWorkspaceInstance(t *testing.T, conn *gorm.DB, object map[string]interface{}) uuid.UUID {
69+
columns := []string{"id", "workspaceId", "region", "creationTime", "startedTime", "deployedTime", "stoppedTime", "lastHeartbeat", "ideUrl", "workspaceBaseImage", "workspaceImage", "status_old", "_lastModified", "status", "deleted", "phasePersisted", "configuration", "stoppingTime", "imageBuildInfo"}
70+
statement := fmt.Sprintf(`INSERT INTO d_b_workspace_instance (%s) VALUES ?;`, strings.Join(columns, ", "))
71+
id := uuid.MustParse(insertRawObject(t, conn, columns, statement, object))
72+
73+
t.Cleanup(func() {
74+
tx := conn.Delete(&db.WorkspaceInstance{ID: id})
75+
require.NoError(t, tx.Error)
76+
})
77+
78+
return id
79+
}
80+
81+
func insertRawObject(t *testing.T, conn *gorm.DB, columns []string, statement string, obj map[string]interface{}) string {
82+
t.Helper()
83+
84+
id := obj["id"].(string)
85+
86+
var values []interface{}
87+
for _, col := range columns {
88+
val, ok := obj[col]
89+
if !ok {
90+
values = append(values, "null")
91+
} else {
92+
values = append(values, val)
93+
}
94+
}
95+
96+
tx := conn.Exec(statement, values)
97+
require.NoError(t, tx.Error)
98+
99+
return id
100+
}

components/usage/pkg/db/workspace_test.go

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,28 +71,12 @@ func insertRawWorkspace(t *testing.T, conn *gorm.DB, rawWorkspace map[string]int
7171
INSERT INTO d_b_workspace (
7272
%s
7373
) VALUES ?;`, strings.Join(columns, ", "))
74-
75-
id := rawWorkspace["id"].(string)
76-
77-
var values []interface{}
78-
for _, col := range columns {
79-
val, ok := rawWorkspace[col]
80-
if !ok {
81-
values = append(values, "null")
82-
} else {
83-
values = append(values, val)
84-
}
85-
86-
}
87-
88-
tx := conn.Debug().Exec(statement, values)
89-
require.NoError(t, tx.Error)
74+
id := insertRawObject(t, conn, columns, statement, rawWorkspace)
9075

9176
t.Cleanup(func() {
9277
tx := conn.Delete(&db.Workspace{ID: id})
9378
require.NoError(t, tx.Error)
9479
})
95-
9680
return id
9781
}
9882

0 commit comments

Comments
 (0)