Răsfoiți Sursa

add tag model and page tag relation model

yusuketk 7 ani în urmă
părinte
comite
a7a46bfce1
3 a modificat fișierele cu 443 adăugiri și 0 ștergeri
  1. 2 0
      src/server/models/index.js
  2. 323 0
      src/server/models/page-tag-relation.js
  3. 118 0
      src/server/models/tag.js

+ 2 - 0
src/server/models/index.js

@@ -3,11 +3,13 @@
 module.exports = {
   Page: require('./page'),
   PageGroupRelation: require('./page-group-relation'),
+  PageTagRelation: require('./page-tag-relation'),
   User: require('./user'),
   ExternalAccount: require('./external-account'),
   UserGroup: require('./user-group'),
   UserGroupRelation: require('./user-group-relation'),
   Revision: require('./revision'),
+  tag: require('./tag'),
   Bookmark: require('./bookmark'),
   Comment: require('./comment'),
   Attachment: require('./attachment'),

+ 323 - 0
src/server/models/page-tag-relation.js

@@ -0,0 +1,323 @@
+const debug = require('debug')('growi:models:pageTagRelation');
+const mongoose = require('mongoose');
+const mongoosePaginate = require('mongoose-paginate');
+const ObjectId = mongoose.Schema.Types.ObjectId;
+
+
+/*
+ * define schema
+ */
+const schema = new mongoose.Schema({
+  relatedPage: {
+    type: ObjectId,
+    ref: 'Page',
+    required: true
+  },
+  relatedTag: {
+    type: ObjectId,
+    ref: 'Tag',
+    required: true
+  },
+});
+schema.plugin(mongoosePaginate);
+
+/**
+ * PageTagRelation Class
+ *
+ * @class PageTagRelation
+ */
+class PageTagRelation {
+
+  // /**
+  //  * limit items num for pagination
+  //  *
+  //  * @readonly
+  //  * @static
+  //  * @memberof UserGroupRelation
+  //  */
+  // static get PAGE_ITEMS() {
+  //   return 50;
+  // }
+
+  static set crowi(crowi) {
+    this._crowi = crowi;
+  }
+
+  static get crowi() {
+    return this._crowi;
+  }
+
+  static init() {
+    this.removeAllInvalidRelations();
+  }
+
+  /**
+   * remove all invalid relations that has reference to unlinked document
+   */
+  static removeAllInvalidRelations() {
+    return this.findAllRelation()
+      .then(relations => {
+        // filter invalid documents
+        return relations.filter(relation => {
+          return relation.relatedTag == null || relation.relatedPage == null;
+        });
+      })
+      .then(invalidRelations => {
+        const ids = invalidRelations.map(relation => relation._id);
+        return this.deleteMany({
+          _id: {
+            $in: ids
+          }
+        });
+      });
+  }
+
+  /**
+   * find all page and tag relation
+   *
+   * @static
+   * @returns {Promise<PageTagRelation[]>}
+   * @memberof UserGroupRelation
+   */
+  static findAllRelation() {
+    return this
+      .find()
+      .populate('relatedPage')
+      .populate('relatedTag')
+      .exec();
+  }
+
+  // /**
+  //  * find all user and group relation of UserGroup
+  //  *
+  //  * @static
+  //  * @param {UserGroup} userGroup
+  //  * @returns {Promise<UserGroupRelation[]>}
+  //  * @memberof UserGroupRelation
+  //  */
+  // static findAllRelationForUserGroup(userGroup) {
+  //   debug('findAllRelationForUserGroup is called', userGroup);
+  //   return this
+  //     .find({
+  //       relatedGroup: userGroup
+  //     })
+  //     .populate('relatedUser')
+  //     .exec();
+  // }
+
+  // /**
+  //  * find all user and group relation of UserGroups
+  //  *
+  //  * @static
+  //  * @param {UserGroup[]} userGroups
+  //  * @returns {Promise<UserGroupRelation[]>}
+  //  * @memberof UserGroupRelation
+  //  */
+  // static findAllRelationForUserGroups(userGroups) {
+  //   return this
+  //     .find({
+  //       relatedGroup: {
+  //         $in: userGroups
+  //       }
+  //     })
+  //     .populate('relatedUser')
+  //     .exec();
+  // }
+
+  // /**
+  //  * find all user and group relation of User
+  //  *
+  //  * @static
+  //  * @param {User} user
+  //  * @returns {Promise<UserGroupRelation[]>}
+  //  * @memberof UserGroupRelation
+  //  */
+  // static findAllRelationForUser(user) {
+  //   return this
+  //     .find({
+  //       relatedUser: user.id
+  //     })
+  //     .populate('relatedGroup')
+  //     // filter documents only relatedGroup is not null
+  //     .then(userGroupRelations => {
+  //       return userGroupRelations.filter(relation => {
+  //         return relation.relatedGroup != null;
+  //       });
+  //     });
+  // }
+
+  // /**
+  //  * find all UserGroup IDs that related to specified User
+  //  *
+  //  * @static
+  //  * @param {User} user
+  //  * @returns {Promise<ObjectId[]>}
+  //  */
+  // static async findAllUserGroupIdsRelatedToUser(user) {
+  //   const relations = await this.find({
+  //       relatedUser: user.id
+  //     })
+  //     .select('relatedGroup')
+  //     .exec();
+
+  //   return relations.map(relation => relation.relatedGroup);
+  // }
+
+  // /**
+  //  * find all entities with pagination
+  //  *
+  //  * @see https://github.com/edwardhotchkiss/mongoose-paginate
+  //  *
+  //  * @static
+  //  * @param {UserGroup} userGroup
+  //  * @param {any} opts mongoose-paginate options object
+  //  * @returns {Promise<any>} mongoose-paginate result object
+  //  * @memberof UserGroupRelation
+  //  */
+  // static findUserGroupRelationsWithPagination(userGroup, opts) {
+  //   const query = {
+  //     relatedGroup: userGroup
+  //   };
+  //   const options = Object.assign({}, opts);
+  //   if (options.page == null) {
+  //     options.page = 1;
+  //   }
+  //   if (options.limit == null) {
+  //     options.limit = UserGroupRelation.PAGE_ITEMS;
+  //   }
+
+  //   return this.paginate(query, options)
+  //     .catch((err) => {
+  //       debug('Error on pagination:', err);
+  //     });
+  // }
+
+  /**
+   * count by related page id and related tag
+   *
+   * @static
+   * @param {string} userPageId find query param for relatedPage
+   * @param {User} tagName find query param for relatedTag
+   * @returns {Promise<number>}
+   */
+  static async countByPageIdAndTag(pageId, tagName) {
+    const query = {
+      relatedPage: pageId,
+      relatedTag: tagName
+    };
+
+    return this.count(query);
+  }
+
+  // /**
+  //  * find all "not" related user for UserGroup
+  //  *
+  //  * @static
+  //  * @param {UserGroup} userGroup for find users not related
+  //  * @returns {Promise<User>}
+  //  * @memberof UserGroupRelation
+  //  */
+  // static findUserByNotRelatedGroup(userGroup) {
+  //   const User = UserGroupRelation.crowi.model('User');
+
+  //   return this.findAllRelationForUserGroup(userGroup)
+  //     .then((relations) => {
+  //       const relatedUserIds = relations.map((relation) => {
+  //         return relation.relatedUser.id;
+  //       });
+  //       const query = {
+  //         _id: {
+  //           $nin: relatedUserIds
+  //         },
+  //         status: User.STATUS_ACTIVE
+  //       };
+
+  //       debug('findUserByNotRelatedGroup ', query);
+  //       return User.find(query).exec();
+  //     });
+  // }
+
+  // /**
+  //  * get if the user has relation for group
+  //  *
+  //  * @static
+  //  * @param {User} userData
+  //  * @param {UserGroup} userGroup
+  //  * @returns {Promise<boolean>} is user related for group(or not)
+  //  * @memberof UserGroupRelation
+  //  */
+  // static isRelatedUserForGroup(userData, userGroup) {
+  //   const query = {
+  //     relatedGroup: userGroup.id,
+  //     relatedUser: userData.id
+  //   };
+
+  //   return this
+  //     .count(query)
+  //     .exec()
+  //     .then((count) => {
+  //       // return true or false of the relation is exists(not count)
+  //       return (0 < count);
+  //     });
+  // }
+
+  /**
+   * create tag and page relation
+   *
+   * @static
+   * @param {Tag} tag
+   * @param {Page} page
+   * @returns {Promise<PageTagRelation>} created relation
+   * @memberof PageTagRelation
+   */
+  static createRelation(page, tag) {
+    return this.create({
+      relatedGroup: page.id,
+      relatedUser: tag.id
+    });
+  }
+
+  /**
+   * remove all relation for Page
+   *
+   * @static
+   * @param {Page} page related page for remove
+   * @returns {Promise<any>}
+   * @memberof PageTagRelation
+   */
+  static removeAllByPage(page) {
+    return this.deleteMany({
+      relatedPage: page
+    });
+  }
+
+  /**
+   * remove relation by id
+   *
+   * @static
+   * @param {ObjectId} id
+   * @returns {Promise<any>}
+   * @memberof UserGroupRelation
+   */
+  static removeById(id) {
+
+    return this.findById(id)
+      .then((relationData) => {
+        if (relationData == null) {
+          throw new Error('PageTagRelation data is not exists. id:', id);
+        }
+        else {
+          relationData.remove();
+        }
+      });
+  }
+
+}
+
+module.exports = function(crowi) {
+  PageTagRelation.crowi = crowi;
+  schema.loadClass(PageTagRelation);
+  const model = mongoose.model('PageTagRelation', schema);
+  model.init();
+  return model;
+};

+ 118 - 0
src/server/models/tag.js

@@ -0,0 +1,118 @@
+// const debug = require('debug')('growi:models:tag');
+const mongoose = require('mongoose');
+const mongoosePaginate = require('mongoose-paginate');
+// const ObjectId = mongoose.Schema.Types.ObjectId;
+
+
+/*
+ * define schema
+ */
+const schema = new mongoose.Schema({
+  name: { type: String, required: true, unique: true },
+});
+schema.plugin(mongoosePaginate);
+
+class Tag {
+
+  /**
+   * public fields for Tag model
+   *
+   * @readonly
+   * @static
+   * @memberof Tag
+   */
+  static get TAG_PUBLIC_FIELDS() {
+    return 'name';
+  }
+
+  // /**
+  //  * limit items num for pagination
+  //  *
+  //  * @readonly
+  //  * @static
+  //  * @memberof UserGroup
+  //  */
+  // static get PAGE_ITEMS() {
+  //   return 10;
+  // }
+
+  /*
+   * model static methods
+   */
+
+  // すべてのタグを取得(オプション指定可)
+  static findAllTags(option) {
+    return this.find().exec();
+  }
+
+  // /**
+  //  * find all entities with pagination
+  //  *
+  //  * @see https://github.com/edwardhotchkiss/mongoose-paginate
+  //  *
+  //  * @static
+  //  * @param {any} opts mongoose-paginate options object
+  //  * @returns {Promise<any>} mongoose-paginate result object
+  //  * @memberof Tag
+  //  */
+  // static findTagsWithPagination(opts) {
+  //   const query = {};
+  //   const options = Object.assign({}, opts);
+  //   if (options.page == null) {
+  //     options.page = 1;
+  //   }
+  //   if (options.limit == null) {
+  //     options.limit = Tag.PAGE_ITEMS;
+  //   }
+
+  //   return this.paginate(query, options)
+  //     .catch((err) => {
+  //       debug('Error on pagination:', err);
+  //     });
+  // }
+
+  // // 作成可能なタグ名かの判別
+  // static isRegisterableName(name) {
+  //   const query = { name: name };
+
+  //   return this.findOne(query)
+  //     .then((userGroupData) => {
+  //       return (userGroupData == null);
+  //     });
+  // }
+
+  // // タグ削除
+  // static removeTag(name) {
+  //   const PageTagRelation = mongoose.model('PageTagRelation');
+
+  //   let removed = undefined;
+  //   return this.find({name: name})
+  //     .then(pageTagData => {
+  //       if (pageTagData == null) {
+  //         throw new Exception('UserGroup data is not exists. id:', id);
+  //       }
+  //       return pageTagData.remove();
+  //     })
+  //     .then(removedPageTagData => {
+  //       removed = removedPageTagData;
+  //     })
+  //     // remove relations
+  //     .then(() => {
+  //       return Promise.all([
+  //         PageTagRelation.removeAllByUserGroup(removed),
+  //       ]);
+  //     });
+  // }
+
+  // タグ生成
+  static createTag(name) {
+    return this.create({name: name});
+  }
+}
+
+module.exports = function(crowi) {
+  Tag.crowi = crowi;
+  schema.loadClass(Tag);
+  return mongoose.model('Tag', schema);
+};
+