gae

package module
v0.0.0-...-1387479 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2019 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package gae is a library for interacting with Google App Engine and Datastore.

Index

Examples

Constants

View Source
const (
	// HeaderCursor is the header for holding the pagination cursor.
	HeaderCursor = "x-cursor"
	// HeaderError is the header for holding error description. This is in all
	// lower-case because it is following the specifications and App Engine
	// changes it to all lowercase no matter the original casing.
	HeaderError = "x-error"
	// KindCounterConfig is the entity kind for storing the sharded counter
	// configuration.
	KindCounterConfig = "GAECounterConfig"
	// KindCounterShard is the entity kind for storing a shard of the counter.
	KindCounterShard = "GAECounterShard"
	// KindSession is the kind of entity stored in the Datastore for
	// maintaining session.
	KindSession = "GAESession"
)
View Source
const FolderSeparator = "/"

FolderSeparator is the slash ("/") that Google Cloud Storage uses to denote an object as a folder.

Variables

View Source
var (
	// ErrMultipleEntities is returned when a Datastore retrieval
	// finds more than 1 entity with the specified criteria.
	ErrMultipleEntities = errors.New("multiple entities retrieved when only 1 is expected")

	// ErrNilKey is returned when Key parameters are not expected to be nil.
	ErrNilKey = errors.New("key is nil")

	// ErrUnauth is returned when the request is not authenticated.
	ErrUnauth = errors.New("unauthenticated")
)

Functions

func CheckSession

func CheckSession(ctx context.Context, sessID string) bool

CheckSession checks for a valid session based on its ID.

If the session does not exist, false is returned. If the expiration time of the session is after the current time, returns true. Returns false otherwise.

func CounterCount

func CounterCount(ctx context.Context, name string) (int, error)

CounterCount gets the value of the counter by summing up the values of all the sharded counters.

If the counter exists in memcache, it is returned without touching the Datastore.

func CounterIncreaseShards

func CounterIncreaseShards(ctx context.Context, name string, n int) error

CounterIncreaseShards increases the number of shards for the named counter.

The entity is only saved to the Datastore if it differs. The number of shards can only increase and cannot be decreased.

n is the total number of shards that can exist, not the number of shards to increase by.

func CounterIncrement

func CounterIncrement(ctx context.Context, name string) error

CounterIncrement increments the named counter.

This function increases by 1 the value of a randomly selected shard, and also that of the counter in memcache.

func DeleteByID

func DeleteByID(ctx context.Context, id string) error

DeleteByID removes an entity from the Datastore and memcache using the opaque representation of the key.

DeleteByKey is called after conversion of the ID.

func DeleteByKey

func DeleteByKey(ctx context.Context, k *datastore.Key) error

DeleteByKey removes an entity from the Datastore.

In addition to being an alias to:

datastore.Delete(ctx, k)

this function also removes the item from memcache.

func IsDuplicateError

func IsDuplicateError(e error) bool

IsDuplicateError checks if an error is the `DuplicateError` type.

func IsInsufficientError

func IsInsufficientError(e error) bool

IsInsufficientError checks if an error is the `InsufficientError` type.

func IsInvalidError

func IsInvalidError(e error) bool

IsInvalidError checks if an error is the `InvalidError` type.

func IsJSONUnmarshalError

func IsJSONUnmarshalError(e error) bool

IsJSONUnmarshalError checks if an error is the `JSONUnmarshalError` type.

func IsMismatchError

func IsMismatchError(e error) bool

IsMismatchError checks if an error is the `MismatchError` type.

func IsMissingError

func IsMissingError(e error) bool

IsMissingError checks if an error is the `MissingError` type.

func IsNilError

func IsNilError(e error) bool

IsNilError checks if an error is the `NilError` type.

func IsNotFoundError

func IsNotFoundError(e error) bool

IsNotFoundError checks if an error is the `NotFoundError` type.

func IsTypeError

func IsTypeError(e error) bool

IsTypeError checks if an error is the "TypeError" type.

func IsValid

func IsValid(m Datastorer) bool

IsValid checks if a Datastorer has satisfied its validation rules.

func IsValidityError

func IsValidityError(e error) bool

IsValidityError checks if an error is the `ValidityError` type.

func LoadByID

func LoadByID(ctx context.Context, id string, m Datastorer) error

LoadByID retrieves a model from the Datastore using the opaque representation of the key.

LoadByKey is called after conversion of the ID.

func LoadByKey

func LoadByKey(ctx context.Context, k *datastore.Key, m Datastorer) error

LoadByKey retrieves a model from the Datastore.

The SetKey method of Datastore is called to set the key (and any other properties determined by the implementation) after retrieving from the Datastore.

func MakeSessionCookie

func MakeSessionCookie(ctx context.Context, name string, obj interface{},
	duration int64) (*http.Cookie, error)

MakeSessionCookie creates a session and a cookie based on the database Key encoded value.

The session is also placed in Memcache in addition to the Datastore.

The `obj` parameter is the value to be stored in the cookie. It is JSONified before storing as a string. The `duration` parameter is the number of seconds for which the cookie is to be valid.

func PrepPageParams

func PrepPageParams(params url.Values) (limit int, cursor string)

PrepPageParams parses the query parameters to get the pagination cursor and count.

The cursor should be specified as "cursor". If not specified, an empty string is returned.

The count should be specified as "ipp". Default value is 50.

func RetrieveEntityByID

func RetrieveEntityByID(ctx context.Context, id string, m Datastorer) error

RetrieveEntityByID attempts to retrieve the entity from Memcache before retrieving from the Datastore.

If the entity is retrieved from the Datastore, it is placed into Memcache.

func RetrieveEntityByKey

func RetrieveEntityByKey(ctx context.Context, key *datastore.Key, m Datastorer) error

RetrieveEntityByKey does the same thing as RetrieveEntityByID.

It converts the Key to a string before proxying the invocation to RetrieveEntityByID

func Save

func Save(ctx context.Context, m Datastorer) error

Save checks for validity of the model prior to saving to the Datastore.

Save also invokes the Presave method of m if it is set to perform any pre-saving actions prior to updating the entity in the Datastore.

The validity check is performed before the pre-saving operation.

After saving, the key is assigned to m.

func SaveCacheEntity

func SaveCacheEntity(ctx context.Context, m Datastorer) error

SaveCacheEntity saves and caches the entity.

The operation to save the entity to the Datastore is performed first. If that fails, this function returns with the error.

After saving the entity, it is then put into Memcache. Any error from Memcache is ignored.

func WriteErrorResponse

func WriteErrorResponse(w http.ResponseWriter, code int, er ErrorResponse)

WriteErrorResponse writes an error response along with a payload that provides more information about the error for the client.

func WriteJSON

func WriteJSON(w http.ResponseWriter, m Datastorer, status int)

WriteJSON writes an instance of Datastorer as a JSON string into the response body and sets the status code as specified.

If there is any error writing the JSON, a 500 Internal Server error is returned.

func WriteJSONColl

func WriteJSONColl(w http.ResponseWriter, m []Datastorer, status int, cursor string)

WriteJSONColl writes a slice of Datastorer instances as JSON string into the response body and sets the status code as specified.

Due to the nature of the language, the slice of the implementing structs cannot be passed to this function as-is - it needs to be changed into a slice of Datastorer explicity. E.g.

coll := make([]gae.Datastorer, len(users))
for k, v := range users {
	coll[k] = &v
}

If there is any error writing the JSON, a 500 Internal Server error is returned.

func WriteLogRespErr

func WriteLogRespErr(c context.Context, w http.ResponseWriter, code int, e error)

WriteLogRespErr logs the error string and then writes it to the response header (HeaderError) before setting the response code.

func WriteRespErr

func WriteRespErr(w http.ResponseWriter, code int, e error)

WriteRespErr writes the error string to the response header (HeaderError) before setting the response code.

Types

type Datastorer

type Datastorer interface {
	Key() *datastore.Key
	MakeKey(context.Context) *datastore.Key
	SetKey(*datastore.Key) error
	ValidationError() []string
}

Datastorer is an interface that all application models must implement in order to be able to save to and load from the Datastore.

The MakeKey method is for getting the Key of the entity (if present) or make a new one for saving (if absent).

SetKey is used to assign values to other properties that are not stored as values of the entity, but as either the string/numeric ID or the parent of the Key.

ValidationError returns a slice of string with the fields that do not meet the validation rules. This is used by IsValid to determine the validity of the model.

type DateTime

type DateTime struct {
	time.Time
}

DateTime is an auxillary struct for time.Time specifically for the purpose of converting to RFC3339 time format in JSON.

DateTime handles time up to the seconds, ignoring the microseconds.

func NewDateTime

func NewDateTime(tstamp string) (DateTime, error)

NewDateTime creates a new DateTime instance from a string. The parameter `tstamp` is a string in the format "YYYY-MM-DDTHH:mm:ss+HH:mm"

Example
t, _ := NewDateTime("2017-07-03T09:44:00+08:00")
fmt.Println(t.String())
Output:

2017-07-03T09:44:00+08:00

func NewDateTimeNow

func NewDateTimeNow() DateTime

NewDateTimeNow creates a new DateTime instance representing the moment in time the function was called. This is basically shorthand for:

DateTime{time.Now()}

func (*DateTime) Equal

func (d1 *DateTime) Equal(d2 DateTime) bool

Equal checks whether the two timestamps are referring to the same moment, taking into account timezone differences while ignoring sub-second differences.

Example (DateTime)
t1 := time.Date(2017, time.July, 3, 17, 59, 59, 1, time.Local)
t2 := time.Date(2017, time.July, 3, 9, 59, 59, 59, time.UTC)
ta := DateTime{t1}
tb := DateTime{t2}
if ta.Equal(tb) {
	fmt.Println("Equal")
} else {
	fmt.Println("Not equal")
}
Output:

Equal
Example (Time)
t1 := time.Date(2017, time.July, 3, 17, 59, 59, 1, time.Local)
t2 := time.Date(2017, time.July, 3, 9, 59, 59, 59, time.UTC)
if t1.Equal(t2) {
	fmt.Println("Equal")
} else {
	fmt.Println("Not equal")
}
Output:

Not equal

func (*DateTime) MarshalJSON

func (d *DateTime) MarshalJSON() ([]byte, error)

MarshalJSON converts the time into a format like

"2006-01-02T15:04:05+07:00"

or an empty string if `time.Time.IsZero()`

Example (DateTime)
t1 := DateTime{}
js, _ := t1.MarshalJSON()
fmt.Println(string(js))
Output:

""
Example (Time)
//Compare to the output of time.Time
t1 := time.Time{}
js, _ := json.Marshal(t1.Format(time.RFC3339))
fmt.Println(string(js))
Output:

"0001-01-01T00:00:00Z"

func (*DateTime) String

func (d *DateTime) String() string

String for DateTime returns the time in this format "YYYY-MM-DDTHH:mm:ss+HH:mm"

e.g. 2006-01-02T15:04:05+07:00

In other words, the output is formatted using `time.RFC3339`

Example (DateTime)
//To create a new DateTime instance
t1 := DateTime{}
fmt.Println(t1.String())
Output:

0001-01-01T00:00:00Z
Example (Time)
//Compare to the output of time.Time
t1 := time.Time{}
fmt.Println(t1.String())
Output:

0001-01-01 00:00:00 +0000 UTC

func (*DateTime) UnmarshalJSON

func (d *DateTime) UnmarshalJSON(input []byte) error

UnmarshalJSON expects the input to a string like

"2006-01-02T15:04:05+07:00"

to convert into a time.Time struct wrapped inside DateTime. It is able to understand an empty string ("") and convert it to a zeroed `time.Time` instance.

type DuplicateError

type DuplicateError struct {
	Msg  string
	Name string
}

DuplicateError is for when a duplicate value is present.

func (DuplicateError) Error

func (this DuplicateError) Error() string

Error for DuplicateError returns

Duplicate value

or

Duplicate value for <Name>

if the `Name` field is set. The `Msg` field is appended to this message if set, separated by a hyphen.

type ErrorResponse

type ErrorResponse struct {
	// ErrorCode is a code that identifies the error. E.g. BAD_FORMAT
	ErrorCode string `json:"errorCode,omitempty"`
	// Field is the name of the field that has the error.
	Field string `json:"field,omitempty"`
	// HelpURL is the URL to the help page that describes the error in more
	// detail. The page should also help the developers know how to fix the
	// error, the cause and resolutions.
	HelpURL string `json:"helpUrl,omitempty"`
	// Message contains a user-friendly message. It may be used to surface to
	// the client directly. For localization, some coordination may be
	// required between the client and server to show the message in the local
	// language.
	Message string `json:"message,omitempty"`
	// OriginalValue contains the original value from the request.
	OriginalValue string `json:"originalValue,omitempty"`
}

ErrorResponse should be the return payload if the API endpoints return an error response (i.e. error codes in the 4xx and 5xx ranges).

All of the fields are optional. If not set, the fields are omitted from the JSON output.

func (ErrorResponse) Equal

func (er ErrorResponse) Equal(e ErrorResponse) bool

Equal checks if two instances of ErrorResponse are equal. They are considered equal if and only if all fields are identical (case-sensitive).

func (ErrorResponse) Error

func (er ErrorResponse) Error() string

Error returns

<Message> (<ErrorCode>) - <Field>(<OriginalValue>)

If the "ErrorCode" is empty, the parentheses around it will not be included.

The same applies for "OriginalValue".

type GCStorage

type GCStorage struct {
	// contains filtered or unexported fields
}

GCStorage utilises the API to access Google Cloud Storage.

func NewGCStorage

func NewGCStorage(ctx context.Context, client *storage.Client,
	bucketName string) (GCStorage, error)

NewGCStorage creates a new Google Cloud Storage client.

The client has to be created from the caller so that it may be closed on a per request basis.

func (*GCStorage) CreateFolder

func (gcs *GCStorage) CreateFolder(ctx context.Context, name string) error

CreateFolder creates an empty folder in Cloud Storage. This is akin to the "mkdir" command in Bash.

Note that in Cloud Storage, there is no concept of a folder. A folder is created when the name of the object ends with a slash ("/"). Therefore if the name does not end with a slash, an error is returned.

func (*GCStorage) Delete

func (gcs *GCStorage) Delete(ctx context.Context, objName string) error

Delete deletes an object from Cloud Storage.

This can delete both a file or "folder", noting that the concept of a folder does not exist in Cloud Storage other than through the name of the object.

func (*GCStorage) GetBucketName

func (gcs *GCStorage) GetBucketName() string

GetBucketName gets the name of the bucket

func (*GCStorage) ListFiles

func (gcs *GCStorage) ListFiles(ctx context.Context, foldername string) ([]*storage.ObjectAttrs, error)

ListFiles lists the contents of a folder.

The returned list of results contains the names of the objects in its full path. To read the names of the files less the directory, use `ListFilesAsString`.

For the list of properties available with `ObjectAttrs`, see https://godoc.org/cloud.google.com/go/storage#ObjectAttrs

func (*GCStorage) ListFilesAsString

func (gcs *GCStorage) ListFilesAsString(ctx context.Context, foldername string) ([]string, error)

ListFilesAsString lists the file names inside a folder.

The list of returned names is the canonical names of the files (i.e. less the path of the folder).

func (*GCStorage) ReadFile

func (gcs *GCStorage) ReadFile(ctx context.Context, name string) ([]byte, error)

ReadFile reads the contents of the object in Cloud Storage.

Note that the full "path" of the object must be specified.

func (*GCStorage) WriteFile

func (gcs *GCStorage) WriteFile(ctx context.Context, name string,
	src io.Reader, mime string) error

WriteFile writes a file to Cloud Storage.

It reads the bytes from the provided `src` Reader and writes them to the object in the bucket with the specified MIME type.

type InsufficientError

type InsufficientError struct {
	Msg  string
	Name string
}

InsufficientError is for when the quantity of an element is insufficient.

func (InsufficientError) Error

func (this InsufficientError) Error() string

Error for InsufficientError returns

Insufficient value

or

Insufficient value for <Name>

if the `Name` field is set. The `Msg` field is appended to this message if set, separated by a hyphen.

type InvalidError

type InvalidError struct {
	Msg string
}

InvalidError is a generic error for describing invalid conditions.

An example is when the request parameter value is in an invalid format.

func (InvalidError) Error

func (this InvalidError) Error() string

Error for InvalidError returns a string in the format:

Invalid value (<msg>)

type JSONUnmarshalError

type JSONUnmarshalError struct {
	Msg string
	Err error
}

JSONUnmarshalError is for unmarshalling errors when reading request JSON payload.

The Msg field should provide an indication of where the error originated from. E.g. CreateSchoolAPI - request body

func (JSONUnmarshalError) Error

func (this JSONUnmarshalError) Error() string

Error for JSONUnmarshalError returns a string in the format:

Unable to parse JSON (<msg>) - <error string>

type MismatchError

type MismatchError struct {
	Msg string
}

MismatchError is used in situations where multiple provided values do not match each other.

func (MismatchError) Error

func (this MismatchError) Error() string

Error for MismatchError returns a string in the format:

Mismatched values - <msg>

type MissingError

type MissingError struct {
	Msg string
}

MissingError is for missing parameter values or a value is not provided when expected.

The Msg field should provide a brief description of the parameter whose value is missing.

func (MissingError) Error

func (this MissingError) Error() string

Error for MissingError returns:

Missing value

or

Missing value - <msg>

if the `Msg` field is set.

type NilError

type NilError struct {
	Msg string
	Err error
}

NilError is for situations where variables are nil.

func (NilError) Error

func (this NilError) Error() string

Error for NilError returns a string in the format:

Nil error (<msg>) - <error>

type NotFoundError

type NotFoundError struct {
	Kind string
	Err  error
}

NotFoundError is a generic error for operations not being able to retrieve or find an entity.

If the error is for a Datastore operation, the `Kind` field should be specified.

func (NotFoundError) Error

func (this NotFoundError) Error() string

Error for NotFoundError returns a string in one of the following formats:

  • Entity not found - <error string>
  • '<kind>' entity not found - <error string>

type Page

type Page struct {
	Title       string
	Description string
	Dictionary  map[string]string
	Path        string
	Public      bool
	Param       map[string]string
	Handler     func(http.ResponseWriter, *http.Request)
	Template    string
}

Page describes the contents for a page. It is to be used with templates.

func (*Page) AddVar

func (p *Page) AddVar(word, meaning string)

AddVar is a convenient method to adding values into the Dictionary map.

This method performs the additional check for initialization of the Dictionary map so that the calling code has the option of not initializing the map.

func (*Page) ToDictionary

func (p *Page) ToDictionary() map[string]interface{}

ToDictionary creates a map with the existing values in the `Dictionary` field combined with the `Title` and `Description` fields.

This is for use with templates where additional variables are needed.

Note that if dictionary also contains the same keys ("Title" and "Dictionary"), they will be overridden.

type Presaver

type Presaver interface {
	Presave()
}

Presaver specifies a method Presave with no return values.

Data models that require some "cleanup" before saving into the Datastore should implement this method to do the cleanup.

Presave is called after IsValid.

type Session

type Session struct {
	KeyID      *datastore.Key `datastore:"-"`
	Name       string         `datastore:",noindex"`
	Value      string         `datastore:",noindex"`
	Expiration time.Time      `datastore:",noindex"`
}

Session keeps track of a user's session information.

Any value that it needs to store should be jsonified and stored as a string in the Value field.

func (*Session) Valid

func (s *Session) Valid() bool

Valid returns true if the Expiration field is after the current time.

If the value is not set (i.e. `IsZero`) then the session is also not valid.

type TypeError

type TypeError struct {
	Name  string
	Cause string
}

TypeError is for errors having to do with types and conversion.

func (TypeError) Error

func (e TypeError) Error() string

Error returns a string in different formats depending on the properties specified.

Basic (nothing specified): "type error"

Name specified only: "type error on <name>

Cause specified only: "type error - <cause>"

Name and Cause specified: "type error on <name> - <cause>"

type ValidityError

type ValidityError struct {
	Msg string
}

ValidityError is for errors in model validation.

func (ValidityError) Error

func (e ValidityError) Error() string

Error returns a string in the format:

validation error: <error string>

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL