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" }