예제 #1
0
func (c *Controller) insertIntoDB(xAPIVersion, user, app string, docs model.DocumentSlice) (int, string) {
	// データベースのセッションを取得
	sess := c.session.New()
	defer sess.Close()
	db := sess.DB(miscs.GlobalConfig.MongoDB.DBName)

	if valid, err := isValidVoidedStatements(db, docs, xAPIVersion, user, app); !valid && err != nil {
		return NewBadRequestErrF("Invalid voided statement: %s", err).Response()
	}

	quota, err := model.GetQuota(db, user)
	if err != nil {
		logger.Err("An unexpected error occured on get quota: ", err)
		return http.StatusInternalServerError, "Internal Server Error"
	}

	// ユーザーのディスク使用量をチェック
	if !quota.Check() {
		return NewBadRequestErrF("The disk is full of user: %s", user).Response()
	}

	if err := quota.IncrementUsageTo(db, getSizeOfDocuments(docs)); err != nil {
		logger.Err("An unexpected error occured on increment quota: ", err)
		return http.StatusInternalServerError, "Internal Server Error"
	}

	// データベースに挿入し、duplicate key エラーが発生しない場合に正常終了、
	// そうでなければ Conflict を返す。xAPI の仕様によると Conflict は
	// statement の id フィールド値が重複する場合と規定されている。
	// そこで、この箇所では statement の id フィールドを unique index にすることで
	// duplicate key エラーを発生させ、Conflict の判定を行っている。
	if err := docs.InsertTo(db.C("statement")); err != nil {
		if !mgo.IsDup(err) {
			logger.Err("An unexpected error occured on insert statement into DB: ", err)
			return http.StatusInternalServerError, "Internal Server Error"
		}

		return http.StatusConflict, "Conflict"
	}

	return http.StatusOK, "ok"
}