Documentation
¶
Index ¶
- func GetMulti[T Model](ctx context.Context, c *Client, ids any) ([]T, error)
- func Query[T Model](ctx context.Context, c *Client, q *QueryBuilder, cursor string) ([]T, string, error)
- func WithEncryptionKeyContext(ctx context.Context, key []byte) context.Context
- type AfterDelete
- type AfterSave
- type Base
- type BeforeDelete
- type BeforeSave
- type Client
- func (c *Client) Cache() cache.Cache
- func (c *Client) Close() error
- func (c *Client) Delete(ctx context.Context, val interface{}) error
- func (c *Client) DeleteMulti(ctx context.Context, vals interface{}) error
- func (c *Client) Get(ctx context.Context, val interface{}) error
- func (c *Client) GetMulti(ctx context.Context, vals interface{}) error
- func (c *Client) Key(val interface{}) *datastore.Key
- func (c *Client) Keys(val interface{}) []*datastore.Key
- func (c *Client) Put(ctx context.Context, val interface{}) error
- func (c *Client) PutMulti(ctx context.Context, vals interface{}) error
- func (c *Client) Query(ctx context.Context, q *QueryBuilder, cursor string, vals interface{}) ([]*datastore.Key, string, error)
- func (c *Client) Store() ds.Store
- func (c *Client) Transact(ctx context.Context, f func(tx *Transaction) error) (*datastore.Commit, error)
- type Model
- type OnLoad
- type Option
- type QueryBuilder
- func (q *QueryBuilder) Ancestor(ancestor *datastore.Key) *QueryBuilder
- func (q *QueryBuilder) FilterField(fieldName, operator string, value interface{}) *QueryBuilder
- func (q *QueryBuilder) Filters() []ds.Filter
- func (q *QueryBuilder) GetAncestor() *datastore.Key
- func (q *QueryBuilder) GetCursor() string
- func (q *QueryBuilder) GetLimit() int
- func (q *QueryBuilder) GetNamespace() string
- func (q *QueryBuilder) GetOffset() int
- func (q *QueryBuilder) IsKeysOnly() bool
- func (q *QueryBuilder) KeysOnly() *QueryBuilder
- func (q *QueryBuilder) Kind() string
- func (q *QueryBuilder) Limit(limit int) *QueryBuilder
- func (q *QueryBuilder) Namespace(ns string) *QueryBuilder
- func (q *QueryBuilder) Offset(offset int) *QueryBuilder
- func (q *QueryBuilder) Order(fieldName string) *QueryBuilder
- func (q *QueryBuilder) Orders() []ds.Order
- func (q *QueryBuilder) Start(cursor string) *QueryBuilder
- type Transaction
- func (t *Transaction) Delete(val interface{}) error
- func (t *Transaction) DeleteMulti(vals interface{}) error
- func (t *Transaction) Get(val interface{}) error
- func (t *Transaction) GetMulti(vals interface{}) error
- func (t *Transaction) Put(val interface{}) error
- func (t *Transaction) PutMulti(vals interface{}) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GetMulti ¶
GetMulti is a generic convenience wrapper around Client.GetMulti that accepts a slice of IDs (int, int64, string, or *datastore.Key) or model structs and returns a typed slice. Entities that do not exist in the datastore are set to nil in the returned slice.
func Query ¶
func Query[T Model](ctx context.Context, c *Client, q *QueryBuilder, cursor string) ([]T, string, error)
Query is a generic convenience wrapper around Client.Query that returns a typed slice. It handles allocation and type assertion internally.
func WithEncryptionKeyContext ¶
WithEncryptionKeyContext returns a copy of ctx carrying the given AES encryption key. This key takes priority over both WithEncryptionKey and the DATASTORE_ENCRYPTION_KEY environment variable when loading or saving fields tagged with model:"<name>,encrypt".
Use this when the encryption key must be determined at runtime on a per-request basis (e.g. derived from user credentials or a key-management service) rather than fixed at Client creation time.
Types ¶
type AfterDelete ¶
AfterDelete is an optional interface that a model can implement to run side-effect logic (e.g. cache invalidation, cascading deletes) after the entity has been successfully deleted from the datastore.
type AfterSave ¶
AfterSave is an optional interface that a model can implement to run side-effect logic after the entity has been successfully written to the datastore. The Model parameter contains the previously saved state (nil for new entities), enabling change-detection workflows such as audit logging or sending notifications.
type Base ¶
type Base struct {
// contains filtered or unexported fields
}
Base provides a default implementation of the Model interface along with datastore.PropertyLoadSaver and datastore.KeyLoader. Embed this struct in your model to gain automatic key mapping, property marshaling/encryption, lifecycle hooks, and change tracking.
Fields are configured via the "model" struct tag:
model:"id" — maps the field as the entity's datastore key ID (string or int64) model:"parent" — maps the field as the entity's parent key model:"ns" — maps the field as the entity's namespace model:"created" — auto-set to UTC now on first save model:"modified" — auto-set to UTC now on every save model:"<name>,marshal" — JSON-marshal the field into a single datastore property model:"<name>,encrypt" — JSON-marshal and AES-encrypt the field
func (*Base) IsNew ¶
IsNew reports whether the entity has not yet been loaded from the datastore. It returns true for freshly constructed structs that have never been Get'd.
func (*Base) Key ¶
Key returns the datastore key for this entity. The key is populated automatically when the entity is loaded from the datastore or after a successful Put operation.
type BeforeDelete ¶
BeforeDelete is an optional interface that a model can implement to run cleanup or validation logic before the entity is deleted from the datastore.
type BeforeSave ¶
BeforeSave is an optional interface that a model can implement to run validation or transformation logic before the entity is written to the datastore. The Model parameter contains the previously saved state of the entity (nil for new entities), allowing comparison between old and new values.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client wraps datastore and cache operations.
func New ¶
New creates a new Client with the given options.
Caching backend is auto-detected in the following order unless overridden with WithCache:
- App Engine Memcache (when running on App Engine)
- Redis (when REDIS_ADDR environment variable is set)
- In-memory cache (fallback)
func (*Client) Cache ¶
Cache returns an application-level cache.Cache for general-purpose caching operations (Get, Set, Delete, Load, Save, RateLimit, etc).
func (*Client) Delete ¶
Delete removes a single entity from the datastore. If val implements BeforeDelete, it is called before deletion. If val implements AfterDelete, it is called after successful deletion.
func (*Client) DeleteMulti ¶
DeleteMulti removes multiple entities from the datastore. vals can be a slice of model structs or a []*datastore.Key. BeforeDelete and AfterDelete hooks are called for each entity that implements them.
func (*Client) Get ¶
Get loads a single entity from the datastore into val. The entity's key is derived from val's struct tags (see Client.Key). After loading, the entity's Base.LoadKey is called to map the key back into the struct fields.
func (*Client) GetMulti ¶
GetMulti loads multiple entities from the datastore. vals must be a slice of pointer-to-struct (e.g. []*MyModel). Entities that do not exist in the datastore are set to nil in the slice rather than returning an error. Only non-ErrNoSuchEntity errors are returned.
func (*Client) Key ¶
Key returns the datastore key for a single model struct. The key is constructed from the struct's model:"id" (string or int64), model:"parent" (datastore.Key or parent model pointer), and model:"ns" (namespace) tags.
func (*Client) Keys ¶
Keys returns a slice of datastore keys derived from a slice of model structs. Each entity's key is built from its model:"id", model:"parent", and model:"ns" struct tags.
func (*Client) Put ¶
Put saves a single entity to the datastore. For new entities with an auto-generated int64 ID, the ID is written back into the struct after a successful save. If val implements BeforeSave, it is called before writing. If val implements AfterSave, it is called after writing with the previous state of the entity.
func (*Client) PutMulti ¶
PutMulti saves multiple entities to the datastore. vals must be a slice of pointer-to-struct. Auto-generated IDs are written back into each struct. BeforeSave and AfterSave hooks are called for each entity that implements them. AfterSave hooks run concurrently.
func (*Client) Query ¶
func (c *Client) Query(ctx context.Context, q *QueryBuilder, cursor string, vals interface{}) ([]*datastore.Key, string, error)
Query executes a query using a keys-only strategy: it first fetches all matching keys, then hydrates the entities via Client.GetMulti. If vals is non-nil, it must be a pointer to a slice (e.g. *[]*MyModel) and will be populated with the loaded entities. The returned string is the cursor for pagination; pass it back as the cursor argument to resume.
func (*Client) Store ¶
Store returns the underlying ds.Store. To access backend-specific clients, type-assert to ds.CloudAccess or ds.LocalAccess:
if ca, ok := c.Store().(ds.CloudAccess); ok {
raw := ca.DatastoreClient()
}
if la, ok := c.Store().(ds.LocalAccess); ok {
sqlDB, err := la.DB("")
}
func (*Client) Transact ¶
func (c *Client) Transact(ctx context.Context, f func(tx *Transaction) error) (*datastore.Commit, error)
Transact runs f inside a datastore transaction. If f returns nil, the transaction is committed and any pending auto-generated IDs are resolved back into their corresponding structs via Base.LoadKey. If f returns an error, the transaction is rolled back.
type Model ¶
type Model interface {
// IsNew reports whether the entity has not yet been loaded from the datastore.
IsNew() bool
// Key returns the datastore key for this entity, or nil if not yet assigned.
Key() *datastore.Key
}
Model is the interface that all dsorm-managed structs must implement. Embed Base in your struct to get a default implementation.
type OnLoad ¶
OnLoad is an optional interface that a model can implement to run custom logic immediately after the entity is loaded from the datastore. It is called after all properties have been deserialized and decrypted.
type Option ¶
type Option func(*options)
Option configures a Client created via New.
func WithCache ¶
WithCache overrides the auto-detected caching backend with the provided implementation. By default, New selects App Engine Memcache, Redis (via REDIS_ADDR env), or in-memory cache, in that order.
func WithDatastoreClient ¶
WithDatastoreClient provides an existing cloud.google.com/go/datastore client instead of creating one internally. Useful for environments that require custom client configuration (e.g. emulator endpoints).
func WithEncryptionKey ¶
WithEncryptionKey sets the AES encryption key used for fields tagged with model:"<name>,encrypt". If not set, the DATASTORE_ENCRYPTION_KEY environment variable is used as a fallback at load/save time.
func WithNoCache ¶
func WithNoCache() Option
WithNoCache disables the caching layer entirely. All reads and writes go directly to the datastore with no intermediate cache. This is useful for distributed systems where no shared caching backend (Redis, Memcache) is available and the default in-memory cache would cause stale reads across instances.
The same effect can be achieved by setting the DSORM_NO_CACHE environment variable to "1" or "true".
func WithProjectID ¶
WithProjectID sets the Google Cloud project ID. If not specified, the DATASTORE_PROJECT_ID or GOOGLE_CLOUD_PROJECT environment variables are used as fallbacks.
type QueryBuilder ¶
type QueryBuilder struct {
// contains filtered or unexported fields
}
QueryBuilder represents a common query interface for dsorm.
func NewQuery ¶
func NewQuery(kind string) *QueryBuilder
NewQuery creates a new query for a specific kind.
func (*QueryBuilder) Ancestor ¶
func (q *QueryBuilder) Ancestor(ancestor *datastore.Key) *QueryBuilder
Ancestor sets the ancestor datastore key to queries.
func (*QueryBuilder) FilterField ¶
func (q *QueryBuilder) FilterField(fieldName, operator string, value interface{}) *QueryBuilder
FilterField adds a field-specific filter to the query.
func (*QueryBuilder) Filters ¶
func (q *QueryBuilder) Filters() []ds.Filter
func (*QueryBuilder) GetAncestor ¶
func (q *QueryBuilder) GetAncestor() *datastore.Key
func (*QueryBuilder) GetCursor ¶
func (q *QueryBuilder) GetCursor() string
func (*QueryBuilder) GetLimit ¶
func (q *QueryBuilder) GetLimit() int
func (*QueryBuilder) GetNamespace ¶
func (q *QueryBuilder) GetNamespace() string
func (*QueryBuilder) GetOffset ¶
func (q *QueryBuilder) GetOffset() int
func (*QueryBuilder) IsKeysOnly ¶
func (q *QueryBuilder) IsKeysOnly() bool
func (*QueryBuilder) KeysOnly ¶
func (q *QueryBuilder) KeysOnly() *QueryBuilder
KeysOnly makes the query return only keys.
func (*QueryBuilder) Limit ¶
func (q *QueryBuilder) Limit(limit int) *QueryBuilder
Limit sets the maximum number of items to return.
func (*QueryBuilder) Namespace ¶
func (q *QueryBuilder) Namespace(ns string) *QueryBuilder
Namespace sets the namespace for the query.
func (*QueryBuilder) Offset ¶
func (q *QueryBuilder) Offset(offset int) *QueryBuilder
Offset sets the number of items to skip.
func (*QueryBuilder) Order ¶
func (q *QueryBuilder) Order(fieldName string) *QueryBuilder
Order adds an order to the query.
func (*QueryBuilder) Orders ¶
func (q *QueryBuilder) Orders() []ds.Order
func (*QueryBuilder) Start ¶
func (q *QueryBuilder) Start(cursor string) *QueryBuilder
Start sets the cursor string where the query will begin.
type Transaction ¶
type Transaction struct {
// contains filtered or unexported fields
}
Transaction wraps a datastore transaction with dsorm functionality including automatic key mapping, lifecycle hooks, and pending key resolution for auto-ID entities.
func (*Transaction) Delete ¶
func (t *Transaction) Delete(val interface{}) error
Delete removes a single entity within the transaction.
func (*Transaction) DeleteMulti ¶
func (t *Transaction) DeleteMulti(vals interface{}) error
DeleteMulti removes multiple entities within the transaction.
func (*Transaction) Get ¶
func (t *Transaction) Get(val interface{}) error
Get loads a single entity within the transaction. Behaves like Client.Get but operates within the transaction's isolation.
func (*Transaction) GetMulti ¶
func (t *Transaction) GetMulti(vals interface{}) error
GetMulti loads multiple entities within the transaction. Behaves like Client.GetMulti: entities that do not exist are set to nil in the slice.
func (*Transaction) Put ¶
func (t *Transaction) Put(val interface{}) error
Put saves a single entity within the transaction. For new entities with auto-generated IDs, the ID is resolved after Client.Transact commits successfully.
func (*Transaction) PutMulti ¶
func (t *Transaction) PutMulti(vals interface{}) error
PutMulti saves multiple entities within the transaction. Auto-generated IDs are resolved after Client.Transact commits.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cache provides application-level caching utilities built on top of the dsorm cache backends (Redis, memory, memcache).
|
Package cache provides application-level caching utilities built on top of the dsorm cache backends (Redis, memory, memcache). |
|
memory
Package memory provides an in-memory cache implementation backed by an LRU eviction policy with per-item TTL support.
|
Package memory provides an in-memory cache implementation backed by an LRU eviction policy with per-item TTL support. |
|
internal
|
|