2017-07-24 16:24:21 +01:00
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
// by contacting <sales@documize.com>.
//
// https://documize.com
2017-07-26 10:50:26 +01:00
// Package mysql handles data persistence for spaces.
package mysql
2017-07-24 16:24:21 +01:00
import (
"fmt"
"time"
2017-07-26 10:50:26 +01:00
"github.com/documize/community/core/env"
2017-07-24 16:24:21 +01:00
"github.com/documize/community/core/streamutil"
"github.com/documize/community/domain"
"github.com/documize/community/domain/store/mysql"
2017-07-26 10:50:26 +01:00
"github.com/documize/community/model/space"
2017-07-24 16:24:21 +01:00
"github.com/pkg/errors"
)
2017-07-26 10:50:26 +01:00
// Scope provides data access to MySQL.
type Scope struct {
Runtime * env . Runtime
}
2017-07-24 16:24:21 +01:00
// Add adds new folder into the store.
2017-07-26 10:50:26 +01:00
func ( s Scope ) Add ( ctx domain . RequestContext , sp space . Space ) ( err error ) {
sp . UserID = ctx . UserID
2017-07-24 16:24:21 +01:00
sp . Created = time . Now ( ) . UTC ( )
sp . Revised = time . Now ( ) . UTC ( )
2017-07-26 10:50:26 +01:00
stmt , err := ctx . Transaction . Preparex ( "INSERT INTO label (refid, label, orgid, userid, type, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?)" )
2017-07-24 16:24:21 +01:00
defer streamutil . Close ( stmt )
if err != nil {
err = errors . Wrap ( err , "unable to prepare insert for label" )
return
}
_ , err = stmt . Exec ( sp . RefID , sp . Name , sp . OrgID , sp . UserID , sp . Type , sp . Created , sp . Revised )
if err != nil {
err = errors . Wrap ( err , "unable to execute insert for label" )
return
}
return
}
// Get returns a space from the store.
2017-07-26 10:50:26 +01:00
func ( s Scope ) Get ( ctx domain . RequestContext , id string ) ( sp space . Space , err error ) {
2017-07-24 16:24:21 +01:00
stmt , err := s . Runtime . Db . Preparex ( "SELECT id,refid,label as name,orgid,userid,type,created,revised FROM label WHERE orgid=? and refid=?" )
defer streamutil . Close ( stmt )
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to prepare select for label %s" , id ) )
return
}
2017-07-26 10:50:26 +01:00
err = stmt . Get ( & sp , ctx . OrgID , id )
2017-07-24 16:24:21 +01:00
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select for label %s" , id ) )
return
}
return
}
2017-08-07 14:42:02 +01:00
// PublicSpaces returns spaces that anyone can see.
2017-07-26 10:50:26 +01:00
func ( s Scope ) PublicSpaces ( ctx domain . RequestContext , orgID string ) ( sp [ ] space . Space , err error ) {
2017-07-24 16:24:21 +01:00
sql := "SELECT id,refid,label as name,orgid,userid,type,created,revised FROM label a where orgid=? AND type=1"
err = s . Runtime . Db . Select ( & sp , sql , orgID )
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "Unable to execute GetPublicFolders for org %s" , orgID ) )
return
}
return
}
2017-08-07 14:42:02 +01:00
// GetAll returns spaces that the user can see.
// Also handles which spaces can be seen by anonymous users.
2017-07-26 10:50:26 +01:00
func ( s Scope ) GetAll ( ctx domain . RequestContext ) ( sp [ ] space . Space , err error ) {
2017-07-24 16:24:21 +01:00
sql := `
2017-09-15 11:08:05 +01:00
SELECT id , refid , label as name , orgid , userid , type , created , revised FROM label
WHERE orgid = ?
AND refid IN ( SELECT refid FROM permission WHERE orgid = ? AND location = ' space ' AND refid IN (
SELECT refid from permission WHERE orgid = ? AND who = ' user ' AND whoid = ? AND location = ' space ' UNION ALL
SELECT p . refid from permission p LEFT JOIN rolemember r ON p . whoid = r . roleid WHERE p . orgid = ? AND p . who = ' role '
AND p . location = ' space ' AND p . action = ' view ' AND r . userid = ?
) )
2017-08-07 14:42:02 +01:00
ORDER BY name `
2017-07-24 16:24:21 +01:00
err = s . Runtime . Db . Select ( & sp , sql ,
2017-07-26 10:50:26 +01:00
ctx . OrgID ,
ctx . OrgID ,
ctx . OrgID ,
2017-09-15 11:08:05 +01:00
ctx . UserID ,
2017-07-26 10:50:26 +01:00
ctx . OrgID ,
ctx . UserID )
2017-07-24 16:24:21 +01:00
if err != nil {
2017-09-15 11:08:05 +01:00
err = errors . Wrap ( err , fmt . Sprintf ( "failed space.GetAll org %s" , ctx . OrgID ) )
2017-07-24 16:24:21 +01:00
return
}
return
}
// Update saves space changes.
2017-07-26 10:50:26 +01:00
func ( s Scope ) Update ( ctx domain . RequestContext , sp space . Space ) ( err error ) {
2017-07-24 16:24:21 +01:00
sp . Revised = time . Now ( ) . UTC ( )
2017-07-26 10:50:26 +01:00
stmt , err := ctx . Transaction . PrepareNamed ( "UPDATE label SET label=:name, type=:type, userid=:userid, revised=:revised WHERE orgid=:orgid AND refid=:refid" )
2017-07-24 16:24:21 +01:00
defer streamutil . Close ( stmt )
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to prepare update for label %s" , sp . RefID ) )
return
}
_ , err = stmt . Exec ( & sp )
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute update for label %s" , sp . RefID ) )
return
}
return
}
2017-08-07 14:42:02 +01:00
// Viewers returns the list of people who can see shared spaces.
2017-07-26 10:50:26 +01:00
func ( s Scope ) Viewers ( ctx domain . RequestContext ) ( v [ ] space . Viewer , err error ) {
2017-07-24 16:24:21 +01:00
sql := `
2017-08-07 14:42:02 +01:00
SELECT a . userid ,
COALESCE ( u . firstname , ' ' ) as firstname ,
COALESCE ( u . lastname , ' ' ) as lastname ,
COALESCE ( u . email , ' ' ) as email ,
a . labelid ,
b . label as name ,
b . type
FROM labelrole a
LEFT JOIN label b ON b . refid = a . labelid
LEFT JOIN user u ON u . refid = a . userid
WHERE a . orgid = ? AND b . type != 2
GROUP BY a . labelid , a . userid
ORDER BY u . firstname , u . lastname `
2017-07-24 16:24:21 +01:00
2017-07-26 10:50:26 +01:00
err = s . Runtime . Db . Select ( & v , sql , ctx . OrgID )
2017-07-24 16:24:21 +01:00
return
}
// Delete removes space from the store.
2017-07-26 10:50:26 +01:00
func ( s Scope ) Delete ( ctx domain . RequestContext , id string ) ( rows int64 , err error ) {
2017-07-24 16:24:21 +01:00
b := mysql . BaseQuery { }
2017-07-26 10:50:26 +01:00
return b . DeleteConstrained ( ctx . Transaction , "label" , ctx . OrgID , id )
2017-07-24 16:24:21 +01:00
}