Skip to content

Add inc/dec #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
29 changes: 28 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
# # Change Log

## 0.8.0
## 0.7.1

* Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service
* Add `upsertDocument` support to `Databases` service
* Update doc examples to use correct syntax

## 0.7.0

* Add `<REGION>` to doc examples due to the new multi region endpoints
* Add doc examples and methods for bulk api transactions: `createDocuments`, `deleteDocuments` etc.
* Add doc examples, class and methods for new `Sites` service
* Add doc examples, class and methods for new `Tokens` service
* Add enums for `BuildRuntime `, `Adapter`, `Framework`, `DeploymentDownloadType` and `VCSDeploymentType`
* Update enum for `runtimes` with Pythonml312, Dart219, Flutter327 and Flutter329
* Add `token` param to `getFilePreview` and `getFileView` for File tokens usage
* Add `queries` and `search` params to `listMemberships` method
* Remove `search` param from `listExecutions` method

## 0.6.0

* Add bulk API methods: `createDocuments`, `deleteDocuments` etc.

## 0.5.0

* Fix requests failing by removing `Content-Type` header from `GET` and `HEAD` requests


## 0.7.1

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Appwrite Go SDK

![License](https://img.shields.io/github/license/appwrite/sdk-for-go.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.7.0-blue.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.7.4-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
Expand Down
4 changes: 2 additions & 2 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ type Client struct {
func New(optionalSetters ...ClientOption) Client {
headers := map[string]string{
"X-Appwrite-Response-Format" : "1.7.0",
"user-agent" : fmt.Sprintf("AppwriteGoSDK/0.8.0 (%s; %s)", runtime.GOOS, runtime.GOARCH),
"user-agent" : fmt.Sprintf("AppwriteGoSDK/0.7.1 (%s; %s)", runtime.GOOS, runtime.GOARCH),
"x-sdk-name": "Go",
"x-sdk-platform": "server",
"x-sdk-language": "go",
"x-sdk-version": "0.8.0",
"x-sdk-version": "0.7.1",
}
httpClient, err := GetDefaultClient(defaultTimeout)
if err != nil {
Expand Down
278 changes: 244 additions & 34 deletions databases/databases.go
Original file line number Diff line number Diff line change
Expand Up @@ -2364,8 +2364,12 @@ func (srv *Databases) CreateDocument(DatabaseId string, CollectionId string, Doc

}

// CreateDocuments create new Documents. Before using this route, you should
// create a new collection resource using either a [server
// CreateDocuments **WARNING: Experimental Feature** - This endpoint is
// experimental and not yet officially supported. It may be subject to
// breaking changes or removal in future versions.
//
// Create new Documents. Before using this route, you should create a new
// collection resource using either a [server
// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection)
// API or directly from your database console.
func (srv *Databases) CreateDocuments(DatabaseId string, CollectionId string, Documents []interface{})(*models.DocumentList, error) {
Expand Down Expand Up @@ -2403,41 +2407,22 @@ func (srv *Databases) CreateDocuments(DatabaseId string, CollectionId string, Do
return &parsed, nil

}
type UpsertDocumentsOptions struct {
Documents []interface{}
enabledSetters map[string]bool
}
func (options UpsertDocumentsOptions) New() *UpsertDocumentsOptions {
options.enabledSetters = map[string]bool{
"Documents": false,
}
return &options
}
type UpsertDocumentsOption func(*UpsertDocumentsOptions)
func (srv *Databases) WithUpsertDocumentsDocuments(v []interface{}) UpsertDocumentsOption {
return func(o *UpsertDocumentsOptions) {
o.Documents = v
o.enabledSetters["Documents"] = true
}
}

// UpsertDocuments create or update Documents. Before using this route, you
// should create a new collection resource using either a [server
// UpsertDocuments **WARNING: Experimental Feature** - This endpoint is
// experimental and not yet officially supported. It may be subject to
// breaking changes or removal in future versions.
//
// Create or update Documents. Before using this route, you should create a
// new collection resource using either a [server
// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection)
// API or directly from your database console.
func (srv *Databases) UpsertDocuments(DatabaseId string, CollectionId string, optionalSetters ...UpsertDocumentsOption)(*models.DocumentList, error) {
func (srv *Databases) UpsertDocuments(DatabaseId string, CollectionId string, Documents []interface{})(*models.DocumentList, error) {
r := strings.NewReplacer("{databaseId}", DatabaseId, "{collectionId}", CollectionId)
path := r.Replace("/databases/{databaseId}/collections/{collectionId}/documents")
options := UpsertDocumentsOptions{}.New()
for _, opt := range optionalSetters {
opt(options)
}
params := map[string]interface{}{}
params["databaseId"] = DatabaseId
params["collectionId"] = CollectionId
if options.enabledSetters["Documents"] {
params["documents"] = options.Documents
}
params["documents"] = Documents
headers := map[string]interface{}{
"content-type": "application/json",
}
Expand Down Expand Up @@ -2492,9 +2477,13 @@ func (srv *Databases) WithUpdateDocumentsQueries(v []string) UpdateDocumentsOpti
}
}

// UpdateDocuments update all documents that match your queries, if no queries
// are submitted then all documents are updated. You can pass only specific
// fields to be updated.
// UpdateDocuments **WARNING: Experimental Feature** - This endpoint is
// experimental and not yet officially supported. It may be subject to
// breaking changes or removal in future versions.
//
// Update all documents that match your queries, if no queries are submitted
// then all documents are updated. You can pass only specific fields to be
// updated.
func (srv *Databases) UpdateDocuments(DatabaseId string, CollectionId string, optionalSetters ...UpdateDocumentsOption)(*models.DocumentList, error) {
r := strings.NewReplacer("{databaseId}", DatabaseId, "{collectionId}", CollectionId)
path := r.Replace("/databases/{databaseId}/collections/{collectionId}/documents")
Expand Down Expand Up @@ -2557,8 +2546,12 @@ func (srv *Databases) WithDeleteDocumentsQueries(v []string) DeleteDocumentsOpti
}
}

// DeleteDocuments bulk delete documents using queries, if no queries are
// passed then all documents are deleted.
// DeleteDocuments **WARNING: Experimental Feature** - This endpoint is
// experimental and not yet officially supported. It may be subject to
// breaking changes or removal in future versions.
//
// Bulk delete documents using queries, if no queries are passed then all
// documents are deleted.
func (srv *Databases) DeleteDocuments(DatabaseId string, CollectionId string, optionalSetters ...DeleteDocumentsOption)(*models.DocumentList, error) {
r := strings.NewReplacer("{databaseId}", DatabaseId, "{collectionId}", CollectionId)
path := r.Replace("/databases/{databaseId}/collections/{collectionId}/documents")
Expand Down Expand Up @@ -2660,6 +2653,75 @@ func (srv *Databases) GetDocument(DatabaseId string, CollectionId string, Docume
}
return &parsed, nil

}
type UpsertDocumentOptions struct {
Permissions []string
enabledSetters map[string]bool
}
func (options UpsertDocumentOptions) New() *UpsertDocumentOptions {
options.enabledSetters = map[string]bool{
"Permissions": false,
}
return &options
}
type UpsertDocumentOption func(*UpsertDocumentOptions)
func (srv *Databases) WithUpsertDocumentPermissions(v []string) UpsertDocumentOption {
return func(o *UpsertDocumentOptions) {
o.Permissions = v
o.enabledSetters["Permissions"] = true
}
}

// UpsertDocument **WARNING: Experimental Feature** - This endpoint is
// experimental and not yet officially supported. It may be subject to
// breaking changes or removal in future versions.
//
// Create or update a Document. Before using this route, you should create a
// new collection resource using either a [server
// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection)
// API or directly from your database console.
func (srv *Databases) UpsertDocument(DatabaseId string, CollectionId string, DocumentId string, Data interface{}, optionalSetters ...UpsertDocumentOption)(*models.Document, error) {
r := strings.NewReplacer("{databaseId}", DatabaseId, "{collectionId}", CollectionId, "{documentId}", DocumentId)
path := r.Replace("/databases/{databaseId}/collections/{collectionId}/documents/{documentId}")
options := UpsertDocumentOptions{}.New()
for _, opt := range optionalSetters {
opt(options)
}
params := map[string]interface{}{}
params["databaseId"] = DatabaseId
params["collectionId"] = CollectionId
params["documentId"] = DocumentId
params["data"] = Data
if options.enabledSetters["Permissions"] {
params["permissions"] = options.Permissions
}
headers := map[string]interface{}{
"content-type": "application/json",
}

resp, err := srv.client.Call("PUT", path, headers, params)
if err != nil {
return nil, err
}
if strings.HasPrefix(resp.Type, "application/json") {
bytes := []byte(resp.Result.(string))

parsed := models.Document{}.New(bytes)

err = json.Unmarshal(bytes, parsed)
if err != nil {
return nil, err
}

return parsed, nil
}
var parsed models.Document
parsed, ok := resp.Result.(models.Document)
if !ok {
return nil, errors.New("unexpected response type")
}
return &parsed, nil

}
type UpdateDocumentOptions struct {
Data interface{}
Expand Down Expand Up @@ -2769,6 +2831,154 @@ func (srv *Databases) DeleteDocument(DatabaseId string, CollectionId string, Doc
}
return &parsed, nil

}
type DecrementDocumentAttributeOptions struct {
Value float64
Min float64
enabledSetters map[string]bool
}
func (options DecrementDocumentAttributeOptions) New() *DecrementDocumentAttributeOptions {
options.enabledSetters = map[string]bool{
"Value": false,
"Min": false,
}
return &options
}
type DecrementDocumentAttributeOption func(*DecrementDocumentAttributeOptions)
func (srv *Databases) WithDecrementDocumentAttributeValue(v float64) DecrementDocumentAttributeOption {
return func(o *DecrementDocumentAttributeOptions) {
o.Value = v
o.enabledSetters["Value"] = true
}
}
func (srv *Databases) WithDecrementDocumentAttributeMin(v float64) DecrementDocumentAttributeOption {
return func(o *DecrementDocumentAttributeOptions) {
o.Min = v
o.enabledSetters["Min"] = true
}
}

// DecrementDocumentAttribute decrement a specific attribute of a document by
// a given value.
func (srv *Databases) DecrementDocumentAttribute(DatabaseId string, CollectionId string, DocumentId string, Attribute string, optionalSetters ...DecrementDocumentAttributeOption)(*models.Document, error) {
r := strings.NewReplacer("{databaseId}", DatabaseId, "{collectionId}", CollectionId, "{documentId}", DocumentId, "{attribute}", Attribute)
path := r.Replace("/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/decrement")
options := DecrementDocumentAttributeOptions{}.New()
for _, opt := range optionalSetters {
opt(options)
}
params := map[string]interface{}{}
params["databaseId"] = DatabaseId
params["collectionId"] = CollectionId
params["documentId"] = DocumentId
params["attribute"] = Attribute
if options.enabledSetters["Value"] {
params["value"] = options.Value
}
if options.enabledSetters["Min"] {
params["min"] = options.Min
}
headers := map[string]interface{}{
"content-type": "application/json",
}

resp, err := srv.client.Call("PATCH", path, headers, params)
if err != nil {
return nil, err
}
if strings.HasPrefix(resp.Type, "application/json") {
bytes := []byte(resp.Result.(string))

parsed := models.Document{}.New(bytes)

err = json.Unmarshal(bytes, parsed)
if err != nil {
return nil, err
}

return parsed, nil
}
var parsed models.Document
parsed, ok := resp.Result.(models.Document)
if !ok {
return nil, errors.New("unexpected response type")
}
return &parsed, nil

}
type IncrementDocumentAttributeOptions struct {
Value float64
Max float64
enabledSetters map[string]bool
}
func (options IncrementDocumentAttributeOptions) New() *IncrementDocumentAttributeOptions {
options.enabledSetters = map[string]bool{
"Value": false,
"Max": false,
}
return &options
}
type IncrementDocumentAttributeOption func(*IncrementDocumentAttributeOptions)
func (srv *Databases) WithIncrementDocumentAttributeValue(v float64) IncrementDocumentAttributeOption {
return func(o *IncrementDocumentAttributeOptions) {
o.Value = v
o.enabledSetters["Value"] = true
}
}
func (srv *Databases) WithIncrementDocumentAttributeMax(v float64) IncrementDocumentAttributeOption {
return func(o *IncrementDocumentAttributeOptions) {
o.Max = v
o.enabledSetters["Max"] = true
}
}

// IncrementDocumentAttribute increment a specific attribute of a document by
// a given value.
func (srv *Databases) IncrementDocumentAttribute(DatabaseId string, CollectionId string, DocumentId string, Attribute string, optionalSetters ...IncrementDocumentAttributeOption)(*models.Document, error) {
r := strings.NewReplacer("{databaseId}", DatabaseId, "{collectionId}", CollectionId, "{documentId}", DocumentId, "{attribute}", Attribute)
path := r.Replace("/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/increment")
options := IncrementDocumentAttributeOptions{}.New()
for _, opt := range optionalSetters {
opt(options)
}
params := map[string]interface{}{}
params["databaseId"] = DatabaseId
params["collectionId"] = CollectionId
params["documentId"] = DocumentId
params["attribute"] = Attribute
if options.enabledSetters["Value"] {
params["value"] = options.Value
}
if options.enabledSetters["Max"] {
params["max"] = options.Max
}
headers := map[string]interface{}{
"content-type": "application/json",
}

resp, err := srv.client.Call("PATCH", path, headers, params)
if err != nil {
return nil, err
}
if strings.HasPrefix(resp.Type, "application/json") {
bytes := []byte(resp.Result.(string))

parsed := models.Document{}.New(bytes)

err = json.Unmarshal(bytes, parsed)
if err != nil {
return nil, err
}

return parsed, nil
}
var parsed models.Document
parsed, ok := resp.Result.(models.Document)
if !ok {
return nil, errors.New("unexpected response type")
}
return &parsed, nil

}
type ListIndexesOptions struct {
Queries []string
Expand Down
Loading