예제 #1
0
func buildKey(req *wcg.Request, key *datastore.Key) *datastore.Key {
	kind := entities.FindKind(key.Kind(), key.Namespace())
	if kind == nil {
		return nil
	}
	if key.Parent() != nil {
		return kind.NewKey(req, key.StringID(), buildKey(req, key.Parent()))
	}
	return kind.NewKey(req, key.StringID(), nil)
}
예제 #2
0
func setupAPIDatastore(app *server.App) {
	var API = app.API()

	if lib.IsOnLocalGAE() {
		API.GET("/datastore/cleanup/:kind.json",
			server.Handler(func(req *wcg.Request) response.Response {
				k := entities.FindKind(req.Param("kind"), req.Query("ns"))
				if k == nil {
					return response.NotFound(req)
				}
				num := k.DeleteQuery().MustCommit(req)
				return response.NewJSONResponse(map[string]int{
					"entities": num,
				})
			}),
		)
	}

	API.GET("/datastore/export/:kind.json",
		middleware.APITokenOnly(),
		server.Handler(func(req *wcg.Request) response.Response {
			k := entities.FindKind(req.Param("kind"), req.Query("ns"))
			if k == nil {
				return response.NotFound(req)
			}
			// TODO: export with gzip
			return middleware.EntityStreaming(
				k.Query().Order(fmt.Sprintf("-%s", k.TimestampFieldName)).Limit(
					wcg.ParseInt(req.Query("limit"), 100, -1, math.MaxInt32),
				),
				true,
			).Handle(req)
		}))

	API.POST("/datastore/import/:kind.json",
		middleware.APITokenOnly(),
		server.Handler(func(req *wcg.Request) response.Response {
			k := entities.FindKind(req.Param("kind"), req.Query("ns"))
			if k == nil {
				return response.NotFound(req)
			}
			var line = 0
			var total = 0
			var errors = make([]*entityImportError, 0)
			var list = make([]interface{}, 0, 100)
			var keys = make([]*datastore.Key, 0, 100)
			var buff []byte
			var err error
			reader := bufio.NewReaderSize(req.HTTPRequest().Body, 4096)
			for err != io.EOF {
				buff, err = reader.ReadBytes('\n')
				line += 1
				if err != nil && err != io.EOF {
					return response.InternalServerError(req, err)
				}
				buff = bytes.TrimSpace(buff)
				if len(buff) == 0 { // skip empty row
					continue
				}
				var row entityImportRow
				if err2 := json.Unmarshal(buff, &row); err2 != nil {
					errors = append(errors, &entityImportError{
						Line:  line,
						Error: fmt.Sprintf("%v - (row: %q)", err2, buff),
					})
					continue
				}
				ent, err2 := k.NewEntityFromJSON([]byte(row.Entity))
				if err2 != nil {
				}
				total = total + 1
				keys = append(keys, buildKey(req, row.Key))
				list = append(list, ent)
				if len(list) == 100 {
					k.PutMulti().DatastoreKeys(keys...).DoNotUpdateTimestamp(true).MustUpdate(req, list)
					list = make([]interface{}, 0, 100)
					keys = make([]*datastore.Key, 0, 100)
				}
			}
			if len(list) > 0 {
				k.PutMulti().DatastoreKeys(keys...).DoNotUpdateTimestamp(true).MustUpdate(req, list)
			}
			return response.NewJSONResponse(&entityImportResult{
				Total:  total,
				Lines:  line - 1,
				Errors: errors,
			})
		}))
}