示例#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"
}
示例#2
0
func formatCanonicalResponse(docs model.DocumentSlice, languages acceptlang.AcceptLanguages) ([]byte, error) {
	var formatFilterPriori []string
	if languages.Len() > 0 {
		var langstr []string
		for _, lang := range languages {
			langstr = append(langstr, lang.Language)
		}
		formatFilterPriori = append(langstr, canonFormatFilterPriority...)
	} else {
		formatFilterPriori = canonFormatFilterPriority
	}

	// Language Map 型をもつフィールドの言語の種類を一つに絞る
	docs.Map(func(d model.Document) model.Document {
		// TODO: 工夫すれば、Mongo の Projection 機能でいけるかもしれない
		if verb, ok := d.Data["verb"].(map[string]interface{}); ok {
			if display, ok := verb["display"].(map[string]interface{}); ok {
				verb["display"] = projectMapSingle(display, formatFilterPriori)
			}
		}
		if object, ok := d.Data["object"].(map[string]interface{}); ok {
			if objectDefinition, ok := object["definition"].(map[string]interface{}); ok {
				if name, ok := objectDefinition["name"].(map[string]interface{}); ok {
					objectDefinition["name"] =
						projectMapSingle(name, formatFilterPriori)
				}
				if description, ok := objectDefinition["description"].(map[string]interface{}); ok {
					objectDefinition["description"] =
						projectMapSingle(description, formatFilterPriori)
				}
				if choices, ok := objectDefinition["choices"].([]interface{}); ok {
					objectDefinition["choices"] =
						projectDescriptionInArray(choices, formatFilterPriori)
				}
				if scale, ok := objectDefinition["scale"].([]interface{}); ok {
					objectDefinition["scale"] =
						projectDescriptionInArray(scale, formatFilterPriori)
				}
				if source, ok := objectDefinition["source"].([]interface{}); ok {
					objectDefinition["source"] =
						projectDescriptionInArray(source, formatFilterPriori)
				}
				if target, ok := objectDefinition["target"].([]interface{}); ok {
					objectDefinition["target"] =
						projectDescriptionInArray(target, formatFilterPriori)
				}
				if steps, ok := objectDefinition["steps"].([]interface{}); ok {
					objectDefinition["steps"] =
						projectDescriptionInArray(steps, formatFilterPriori)
				}
			}
		}
		if attachments, ok := d.Data["attachments"].(map[string]interface{}); ok {
			if display, ok := attachments["display"].(map[string]interface{}); ok {
				attachments["display"] =
					projectMapSingle(display, formatFilterPriori)
			}
			if display, ok := attachments["description"].(map[string]interface{}); ok {
				attachments["description"] =
					projectMapSingle(display, formatFilterPriori)
			}
		}

		return d
	})

	return json.Marshal(map[string]interface{}{
		"statements": docs.ToDataArray(),
		"more":       "",
	})
}