Skip to content
Open
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.git
.gitignore
gce-deploy-service-account.json
gce-deploy-service-account.json
google-datastore-service-account.json
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
gce-deploy-service-account.json
google-datastore-service-account.json
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ RUN echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/reposit
git

# Set up gin development tool
# Turn on Go 1.11 Modules and build
WORKDIR $GOPATH/src
RUN go get -v github.com/codegangsta/gin
ENV GIN_BIN=/../../../tmp/gin-bin
ENV GIN_PORT=8080
ENV BIN_APP_PORT=8081
ENV APP_PORT=8081
WORKDIR $GOPATH/src/app
ENV GO111MODULE=on
ENV CGO_ENABLED=0
RUN go get -v github.com/codegangsta/gin

# Copy code to image
WORKDIR $GOPATH/src/app
COPY . .

# Turn on Go 1.11 Modules and build
ENV GO111MODULE=on
ENV CGO_ENABLED=0
RUN go build -o /bin/app

CMD gin run main.go
Expand Down
4 changes: 2 additions & 2 deletions app/drawing/controllers/fetch_one.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func FetchOne(c echo.Context) error {
id, _ := strconv.Atoi(c.Param("id"))
id, _ := strconv.ParseInt(c.Param("id"), 10, 64)

return c.JSON(http.StatusOK, store.New().Get(id))
return c.JSON(http.StatusOK, store.New(c.Request().Context()).Get(id))
}
2 changes: 1 addition & 1 deletion app/drawing/controllers/fetch_recent.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ import (
)

func FetchRecent(c echo.Context) error {
return c.JSON(http.StatusOK, store.New().GetRecent())
return c.JSON(http.StatusOK, store.New(c.Request().Context()).GetRecent())
}
4 changes: 2 additions & 2 deletions app/drawing/controllers/submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import (
func Submit(c echo.Context) error {
points, _ := c.Get("points").([]types.OriginalPoint)

id := store.New().Create(points)
id := store.New(c.Request().Context()).Create(points)

processing.AddToQueue(id)

return c.JSON(http.StatusOK, Response{id})
}

type Response struct {
Id int `json:"id"`
Id int64 `json:"id"`
}
4 changes: 2 additions & 2 deletions app/drawing/middleware/id_exists.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import (

func IdExists(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
id, err := strconv.Atoi(c.Param("id"))
id, err := strconv.ParseInt(c.Param("id"), 10, 64)

if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "The request is not properly formatted.")
}

if store.New().Exists(id) != true {
if store.New(c.Request().Context()).Exists(id) != true {
return echo.NewHTTPError(http.StatusNotFound, "This drawing doesn't exist.")
}

Expand Down
9 changes: 6 additions & 3 deletions app/drawing/processing/original_points_factory.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package processing

import (
"context"

"api/app/drawing/store"
"api/app/drawing/types"
)

type OriginalPointsFactory struct{}

func (factory OriginalPointsFactory) Build(drawingId int) []types.OriginalPoint {
func (factory OriginalPointsFactory) Build(drawingId int64) []types.OriginalPoint {
drawing := factory.getDrawing(drawingId)
factory.normalizeTime(drawing.OriginalPoints)

return drawing.OriginalPoints
}

func (factory OriginalPointsFactory) getDrawing(drawingId int) types.Drawing {
store := store.New()
func (factory OriginalPointsFactory) getDrawing(drawingId int64) types.Drawing {
ctx := context.Background()
store := store.New(ctx)
drawing := store.Get(drawingId)

if drawing.Id == 0 {
Expand Down
9 changes: 6 additions & 3 deletions app/drawing/processing/processor.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package processing

import (
"context"

"api/app/drawing/processing/draw_vector"
"api/app/drawing/store"
"api/app/drawing/types"
)

func Process(drawingId int) {
func Process(drawingId int64) {
var originalPointsFactory OriginalPointsFactory = OriginalPointsFactory{}

originalPoints := originalPointsFactory.Build(drawingId)
Expand All @@ -15,7 +17,8 @@ func Process(drawingId int) {
saveDrawVectors(drawingId, vectors)
}

func saveDrawVectors(drawingId int, vectors []types.DrawVector) {
store := store.New()
func saveDrawVectors(drawingId int64, vectors []types.DrawVector) {
ctx := context.Background()
store := store.New(ctx)
store.AddVectors(drawingId, vectors)
}
8 changes: 4 additions & 4 deletions app/drawing/processing/queuer.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package processing

var creationQueue, workQueue chan int
var creationQueue, workQueue chan int64

func PrepareQueues() {
processorCount := 5
creationQueue = make(chan int)
workQueue = make(chan int, processorCount)
creationQueue = make(chan int64)
workQueue = make(chan int64, processorCount)

go processCreationQueue()

Expand All @@ -14,7 +14,7 @@ func PrepareQueues() {
}
}

func AddToQueue(id int) {
func AddToQueue(id int64) {
creationQueue <- id
}

Expand Down
14 changes: 14 additions & 0 deletions app/drawing/store/google_datastore/drawing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package google_datastore

import (
"time"
)

type DatastoreDrawing struct {
Id int64 `datastore:"id,omitempty"`
Featured bool `datastore:"featured"`
OriginalPoints string `datastore:"original_points,noindex"`
DrawVectors string `datastore:"draw_vectors,noindex"`
CreatedAt time.Time `datastore:"created_at"`
LastDrawVectorCalculatedAt time.Time `datastore:"last_draw_vector_calculated_at,noindex"`
}
61 changes: 61 additions & 0 deletions app/drawing/store/google_datastore/formatter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package google_datastore

import (
"encoding/json"
"fmt"
"strings"

"api/app/drawing/types"
"api/app/formatting"
)

func formatDatastoreDrawing(datastoreDrawing DatastoreDrawing) types.Drawing {
drawing := types.Drawing{
Id: datastoreDrawing.Id,
Featured: datastoreDrawing.Featured,
CreatedAt: formatting.JSONTime(datastoreDrawing.CreatedAt),
LastDrawVectorCalculatedAt: formatting.JSONTime(datastoreDrawing.LastDrawVectorCalculatedAt),
}

json.Unmarshal([]byte(datastoreDrawing.OriginalPoints), &drawing.OriginalPoints)
json.Unmarshal([]byte(datastoreDrawing.DrawVectors), &drawing.DrawVectors)

return drawing
}

func formatDatastoreDrawingPreviews(datastoreDrawings []*DatastoreDrawing) []types.DrawingPreview {
drawings := []types.DrawingPreview{}

for _, datastoreDrawing := range datastoreDrawings {
drawings = append(drawings, formatDatastoreDrawingPreview(datastoreDrawing))
}

return drawings
}

func formatDatastoreDrawingPreview(datastoreDrawing *DatastoreDrawing) types.DrawingPreview {
drawingPreview := types.DrawingPreview{
Id: datastoreDrawing.Id,
SvgPath: buildSvgPath(datastoreDrawing),
}

return drawingPreview
}

func buildSvgPath(datastoreDrawing *DatastoreDrawing) string {
var path strings.Builder
var originalPoints []types.OriginalPoint

path.Grow(len(originalPoints) * 10)
json.Unmarshal([]byte(datastoreDrawing.OriginalPoints), &originalPoints)

for i, point := range originalPoints {
if i == 0 {
fmt.Fprintf(&path, "M %d %d ", point.X, point.Y)
} else {
fmt.Fprintf(&path, "L %d %d ", point.X, point.Y)
}
}

return path.String()
}
94 changes: 94 additions & 0 deletions app/drawing/store/google_datastore/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package google_datastore

import (
"time"
"context"
"encoding/json"
"cloud.google.com/go/datastore"

"api/app/drawing/types"
)

type GoogleDatastoreStore struct {
Ctx context.Context
Client *datastore.Client
}

func (store *GoogleDatastoreStore) Exists(id int64) bool {
var drawing DatastoreDrawing
key := datastore.IDKey("Drawing", id, nil)

if err := store.Client.Get(store.Ctx, key, &drawing); err != nil {
return false
}

return true
}

func (store *GoogleDatastoreStore) Get(id int64) types.Drawing {
var drawing DatastoreDrawing
key := datastore.IDKey("Drawing", id, nil)

if err := store.Client.Get(store.Ctx, key, &drawing); err != nil {
panic(err)
}

drawing.Id = id

return formatDatastoreDrawing(drawing)
}

func (store *GoogleDatastoreStore) GetRecent() []types.DrawingPreview {
var datastoreDrawings []*DatastoreDrawing

query := datastore.NewQuery("Drawing").Order("-created_at").Limit(20)
keys, err := store.Client.GetAll(store.Ctx, query, &datastoreDrawings)
if err != nil {
panic(err)
}

// Set the id field on each Task from the corresponding key.
for i, key := range keys {
datastoreDrawings[i].Id = key.ID
}

return formatDatastoreDrawingPreviews(datastoreDrawings)
}

func (store *GoogleDatastoreStore) Create(points []types.OriginalPoint) int64 {
json, _ := json.Marshal(points)
drawing := &DatastoreDrawing{
OriginalPoints: string(json[:]),
DrawVectors: "[]",
CreatedAt: time.Now(),
}

key := datastore.IncompleteKey("Drawing", nil)
resultKey, err := store.Client.Put(store.Ctx, key, drawing)

if err != nil {
panic(err)
}

return resultKey.ID
}

func (store *GoogleDatastoreStore) AddVectors(drawingId int64, vectors []types.DrawVector) {
key := datastore.IDKey("Drawing", drawingId, nil)

_, err := store.Client.RunInTransaction(store.Ctx, func(tx *datastore.Transaction) error {
var drawing DatastoreDrawing
if err := tx.Get(key, &drawing); err != nil {
return err
}
json, _ := json.Marshal(vectors)
drawing.DrawVectors = string(json)
_, err := tx.Put(key, &drawing)
return err
})


if err != nil {
panic(err)
}
}
2 changes: 1 addition & 1 deletion app/drawing/store/mysql/sql_drawing.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

type SqlDrawing struct {
Id int `db:"id"`
Id int64 `db:"id"`
Featured bool `db:"featured"`
OriginalPoints string `db:"originalPoints"`
DrawVectors string `db:"drawVectors"`
Expand Down
10 changes: 5 additions & 5 deletions app/drawing/store/mysql/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type MySqlStore struct {
DB *sqlx.DB
}

func (store *MySqlStore) Exists(id int) bool {
func (store *MySqlStore) Exists(id int64) bool {
var count int
err := store.DB.Get(&count, "SELECT COUNT(id) FROM drawings WHERE id = ?", id)

Expand All @@ -22,7 +22,7 @@ func (store *MySqlStore) Exists(id int) bool {
return count > 0
}

func (store *MySqlStore) Get(id int) types.Drawing {
func (store *MySqlStore) Get(id int64) types.Drawing {
var sqlDrawing SqlDrawing

err := store.DB.Get(&sqlDrawing, "SELECT * FROM drawings WHERE id = ?", id)
Expand All @@ -46,16 +46,16 @@ func (store *MySqlStore) GetRecent() []types.DrawingPreview {
return formatSqlDrawingPreviews(sqlDrawings)
}

func (store *MySqlStore) Create(points []types.OriginalPoint) int {
func (store *MySqlStore) Create(points []types.OriginalPoint) int64 {
json, _ := json.Marshal(points)

result := store.DB.MustExec(`INSERT INTO drawings (originalPoints, drawVectors) VALUES (?, '[]')`, string(json[:]))
id, _ := result.LastInsertId()

return int(id)
return int64(id)
}

func (store *MySqlStore) AddVectors(drawingId int, vectors []types.DrawVector) {
func (store *MySqlStore) AddVectors(drawingId int64, vectors []types.DrawVector) {
json, _ := json.Marshal(vectors)

store.DB.MustExec("UPDATE drawings SET drawVectors = ? WHERE id = ?", string(json), drawingId)
Expand Down
Loading