Skip to content

Instantly share code, notes, and snippets.

@ctalladen78
Last active June 18, 2025 19:05
Show Gist options
  • Save ctalladen78/43b946f27d7dd867aacb7d386da7c191 to your computer and use it in GitHub Desktop.
Save ctalladen78/43b946f27d7dd867aacb7d386da7c191 to your computer and use it in GitHub Desktop.
Basic CRUD operations with single table dynamodb design
package main
import (
// "errors"
"fmt"
"log"
"time"
// "sync"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
)
// TODO
type DbController struct {
conn *dynamodb.DynamoDB
}
// https://docs.aws.amazon.com/sdk-for-go/api/aws/endpoints/
// https://docs.aws.amazon.com/sdk-for-go/api/aws/session/
// TODO start remote aws dynamodb session
// TODO start remote aws api gateway session
// uses localhost only
func InitDbConnection(h string) *DbController {
return &DbController{
conn: dynamodb.New(session.New(&aws.Config{
Region: aws.String("us-east-1"),
Endpoint: aws.String(h),
})),
}
}
func (ctrl *DbController) GetUser(userId string) (interface{}, error) {
fmt.Println("GET USER", userId)
var pkey = map[string]*dynamodb.AttributeValue{
"object_id": {
S: aws.String("USER"),
},
"object_sk": {
S: aws.String(userId),
},
}
// TodoObject and table key attributes do not match because of extra "cratedat" field
// pkey, err := dynamodbattribute.MarshalMap(t)
input := &dynamodb.GetItemInput{
TableName: aws.String("tasl_app_main"),
Key: pkey,
}
res, err := ctrl.conn.GetItem(input)
// user := &User{}
if err != nil {
return nil, err
}
var out interface{}
err = dynamodbattribute.UnmarshalMap(res.Item, &out)
if err != nil {
return nil, err
}
log.Println("GET ITEM output", res)
return out, nil
}
func (ctrl *DbController) SaveUserToDBGoroutine(uid string, email string, name string, avatar string, fchan chan *User) {
u := &User{}
u.ObjectId = string([]byte("USER"))
u.ObjectSk = string([]byte("USER-" + uid))
u.AvatarLink = avatar
u.Email = email
u.Name = name
u.Bio = "Hi!"
u.CreatedAt = time.Now().Format(time.RFC3339)
user, err := ctrl.SaveItemST(u)
if err != nil {
log.Println("ERROR ", err)
}
fmt.Printf("SAVE USER SUCCESS %s", user)
fchan <- u
}
func getTripItemInListGoRoutine(pkid string, skid string, imap map[string]*Trip, retval chan map[string]*Trip) {
trip, err := ctrl.GetTripItemST(pkid, skid)
if err != nil {
retval <- nil
}
id := fmt.Sprintf("%s+%s", pkid, skid)
imap[id] = trip.(*Trip)
retval <- imap
}
func getItemInListGoRoutine(pkid string, skid string, imap map[string]interface{}, retval chan map[string]interface{}) {
res, err := ctrl.GetItemDetailST(pkid, skid)
if err != nil {
imap[pkid] = nil
}
id := fmt.Sprintf("%s+%s", pkid, skid)
imap[id] = res
retval <- imap
}
func (ctrl *DbController) SaveItemST(item interface{}) (interface{}, error) {
newItemAV, err := dynamodbattribute.MarshalMap(item) // conver interface object to av item map
// log.Printf("PUT INPUT AV %v", newItemAV)
if err != nil {
return nil, err
}
input := &dynamodb.PutItemInput{
Item: newItemAV,
// ConditionExpression: aws.String("attribute_exists(object_id)"),
TableName: aws.String("tasl_app_main"),
// ConditionExpression: aws.String("if not exists")
}
log.Printf("ADD ITEM %v", input)
o, err := ctrl.conn.PutItem(input)
if err != nil {
return nil, err
}
return o.Attributes, err
}
func (ctrl *DbController) GetTripItemST(pkid string, skid string) (interface{}, error) {
// pkid := fmt.Sprintf("%s-%s", item_pref, objId)
// skid := fmt.Sprintf("DETAIL-%s", objId)
var pkey = map[string]*dynamodb.AttributeValue{
"object_id": {
S: aws.String(pkid),
},
"object_sk": {
S: aws.String(skid),
},
}
// TodoObject and table key attributes do not match because of extra "cratedat" field
// pkey, err := dynamodbattribute.MarshalMap(t)
input := &dynamodb.GetItemInput{
TableName: aws.String("tasl_app_main"),
Key: pkey,
}
log.Println("GET ITEM input", input)
res, err := ctrl.conn.GetItem(input)
if err != nil {
return nil, err
}
var out *Trip
err = dynamodbattribute.UnmarshalMap(res.Item, &out)
if err != nil {
return nil, err
}
return out, nil
}
func (ctrl *DbController) GetItemDetailST(pkid string, skid string) (interface{}, error) {
// pkid := fmt.Sprintf("%s-%s", item_pref, objId)
// skid := fmt.Sprintf("DETAIL-%s", objId)
var pkey = map[string]*dynamodb.AttributeValue{
"object_id": {
S: aws.String(pkid),
},
"object_sk": {
S: aws.String(skid),
},
}
// TodoObject and table key attributes do not match because of extra "cratedat" field
// pkey, err := dynamodbattribute.MarshalMap(t)
input := &dynamodb.GetItemInput{
TableName: aws.String("tasl_app_main"),
Key: pkey,
}
log.Println("GET ITEM input", input)
res, err := ctrl.conn.GetItem(input)
if err != nil {
return nil, err
}
var out interface{}
err = dynamodbattribute.UnmarshalMap(res.Item, &out)
if err != nil {
return nil, err
}
return out, nil
}
func (ctrl *DbController) QueryCityST(cityId string) (interface{}, error) {
pkid := fmt.Sprintf("CITY")
c, err := ctrl.GetItemDetailST(pkid, cityId)
if err != nil {
return nil, err
}
return c, nil
}
func (ctrl *DbController) GetUserProfileDetailsST(userId string) (interface{}, error) {
pkid := fmt.Sprintf("USER")
u, err := ctrl.GetItemDetailST(pkid, userId)
if err != nil {
return nil, err
}
return u, nil
}
func queryPlaceCountGoRoutine(tripID string, cmap map[string]int, retval chan map[string]int) {
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":tid": {S: aws.String(tripID)},
":pfx": {S: aws.String("TRIP-LOCATION-")},
},
// IndexName: aws.String("user_idx"),
KeyConditionExpression: aws.String("object_id = :tid and begins_with(object_sk, :pfx)"),
ProjectionExpression: aws.String("place_id"),
Limit: aws.Int64(50),
}
fmt.Println("QUERY PLACE LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var plist []interface{}
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &plist)
if err != nil {
cmap[tripID] = 0
retval <- cmap
}
cmap[tripID] = len(plist)
retval <- cmap
}
func (ctrl *DbController) QueryAllCitiesST() ([]interface{}, error) {
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":ct": {S: aws.String("CITY")},
":skpref": {S: aws.String("CITY")},
},
KeyConditionExpression: aws.String("object_id = :ct and begins_with(object_sk, :skpref) "),
}
fmt.Println("QUERY CITY LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var clist []interface{}
// fmt.Println(res)
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &clist)
if err != nil {
return nil, err
}
// TODO sort by city ranking
nlist, err := sortCityList(&clist)
if err != nil {
return nil, err
}
return nlist, nil
}
func (ctrl *DbController) getPlaceCount(tripId string) (int, error) {
// TODO query place count only
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":tid": {S: aws.String(tripId)},
":skpref": {S: aws.String("PLACE-LOCATION")},
},
KeyConditionExpression: aws.String("object_id = :tid and begins_with(object_sk, :skpref) "),
}
// fmt.Println("QUERY CITY LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var slist int
fmt.Println("GET PLACE COUNT ", res)
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &slist)
if err != nil {
return 0, err
}
// suggestions count only
qInput = &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":tid": {S: aws.String(tripId)},
":skpref": {S: aws.String("SUGGESTION-LOCATION")},
},
KeyConditionExpression: aws.String("object_id = :tid and begins_with(object_sk, :skpref) "),
}
// fmt.Println("QUERY CITY LIST INPUT", qInput)
res, err = ctrl.conn.Query(qInput)
var plist int
fmt.Println("GET PLACE COUNT ", res)
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &plist)
if err != nil {
return 0, err
}
return 0, err
}
func sortCityList(clist *[]interface{}) ([]interface{}, error) {
var newList []interface{}
// rank := []string{"New York City", "Los Angeles", "San Fransisco", "Tokyo", "Paris",
// "Seoul", "Kyoto", "London", "Berlin", "Rome", "Venezia", "Vienna", "Stockholm", "Barcelona", "Prague", "Sydney", "Bangkok", "Taipei", "Singapore",
// "Miami", "Mexico City", "Las Vegas"}
rank := []string{"New York City", "Los Angeles", "San Fransisco", "Tokyo", "Paris",
"Seoul", "Kyoto", "London", "Berlin", "Rome", "Venezia", "Vienna", "Stockholm", "Barcelona", "Sydney", "Bangkok", "Taipei", "Singapore",
"Miami", "Las Vegas"}
for i := range rank {
for _, cmap := range *clist {
// https://stackoverflow.com/questions/31815969/go-cannot-range-over-my-var-type-interface
if city, ok := cmap.(map[string]interface{}); ok {
// log.Printf(" PRINT CITY LIST CITY %s ", city["city_name"])
// for key, val := range city {
// log.Printf(" PRINT CITY LIST CITY %s : %s", key, val)
// }
if rank[i] == city["city_name"] {
newList = append(newList, city)
}
}
}
}
// log.Printf(" NEW CITY LIST %s ", newList)
return newList, nil
}
func (ctrl *DbController) GetBucketList(userid string) (interface{}, error) {
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":uid": {S: aws.String(userid)},
":pfx": {S: aws.String("BUCKET-ITEM-")},
},
KeyConditionExpression: aws.String("object_id = :uid and begins_with(object_sk, :pfx)"),
Limit: aws.Int64(50),
}
fmt.Println("QUERY BUCKET LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var blist []interface{}
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &blist)
if err != nil {
return nil, err
}
umap := make(map[string]interface{}) // place map
uChan := make(chan map[string]interface{})
for _, pid := range blist {
pkid := fmt.Sprintf("PLACE")
pids := pid.(map[string]interface{})
skid := pids["place_id"].(string)
go getItemInListGoRoutine(pkid, skid, umap, uChan)
<-uChan
}
close(uChan)
return umap, nil
}
// TODO query placeid from trip
// TODO save places to user bucket list
func (ctrl *DbController) SavePlacesToBucketList(t *Trip, uid string) error {
// fmt.Println("ADD BUCKET ITEM TO TRIP ID", t.ObjectId)
// fmt.Println("ADD BUCKET ITEM TO TRIP SK", t.ObjectSk)
// query user following by userId
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":tid": {S: aws.String(t.ObjectId)},
":pfx": {S: aws.String("TRIP-LOCATION-")},
},
// IndexName: aws.String("user_idx"),
ProjectionExpression: aws.String("place_id"),
KeyConditionExpression: aws.String("object_id = :tid and begins_with(object_sk, :pfx)"),
Limit: aws.Int64(50),
}
fmt.Println("QUERY PLACE LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var plist []interface{}
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &plist)
if err != nil {
return err
}
// TODO for loop go routine for each placeid
for _, pid := range plist {
// fmt.Println("PLACE ID", pid)
// https://gist.github.com/nevzatalkan/f5c5ef66e88dd446976401967b6731e8
pids := pid.(map[string]interface{})
// fmt.Println("PLACE ID", ppid["place_id"])
// lpkid := fmt.Sprintf("PLACE")
objSk := fmt.Sprintf("BUCKET-ITEM-%s", pids["place_id"])
if err != nil {
// return nil, err
}
b := &BucketItem{}
b.ObjectId = uid
b.ObjectSk = objSk
b.PlaceId = pids["place_id"].(string)
// b.Name = pids["name"].(string)
b.CreatedBy = uid
b.CreatedAt = time.Now().Format(time.RFC3339)
// b.CreatedAt = t.CreatedAt
go ctrl.SaveItemST(b)
}
return nil
}
func (ctrl *DbController) RemoveFollowingUserST(objId string) (interface{}, error) {
// pk := fmt.Sprintf("FOLLOWING-%s", objId)
// tsk := fmt.Sprintf("USER-%s", objId)
// TODO remove item by pk sk
return nil, nil
}
func (ctrl *DbController) RemoveFollowingTripST(objId string) (interface{}, error) {
// pk := fmt.Sprintf("FOLLOWING-%s", objId)
// tsk := fmt.Sprintf("TRIP-%s", objId)
// TODO remove item by pk sk
return nil, nil
}
func (ctrl *DbController) GetFollowingTripST(userId string) (interface{}, interface{}, error) {
// query triplist following by userId
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":uid": {S: aws.String(userId)},
":pfx": {S: aws.String("FOLLOWING-TRIP")},
},
// IndexName: aws.String("user_idx"),
KeyConditionExpression: aws.String("object_id = :uid and begins_with(object_sk, :pfx)"),
Limit: aws.Int64(50),
}
fmt.Println("QUERY USER LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var tlist []*Following
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &tlist)
if err != nil {
return nil, nil, err
}
if len(tlist) == 0 {
return nil, nil, err
}
tmap := map[string]*Trip{} // trip map
tChan := make(chan map[string]*Trip)
// query trip
for i := range tlist {
tid := fmt.Sprintf("%v", tlist[i].FollowingID)
// pkid := fmt.Sprintf("TRIP-%s", tid)
skid := fmt.Sprintf("TRIP-DETAIL")
go getTripItemInListGoRoutine(tid, skid, tmap, tChan)
// log.Println("GET USER OUTPUT", <-uChan)
<-tChan
}
cmap := make(map[string]interface{}) // city map
cChan := make(chan map[string]interface{})
// query city
for _, v := range tmap {
cid := fmt.Sprintf("%v", v.CityRef) // TODO type conversion error
// cid := fmt.Sprintf("%v", vv.CityRef) // TODO type conversion error
pkid := fmt.Sprintf("CITY")
skid := fmt.Sprintf("CITY-%s", cid)
go getItemInListGoRoutine(pkid, skid, cmap, cChan)
// go queryCityInListGoRoutine(cid, cmap, cChan)
// log.Println("GET USER OUTPUT", <-uChan)
<-cChan
}
close(tChan)
close(cChan)
return tmap, cmap, nil
}
func (ctrl *DbController) GetFollowingUserST(userId string) (interface{}, error) {
// query user following by userId
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":uid": {S: aws.String(userId)},
":pfx": {S: aws.String("FOLLOWING-USER")},
},
// IndexName: aws.String("user_idx"),
KeyConditionExpression: aws.String("object_id = :uid and begins_with(object_sk, :pfx)"),
Limit: aws.Int64(50),
}
fmt.Println("QUERY USER LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var ulist []*Following
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &ulist)
if err != nil {
return nil, err
}
// query user
umap := make(map[string]interface{}) // user map
uChan := make(chan map[string]interface{})
for i := range ulist {
tid := fmt.Sprintf("%v", ulist[i].FollowingID)
pkid := fmt.Sprintf("USER")
// skid := fmt.Sprintf("USER-%s", tid)
go getItemInListGoRoutine(pkid, tid, umap, uChan)
// go getUserInListGoRoutine(tid, tmap, tChan)
// log.Println("GET USER OUTPUT", <-uChan)
<-uChan
}
close(uChan)
return umap, nil
}
func (ctrl *DbController) QueryLocationListByTripRefST(tripId string) (interface{}, interface{}, error) {
// TODO query location by tripid limit 10
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":tid": {S: aws.String(tripId)},
":idpref": {S: aws.String("TRIP-LOCATION-")},
},
KeyConditionExpression: aws.String("object_id = :tid and begins_with(object_sk, :idpref)"),
Limit: aws.Int64(10),
}
fmt.Println("QUERY TRIP LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var plist []*Location
fmt.Println("TRIP LOCATION LIST ", plist)
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &plist)
if err != nil {
return nil, nil, err
}
if plist == nil {
// TODO query suggestion by tripid limit 10
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":idpref": {S: aws.String("SUGGESTION-")},
":tid": {S: aws.String(tripId)},
},
KeyConditionExpression: aws.String("object_id = :tid and begins_with(object_sk, :idpref)"),
Limit: aws.Int64(10),
}
res, err := ctrl.conn.Query(qInput)
var slist []*Location
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &slist)
if err != nil {
return nil, nil, err
}
// TODO get location in list
smap := make(map[string]interface{}) // location map
schan := make(chan map[string]interface{})
for _, l := range slist {
pid := l.PlaceId
fmt.Println("PLACE ID ", pid)
lpkid := fmt.Sprintf("PLACE")
// lskid := fmt.Sprintf("PLACE-%s", id)
go getItemInListGoRoutine(lpkid, pid, smap, schan)
<-schan
}
fmt.Println("TRIP SUGGESTION MAP ", smap)
close(schan)
return nil, smap, nil
}
// TODO get location in list
lmap := make(map[string]interface{}) // location map
lchan := make(chan map[string]interface{})
for _, l := range plist {
pid := l.PlaceId
lpkid := fmt.Sprintf("PLACE")
// lskid := fmt.Sprintf("PLACE-%s", id)
go getItemInListGoRoutine(lpkid, pid, lmap, lchan)
<-lchan
}
fmt.Println("TRIP LOCATION MAP ", lmap)
close(lchan)
return lmap, nil, nil
}
func (ctrl *DbController) GetTripDetailST(tripId string) (interface{}, interface{}, interface{}, interface{}, interface{}, interface{}, error) {
// tpk := fmt.Sprintf("%s", tripId)
tsk := fmt.Sprintf("TRIP-DETAIL")
trip, err := ctrl.GetTripItemST(tripId, tsk)
if err != nil {
// trip not exists
return nil, nil, nil, nil, nil, nil, err
}
fmt.Println("TRIP DETAIL ", trip)
// get user
utpk := fmt.Sprintf("USER")
utsk := fmt.Sprintf("%s", trip.(*Trip).CreatedBy)
user, err := ctrl.GetItemDetailST(utpk, utsk)
if err != nil {
return nil, nil, nil, nil, nil, nil, err
}
// get city
ctpk := fmt.Sprintf("CITY")
ctsk := fmt.Sprintf("CITY-%s", trip.(*Trip).CityRef)
city, err := ctrl.GetItemDetailST(ctpk, ctsk)
if err != nil {
return nil, nil, nil, nil, nil, nil, err
}
// get category
catpk := fmt.Sprintf("CATEGORY")
catsk := fmt.Sprintf("%s", trip.(*Trip).CategoryRef)
cat, err := ctrl.GetItemDetailST(catpk, catsk)
if err != nil {
return nil, nil, nil, nil, nil, nil, err
}
// get location map
locmap, sugmap, err := ctrl.QueryLocationListByTripRefST(tripId)
if err != nil {
return trip, user, city, cat, nil, nil, err
}
return trip, user, city, cat, locmap, sugmap, nil
}
func (ctrl *DbController) QueryCommentST(tripId string) (map[string]interface{}, []*Comment, error) {
// get comment
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":skpref": {S: aws.String("COMMENT")},
":tid": {S: aws.String(tripId)},
},
KeyConditionExpression: aws.String("object_id = :tid and begins_with(object_sk, :skpref)"),
Limit: aws.Int64(30),
}
fmt.Println("QUERY COMMENT LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var clist []*Comment
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &clist)
if err != nil {
return nil, nil, err
}
log.Println("QUERY COMMENT RESULT", clist)
// get associated user
umap := make(map[string]interface{})
uChan := make(chan map[string]interface{})
for j := range clist {
uid := clist[j].CreatedBy
// utpk := fmt.Sprintf("USER-%s", uid)
// utsk := fmt.Sprintf("DETAIL-%s", uid)
go getItemInListGoRoutine("USER", uid, umap, uChan)
<-uChan
}
close(uChan)
log.Println("QUERY COMMENT RESULT", umap)
return umap, clist, nil
}
// TODO get place count by trip
func (ctrl *DbController) QueryTopTripST(cityId string) (interface{}, interface{}, interface{}, error) {
cityPref := fmt.Sprintf("CITY-%s", cityId)
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":tpx": {S: aws.String("TRIP-")},
":cid": {S: aws.String(cityPref)},
},
KeyConditionExpression: aws.String("object_id = :cid and begins_with(object_sk, :tpx)"),
// projection tripid, description, createdby
Limit: aws.Int64(10),
}
fmt.Println("QUERY TRIP LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var tlist []*Trip
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &tlist)
if err != nil {
return nil, nil, nil, err
}
// TODO run get user goroutines
umap := make(map[string]interface{})
uChan := make(chan map[string]interface{})
tmap := map[string]*Trip{}
tChan := make(chan map[string]*Trip)
cmap := make(map[string]int)
cChan := make(chan map[string]int)
for i := range tlist {
uid := tlist[i].CreatedBy
tid := tlist[i].ObjectSk
// tpk := fmt.Sprintf("TRIP-", tid)
go getItemInListGoRoutine("USER", uid, umap, uChan)
go getTripItemInListGoRoutine(tid, "TRIP-DETAIL", tmap, tChan)
go queryPlaceCountGoRoutine(tid, cmap, cChan)
<-cChan
<-uChan
<-tChan
}
close(cChan)
close(uChan)
close(tChan)
log.Println("GET USER LIST OUTPUT", tlist)
log.Println("GET USER LIST OUTPUT", umap)
return tmap, umap, cmap, nil
}
func (ctrl *DbController) QueryTripListByCityST(cityId string) (interface{}, interface{}, interface{}, error) {
cityPref := fmt.Sprintf("CITY-%s", cityId)
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":tpx": {S: aws.String("TRIP-")},
":cid": {S: aws.String(cityPref)},
},
KeyConditionExpression: aws.String("object_id = :cid and begins_with(object_sk, :tpx)"),
// projection tripid, description, createdby
}
fmt.Println("QUERY TRIP LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var tlist []*Trip
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &tlist)
if err != nil {
return nil, nil, nil, err
}
// TODO get location count
// TODO run get user goroutines
umap := make(map[string]interface{})
uChan := make(chan map[string]interface{})
tmap := map[string]*Trip{}
tChan := make(chan map[string]*Trip)
cmap := make(map[string]int)
cChan := make(chan map[string]int)
for i := range tlist {
uid := tlist[i].CreatedBy
tid := tlist[i].ObjectSk
// tpk := fmt.Sprintf("TRIP-", tid)
go getItemInListGoRoutine("USER", uid, umap, uChan)
go getTripItemInListGoRoutine(tid, "TRIP-DETAIL", tmap, tChan)
go queryPlaceCountGoRoutine(tid, cmap, cChan)
<-cChan
<-uChan
<-tChan
}
close(cChan)
close(uChan)
close(tChan)
log.Println("GET USER LIST OUTPUT", tlist)
log.Println("GET USER LIST OUTPUT", umap)
log.Println("GET USER LIST OUTPUT", cmap)
return tmap, umap, cmap, nil
}
func (ctrl *DbController) QueryTripListByUserST(userId string) (interface{}, map[string]interface{}, error) {
qInput := &dynamodb.QueryInput{
TableName: aws.String("tasl_app_main"),
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":uid": {S: aws.String(userId)},
":idpref": {S: aws.String("TRIP-")},
},
KeyConditionExpression: aws.String("object_id = :uid and begins_with(object_sk, :idpref)"),
// projection tripid, description, createdby
// ProjectionExpression: aws.String("city_id"),
}
fmt.Println("QUERY TRIP LIST INPUT", qInput)
res, err := ctrl.conn.Query(qInput)
var tlist []*Trip
err = dynamodbattribute.UnmarshalListOfMaps(res.Items, &tlist)
if err != nil {
return nil, nil, err
}
// TODO run get city goroutines
cmap := make(map[string]interface{})
cChan := make(chan map[string]interface{})
tmap := map[string]*Trip{}
tChan := make(chan map[string]*Trip)
for i := range tlist {
pid := tlist[i].CityRef
pk := fmt.Sprintf("CITY")
sk := fmt.Sprintf("CITY-%s", pid)
tid := tlist[i].ObjectSk
go getItemInListGoRoutine(pk, sk, cmap, cChan)
go getTripItemInListGoRoutine(tid, "TRIP-DETAIL", tmap, tChan)
<-cChan
<-tChan
}
close(cChan)
close(tChan)
log.Println("GET USER LIST OUTPUT", cmap)
log.Println("GET USER LIST OUTPUT", tlist)
return tmap, cmap, nil
}
func (ctrl *DbController) IncrementTripLike(tid string) error {
oldItemKeys := map[string]*dynamodb.AttributeValue{
"object_id": {S: aws.String(tid)}, // hash key
"object_sk": {S: aws.String("TRIP-DETAIL")}, // hash key
}
updateInput := &dynamodb.UpdateItemInput{
TableName: aws.String("tasl_app_main"),
Key: oldItemKeys, // match key attributes per table definition
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":one": {N: aws.String(fmt.Sprintf("%d", 1))}, // set new value
},
ConditionExpression: aws.String("attribute_exists(object_id)"),
ReturnValues: aws.String("UPDATED_NEW"), // enum of ReturnValue class UPDATED_NEW ALL_NEW ALL_OLD
UpdateExpression: aws.String("ADD like_counter :one"), // SET,REMOVE the attribute to update
}
result, err := ctrl.conn.UpdateItem(updateInput)
if err != nil {
return err
}
log.Printf("UPDATE RESULT %s", result.Attributes)
var out interface{}
err = dynamodbattribute.UnmarshalMap(result.Attributes, &out)
if err != nil {
return err
}
return nil
}
func (ctrl *DbController) UpdateUserBioST(newUser *User) (interface{}, error) {
oldItemKeys := map[string]*dynamodb.AttributeValue{
"object_id": {S: aws.String("USER")}, // hash key
"object_sk": {S: aws.String(newUser.ObjectId)}, // hash key
}
updateInput := &dynamodb.UpdateItemInput{
TableName: aws.String("tasl_app_main"),
Key: oldItemKeys, // match key attributes per table definition
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":B": {S: aws.String(newUser.Bio)}, // set new value
},
ExpressionAttributeNames: map[string]*string{
"#bio": aws.String("bio"),
},
ConditionExpression: aws.String("attribute_exists(object_id)"),
ReturnValues: aws.String("UPDATED_NEW"), // enum of ReturnValue class UPDATED_NEW ALL_NEW ALL_OLD
UpdateExpression: aws.String("set #bio = :B"), // SET,REMOVE the attribute to update
}
log.Printf("UPDATE USER INPUT %v", updateInput)
result, err := ctrl.conn.UpdateItem(updateInput)
if err != nil {
return nil, err
}
log.Printf("UPDATE RESULT %s", result.Attributes)
var out interface{}
err = dynamodbattribute.UnmarshalMap(result.Attributes, &out)
if err != nil {
return nil, err
}
return out, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment