Skip to content

Commit d2389a8

Browse files
committed
[dev] initial backend with crud operations
1 parent b35bbdf commit d2389a8

15 files changed

+1247
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.idea
2+
.vscode
3+
cheduler-go
4+
db.sqlite
5+
application*
6+
__debug_bin

api/index.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package api
2+
3+
import (
4+
remote "github.com/mkozhukh/go-remote"
5+
6+
"web-widgets/scheduler-go/data"
7+
)
8+
9+
func BuildAPI(db *data.DAO) *remote.Server {
10+
if remote.MaxSocketMessageSize < 32000 {
11+
remote.MaxSocketMessageSize = 32000
12+
}
13+
14+
api := remote.NewServer(&remote.ServerConfig{
15+
WebSocket: true,
16+
})
17+
18+
return api
19+
}

common/int.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package common
2+
3+
import (
4+
"encoding/json"
5+
)
6+
7+
const QuotesByte = 34
8+
9+
type FuzzyInt int
10+
11+
func (f *FuzzyInt) UnmarshalJSON(data []byte) error {
12+
var err error
13+
var temp int
14+
if data[0] == QuotesByte {
15+
// empty string => 0
16+
if len(data) > 2 {
17+
err = json.Unmarshal(data[1:len(data)-1], &temp)
18+
}
19+
} else {
20+
err = json.Unmarshal(data, &temp)
21+
}
22+
*f = FuzzyInt(temp)
23+
return err
24+
}

config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package main
2+
3+
import "web-widgets/scheduler-go/data"
4+
5+
type ConfigServer struct {
6+
URL string
7+
Port string
8+
Cors []string
9+
}
10+
11+
type AppConfig struct {
12+
Server ConfigServer
13+
DB data.DBConfig
14+
}

config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
db:
2+
path: db.sqlite
3+
resetonstart: true
4+
server:
5+
url: "http://localhost:3000"
6+
port: ":3000"
7+
cors:
8+
- "*"

data/data.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package data
2+
3+
import (
4+
"time"
5+
)
6+
7+
type Event struct {
8+
ID int `json:"id"`
9+
Name string `json:"text"`
10+
StartDate *time.Time `json:"start_date"`
11+
EndDate *time.Time `json:"end_date"`
12+
Readonly bool `json:"readonly"`
13+
AllDay bool `json:"allDay"`
14+
Type string `json:"type"`
15+
Details string `json:"details"`
16+
}

data/db.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package data
2+
3+
import (
4+
"log"
5+
6+
"gorm.io/driver/sqlite"
7+
"gorm.io/gorm"
8+
"gorm.io/gorm/logger"
9+
)
10+
11+
var Debug = 1
12+
13+
func logError(e error) {
14+
if e != nil && Debug > 0 {
15+
log.Printf("[ERROR]\n%s\n", e)
16+
}
17+
}
18+
19+
type DBConfig struct {
20+
Path string
21+
ResetOnStart bool
22+
}
23+
24+
type DAO struct {
25+
db *gorm.DB
26+
27+
Events *EventsDAO
28+
}
29+
30+
func (d *DAO) GetDB() *gorm.DB {
31+
return d.db
32+
}
33+
34+
func (d *DAO) mustExec(sql string) {
35+
err := d.db.Exec(sql).Error
36+
if err != nil {
37+
panic(err)
38+
}
39+
}
40+
41+
func NewDAO(config DBConfig, url string) *DAO {
42+
db, err := gorm.Open(sqlite.Open(config.Path), &gorm.Config{
43+
Logger: logger.Default.LogMode(logger.Error),
44+
})
45+
if err != nil {
46+
panic("failed to connect database")
47+
}
48+
49+
db.AutoMigrate(&Event{})
50+
51+
dao := &DAO{
52+
db: db,
53+
Events: NewEventsDAO(db),
54+
}
55+
56+
if config.ResetOnStart {
57+
dataDown(dao)
58+
dataUp(dao)
59+
}
60+
61+
return dao
62+
}

data/demodata.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package data
2+
3+
import (
4+
"encoding/json"
5+
"io/ioutil"
6+
"time"
7+
"web-widgets/scheduler-go/common"
8+
)
9+
10+
type EventDemo struct {
11+
ID common.FuzzyInt `json:"id"`
12+
Name string `json:"text"`
13+
StartDate string `json:"start_date"`
14+
EndDate string `json:"end_date"`
15+
Readonly bool `json:"readonly"`
16+
AllDay bool `json:"allDay"`
17+
Type string `json:"type"`
18+
Details string `json:"details"`
19+
}
20+
21+
func (d *EventDemo) GetModel() *Event {
22+
sDate, _ := time.Parse("2006-01-02 15:04:05", d.StartDate)
23+
eDate, _ := time.Parse("2006-01-02 15:04:05", d.EndDate)
24+
25+
return &Event{
26+
ID: int(d.ID),
27+
Name: d.Name,
28+
StartDate: &sDate,
29+
EndDate: &eDate,
30+
Readonly: d.Readonly,
31+
AllDay: d.AllDay,
32+
Type: d.Type,
33+
Details: d.Details,
34+
}
35+
}
36+
37+
func getData() ([]EventDemo, error) {
38+
bytes, err := ioutil.ReadFile("./demodata/events.json")
39+
if err != nil {
40+
logError(err)
41+
return nil, err
42+
}
43+
data := make([]EventDemo, 0)
44+
err = json.Unmarshal(bytes, &data)
45+
46+
return data, err
47+
}
48+
49+
func dataDown(d *DAO) {
50+
d.mustExec("DELETE from events")
51+
}
52+
53+
func dataUp(d *DAO) error {
54+
db := d.GetDB()
55+
events, err := getData()
56+
if err != nil {
57+
logError(err)
58+
return err
59+
}
60+
61+
tx := db.Begin()
62+
for _, r := range events {
63+
err = tx.Create(r.GetModel()).Error
64+
if err != nil {
65+
return err
66+
}
67+
}
68+
return tx.Commit().Error
69+
}

data/records.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package data
2+
3+
import (
4+
"time"
5+
"web-widgets/scheduler-go/common"
6+
7+
"gorm.io/gorm"
8+
)
9+
10+
func NewEventsDAO(db *gorm.DB) *EventsDAO {
11+
return &EventsDAO{db}
12+
}
13+
14+
type EventUpdate struct {
15+
ID common.FuzzyInt `json:"id"`
16+
Name string `json:"text"`
17+
StartDate *time.Time `json:"start_date"`
18+
EndDate *time.Time `json:"end_date"`
19+
Readonly bool `json:"readonly"`
20+
AllDay bool `json:"allDay"`
21+
Type string `json:"type"`
22+
Details string `json:"details"`
23+
}
24+
25+
type EventsDAO struct {
26+
db *gorm.DB
27+
}
28+
29+
func (d *EventsDAO) GetAll() ([]Event, error) {
30+
events := make([]Event, 0)
31+
err := d.db.Find(&events).Error
32+
33+
return events, err
34+
}
35+
36+
func (d *EventsDAO) Add(event *Event) (int, error) {
37+
event.ID = 0
38+
err := d.db.Save(event).Error
39+
return event.ID, err
40+
}
41+
42+
func (d *EventsDAO) Update(event *Event) error {
43+
c := Event{}
44+
err := d.db.Find(&c, event.ID).Error
45+
if err != nil || c.ID == 0 {
46+
return err
47+
}
48+
err = d.db.Save(&event).Error
49+
return err
50+
}
51+
52+
func (d *EventsDAO) Delete(id int) error {
53+
err := d.db.Delete(&Event{}, id).Error
54+
return err
55+
}
56+
57+
func (d *EventUpdate) GetModel() *Event {
58+
return &Event{
59+
ID: int(d.ID),
60+
Name: d.Name,
61+
StartDate: d.StartDate,
62+
EndDate: d.EndDate,
63+
Readonly: d.Readonly,
64+
Type: d.Type,
65+
Details: d.Details,
66+
}
67+
}

0 commit comments

Comments
 (0)