92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
package sync
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
|
|
mw "github.com/weltonmoura/initpage/internal/middleware"
|
|
)
|
|
|
|
type Sync struct {
|
|
DB *sql.DB
|
|
}
|
|
|
|
type syncPayload struct {
|
|
Data json.RawMessage `json:"data"`
|
|
Version int `json:"version"`
|
|
}
|
|
|
|
func (s *Sync) Get(w http.ResponseWriter, r *http.Request) {
|
|
uid := mw.GetUserID(r.Context())
|
|
if uid == "" {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
var data string
|
|
var version int
|
|
var updatedAt string
|
|
_ = s.DB.QueryRow(`SELECT data, version, updated_at FROM user_sync WHERE user_id=?`, uid).Scan(&data, &version, &updatedAt)
|
|
if data == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"data":null,"version":0}`))
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"data":` + data + `,"version":` + itoa(version) + `}`))
|
|
}
|
|
|
|
func (s *Sync) Put(w http.ResponseWriter, r *http.Request) {
|
|
uid := mw.GetUserID(r.Context())
|
|
if uid == "" {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
var p syncPayload
|
|
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
w.Write([]byte(`{"error":"json inválido"}`))
|
|
return
|
|
}
|
|
if len(p.Data) > 256*1024 {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
w.Write([]byte(`{"error":"dados muito grandes"}`))
|
|
return
|
|
}
|
|
// valida JSON básico
|
|
if !json.Valid(p.Data) {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
w.Write([]byte(`{"error":"json inválido"}`))
|
|
return
|
|
}
|
|
_, err := s.DB.Exec(`INSERT INTO user_sync(user_id,data,version,updated_at) VALUES(?,?,?,?)
|
|
ON CONFLICT(user_id) DO UPDATE SET data=excluded.data, version=excluded.version, updated_at=excluded.updated_at`,
|
|
uid, string(p.Data), p.Version, time.Now())
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"ok":true}`))
|
|
}
|
|
|
|
func itoa(i int) string {
|
|
if i == 0 {
|
|
return "0"
|
|
}
|
|
sign := ""
|
|
if i < 0 {
|
|
sign = "-"
|
|
i = -i
|
|
}
|
|
b := [12]byte{}
|
|
n := len(b)
|
|
for i > 0 {
|
|
n--
|
|
b[n] = byte('0' + i%10)
|
|
i /= 10
|
|
}
|
|
return sign + string(b[n:])
|
|
}
|