@@ -20,7 +20,6 @@ package sql
20
20
21
21
import (
22
22
"context"
23
- "database/sql"
24
23
"fmt"
25
24
"slices"
26
25
@@ -32,6 +31,9 @@ import (
32
31
"github.com/cs3org/reva/pkg/spaces"
33
32
"github.com/cs3org/reva/pkg/utils/cfg"
34
33
"github.com/pkg/errors"
34
+ "gorm.io/driver/mysql"
35
+ "gorm.io/driver/sqlite"
36
+ "gorm.io/gorm"
35
37
)
36
38
37
39
func init () {
@@ -41,66 +43,75 @@ func init() {
41
43
// Config is the configuration to use for the mysql driver
42
44
// implementing the projects.Catalogue interface.
43
45
type Config struct {
46
+ Engine string `mapstructure:"engine"` // mysql | sqlite
44
47
DBUsername string `mapstructure:"db_username"`
45
48
DBPassword string `mapstructure:"db_password"`
46
- DBAddress string `mapstructure:"db_address"`
49
+ DBHost string `mapstructure:"db_host"`
50
+ DBPort int `mapstructure:"db_port"`
47
51
DBName string `mapstructure:"db_name"`
48
52
}
49
53
50
54
type mgr struct {
51
55
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
61
57
}
62
58
63
59
// Project represents a project in the DB.
64
60
type Project struct {
65
- StorageID string
61
+ gorm.Model
62
+ StorageID string `gorm:"size:255"`
66
63
Path string
67
- Name string
68
- Owner string
64
+ Name string `gorm:"size:255;uniqueIndex:i_name"`
65
+ Owner string `gorm:"size:255"`
69
66
Readers string
70
67
Writers string
71
68
Admins string
72
69
}
73
70
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
+
77
95
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 " )
79
97
}
80
98
81
- m := & mgr {
82
- c : conf ,
99
+ mgr := & mgr {
100
+ c : & c ,
83
101
db : db ,
84
102
}
85
- return m , nil
103
+ return mgr , nil
86
104
}
87
105
88
106
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...
96
108
97
109
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
104
115
}
105
116
106
117
projects := []* provider.StorageSpace {}
0 commit comments