Skip to content

Commit 363220f

Browse files
authored
ORMify projects table (#5081)
1 parent 87693ac commit 363220f

File tree

5 files changed

+114
-143
lines changed

5 files changed

+114
-143
lines changed

go.mod

+10-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ require (
5858
go.step.sm/crypto v0.57.0
5959
golang.org/x/crypto v0.32.0
6060
golang.org/x/oauth2 v0.25.0
61-
golang.org/x/sync v0.10.0
61+
golang.org/x/sync v0.11.0
6262
golang.org/x/sys v0.29.0
6363
golang.org/x/term v0.28.0
6464
google.golang.org/genproto v0.0.0-20241209162323-e6fa225c2576
@@ -67,7 +67,14 @@ require (
6767
gotest.tools v2.2.0+incompatible
6868
)
6969

70-
require github.com/google/go-cmp v0.6.0 // indirect
70+
require (
71+
github.com/google/go-cmp v0.6.0 // indirect
72+
github.com/jinzhu/inflection v1.0.0 // indirect
73+
github.com/jinzhu/now v1.1.5 // indirect
74+
gorm.io/driver/mysql v1.5.7 // indirect
75+
gorm.io/driver/sqlite v1.5.7 // indirect
76+
gorm.io/gorm v1.25.12 // indirect
77+
)
7178

7279
require (
7380
filippo.io/edwards25519 v1.1.0 // indirect
@@ -128,7 +135,7 @@ require (
128135
go.opentelemetry.io/otel/trace v1.31.0 // indirect
129136
golang.org/x/mod v0.22.0 // indirect
130137
golang.org/x/net v0.34.0 // indirect
131-
golang.org/x/text v0.21.0 // indirect
138+
golang.org/x/text v0.22.0 // indirect
132139
golang.org/x/tools v0.28.0 // indirect
133140
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
134141
gopkg.in/src-d/go-errors.v1 v1.0.0 // indirect

go.sum

+16
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,7 @@ github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaC
10091009
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
10101010
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
10111011
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
1012+
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
10121013
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
10131014
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
10141015
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
@@ -1228,6 +1229,10 @@ github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZ
12281229
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
12291230
github.com/jedib0t/go-pretty v4.3.0+incompatible h1:CGs8AVhEKg/n9YbUenWmNStRW2PHJzaeDodcfvRAbIo=
12301231
github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag=
1232+
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
1233+
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
1234+
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
1235+
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
12311236
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
12321237
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
12331238
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
@@ -1836,6 +1841,8 @@ golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
18361841
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
18371842
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
18381843
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
1844+
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
1845+
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
18391846
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
18401847
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
18411848
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1997,6 +2004,8 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
19972004
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
19982005
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
19992006
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
2007+
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
2008+
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
20002009
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
20012010
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
20022011
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -2441,6 +2450,13 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
24412450
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
24422451
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
24432452
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2453+
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
2454+
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
2455+
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
2456+
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
2457+
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
2458+
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
2459+
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
24442460
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
24452461
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
24462462
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

pkg/projects/manager/sql/init.sql

-14
This file was deleted.

pkg/projects/manager/sql/sql.go

+45-34
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package sql
2020

2121
import (
2222
"context"
23-
"database/sql"
2423
"fmt"
2524
"slices"
2625

@@ -32,6 +31,9 @@ import (
3231
"github.com/cs3org/reva/pkg/spaces"
3332
"github.com/cs3org/reva/pkg/utils/cfg"
3433
"github.com/pkg/errors"
34+
"gorm.io/driver/mysql"
35+
"gorm.io/driver/sqlite"
36+
"gorm.io/gorm"
3537
)
3638

3739
func init() {
@@ -41,66 +43,75 @@ func init() {
4143
// Config is the configuration to use for the mysql driver
4244
// implementing the projects.Catalogue interface.
4345
type Config struct {
46+
Engine string `mapstructure:"engine"` // mysql | sqlite
4447
DBUsername string `mapstructure:"db_username"`
4548
DBPassword string `mapstructure:"db_password"`
46-
DBAddress string `mapstructure:"db_address"`
49+
DBHost string `mapstructure:"db_host"`
50+
DBPort int `mapstructure:"db_port"`
4751
DBName string `mapstructure:"db_name"`
4852
}
4953

5054
type mgr struct {
5155
c *Config
52-
db *sql.DB
53-
}
54-
55-
func New(ctx context.Context, m map[string]any) (projects.Catalogue, error) {
56-
var c Config
57-
if err := cfg.Decode(m, &c); err != nil {
58-
return nil, err
59-
}
60-
return NewFromConfig(ctx, &c)
56+
db *gorm.DB
6157
}
6258

6359
// Project represents a project in the DB.
6460
type Project struct {
65-
StorageID string
61+
gorm.Model
62+
StorageID string `gorm:"size:255"`
6663
Path string
67-
Name string
68-
Owner string
64+
Name string `gorm:"size:255;uniqueIndex:i_name"`
65+
Owner string `gorm:"size:255"`
6966
Readers string
7067
Writers string
7168
Admins string
7269
}
7370

74-
// NewFromConfig creates a Repository with a SQL driver using the given config.
75-
func NewFromConfig(ctx context.Context, conf *Config) (projects.Catalogue, error) {
76-
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s", conf.DBUsername, conf.DBPassword, conf.DBAddress, conf.DBName))
71+
func New(ctx context.Context, m map[string]any) (projects.Catalogue, error) {
72+
var c Config
73+
if err := cfg.Decode(m, &c); err != nil {
74+
return nil, err
75+
}
76+
var db *gorm.DB
77+
var err error
78+
switch c.Engine {
79+
case "sqlite":
80+
db, err = gorm.Open(sqlite.Open(c.DBName), &gorm.Config{})
81+
case "mysql":
82+
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true", c.DBUsername, c.DBPassword, c.DBHost, c.DBPort, c.DBName)
83+
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
84+
default: // default is mysql
85+
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true", c.DBUsername, c.DBPassword, c.DBHost, c.DBPort, c.DBName)
86+
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
87+
}
88+
if err != nil {
89+
return nil, errors.Wrap(err, "Failed to connect to Projects database")
90+
}
91+
92+
// Migrate schemas
93+
err = db.AutoMigrate(&Project{})
94+
7795
if err != nil {
78-
return nil, errors.Wrap(err, "sql: error opening connection to mysql database")
96+
return nil, errors.Wrap(err, "Failed to mgirate Project schema")
7997
}
8098

81-
m := &mgr{
82-
c: conf,
99+
mgr := &mgr{
100+
c: &c,
83101
db: db,
84102
}
85-
return m, nil
103+
return mgr, nil
86104
}
87105

88106
func (m *mgr) ListProjects(ctx context.Context, user *userpb.User) ([]*provider.StorageSpace, error) {
89-
// TODO: for the time being we load everything in memory. We may find a better
90-
// solution in future when the number of projects will grow.
91-
query := "SELECT storage_id, path, name, owner, readers, writers, admins FROM projects"
92-
results, err := m.db.QueryContext(ctx, query)
93-
if err != nil {
94-
return nil, errors.Wrap(err, "error getting projects from db")
95-
}
107+
// TODO: we reallyyy should not be loading everything into memory here...
96108

97109
var dbProjects []*Project
98-
for results.Next() {
99-
var p Project
100-
if err := results.Scan(&p.StorageID, &p.Path, &p.Name, &p.Owner, &p.Readers, &p.Writers, &p.Admins); err != nil {
101-
return nil, errors.Wrap(err, "error scanning rows from db")
102-
}
103-
dbProjects = append(dbProjects, &p)
110+
111+
query := m.db.Model(&Project{})
112+
res := query.Find(&dbProjects)
113+
if res.Error != nil {
114+
return nil, res.Error
104115
}
105116

106117
projects := []*provider.StorageSpace{}

0 commit comments

Comments
 (0)