|
|
|
|
@@ -69,7 +69,7 @@ type StoredBlob struct {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type SharedDocument struct {
|
|
|
|
|
Document models.SaDocument
|
|
|
|
|
Document models.SaDocumentTree
|
|
|
|
|
Content *models.SaDocumentContent
|
|
|
|
|
Blob *models.SaDocumentBlob
|
|
|
|
|
}
|
|
|
|
|
@@ -94,26 +94,26 @@ func (s *Service) database() *gorm.DB {
|
|
|
|
|
return models.DBService
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Service) List(userID uint, projectIdentity string) ([]models.SaDocument, error) {
|
|
|
|
|
func (s *Service) List(userID uint, projectIdentity string) ([]models.SaDocumentTree, error) {
|
|
|
|
|
project, err := s.ownedProject(userID, projectIdentity)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
var documents []models.SaDocument
|
|
|
|
|
var documents []models.SaDocumentTree
|
|
|
|
|
err = s.database().Where("project_id = ?", project.ID).
|
|
|
|
|
Order("kind asc, normalized_name asc, id asc").Find(&documents).Error
|
|
|
|
|
return documents, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Service) CreateFolder(userID uint, projectIdentity string, input CreateInput) (*models.SaDocument, error) {
|
|
|
|
|
func (s *Service) CreateFolder(userID uint, projectIdentity string, input CreateInput) (*models.SaDocumentTree, error) {
|
|
|
|
|
return s.createNode(userID, projectIdentity, input, models.DocumentKindFolder, "", "", 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Service) CreateMarkdown(userID uint, projectIdentity string, input CreateInput) (*models.SaDocument, error) {
|
|
|
|
|
func (s *Service) CreateMarkdown(userID uint, projectIdentity string, input CreateInput) (*models.SaDocumentTree, error) {
|
|
|
|
|
if strings.TrimSpace(filepath.Ext(input.Name)) == "" {
|
|
|
|
|
input.Name += ".md"
|
|
|
|
|
}
|
|
|
|
|
var created *models.SaDocument
|
|
|
|
|
var created *models.SaDocumentTree
|
|
|
|
|
err := s.database().Transaction(func(tx *gorm.DB) error {
|
|
|
|
|
service := NewService(tx, s.root)
|
|
|
|
|
document, err := service.createNode(userID, projectIdentity, input, models.DocumentKindFile, ".md", "text/markdown; charset=utf-8", int64(len([]byte(input.Markdown))))
|
|
|
|
|
@@ -129,7 +129,7 @@ func (s *Service) CreateMarkdown(userID uint, projectIdentity string, input Crea
|
|
|
|
|
return created, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Service) createNode(userID uint, projectIdentity string, input CreateInput, kind, extension, mimeType string, size int64) (*models.SaDocument, error) {
|
|
|
|
|
func (s *Service) createNode(userID uint, projectIdentity string, input CreateInput, kind, extension, mimeType string, size int64) (*models.SaDocumentTree, error) {
|
|
|
|
|
project, err := s.ownedProject(userID, projectIdentity)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
@@ -149,11 +149,11 @@ func (s *Service) createNode(userID uint, projectIdentity string, input CreateIn
|
|
|
|
|
if kind == models.DocumentKindFile {
|
|
|
|
|
extension = strings.ToLower(filepath.Ext(name))
|
|
|
|
|
}
|
|
|
|
|
document := &models.SaDocument{
|
|
|
|
|
document := &models.SaDocumentTree{
|
|
|
|
|
ProjectID: project.ID, ProjectIdentity: project.Identity,
|
|
|
|
|
ParentID: parentID, ParentIdentity: parentIdentity,
|
|
|
|
|
ParentScope: identityValue(parentIdentity),
|
|
|
|
|
CreatedBy: userID, SourceInboxItemID: input.SourceInboxItemID,
|
|
|
|
|
CreatedBy: userID, SourceInboxItemID: input.SourceInboxItemID,
|
|
|
|
|
Kind: kind, Name: name, NormalizedName: normalizeName(name),
|
|
|
|
|
Extension: extension, MimeType: mimeType, Size: size, Revision: 1,
|
|
|
|
|
ScanStatus: "not_scanned",
|
|
|
|
|
@@ -167,8 +167,8 @@ func (s *Service) createNode(userID uint, projectIdentity string, input CreateIn
|
|
|
|
|
return document, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Service) CreateUploaded(userID uint, projectIdentity, parentIdentity string, stored StoredBlob) (*models.SaDocument, error) {
|
|
|
|
|
var created *models.SaDocument
|
|
|
|
|
func (s *Service) CreateUploaded(userID uint, projectIdentity, parentIdentity string, stored StoredBlob) (*models.SaDocumentTree, error) {
|
|
|
|
|
var created *models.SaDocumentTree
|
|
|
|
|
err := s.database().Transaction(func(tx *gorm.DB) error {
|
|
|
|
|
service := NewService(tx, s.root)
|
|
|
|
|
document, err := service.createNode(userID, projectIdentity, CreateInput{
|
|
|
|
|
@@ -197,7 +197,7 @@ func (s *Service) Get(userID uint, projectIdentity, documentIdentity string) (*S
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
var document models.SaDocument
|
|
|
|
|
var document models.SaDocumentTree
|
|
|
|
|
if err := s.database().Where("identity = ? AND project_id = ?", strings.TrimSpace(documentIdentity), project.ID).First(&document).Error; err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
@@ -212,7 +212,7 @@ func (s *Service) Update(userID uint, projectIdentity, documentIdentity string,
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
var document models.SaDocument
|
|
|
|
|
var document models.SaDocumentTree
|
|
|
|
|
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).
|
|
|
|
|
Where("identity = ? AND project_id = ?", strings.TrimSpace(documentIdentity), project.ID).
|
|
|
|
|
First(&document).Error; err != nil {
|
|
|
|
|
@@ -306,7 +306,7 @@ func (s *Service) Delete(userID uint, projectIdentity, documentIdentity string)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
var document models.SaDocument
|
|
|
|
|
var document models.SaDocumentTree
|
|
|
|
|
if err := s.database().Where("identity = ? AND project_id = ?", documentIdentity, project.ID).First(&document).Error; err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
@@ -314,7 +314,7 @@ func (s *Service) Delete(userID uint, projectIdentity, documentIdentity string)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return s.database().Where("id IN ?", ids).Delete(&models.SaDocument{}).Error
|
|
|
|
|
return s.database().Where("id IN ?", ids).Delete(&models.SaDocumentTree{}).Error
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Service) Store(projectIdentity, originalName string, source io.Reader) (StoredBlob, error) {
|
|
|
|
|
@@ -482,7 +482,7 @@ func (s *Service) ResolveShare(token string) (*SharedDocument, error) {
|
|
|
|
|
).First(&share).Error; err != nil {
|
|
|
|
|
return nil, ErrShareNotFound
|
|
|
|
|
}
|
|
|
|
|
var document models.SaDocument
|
|
|
|
|
var document models.SaDocumentTree
|
|
|
|
|
if err := s.database().Where("id = ?", share.DocumentID).First(&document).Error; err != nil {
|
|
|
|
|
return nil, ErrShareNotFound
|
|
|
|
|
}
|
|
|
|
|
@@ -508,7 +508,7 @@ func (s *Service) Export(document SharedDocument, format string) ([]byte, string
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Service) loadDocument(document models.SaDocument) (*SharedDocument, error) {
|
|
|
|
|
func (s *Service) loadDocument(document models.SaDocumentTree) (*SharedDocument, error) {
|
|
|
|
|
result := &SharedDocument{Document: document}
|
|
|
|
|
var content models.SaDocumentContent
|
|
|
|
|
if err := s.database().Where("document_id = ?", document.ID).First(&content).Error; err == nil {
|
|
|
|
|
@@ -536,7 +536,7 @@ func (s *Service) resolveParent(projectID uint, identity string) (*uint, *string
|
|
|
|
|
if identity == "" {
|
|
|
|
|
return nil, nil, nil
|
|
|
|
|
}
|
|
|
|
|
var parent models.SaDocument
|
|
|
|
|
var parent models.SaDocumentTree
|
|
|
|
|
if err := s.database().Where("identity = ? AND project_id = ? AND kind = ?", identity, projectID, models.DocumentKindFolder).First(&parent).Error; err != nil {
|
|
|
|
|
return nil, nil, ErrInvalidParent
|
|
|
|
|
}
|
|
|
|
|
@@ -559,7 +559,7 @@ func (s *Service) availableName(projectID uint, parentID *uint, name string) (st
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Service) nameExists(projectID uint, parentID *uint, normalized string, exceptID uint) bool {
|
|
|
|
|
query := s.database().Model(&models.SaDocument{}).Where("project_id = ? AND normalized_name = ?", projectID, normalized)
|
|
|
|
|
query := s.database().Model(&models.SaDocumentTree{}).Where("project_id = ? AND normalized_name = ?", projectID, normalized)
|
|
|
|
|
if parentID == nil {
|
|
|
|
|
query = query.Where("parent_id IS NULL")
|
|
|
|
|
} else {
|
|
|
|
|
@@ -578,7 +578,7 @@ func (s *Service) isDescendant(ancestorID, candidateID uint) (bool, error) {
|
|
|
|
|
if current == ancestorID {
|
|
|
|
|
return true, nil
|
|
|
|
|
}
|
|
|
|
|
var document models.SaDocument
|
|
|
|
|
var document models.SaDocumentTree
|
|
|
|
|
if err := s.database().Unscoped().Select("parent_id").Where("id = ?", current).First(&document).Error; err != nil {
|
|
|
|
|
return false, err
|
|
|
|
|
}
|
|
|
|
|
@@ -594,7 +594,7 @@ func (s *Service) subtreeIDs(projectID, rootID uint) ([]uint, error) {
|
|
|
|
|
result := []uint{rootID}
|
|
|
|
|
frontier := []uint{rootID}
|
|
|
|
|
for len(frontier) > 0 {
|
|
|
|
|
var children []models.SaDocument
|
|
|
|
|
var children []models.SaDocumentTree
|
|
|
|
|
if err := s.database().Select("id").Where("project_id = ? AND parent_id IN ?", projectID, frontier).Find(&children).Error; err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|