forked from OpenBazaar/openbazaar-go
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Migration008.go
219 lines (201 loc) · 9.13 KB
/
Migration008.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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
package migrations
import (
"database/sql"
"fmt"
"io/ioutil"
"os"
"path"
"strings"
"time"
"github.com/OpenBazaar/jsonpb"
"github.com/OpenBazaar/openbazaar-go/pb"
)
const (
Migration008_OrderState_PENDING = 0
Migration008_OrderState_AWAITING_PAYMENT = 1
Migration008_OrderState_DISPUTED = 10
Migration008_casesCreateSQL = "create table cases (caseID text primary key not null, buyerContract blob, vendorContract blob, buyerValidationErrors blob, vendorValidationErrors blob, buyerPayoutAddress text, vendorPayoutAddress text, buyerOutpoints blob, vendorOutpoints blob, state integer, read integer, timestamp integer, buyerOpened integer, claim text, disputeResolution blob, lastNotifiedAt integer not null default 0);"
Migration008_purchasesCreateSQL = "create table purchases (orderID text primary key not null, contract blob, state integer, read integer, timestamp integer, total integer, thumbnail text, vendorID text, vendorHandle text, title text, shippingName text, shippingAddress text, paymentAddr text, funded integer, transactions blob, lastNotifiedAt integer not null default 0);"
Migration008_salesCreateSQL = "create table sales (orderID text primary key not null, contract blob, state integer, read integer, timestamp integer, total integer, thumbnail text, buyerID text, buyerHandle text, title text, shippingName text, shippingAddress text, paymentAddr text, funded integer, transactions blob, needsSync integer, lastNotifiedAt integer not null default 0);"
)
type Migration008 struct{}
func (Migration008) Up(repoPath, databasePassword string, testnetEnabled bool) error {
var (
databaseFilePath string
executedAt = time.Now()
repoVersionFilePath = path.Join(repoPath, "repover")
)
if testnetEnabled {
databaseFilePath = path.Join(repoPath, "datastore", "testnet.db")
} else {
databaseFilePath = path.Join(repoPath, "datastore", "mainnet.db")
}
const (
alterCasesSQL = "alter table cases rename to cases_old;"
alterPurchasesSQL = "alter table purchases rename to purchases_old;"
alterSalesSQL = "alter table sales rename to sales_old;"
createNewDisputedCasesSQL = "create table cases (caseID text primary key not null, buyerContract blob, vendorContract blob, buyerValidationErrors blob, vendorValidationErrors blob, buyerPayoutAddress text, vendorPayoutAddress text, buyerOutpoints blob, vendorOutpoints blob, state integer, read integer, timestamp integer, buyerOpened integer, claim text, disputeResolution blob, lastDisputeExpiryNotifiedAt integer not null default 0);"
createNewPurchasesSQL = "create table purchases (orderID text primary key not null, contract blob, state integer, read integer, timestamp integer, total integer, thumbnail text, vendorID text, vendorHandle text, title text, shippingName text, shippingAddress text, paymentAddr text, funded integer, transactions blob, lastDisputeTimeoutNotifiedAt integer not null default 0, lastDisputeExpiryNotifiedAt integer, disputedAt integer not null default 0);"
createNewSalesSQL = "create table sales (orderID text primary key not null, contract blob, state integer, read integer, timestamp integer, total integer, thumbnail text, buyerID text, buyerHandle text, title text, shippingName text, shippingAddress text, paymentAddr text, funded integer, transactions blob, needsSync integer, lastDisputeTimeoutNotifiedAt integer not null default 0);"
insertCasesSQL = "insert into cases select caseID, buyerContract, vendorContract, buyerValidationErrors, vendorValidationErrors, buyerPayoutAddress, vendorPayoutAddress, buyerOutpoints, vendorOutpoints, state, read, timestamp, buyerOpened, claim, disputeResolution, lastNotifiedAt from cases_old;"
insertPurchasesSQL = "insert into purchases select orderID, contract, state, read, timestamp, total, thumbnail, vendorID, vendorHandle, title, shippingName, shippingAddress, paymentAddr, funded, transactions, lastNotifiedAt, 0, 0 from purchases_old;"
insertSalesSQL = "insert into sales select orderID, contract, state, read, timestamp, total, thumbnail, buyerID, buyerHandle, title, shippingName, shippingAddress, paymentAddr, funded, transactions, needsSync, lastNotifiedAt from sales_old;"
dropCasesTableSQL = "drop table cases_old;"
dropPurchasesTableSQL = "drop table purchases_old;"
dropSalesTableSQL = "drop table sales_old;"
)
db, err := sql.Open("sqlite3", databaseFilePath)
if err != nil {
return err
}
defer db.Close()
if databasePassword != "" {
p := fmt.Sprintf("pragma key = '%s';", databasePassword)
_, err := db.Exec(p)
if err != nil {
return err
}
}
migration := strings.Join([]string{
alterCasesSQL,
createNewDisputedCasesSQL,
insertCasesSQL,
dropCasesTableSQL,
alterPurchasesSQL,
createNewPurchasesSQL,
insertPurchasesSQL,
dropPurchasesTableSQL,
alterSalesSQL,
createNewSalesSQL,
insertSalesSQL,
dropSalesTableSQL,
}, " ")
tx, err := db.Begin()
if err != nil {
return err
}
if _, err = tx.Exec(migration); err != nil {
tx.Rollback()
return err
}
if err = tx.Commit(); err != nil {
return err
}
_, err = db.Exec("update cases set lastDisputeExpiryNotifiedAt = ?", executedAt.Unix())
if err != nil {
return err
}
_, err = db.Exec("update purchases set lastDisputeTimeoutNotifiedAt = ?", executedAt.Unix())
if err != nil {
return err
}
_, err = db.Exec("update purchases set lastDisputeExpiryNotifiedAt = ? where state = ?", executedAt.Unix(), Migration008_OrderState_DISPUTED)
if err != nil {
return err
}
_, err = db.Exec("update sales set lastDisputeTimeoutNotifiedAt = ?", executedAt.Unix())
if err != nil {
return err
}
updateDisputedAtRows, err := db.Query("select orderId, contract from purchases where state = ?", Migration008_OrderState_DISPUTED)
if err != nil {
return err
}
var updateDisputedAtTimestamps = make(map[string]int64)
for updateDisputedAtRows.Next() {
var (
orderID string
contractData string
contract = &pb.RicardianContract{}
)
if err := updateDisputedAtRows.Scan(&orderID, &contractData); err != nil {
return err
}
if err := jsonpb.UnmarshalString(contractData, contract); err != nil {
return err
}
if contract.Dispute != nil && contract.Dispute.Timestamp != nil {
updateDisputedAtTimestamps[orderID] = contract.Dispute.Timestamp.Seconds
}
}
if err = updateDisputedAtRows.Close(); err != nil {
return err
}
for orderID, unixTimestamp := range updateDisputedAtTimestamps {
_, err := db.Exec("update purchases set disputedAt = ? where orderId = ?", unixTimestamp, orderID)
if err != nil {
return err
}
}
// Bump schema version
err = ioutil.WriteFile(repoVersionFilePath, []byte("9"), os.ModePerm)
if err != nil {
return err
}
return nil
}
func (Migration008) Down(repoPath, databasePassword string, testnetEnabled bool) error {
var (
databaseFilePath string
repoVersionFilePath = path.Join(repoPath, "repover")
)
if testnetEnabled {
databaseFilePath = path.Join(repoPath, "datastore", "testnet.db")
} else {
databaseFilePath = path.Join(repoPath, "datastore", "mainnet.db")
}
db, err := sql.Open("sqlite3", databaseFilePath)
if err != nil {
return err
}
defer db.Close()
if databasePassword != "" {
p := fmt.Sprintf("pragma key = '%s';", databasePassword)
_, err := db.Exec(p)
if err != nil {
return err
}
}
const (
alterCasesSQL = "alter table cases rename to cases_old;"
alterPurchasesSQL = "alter table purchases rename to purchases_old;"
alterSalesSQL = "alter table sales rename to sales_old;"
insertCasesSQL = "insert into cases select caseID, buyerContract, vendorContract, buyerValidationErrors, vendorValidationErrors, buyerPayoutAddress, vendorPayoutAddress, buyerOutpoints, vendorOutpoints, state, read, timestamp, buyerOpened, claim, disputeResolution, lastDisputeExpiryNotifiedAt from cases_old;"
insertPurchasesSQL = "insert into purchases select orderID, contract, state, read, timestamp, total, thumbnail, vendorID, vendorHandle, title, shippingName, shippingAddress, paymentAddr, funded, transactions, lastDisputeTimeoutNotifiedAt from purchases_old;"
insertSalesSQL = "insert into sales select orderID, contract, state, read, timestamp, total, thumbnail, buyerID, buyerHandle, title, shippingName, shippingAddress, paymentAddr, funded, transactions, needsSync, lastDisputeTimeoutNotifiedAt from sales_old;"
dropCasesTableSQL = "drop table cases_old;"
dropPurchasesTableSQL = "drop table purchases_old;"
dropSalesTableSQL = "drop table sales_old;"
)
migration := strings.Join([]string{
alterCasesSQL,
Migration008_casesCreateSQL,
insertCasesSQL,
dropCasesTableSQL,
alterPurchasesSQL,
Migration008_purchasesCreateSQL,
insertPurchasesSQL,
dropPurchasesTableSQL,
alterSalesSQL,
Migration008_salesCreateSQL,
insertSalesSQL,
dropSalesTableSQL,
}, " ")
tx, err := db.Begin()
if err != nil {
return err
}
if _, err = tx.Exec(migration); err != nil {
tx.Rollback()
return err
}
if err = tx.Commit(); err != nil {
return err
}
// Revert schema version
err = ioutil.WriteFile(repoVersionFilePath, []byte("8"), os.ModePerm)
if err != nil {
return err
}
return nil
}