V3-663 Extend database with Project entity (#622)
* V3-663 Extend database with Project entity * fixing linter
This commit is contained in:
parent
6576d31b29
commit
75213fa633
@ -9,6 +9,8 @@ type DB interface {
|
||||
Users() Users
|
||||
// Companies is getter for Companies repository
|
||||
Companies() Companies
|
||||
// Projects is getter for Projects repository
|
||||
Projects() Projects
|
||||
|
||||
// CreateTables is a method for creating all tables for satellitedb
|
||||
CreateTables() error
|
||||
|
42
pkg/satellite/projects.go
Normal file
42
pkg/satellite/projects.go
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2018 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package satellite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/skyrings/skyring-common/tools/uuid"
|
||||
)
|
||||
|
||||
// Projects exposes methods to manage Project table in database.
|
||||
type Projects interface {
|
||||
// GetAll is a method for querying all projects from the database.
|
||||
GetAll(ctx context.Context) ([]Project, error)
|
||||
// GetByUserID is a method for querying project from the database by userID.
|
||||
GetByUserID(ctx context.Context, userID uuid.UUID) (*Project, error)
|
||||
// Get is a method for querying project from the database by id.
|
||||
Get(ctx context.Context, id uuid.UUID) (*Project, error)
|
||||
// Insert is a method for inserting project into the database.
|
||||
Insert(ctx context.Context, user *Project) (*Project, error)
|
||||
// Delete is a method for deleting project by Id from the database.
|
||||
Delete(ctx context.Context, id uuid.UUID) error
|
||||
// Update is a method for updating project entity.
|
||||
Update(ctx context.Context, user *Project) error
|
||||
}
|
||||
|
||||
// Project is a database object that describes Project entity
|
||||
type Project struct {
|
||||
ID uuid.UUID
|
||||
// FK on Users table. ID of project creator.
|
||||
// TODO: Should it be named OwnerID?
|
||||
UserID uuid.UUID
|
||||
|
||||
Name string
|
||||
Description string
|
||||
// Indicates if user accepted terms and conditions during project creation.
|
||||
IsAgreedWithTerms bool
|
||||
|
||||
CreatedAt time.Time
|
||||
}
|
@ -199,9 +199,9 @@ func TestCompanyRepository(t *testing.T) {
|
||||
func TestCompanyFromDbx(t *testing.T) {
|
||||
|
||||
t.Run("can't create dbo from nil dbx model", func(t *testing.T) {
|
||||
user, err := companyFromDBX(nil)
|
||||
company, err := companyFromDBX(nil)
|
||||
|
||||
assert.Nil(t, user)
|
||||
assert.Nil(t, company)
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
@ -211,9 +211,9 @@ func TestCompanyFromDbx(t *testing.T) {
|
||||
Id: []byte("qweqwe"),
|
||||
}
|
||||
|
||||
user, err := companyFromDBX(&dbxCompany)
|
||||
company, err := companyFromDBX(&dbxCompany)
|
||||
|
||||
assert.Nil(t, user)
|
||||
assert.Nil(t, company)
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
@ -229,9 +229,9 @@ func TestCompanyFromDbx(t *testing.T) {
|
||||
UserId: []byte("qweqwe"),
|
||||
}
|
||||
|
||||
user, err := companyFromDBX(&dbxCompany)
|
||||
company, err := companyFromDBX(&dbxCompany)
|
||||
|
||||
assert.Nil(t, user)
|
||||
assert.Nil(t, company)
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
@ -4,7 +4,6 @@
|
||||
package satellitedb
|
||||
|
||||
import (
|
||||
"storj.io/storj/internal/migrate"
|
||||
"storj.io/storj/pkg/satellite"
|
||||
|
||||
"storj.io/storj/pkg/satellite/satellitedb/dbx"
|
||||
@ -40,9 +39,20 @@ func (db *Database) Companies() satellite.Companies {
|
||||
return &companies{db.db}
|
||||
}
|
||||
|
||||
// Projects is getter for Projects repository
|
||||
func (db *Database) Projects() satellite.Projects {
|
||||
return &projects{db.db}
|
||||
}
|
||||
|
||||
// CreateTables is a method for creating all tables for satellitedb
|
||||
func (db *Database) CreateTables() error {
|
||||
return migrate.Create("satellitedb", db.db)
|
||||
//TODO: this code will be returned in the new commit
|
||||
//return migrate.Create("satellitedb", db.db)
|
||||
|
||||
//TODO: this code should be removed in the new commit
|
||||
_, err := db.db.Exec(db.db.Schema())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Close is used to close db connection
|
||||
|
@ -53,4 +53,30 @@ read one (
|
||||
)
|
||||
create company ( )
|
||||
update company ( where company.id = ? )
|
||||
delete company ( where company.id = ? )
|
||||
delete company ( where company.id = ? )
|
||||
|
||||
model project (
|
||||
key id
|
||||
|
||||
field id blob
|
||||
field user_id user.id cascade
|
||||
|
||||
field name text ( updatable )
|
||||
field description text ( updatable )
|
||||
field is_agreed_with_terms bool ( updatable )
|
||||
|
||||
field created_at timestamp ( autoinsert )
|
||||
)
|
||||
|
||||
read all ( select project)
|
||||
read one (
|
||||
select project
|
||||
where project.id = ?
|
||||
)
|
||||
read one (
|
||||
select project
|
||||
where project.user_id = ?
|
||||
)
|
||||
create project ( )
|
||||
update project ( where project.id = ? )
|
||||
delete project ( where project.id = ? )
|
@ -287,6 +287,15 @@ CREATE TABLE companies (
|
||||
postal_code TEXT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY ( id )
|
||||
);
|
||||
CREATE TABLE projects (
|
||||
id BLOB NOT NULL,
|
||||
user_id BLOB NOT NULL REFERENCES users( id ) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
is_agreed_with_terms INTEGER NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY ( id )
|
||||
);`
|
||||
}
|
||||
|
||||
@ -661,6 +670,131 @@ func (f Company_CreatedAt_Field) value() interface{} {
|
||||
|
||||
func (Company_CreatedAt_Field) _Column() string { return "created_at" }
|
||||
|
||||
type Project struct {
|
||||
Id []byte
|
||||
UserId []byte
|
||||
Name string
|
||||
Description string
|
||||
IsAgreedWithTerms bool
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (Project) _Table() string { return "projects" }
|
||||
|
||||
type Project_Update_Fields struct {
|
||||
Name Project_Name_Field
|
||||
Description Project_Description_Field
|
||||
IsAgreedWithTerms Project_IsAgreedWithTerms_Field
|
||||
}
|
||||
|
||||
type Project_Id_Field struct {
|
||||
_set bool
|
||||
_value []byte
|
||||
}
|
||||
|
||||
func Project_Id(v []byte) Project_Id_Field {
|
||||
return Project_Id_Field{_set: true, _value: v}
|
||||
}
|
||||
|
||||
func (f Project_Id_Field) value() interface{} {
|
||||
if !f._set {
|
||||
return nil
|
||||
}
|
||||
return f._value
|
||||
}
|
||||
|
||||
func (Project_Id_Field) _Column() string { return "id" }
|
||||
|
||||
type Project_UserId_Field struct {
|
||||
_set bool
|
||||
_value []byte
|
||||
}
|
||||
|
||||
func Project_UserId(v []byte) Project_UserId_Field {
|
||||
return Project_UserId_Field{_set: true, _value: v}
|
||||
}
|
||||
|
||||
func (f Project_UserId_Field) value() interface{} {
|
||||
if !f._set {
|
||||
return nil
|
||||
}
|
||||
return f._value
|
||||
}
|
||||
|
||||
func (Project_UserId_Field) _Column() string { return "user_id" }
|
||||
|
||||
type Project_Name_Field struct {
|
||||
_set bool
|
||||
_value string
|
||||
}
|
||||
|
||||
func Project_Name(v string) Project_Name_Field {
|
||||
return Project_Name_Field{_set: true, _value: v}
|
||||
}
|
||||
|
||||
func (f Project_Name_Field) value() interface{} {
|
||||
if !f._set {
|
||||
return nil
|
||||
}
|
||||
return f._value
|
||||
}
|
||||
|
||||
func (Project_Name_Field) _Column() string { return "name" }
|
||||
|
||||
type Project_Description_Field struct {
|
||||
_set bool
|
||||
_value string
|
||||
}
|
||||
|
||||
func Project_Description(v string) Project_Description_Field {
|
||||
return Project_Description_Field{_set: true, _value: v}
|
||||
}
|
||||
|
||||
func (f Project_Description_Field) value() interface{} {
|
||||
if !f._set {
|
||||
return nil
|
||||
}
|
||||
return f._value
|
||||
}
|
||||
|
||||
func (Project_Description_Field) _Column() string { return "description" }
|
||||
|
||||
type Project_IsAgreedWithTerms_Field struct {
|
||||
_set bool
|
||||
_value bool
|
||||
}
|
||||
|
||||
func Project_IsAgreedWithTerms(v bool) Project_IsAgreedWithTerms_Field {
|
||||
return Project_IsAgreedWithTerms_Field{_set: true, _value: v}
|
||||
}
|
||||
|
||||
func (f Project_IsAgreedWithTerms_Field) value() interface{} {
|
||||
if !f._set {
|
||||
return nil
|
||||
}
|
||||
return f._value
|
||||
}
|
||||
|
||||
func (Project_IsAgreedWithTerms_Field) _Column() string { return "is_agreed_with_terms" }
|
||||
|
||||
type Project_CreatedAt_Field struct {
|
||||
_set bool
|
||||
_value time.Time
|
||||
}
|
||||
|
||||
func Project_CreatedAt(v time.Time) Project_CreatedAt_Field {
|
||||
return Project_CreatedAt_Field{_set: true, _value: v}
|
||||
}
|
||||
|
||||
func (f Project_CreatedAt_Field) value() interface{} {
|
||||
if !f._set {
|
||||
return nil
|
||||
}
|
||||
return f._value
|
||||
}
|
||||
|
||||
func (Project_CreatedAt_Field) _Column() string { return "created_at" }
|
||||
|
||||
func toUTC(t time.Time) time.Time {
|
||||
return t.UTC()
|
||||
}
|
||||
@ -901,6 +1035,39 @@ func (obj *sqlite3Impl) Create_Company(ctx context.Context,
|
||||
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) Create_Project(ctx context.Context,
|
||||
project_id Project_Id_Field,
|
||||
project_user_id Project_UserId_Field,
|
||||
project_name Project_Name_Field,
|
||||
project_description Project_Description_Field,
|
||||
project_is_agreed_with_terms Project_IsAgreedWithTerms_Field) (
|
||||
project *Project, err error) {
|
||||
|
||||
__now := obj.db.Hooks.Now().UTC()
|
||||
__id_val := project_id.value()
|
||||
__user_id_val := project_user_id.value()
|
||||
__name_val := project_name.value()
|
||||
__description_val := project_description.value()
|
||||
__is_agreed_with_terms_val := project_is_agreed_with_terms.value()
|
||||
__created_at_val := __now
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literal("INSERT INTO projects ( id, user_id, name, description, is_agreed_with_terms, created_at ) VALUES ( ?, ?, ?, ?, ?, ? )")
|
||||
|
||||
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||
obj.logStmt(__stmt, __id_val, __user_id_val, __name_val, __description_val, __is_agreed_with_terms_val, __created_at_val)
|
||||
|
||||
__res, err := obj.driver.Exec(__stmt, __id_val, __user_id_val, __name_val, __description_val, __is_agreed_with_terms_val, __created_at_val)
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
__pk, err := __res.LastInsertId()
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
return obj.getLastProject(ctx, __pk)
|
||||
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) Get_User_By_Email_And_PasswordHash(ctx context.Context,
|
||||
user_email User_Email_Field,
|
||||
user_password_hash User_PasswordHash_Field) (
|
||||
@ -1008,6 +1175,102 @@ func (obj *sqlite3Impl) Get_Company_By_Id(ctx context.Context,
|
||||
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) All_Project(ctx context.Context) (
|
||||
rows []*Project, err error) {
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literal("SELECT projects.id, projects.user_id, projects.name, projects.description, projects.is_agreed_with_terms, projects.created_at FROM projects")
|
||||
|
||||
var __values []interface{}
|
||||
__values = append(__values)
|
||||
|
||||
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||
obj.logStmt(__stmt, __values...)
|
||||
|
||||
__rows, err := obj.driver.Query(__stmt, __values...)
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
defer __rows.Close()
|
||||
|
||||
for __rows.Next() {
|
||||
project := &Project{}
|
||||
err = __rows.Scan(&project.Id, &project.UserId, &project.Name, &project.Description, &project.IsAgreedWithTerms, &project.CreatedAt)
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
rows = append(rows, project)
|
||||
}
|
||||
if err := __rows.Err(); err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
return rows, nil
|
||||
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) Get_Project_By_Id(ctx context.Context,
|
||||
project_id Project_Id_Field) (
|
||||
project *Project, err error) {
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literal("SELECT projects.id, projects.user_id, projects.name, projects.description, projects.is_agreed_with_terms, projects.created_at FROM projects WHERE projects.id = ?")
|
||||
|
||||
var __values []interface{}
|
||||
__values = append(__values, project_id.value())
|
||||
|
||||
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||
obj.logStmt(__stmt, __values...)
|
||||
|
||||
project = &Project{}
|
||||
err = obj.driver.QueryRow(__stmt, __values...).Scan(&project.Id, &project.UserId, &project.Name, &project.Description, &project.IsAgreedWithTerms, &project.CreatedAt)
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
return project, nil
|
||||
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) Get_Project_By_UserId(ctx context.Context,
|
||||
project_user_id Project_UserId_Field) (
|
||||
project *Project, err error) {
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literal("SELECT projects.id, projects.user_id, projects.name, projects.description, projects.is_agreed_with_terms, projects.created_at FROM projects WHERE projects.user_id = ? LIMIT 2")
|
||||
|
||||
var __values []interface{}
|
||||
__values = append(__values, project_user_id.value())
|
||||
|
||||
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||
obj.logStmt(__stmt, __values...)
|
||||
|
||||
__rows, err := obj.driver.Query(__stmt, __values...)
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
defer __rows.Close()
|
||||
|
||||
if !__rows.Next() {
|
||||
if err := __rows.Err(); err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
return nil, makeErr(sql.ErrNoRows)
|
||||
}
|
||||
|
||||
project = &Project{}
|
||||
err = __rows.Scan(&project.Id, &project.UserId, &project.Name, &project.Description, &project.IsAgreedWithTerms, &project.CreatedAt)
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
|
||||
if __rows.Next() {
|
||||
return nil, tooManyRows("Project_By_UserId")
|
||||
}
|
||||
|
||||
if err := __rows.Err(); err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
|
||||
return project, nil
|
||||
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) Update_User_By_Id(ctx context.Context,
|
||||
user_id User_Id_Field,
|
||||
update User_Update_Fields) (
|
||||
@ -1148,6 +1411,66 @@ func (obj *sqlite3Impl) Update_Company_By_Id(ctx context.Context,
|
||||
return company, nil
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) Update_Project_By_Id(ctx context.Context,
|
||||
project_id Project_Id_Field,
|
||||
update Project_Update_Fields) (
|
||||
project *Project, err error) {
|
||||
var __sets = &__sqlbundle_Hole{}
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("UPDATE projects SET "), __sets, __sqlbundle_Literal(" WHERE projects.id = ?")}}
|
||||
|
||||
__sets_sql := __sqlbundle_Literals{Join: ", "}
|
||||
var __values []interface{}
|
||||
var __args []interface{}
|
||||
|
||||
if update.Name._set {
|
||||
__values = append(__values, update.Name.value())
|
||||
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("name = ?"))
|
||||
}
|
||||
|
||||
if update.Description._set {
|
||||
__values = append(__values, update.Description.value())
|
||||
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("description = ?"))
|
||||
}
|
||||
|
||||
if update.IsAgreedWithTerms._set {
|
||||
__values = append(__values, update.IsAgreedWithTerms.value())
|
||||
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("is_agreed_with_terms = ?"))
|
||||
}
|
||||
|
||||
if len(__sets_sql.SQLs) == 0 {
|
||||
return nil, emptyUpdate()
|
||||
}
|
||||
|
||||
__args = append(__args, project_id.value())
|
||||
|
||||
__values = append(__values, __args...)
|
||||
__sets.SQL = __sets_sql
|
||||
|
||||
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||
obj.logStmt(__stmt, __values...)
|
||||
|
||||
project = &Project{}
|
||||
_, err = obj.driver.Exec(__stmt, __values...)
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
|
||||
var __embed_stmt_get = __sqlbundle_Literal("SELECT projects.id, projects.user_id, projects.name, projects.description, projects.is_agreed_with_terms, projects.created_at FROM projects WHERE projects.id = ?")
|
||||
|
||||
var __stmt_get = __sqlbundle_Render(obj.dialect, __embed_stmt_get)
|
||||
obj.logStmt("(IMPLIED) "+__stmt_get, __args...)
|
||||
|
||||
err = obj.driver.QueryRow(__stmt_get, __args...).Scan(&project.Id, &project.UserId, &project.Name, &project.Description, &project.IsAgreedWithTerms, &project.CreatedAt)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
return project, nil
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) Delete_User_By_Id(ctx context.Context,
|
||||
user_id User_Id_Field) (
|
||||
deleted bool, err error) {
|
||||
@ -1200,6 +1523,32 @@ func (obj *sqlite3Impl) Delete_Company_By_Id(ctx context.Context,
|
||||
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) Delete_Project_By_Id(ctx context.Context,
|
||||
project_id Project_Id_Field) (
|
||||
deleted bool, err error) {
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literal("DELETE FROM projects WHERE projects.id = ?")
|
||||
|
||||
var __values []interface{}
|
||||
__values = append(__values, project_id.value())
|
||||
|
||||
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||
obj.logStmt(__stmt, __values...)
|
||||
|
||||
__res, err := obj.driver.Exec(__stmt, __values...)
|
||||
if err != nil {
|
||||
return false, obj.makeErr(err)
|
||||
}
|
||||
|
||||
__count, err := __res.RowsAffected()
|
||||
if err != nil {
|
||||
return false, obj.makeErr(err)
|
||||
}
|
||||
|
||||
return __count > 0, nil
|
||||
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) getLastUser(ctx context.Context,
|
||||
pk int64) (
|
||||
user *User, err error) {
|
||||
@ -1236,6 +1585,24 @@ func (obj *sqlite3Impl) getLastCompany(ctx context.Context,
|
||||
|
||||
}
|
||||
|
||||
func (obj *sqlite3Impl) getLastProject(ctx context.Context,
|
||||
pk int64) (
|
||||
project *Project, err error) {
|
||||
|
||||
var __embed_stmt = __sqlbundle_Literal("SELECT projects.id, projects.user_id, projects.name, projects.description, projects.is_agreed_with_terms, projects.created_at FROM projects WHERE _rowid_ = ?")
|
||||
|
||||
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
|
||||
obj.logStmt(__stmt, pk)
|
||||
|
||||
project = &Project{}
|
||||
err = obj.driver.QueryRow(__stmt, pk).Scan(&project.Id, &project.UserId, &project.Name, &project.Description, &project.IsAgreedWithTerms, &project.CreatedAt)
|
||||
if err != nil {
|
||||
return nil, obj.makeErr(err)
|
||||
}
|
||||
return project, nil
|
||||
|
||||
}
|
||||
|
||||
func (impl sqlite3Impl) isConstraintError(err error) (
|
||||
constraint string, ok bool) {
|
||||
if e, ok := err.(sqlite3.Error); ok {
|
||||
@ -1254,6 +1621,16 @@ func (impl sqlite3Impl) isConstraintError(err error) (
|
||||
func (obj *sqlite3Impl) deleteAll(ctx context.Context) (count int64, err error) {
|
||||
var __res sql.Result
|
||||
var __count int64
|
||||
__res, err = obj.driver.Exec("DELETE FROM projects;")
|
||||
if err != nil {
|
||||
return 0, obj.makeErr(err)
|
||||
}
|
||||
|
||||
__count, err = __res.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, obj.makeErr(err)
|
||||
}
|
||||
count += __count
|
||||
__res, err = obj.driver.Exec("DELETE FROM companies;")
|
||||
if err != nil {
|
||||
return 0, obj.makeErr(err)
|
||||
@ -1321,6 +1698,15 @@ func (rx *Rx) Rollback() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (rx *Rx) All_Project(ctx context.Context) (
|
||||
rows []*Project, err error) {
|
||||
var tx *Tx
|
||||
if tx, err = rx.getTx(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
return tx.All_Project(ctx)
|
||||
}
|
||||
|
||||
func (rx *Rx) Create_Company(ctx context.Context,
|
||||
company_id Company_Id_Field,
|
||||
company_user_id Company_UserId_Field,
|
||||
@ -1339,6 +1725,21 @@ func (rx *Rx) Create_Company(ctx context.Context,
|
||||
|
||||
}
|
||||
|
||||
func (rx *Rx) Create_Project(ctx context.Context,
|
||||
project_id Project_Id_Field,
|
||||
project_user_id Project_UserId_Field,
|
||||
project_name Project_Name_Field,
|
||||
project_description Project_Description_Field,
|
||||
project_is_agreed_with_terms Project_IsAgreedWithTerms_Field) (
|
||||
project *Project, err error) {
|
||||
var tx *Tx
|
||||
if tx, err = rx.getTx(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
return tx.Create_Project(ctx, project_id, project_user_id, project_name, project_description, project_is_agreed_with_terms)
|
||||
|
||||
}
|
||||
|
||||
func (rx *Rx) Create_User(ctx context.Context,
|
||||
user_id User_Id_Field,
|
||||
user_first_name User_FirstName_Field,
|
||||
@ -1364,6 +1765,16 @@ func (rx *Rx) Delete_Company_By_Id(ctx context.Context,
|
||||
return tx.Delete_Company_By_Id(ctx, company_id)
|
||||
}
|
||||
|
||||
func (rx *Rx) Delete_Project_By_Id(ctx context.Context,
|
||||
project_id Project_Id_Field) (
|
||||
deleted bool, err error) {
|
||||
var tx *Tx
|
||||
if tx, err = rx.getTx(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
return tx.Delete_Project_By_Id(ctx, project_id)
|
||||
}
|
||||
|
||||
func (rx *Rx) Delete_User_By_Id(ctx context.Context,
|
||||
user_id User_Id_Field) (
|
||||
deleted bool, err error) {
|
||||
@ -1394,6 +1805,26 @@ func (rx *Rx) Get_Company_By_UserId(ctx context.Context,
|
||||
return tx.Get_Company_By_UserId(ctx, company_user_id)
|
||||
}
|
||||
|
||||
func (rx *Rx) Get_Project_By_Id(ctx context.Context,
|
||||
project_id Project_Id_Field) (
|
||||
project *Project, err error) {
|
||||
var tx *Tx
|
||||
if tx, err = rx.getTx(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
return tx.Get_Project_By_Id(ctx, project_id)
|
||||
}
|
||||
|
||||
func (rx *Rx) Get_Project_By_UserId(ctx context.Context,
|
||||
project_user_id Project_UserId_Field) (
|
||||
project *Project, err error) {
|
||||
var tx *Tx
|
||||
if tx, err = rx.getTx(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
return tx.Get_Project_By_UserId(ctx, project_user_id)
|
||||
}
|
||||
|
||||
func (rx *Rx) Get_User_By_Email_And_PasswordHash(ctx context.Context,
|
||||
user_email User_Email_Field,
|
||||
user_password_hash User_PasswordHash_Field) (
|
||||
@ -1426,6 +1857,17 @@ func (rx *Rx) Update_Company_By_Id(ctx context.Context,
|
||||
return tx.Update_Company_By_Id(ctx, company_id, update)
|
||||
}
|
||||
|
||||
func (rx *Rx) Update_Project_By_Id(ctx context.Context,
|
||||
project_id Project_Id_Field,
|
||||
update Project_Update_Fields) (
|
||||
project *Project, err error) {
|
||||
var tx *Tx
|
||||
if tx, err = rx.getTx(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
return tx.Update_Project_By_Id(ctx, project_id, update)
|
||||
}
|
||||
|
||||
func (rx *Rx) Update_User_By_Id(ctx context.Context,
|
||||
user_id User_Id_Field,
|
||||
update User_Update_Fields) (
|
||||
@ -1438,6 +1880,9 @@ func (rx *Rx) Update_User_By_Id(ctx context.Context,
|
||||
}
|
||||
|
||||
type Methods interface {
|
||||
All_Project(ctx context.Context) (
|
||||
rows []*Project, err error)
|
||||
|
||||
Create_Company(ctx context.Context,
|
||||
company_id Company_Id_Field,
|
||||
company_user_id Company_UserId_Field,
|
||||
@ -1449,6 +1894,14 @@ type Methods interface {
|
||||
company_postal_code Company_PostalCode_Field) (
|
||||
company *Company, err error)
|
||||
|
||||
Create_Project(ctx context.Context,
|
||||
project_id Project_Id_Field,
|
||||
project_user_id Project_UserId_Field,
|
||||
project_name Project_Name_Field,
|
||||
project_description Project_Description_Field,
|
||||
project_is_agreed_with_terms Project_IsAgreedWithTerms_Field) (
|
||||
project *Project, err error)
|
||||
|
||||
Create_User(ctx context.Context,
|
||||
user_id User_Id_Field,
|
||||
user_first_name User_FirstName_Field,
|
||||
@ -1461,6 +1914,10 @@ type Methods interface {
|
||||
company_id Company_Id_Field) (
|
||||
deleted bool, err error)
|
||||
|
||||
Delete_Project_By_Id(ctx context.Context,
|
||||
project_id Project_Id_Field) (
|
||||
deleted bool, err error)
|
||||
|
||||
Delete_User_By_Id(ctx context.Context,
|
||||
user_id User_Id_Field) (
|
||||
deleted bool, err error)
|
||||
@ -1473,6 +1930,14 @@ type Methods interface {
|
||||
company_user_id Company_UserId_Field) (
|
||||
company *Company, err error)
|
||||
|
||||
Get_Project_By_Id(ctx context.Context,
|
||||
project_id Project_Id_Field) (
|
||||
project *Project, err error)
|
||||
|
||||
Get_Project_By_UserId(ctx context.Context,
|
||||
project_user_id Project_UserId_Field) (
|
||||
project *Project, err error)
|
||||
|
||||
Get_User_By_Email_And_PasswordHash(ctx context.Context,
|
||||
user_email User_Email_Field,
|
||||
user_password_hash User_PasswordHash_Field) (
|
||||
@ -1487,6 +1952,11 @@ type Methods interface {
|
||||
update Company_Update_Fields) (
|
||||
company *Company, err error)
|
||||
|
||||
Update_Project_By_Id(ctx context.Context,
|
||||
project_id Project_Id_Field,
|
||||
update Project_Update_Fields) (
|
||||
project *Project, err error)
|
||||
|
||||
Update_User_By_Id(ctx context.Context,
|
||||
user_id User_Id_Field,
|
||||
update User_Update_Fields) (
|
||||
|
@ -22,3 +22,12 @@ CREATE TABLE companies (
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY ( id )
|
||||
);
|
||||
CREATE TABLE projects (
|
||||
id BLOB NOT NULL,
|
||||
user_id BLOB NOT NULL REFERENCES users( id ) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
is_agreed_with_terms INTEGER NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY ( id )
|
||||
);
|
||||
|
138
pkg/satellite/satellitedb/projects.go
Normal file
138
pkg/satellite/satellitedb/projects.go
Normal file
@ -0,0 +1,138 @@
|
||||
// Copyright (C) 2018 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package satellitedb
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/skyrings/skyring-common/tools/uuid"
|
||||
"github.com/zeebo/errs"
|
||||
"storj.io/storj/pkg/satellite"
|
||||
"storj.io/storj/pkg/satellite/satellitedb/dbx"
|
||||
"storj.io/storj/pkg/utils"
|
||||
)
|
||||
|
||||
// implementation of Projects interface repository using spacemonkeygo/dbx orm
|
||||
type projects struct {
|
||||
db *dbx.DB
|
||||
}
|
||||
|
||||
// GetAll is a method for querying all projects from the database.
|
||||
func (projects *projects) GetAll(ctx context.Context) ([]satellite.Project, error) {
|
||||
|
||||
projectsDbxSlice, err := projects.db.All_Project(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
projectsCount := len(projectsDbxSlice)
|
||||
var projectDboSlice []satellite.Project
|
||||
var errors []error
|
||||
|
||||
// Generating []dbo from []dbx and collecting all errors
|
||||
for i := 0; i < projectsCount; i++ {
|
||||
projectDbo, err := projectFromDBX(projectsDbxSlice[i])
|
||||
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
||||
projectDboSlice = append(projectDboSlice, *projectDbo)
|
||||
}
|
||||
|
||||
return projectDboSlice, utils.CombineErrors(errors...)
|
||||
}
|
||||
|
||||
// GetByUserID is a method for querying project from the database by user id
|
||||
func (projects *projects) GetByUserID(ctx context.Context, userID uuid.UUID) (*satellite.Project, error) {
|
||||
|
||||
project, err := projects.db.Get_Project_By_UserId(ctx, dbx.Project_UserId(userID[:]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return projectFromDBX(project)
|
||||
}
|
||||
|
||||
// Get is a method for querying project from the database by id.
|
||||
func (projects *projects) Get(ctx context.Context, id uuid.UUID) (*satellite.Project, error) {
|
||||
|
||||
project, err := projects.db.Get_Project_By_Id(ctx, dbx.Project_Id(id[:]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return projectFromDBX(project)
|
||||
}
|
||||
|
||||
// Insert is a method for inserting project into the database.
|
||||
func (projects *projects) Insert(ctx context.Context, project *satellite.Project) (*satellite.Project, error) {
|
||||
|
||||
projectID, err := uuid.New()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
createdProject, err := projects.db.Create_Project(ctx,
|
||||
dbx.Project_Id(projectID[:]),
|
||||
dbx.Project_UserId(project.UserID[:]),
|
||||
dbx.Project_Name(project.Name),
|
||||
dbx.Project_Description(project.Description),
|
||||
dbx.Project_IsAgreedWithTerms(project.IsAgreedWithTerms))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return projectFromDBX(createdProject)
|
||||
}
|
||||
|
||||
// Delete is a method for deleting project by Id from the database.
|
||||
func (projects *projects) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := projects.db.Delete_Project_By_Id(ctx, dbx.Project_Id(id[:]))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Update is a method for updating user entity
|
||||
func (projects *projects) Update(ctx context.Context, project *satellite.Project) error {
|
||||
|
||||
_, err := projects.db.Update_Project_By_Id(ctx,
|
||||
dbx.Project_Id(project.ID[:]),
|
||||
dbx.Project_Update_Fields{
|
||||
Name: dbx.Project_Name(project.Name),
|
||||
Description: dbx.Project_Description(project.Description),
|
||||
IsAgreedWithTerms: dbx.Project_IsAgreedWithTerms(project.IsAgreedWithTerms),
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// projectFromDBX is used for creating Project entity from autogenerated dbx.Project struct
|
||||
func projectFromDBX(project *dbx.Project) (*satellite.Project, error) {
|
||||
if project == nil {
|
||||
return nil, errs.New("project parameter is nil")
|
||||
}
|
||||
|
||||
id, err := bytesToUUID(project.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userID, err := bytesToUUID(project.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u := &satellite.Project{
|
||||
ID: id,
|
||||
UserID: userID,
|
||||
Name: project.Name,
|
||||
Description: project.Description,
|
||||
IsAgreedWithTerms: project.IsAgreedWithTerms,
|
||||
CreatedAt: project.CreatedAt,
|
||||
}
|
||||
|
||||
return u, nil
|
||||
}
|
257
pkg/satellite/satellitedb/projects_test.go
Normal file
257
pkg/satellite/satellitedb/projects_test.go
Normal file
@ -0,0 +1,257 @@
|
||||
// Copyright (C) 2018 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package satellitedb
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/skyrings/skyring-common/tools/uuid"
|
||||
"storj.io/storj/pkg/satellite/satellitedb/dbx"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"storj.io/storj/internal/testcontext"
|
||||
"storj.io/storj/pkg/satellite"
|
||||
)
|
||||
|
||||
func TestProjectsRepository(t *testing.T) {
|
||||
|
||||
//testing constants
|
||||
const (
|
||||
// for user
|
||||
lastName = "lastName"
|
||||
email = "email@ukr.net"
|
||||
pass = "123456"
|
||||
userName = "name"
|
||||
|
||||
// for project
|
||||
name = "Storj"
|
||||
description = "some description"
|
||||
|
||||
// updated project values
|
||||
newName = "Dropbox"
|
||||
newDescription = "some new description"
|
||||
)
|
||||
|
||||
ctx := testcontext.New(t)
|
||||
defer ctx.Cleanup()
|
||||
|
||||
// creating in-memory db and opening connection
|
||||
// to test with real db3 file use this connection string - "../db/accountdb.db3"
|
||||
db, err := New("sqlite3", "file::memory:?mode=memory&cache=shared")
|
||||
if err != nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
defer ctx.Check(db.Close)
|
||||
|
||||
// creating tables
|
||||
err = db.CreateTables()
|
||||
if err != nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// repositories
|
||||
users := db.Users()
|
||||
projects := db.Projects()
|
||||
|
||||
var user *satellite.User
|
||||
|
||||
t.Run("Can't insert project without user", func(t *testing.T) {
|
||||
|
||||
project := &satellite.Project{
|
||||
Name: name,
|
||||
Description: description,
|
||||
IsAgreedWithTerms: false,
|
||||
}
|
||||
|
||||
createdCompany, err := projects.Insert(ctx, project)
|
||||
|
||||
assert.Nil(t, createdCompany)
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("Insert project successfully", func(t *testing.T) {
|
||||
|
||||
user, err = users.Insert(ctx, &satellite.User{
|
||||
FirstName: userName,
|
||||
LastName: lastName,
|
||||
Email: email,
|
||||
PasswordHash: []byte(pass),
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, user)
|
||||
|
||||
project := &satellite.Project{
|
||||
UserID: user.ID,
|
||||
|
||||
Name: name,
|
||||
Description: description,
|
||||
IsAgreedWithTerms: false,
|
||||
}
|
||||
|
||||
createdProject, err := projects.Insert(ctx, project)
|
||||
|
||||
assert.NotNil(t, createdProject)
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Get project success", func(t *testing.T) {
|
||||
projectByUserID, err := projects.GetByUserID(ctx, user.ID)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, projectByUserID.UserID, user.ID)
|
||||
assert.Equal(t, projectByUserID.Name, name)
|
||||
assert.Equal(t, projectByUserID.Description, description)
|
||||
assert.Equal(t, projectByUserID.IsAgreedWithTerms, false)
|
||||
|
||||
projectByID, err := projects.Get(ctx, projectByUserID.ID)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, projectByID.ID, projectByUserID.ID)
|
||||
assert.Equal(t, projectByID.UserID, user.ID)
|
||||
assert.Equal(t, projectByID.Name, name)
|
||||
assert.Equal(t, projectByID.Description, description)
|
||||
assert.Equal(t, projectByID.IsAgreedWithTerms, false)
|
||||
})
|
||||
|
||||
t.Run("Update project success", func(t *testing.T) {
|
||||
oldProject, err := projects.GetByUserID(ctx, user.ID)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, oldProject)
|
||||
|
||||
// creating new company with updated values
|
||||
newProject := &satellite.Project{
|
||||
ID: oldProject.ID,
|
||||
UserID: user.ID,
|
||||
Name: newName,
|
||||
Description: newDescription,
|
||||
IsAgreedWithTerms: true,
|
||||
}
|
||||
|
||||
err = projects.Update(ctx, newProject)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// fetching updated project from db
|
||||
newProject, err = projects.Get(ctx, oldProject.ID)
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, newProject.ID, oldProject.ID)
|
||||
assert.Equal(t, newProject.UserID, user.ID)
|
||||
assert.Equal(t, newProject.Name, newName)
|
||||
assert.Equal(t, newProject.Description, newDescription)
|
||||
assert.Equal(t, newProject.IsAgreedWithTerms, true)
|
||||
})
|
||||
|
||||
t.Run("Delete project success", func(t *testing.T) {
|
||||
oldProject, err := projects.GetByUserID(ctx, user.ID)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, oldProject)
|
||||
|
||||
err = projects.Delete(ctx, oldProject.ID)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = projects.Get(ctx, oldProject.ID)
|
||||
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("GetAll success", func(t *testing.T) {
|
||||
allProjects, err := projects.GetAll(ctx)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(allProjects), 0)
|
||||
|
||||
newProject := &satellite.Project{
|
||||
UserID: user.ID,
|
||||
Description: description,
|
||||
Name: name,
|
||||
IsAgreedWithTerms: true,
|
||||
}
|
||||
|
||||
_, err = projects.Insert(ctx, newProject)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
|
||||
allProjects, err = projects.GetAll(ctx)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(allProjects), 1)
|
||||
|
||||
newProject2 := &satellite.Project{
|
||||
UserID: user.ID,
|
||||
Description: description,
|
||||
Name: name,
|
||||
IsAgreedWithTerms: true,
|
||||
}
|
||||
|
||||
_, err = projects.Insert(ctx, newProject2)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
|
||||
allProjects, err = projects.GetAll(ctx)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(allProjects), 2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProjectFromDbx(t *testing.T) {
|
||||
|
||||
t.Run("can't create dbo from nil dbx model", func(t *testing.T) {
|
||||
user, err := projectFromDBX(nil)
|
||||
|
||||
assert.Nil(t, user)
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("can't create dbo from dbx model with invalid ID", func(t *testing.T) {
|
||||
dbxProject := dbx.Project{
|
||||
Id: []byte("qweqwe"),
|
||||
}
|
||||
|
||||
project, err := projectFromDBX(&dbxProject)
|
||||
|
||||
assert.Nil(t, project)
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("can't create dbo from dbx model with invalid UserID", func(t *testing.T) {
|
||||
|
||||
projectID, err := uuid.New()
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, err)
|
||||
|
||||
dbxProject := dbx.Project{
|
||||
Id: projectID[:],
|
||||
UserId: []byte("qweqwe"),
|
||||
}
|
||||
|
||||
project, err := projectFromDBX(&dbxProject)
|
||||
|
||||
assert.Nil(t, project)
|
||||
assert.NotNil(t, err)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
@ -48,8 +48,13 @@ func (users *users) GetByCredentials(ctx context.Context, password []byte, email
|
||||
// Insert is a method for inserting user into the database
|
||||
func (users *users) Insert(ctx context.Context, user *satellite.User) (*satellite.User, error) {
|
||||
|
||||
userID, err := uuid.New()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
createdUser, err := users.db.Create_User(ctx,
|
||||
dbx.User_Id(user.ID[:]),
|
||||
dbx.User_Id(userID[:]),
|
||||
dbx.User_FirstName(user.FirstName),
|
||||
dbx.User_LastName(user.LastName),
|
||||
dbx.User_Email(user.Email),
|
||||
|
@ -14,7 +14,7 @@ func bytesToUUID(data []byte) (uuid.UUID, error) {
|
||||
|
||||
copy(id[:], data)
|
||||
if len(id) != len(data) {
|
||||
return uuid.UUID{}, errs.New("Invalid bytes array")
|
||||
return uuid.UUID{}, errs.New("Invalid uuid")
|
||||
}
|
||||
|
||||
return id, nil
|
||||
|
Loading…
Reference in New Issue
Block a user