2017-09-19 17:58:33 +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
2018-09-26 17:59:56 +01:00
package category
2017-09-19 17:58:33 +01:00
import (
"database/sql"
"fmt"
"time"
"github.com/documize/community/domain"
2018-09-26 17:59:56 +01:00
"github.com/documize/community/domain/store"
2017-09-19 17:58:33 +01:00
"github.com/documize/community/model/category"
"github.com/pkg/errors"
)
2018-09-26 17:59:56 +01:00
// Store provides data access to space category information.
type Store struct {
store . Context
2018-09-27 15:14:48 +01:00
store . CategoryStorer
2017-09-19 17:58:33 +01:00
}
// Add inserts the given record into the category table.
2018-09-26 17:59:56 +01:00
func ( s Store ) Add ( ctx domain . RequestContext , c category . Category ) ( err error ) {
2017-09-19 17:58:33 +01:00
c . Created = time . Now ( ) . UTC ( )
c . Revised = time . Now ( ) . UTC ( )
2019-11-15 14:51:52 +00:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "INSERT INTO dmz_category (c_refid, c_orgid, c_spaceid, c_name, c_default, c_created, c_revised) VALUES (?, ?, ?, ?, ?, ?, ?)" ) ,
c . RefID , c . OrgID , c . SpaceID , c . Name , c . IsDefault , c . Created , c . Revised )
2017-09-19 17:58:33 +01:00
if err != nil {
err = errors . Wrap ( err , "unable to execute insert category" )
}
return
}
2017-09-26 16:30:16 +01:00
// GetBySpace returns space categories accessible by user.
2017-09-19 17:58:33 +01:00
// Context is used to for user ID.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetBySpace ( ctx domain . RequestContext , spaceID string ) ( c [ ] category . Category , err error ) {
err = s . Runtime . Db . Select ( & c , s . Bind ( `
2019-11-15 14:51:52 +00:00
SELECT id , c_refid AS refid , c_orgid AS orgid , c_spaceid AS spaceid , c_name AS name , c_default AS isdefault , c_created AS created , c_revised AS revised
2018-09-18 20:55:40 +01:00
FROM dmz_category
WHERE c_orgid = ? AND c_spaceid = ? AND c_refid IN
2019-01-08 12:42:32 +00:00
(
SELECT c_refid
FROM dmz_permission
WHERE c_orgid = ? AND c_who = ' user ' AND ( c_whoid = ? OR c_whoid = '0' ) AND c_location = ' category '
2018-09-18 20:55:40 +01:00
UNION ALL
2019-01-08 12:42:32 +00:00
SELECT p . c_refid
FROM dmz_permission p LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
WHERE p . c_orgid = ? AND p . c_who = ' role ' AND p . c_location = ' category ' AND ( r . c_userid = ? OR r . c_userid = '0' )
)
2018-09-26 17:59:56 +01:00
ORDER BY name ` ) ,
2019-01-08 12:42:32 +00:00
ctx . OrgID , spaceID , ctx . OrgID , ctx . UserID , ctx . OrgID , ctx . UserID )
2017-09-19 17:58:33 +01:00
if err == sql . ErrNoRows {
err = nil
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select categories for space %s" , spaceID ) )
}
return
}
// GetAllBySpace returns all space categories.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetAllBySpace ( ctx domain . RequestContext , spaceID string ) ( c [ ] category . Category , err error ) {
2018-04-05 14:22:23 +01:00
c = [ ] category . Category { }
2018-09-26 17:59:56 +01:00
err = s . Runtime . Db . Select ( & c , s . Bind ( `
2019-11-15 14:51:52 +00:00
SELECT id , c_refid AS refid , c_orgid AS orgid , c_spaceid AS spaceid , c_name AS name , c_default AS isdefault , c_created AS created , c_revised AS revised
2018-09-18 20:55:40 +01:00
FROM dmz_category
2018-09-20 12:47:47 +01:00
WHERE c_orgid = ? AND c_spaceid = ? AND c_spaceid IN
2019-01-08 12:42:32 +00:00
(
SELECT c_refid
FROM dmz_permission
WHERE c_orgid = ? AND c_who = ' user ' AND ( c_whoid = ? OR c_whoid = '0' ) AND c_location = ' space ' AND c_action = ' view '
2018-09-18 20:55:40 +01:00
UNION ALL
2019-01-08 12:42:32 +00:00
SELECT p . c_refid
FROM dmz_permission p LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
2018-09-18 20:55:40 +01:00
WHERE p . c_orgid = ? AND p . c_who = ' role ' AND p . c_location = ' space ' AND p . c_action = ' view ' AND ( r . c_userid = ? OR r . c_userid = '0' )
2019-01-08 12:42:32 +00:00
)
2018-09-26 17:59:56 +01:00
ORDER BY c_name ` ) ,
2019-01-08 12:42:32 +00:00
ctx . OrgID , spaceID , ctx . OrgID , ctx . UserID , ctx . OrgID , ctx . UserID )
2017-09-19 17:58:33 +01:00
2018-04-05 14:22:23 +01:00
if err == sql . ErrNoRows {
2017-09-19 17:58:33 +01:00
err = nil
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select all categories for space %s" , spaceID ) )
}
return
}
2018-06-22 17:01:26 +01:00
// GetByOrg returns all categories accessible by user for their org.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetByOrg ( ctx domain . RequestContext , userID string ) ( c [ ] category . Category , err error ) {
err = s . Runtime . Db . Select ( & c , s . Bind ( `
2019-11-15 14:51:52 +00:00
SELECT id , c_refid AS refid , c_orgid AS orgid , c_spaceid AS spaceid , c_name AS name , c_default AS isdefault , c_created AS created , c_revised AS revised
2018-09-18 20:55:40 +01:00
FROM dmz_category
WHERE c_orgid = ? AND c_refid IN
( SELECT c_refid FROM dmz_permission WHERE c_orgid = ? AND c_location = ' category ' AND c_refid IN (
SELECT c_refid FROM dmz_permission WHERE c_orgid = ? AND c_who = ' user ' AND ( c_whoid = ? OR c_whoid = '0' ) AND c_location = ' category '
UNION ALL
SELECT p . c_refid FROM dmz_permission p LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
WHERE p . c_orgid = ? AND p . c_who = ' role ' AND p . c_location = ' category ' AND ( r . c_userid = ? OR r . c_userid = '0' )
2018-06-22 17:01:26 +01:00
) )
2018-09-26 17:59:56 +01:00
ORDER BY c_name ` ) ,
ctx . OrgID , ctx . OrgID , ctx . OrgID , userID , ctx . OrgID , userID )
2018-06-22 17:01:26 +01:00
if err == sql . ErrNoRows {
err = nil
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select categories for org %s" , ctx . OrgID ) )
}
return
}
2017-09-19 17:58:33 +01:00
// Update saves category name change.
2018-09-26 17:59:56 +01:00
func ( s Store ) Update ( ctx domain . RequestContext , c category . Category ) ( err error ) {
2017-09-19 17:58:33 +01:00
c . Revised = time . Now ( ) . UTC ( )
2019-11-15 14:51:52 +00:00
_ , err = ctx . Transaction . NamedExec ( s . Bind ( "UPDATE dmz_category SET c_name=:name, c_default=:isdefault, c_revised=:revised WHERE c_orgid=:orgid AND c_refid=:refid" ) , c )
2017-09-19 17:58:33 +01:00
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute update for category %s" , c . RefID ) )
}
return
}
// Get returns specified category
2018-09-26 17:59:56 +01:00
func ( s Store ) Get ( ctx domain . RequestContext , id string ) ( c category . Category , err error ) {
err = s . Runtime . Db . Get ( & c , s . Bind ( `
2019-11-15 14:51:52 +00:00
SELECT id , c_refid AS refid , c_orgid AS orgid , c_spaceid AS spaceid , c_name AS name , c_default AS isdefault , c_created AS created , c_revised AS revised
2018-09-18 20:55:40 +01:00
FROM dmz_category
2018-09-26 17:59:56 +01:00
WHERE c_orgid = ? AND c_refid = ? ` ) ,
2017-09-25 14:37:11 +01:00
ctx . OrgID , id )
2017-09-19 17:58:33 +01:00
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to get category %s" , id ) )
}
return
}
// Delete removes category from the store.
2018-09-26 17:59:56 +01:00
func ( s Store ) Delete ( ctx domain . RequestContext , id string ) ( rows int64 , err error ) {
return s . DeleteConstrained ( ctx . Transaction , "dmz_category" , ctx . OrgID , id )
2017-09-19 17:58:33 +01:00
}
// AssociateDocument inserts category membership record into the category member table.
2018-09-26 17:59:56 +01:00
func ( s Store ) AssociateDocument ( ctx domain . RequestContext , m category . Member ) ( err error ) {
2017-09-19 17:58:33 +01:00
m . Created = time . Now ( ) . UTC ( )
m . Revised = time . Now ( ) . UTC ( )
2018-09-26 17:59:56 +01:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "INSERT INTO dmz_category_member (c_refid, c_orgid, c_categoryid, c_spaceid, c_docid, c_created, c_revised) VALUES (?, ?, ?, ?, ?, ?, ?)" ) ,
2018-09-18 20:55:40 +01:00
m . RefID , m . OrgID , m . CategoryID , m . SpaceID , m . DocumentID , m . Created , m . Revised )
2017-09-19 17:58:33 +01:00
if err != nil {
err = errors . Wrap ( err , "unable to execute insert categorymember" )
}
return
}
// DisassociateDocument removes document associatation from category.
2018-09-26 17:59:56 +01:00
func ( s Store ) DisassociateDocument ( ctx domain . RequestContext , categoryID , documentID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_category_member WHERE c_orgid=? AND c_categoryid=? AND c_docid=?" ) ,
2017-09-19 17:58:33 +01:00
ctx . OrgID , categoryID , documentID )
2023-05-15 13:47:22 -04:00
if err == sql . ErrNoRows {
err = nil
}
return
2017-09-19 17:58:33 +01:00
}
// RemoveCategoryMembership removes all category associations from the store.
2018-09-26 17:59:56 +01:00
func ( s Store ) RemoveCategoryMembership ( ctx domain . RequestContext , categoryID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_category_member WHERE c_orgid=? AND c_categoryid=?" ) ,
2017-09-19 17:58:33 +01:00
ctx . OrgID , categoryID )
2023-05-15 13:47:22 -04:00
if err == sql . ErrNoRows {
err = nil
}
return
2017-09-19 17:58:33 +01:00
}
2017-09-26 20:13:44 +01:00
// RemoveSpaceCategoryMemberships removes all category associations from the store for the space.
2018-09-26 17:59:56 +01:00
func ( s Store ) RemoveSpaceCategoryMemberships ( ctx domain . RequestContext , spaceID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_category_member WHERE c_orgid=? AND c_spaceid=?" ) ,
2017-09-26 20:13:44 +01:00
ctx . OrgID , spaceID )
2023-05-15 13:47:22 -04:00
if err == sql . ErrNoRows {
err = nil
}
return
2017-09-26 20:13:44 +01:00
}
// RemoveDocumentCategories removes all document category associations from the store.
2018-09-26 17:59:56 +01:00
func ( s Store ) RemoveDocumentCategories ( ctx domain . RequestContext , documentID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_category_member WHERE c_orgid=? AND c_docid=?" ) ,
2017-09-26 20:13:44 +01:00
ctx . OrgID , documentID )
2023-05-15 13:47:22 -04:00
if err == sql . ErrNoRows {
err = nil
}
return
2017-09-26 20:13:44 +01:00
}
2017-09-19 17:58:33 +01:00
// DeleteBySpace removes all category and category associations for given space.
2018-09-26 17:59:56 +01:00
func ( s Store ) DeleteBySpace ( ctx domain . RequestContext , spaceID string ) ( rows int64 , err error ) {
2023-05-15 13:47:22 -04:00
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_category_member WHERE c_orgid=? AND c_spaceid=?" ) ,
ctx . OrgID , spaceID )
if err == sql . ErrNoRows {
err = nil
}
_ , err = ctx . Transaction . Exec ( s . Bind ( "DELETE FROM dmz_category WHERE c_orgid=? AND c_spaceid=?" ) ,
ctx . OrgID , spaceID )
if err == sql . ErrNoRows {
err = nil
2018-10-10 15:13:09 +01:00
}
2017-09-19 17:58:33 +01:00
2023-05-15 13:47:22 -04:00
return
2017-09-19 17:58:33 +01:00
}
2017-09-21 18:59:43 +01:00
// GetSpaceCategorySummary returns number of documents and users for space categories.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetSpaceCategorySummary ( ctx domain . RequestContext , spaceID string ) ( c [ ] category . SummaryModel , err error ) {
2018-04-05 14:22:23 +01:00
c = [ ] category . SummaryModel { }
2018-09-26 17:59:56 +01:00
err = s . Runtime . Db . Select ( & c , s . Bind ( `
2019-04-01 12:02:23 +01:00
SELECT ' documents ' AS grouptype , c_categoryid AS categoryid , COUNT ( * ) AS count
2018-09-18 20:55:40 +01:00
FROM dmz_category_member
WHERE c_orgid = ? AND c_spaceid = ?
AND c_docid IN (
SELECT c_refid
FROM dmz_doc
2019-04-01 12:02:23 +01:00
WHERE c_orgid = ? AND c_spaceid = ? AND c_lifecycle != 2 AND c_template = ` +s.IsFalse()+ ` AND c_groupid = ' '
2018-08-01 13:50:39 -04:00
UNION ALL
2018-09-18 20:55:40 +01:00
SELECT d . c_refid
2018-08-01 13:50:39 -04:00
FROM (
2018-09-18 20:55:40 +01:00
SELECT c_groupid , MIN ( c_versionorder ) AS latestversion
FROM dmz_doc
2019-04-01 12:02:23 +01:00
WHERE c_orgid = ? AND c_spaceid = ? AND c_lifecycle != 2 AND c_groupid != ' ' AND c_template = ` +s.IsFalse()+ `
2018-09-18 20:55:40 +01:00
GROUP BY c_groupid
) AS x INNER JOIN dmz_doc AS d ON d . c_groupid = x . c_groupid AND d . c_versionorder = x . latestversion
2018-08-01 13:50:39 -04:00
)
2019-04-01 20:08:57 +01:00
GROUP BY c_categoryid
2017-09-21 18:59:43 +01:00
UNION ALL
2019-04-01 12:02:23 +01:00
SELECT ' users ' AS grouptype , c_refid AS categoryid , count ( * ) AS count
2018-09-18 20:55:40 +01:00
FROM dmz_permission
WHERE c_orgid = ? AND c_location = ' category ' AND c_refid IN
( SELECT c_refid FROM dmz_category WHERE c_orgid = ? AND c_spaceid = ? )
2019-04-01 20:08:57 +01:00
GROUP BY c_refid ` ) ,
2018-08-01 13:50:39 -04:00
ctx . OrgID , spaceID ,
ctx . OrgID , spaceID , ctx . OrgID , spaceID ,
ctx . OrgID , ctx . OrgID , spaceID )
2018-03-06 10:39:47 +00:00
2018-04-05 14:22:23 +01:00
if err == sql . ErrNoRows {
2017-09-21 18:59:43 +01:00
err = nil
}
if err != nil {
2017-09-26 16:30:16 +01:00
err = errors . Wrap ( err , fmt . Sprintf ( "select category summary for space %s" , spaceID ) )
2017-09-21 18:59:43 +01:00
}
return
}
2017-09-22 17:23:14 +01:00
// GetDocumentCategoryMembership returns all space categories associated with given document.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetDocumentCategoryMembership ( ctx domain . RequestContext , documentID string ) ( c [ ] category . Category , err error ) {
err = s . Runtime . Db . Select ( & c , s . Bind ( `
2019-11-15 14:51:52 +00:00
SELECT id , c_refid AS refid , c_orgid AS orgid , c_spaceid AS spaceid , c_name AS name , c_default AS isdefault , c_created AS created , c_revised AS revised
2018-09-18 20:55:40 +01:00
FROM dmz_category
2018-09-26 17:59:56 +01:00
WHERE c_orgid = ? AND c_refid IN ( SELECT c_categoryid FROM dmz_category_member WHERE c_orgid = ? AND c_docid = ? ) ` ) ,
ctx . OrgID , ctx . OrgID , documentID )
2017-09-22 17:23:14 +01:00
2018-04-05 14:22:23 +01:00
if err == sql . ErrNoRows {
2017-09-22 17:23:14 +01:00
err = nil
2019-08-27 15:24:59 +01:00
c = [ ] category . Category { }
2017-09-22 17:23:14 +01:00
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "unable to execute select categories for document %s" , documentID ) )
}
return
}
2017-09-26 16:30:16 +01:00
2019-08-27 15:24:59 +01:00
// GetSpaceCategoryMembership returns category/document associations within space,
// for specified user.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetSpaceCategoryMembership ( ctx domain . RequestContext , spaceID string ) ( c [ ] category . Member , err error ) {
err = s . Runtime . Db . Select ( & c , s . Bind ( `
2018-09-18 20:55:40 +01:00
SELECT id , c_refid AS refid , c_orgid AS orgid , c_spaceid AS spaceid , c_categoryid AS categoryid , c_docid AS documentid , c_created AS created , c_revised AS revised
FROM dmz_category_member
2018-09-19 16:03:29 +01:00
WHERE c_orgid = ? AND c_spaceid = ? AND c_spaceid IN
2019-01-08 12:42:32 +00:00
(
SELECT c_refid
FROM dmz_permission
WHERE c_orgid = ? AND c_who = ' user '
AND ( c_whoid = ? OR c_whoid = '0' ) AND c_location = ' space ' AND c_action = ' view '
2018-09-18 20:55:40 +01:00
UNION ALL
2019-01-08 12:42:32 +00:00
SELECT p . c_refid
FROM dmz_permission p LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
2018-09-18 20:55:40 +01:00
WHERE p . c_orgid = ? AND p . c_who = ' role ' AND p . c_location = ' space '
2019-01-08 12:42:32 +00:00
AND p . c_action = ' view ' AND ( r . c_userid = ? OR r . c_userid = '0' )
)
2018-09-26 17:59:56 +01:00
ORDER BY documentid ` ) ,
2019-01-08 12:42:32 +00:00
ctx . OrgID , spaceID , ctx . OrgID , ctx . UserID , ctx . OrgID , ctx . UserID )
2017-09-26 16:30:16 +01:00
if err == sql . ErrNoRows {
err = nil
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "select all category/document membership for space %s" , spaceID ) )
}
return
}
2018-06-22 17:01:26 +01:00
// GetOrgCategoryMembership returns category/document associations within organization.
2018-09-26 17:59:56 +01:00
func ( s Store ) GetOrgCategoryMembership ( ctx domain . RequestContext , userID string ) ( c [ ] category . Member , err error ) {
err = s . Runtime . Db . Select ( & c , s . Bind ( `
2018-09-18 20:55:40 +01:00
SELECT id , c_refid AS refid , c_orgid AS orgid , c_spaceid AS spaceid , c_categoryid AS categoryid , c_docid AS documentid , c_created AS created , c_revised AS revised
FROM dmz_category_member
2018-09-19 16:03:29 +01:00
WHERE c_orgid = ? AND c_spaceid IN
2019-01-08 12:42:32 +00:00
(
SELECT c_refid
FROM dmz_permission
WHERE c_orgid = ? AND c_who = ' user ' AND ( c_whoid = ? OR c_whoid = '0' ) AND c_location = ' space ' AND c_action = ' view '
2018-09-18 20:55:40 +01:00
UNION ALL
2019-01-08 12:42:32 +00:00
SELECT p . c_refid
FROM dmz_permission p LEFT JOIN dmz_group_member r ON p . c_whoid = r . c_groupid
WHERE p . c_orgid = ? AND p . c_who = ' role ' AND p . c_location = ' space ' AND p . c_action = ' view ' AND ( r . c_userid = ? OR r . c_userid = '0' )
)
2018-09-26 17:59:56 +01:00
ORDER BY documentid ` ) ,
2019-01-08 12:42:32 +00:00
ctx . OrgID , ctx . OrgID , userID , ctx . OrgID , userID )
2018-06-22 17:01:26 +01:00
if err == sql . ErrNoRows {
err = nil
}
if err != nil {
err = errors . Wrap ( err , fmt . Sprintf ( "select all category/document membership for organization %s" , ctx . OrgID ) )
}
return
}