-
Notifications
You must be signed in to change notification settings - Fork 16
/
application.go
169 lines (149 loc) · 4.71 KB
/
application.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package types
import (
"database/sql/driver"
"time"
sq "github.com/Masterminds/squirrel"
"github.com/gbl08ma/sqalx"
"github.com/palantir/stacktrace"
)
// ApplicationVersion represents the version of an application
type ApplicationVersion time.Time
// Scan implements the sql.Scanner interface.
func (d *ApplicationVersion) Scan(value interface{}) error {
if value == nil {
return nil
}
b, ok := value.(time.Time)
if !ok {
return stacktrace.NewError("Scan: Invalid val type for scanning")
}
*d = ApplicationVersion(b)
return nil
}
// Value implements the driver.Valuer interface.
func (d ApplicationVersion) Value() (driver.Value, error) {
return time.Time(d), nil
}
// UnmarshalJSON implements the json.Unmarshaler interface
func (d *ApplicationVersion) UnmarshalJSON(b []byte) error {
var t time.Time
err := t.UnmarshalJSON(b)
if err != nil {
return stacktrace.Propagate(err, "")
}
*d = ApplicationVersion(t)
return nil
}
// MarshalJSON implements the json.Marshaler interface
func (d ApplicationVersion) MarshalJSON() ([]byte, error) {
return time.Time(d).MarshalJSON()
}
// Application represents an application
type Application struct {
ID string `dbKey:"true"`
UpdatedAt ApplicationVersion `dbKey:"true"`
UpdatedBy string
EditMessage string
AllowLaunching bool
AllowFileEditing bool
Autorun bool
RuntimeVersion int
}
func GetApplications(node sqalx.Node, filter string, pagParams *PaginationParams) ([]*Application, uint64, error) {
s := sdb.Select().
Where(subQueryEq(
"application.updated_at",
sq.Select("MAX(d.updated_at)").From("application d").Where("d.id = application.id"),
)).
OrderBy("application.id ASC")
if filter != "" {
s = s.Where(
sq.Expr("UPPER(application.id) LIKE '%' || UPPER(?) || '%'", filter),
)
}
s = applyPaginationParameters(s, pagParams)
return GetWithSelectAndCount[*Application](node, s)
}
// GetApplicationsWithIDs returns the latest version of the applications with the specified IDs
func GetApplicationsWithIDs(node sqalx.Node, ids []string) (map[string]*Application, error) {
s := sdb.Select().
Where(subQueryEq(
"application.updated_at",
sq.Select("MAX(d.updated_at)").From("application d").Where("d.id = application.id"),
)).
Where(sq.Eq{"application.id": ids})
items, err := GetWithSelect[*Application](node, s)
if err != nil {
return map[string]*Application{}, stacktrace.Propagate(err, "")
}
result := make(map[string]*Application, len(items))
for i := range items {
result[items[i].ID] = items[i]
}
return result, nil
}
// GetApplicationWalletAddress resolves an application's wallet address based on their ID
// The application must have been launched at least once before
func GetApplicationWalletAddress(node sqalx.Node, id string) (string, error) {
tx, err := node.Beginx()
if err != nil {
return "", stacktrace.Propagate(err, "")
}
defer tx.Commit() // read-only tx
var address string
err = sdb.Select("address").
From("chat_user").
Where(sq.Eq{"chat_user.application_id": id}).
RunWith(tx).QueryRow().Scan(&address)
if err != nil {
return "", stacktrace.Propagate(err, "")
}
return address, nil
}
// GetEarliestVersionOfApplication returns the earliest version of the application with the specified ID
func GetEarliestVersionOfApplication(node sqalx.Node, id string) (ApplicationVersion, error) {
tx, err := node.Beginx()
if err != nil {
return ApplicationVersion{}, stacktrace.Propagate(err, "")
}
defer tx.Commit() // read-only tx
var version ApplicationVersion
err = sdb.Select("MIN(application.updated_at)").
From("application").
Where(sq.Eq{"application.id": id}).
RunWith(tx).QueryRow().Scan(&version)
if err != nil {
return ApplicationVersion{}, stacktrace.Propagate(err, "")
}
return version, nil
}
// Update updates or inserts the Application
func (obj *Application) Update(node sqalx.Node) error {
return Update(node, obj)
}
// Delete deletes the Application
func (obj *Application) Delete(node sqalx.Node) error {
return Delete(node, obj)
}
func (obj *Application) deleteExtra(node sqalx.Node, preSelf bool) error {
if !preSelf {
return nil
}
// delete files
builder := sdb.Delete("application_file").Where(sq.Eq{"application_file.application_id": obj.ID})
logger.Println(builder.ToSql())
_, err := builder.RunWith(node).Exec()
if err != nil {
return stacktrace.Propagate(err, "")
}
// delete values
err = ClearApplicationValuesForApplication(node, obj.ID)
if err != nil {
return stacktrace.Propagate(err, "")
}
// delete all other versions of the application
builder = sdb.Delete("application").Where(sq.Eq{"application.id": obj.ID})
logger.Println(builder.ToSql())
_, err = builder.RunWith(node).Exec()
return stacktrace.Propagate(err, "")
}