@@ -2,6 +2,8 @@ package models
22
33import (
44 "fmt"
5+ "strconv"
6+ "strings"
57
68 "gorm.io/gorm"
79)
@@ -13,21 +15,19 @@ func Migrate(db *gorm.DB) error {
1315 return fmt .Errorf ("error during DB migration: %w" , err )
1416 }
1517
16- /*
17- * Workaround for https://github.com/go-gorm/gorm/issues/5968
18- */
1918 queries := []* gorm.DB {
19+ /*
20+ * Workaround for https://github.com/go-gorm/gorm/issues/5968
21+ * Remove with 3.0.0
22+ */
2023 // Account
2124 db .Unscoped ().Model (& Account {}).Select ("OnBudget" ).Where ("accounts.on_budget IS NULL" ).Update ("OnBudget" , false ),
2225 db .Unscoped ().Model (& Account {}).Select ("External" ).Where ("accounts.external IS NULL" ).Update ("External" , false ),
2326 db .Unscoped ().Model (& Account {}).Select ("Hidden" ).Where ("accounts.hidden IS NULL" ).Update ("Hidden" , false ),
24-
2527 // Category
2628 db .Unscoped ().Model (& Category {}).Select ("Hidden" ).Where ("categories.hidden IS NULL" ).Update ("Hidden" , false ),
27-
2829 // Envelope
2930 db .Unscoped ().Model (& Envelope {}).Select ("Hidden" ).Where ("envelopes.hidden IS NULL" ).Update ("Hidden" , false ),
30-
3131 // Transaction
3232 db .Unscoped ().Model (& Transaction {}).Select ("Reconciled" ).Where ("transactions.reconciled IS NULL" ).Update ("Reconciled" , false ),
3333 db .Unscoped ().Model (& Transaction {}).Select ("ReconciledSource" ).Where ("transactions.reconciled_source IS NULL" ).Update ("ReconciledSource" , false ),
@@ -40,5 +40,71 @@ func Migrate(db *gorm.DB) error {
4040 }
4141 }
4242
43+ /*
44+ * Complex migrations
45+ */
46+
47+ // Migration for https://github.com/envelope-zero/backend/issues/628.
48+ // Remove with 3.0.0
49+ err = migrateImportHashString (db )
50+ if err != nil {
51+ return fmt .Errorf ("error during migrateImportHashString: %w" , err )
52+ }
53+
4354 return nil
4455}
56+
57+ // migrateImportHashString migrates the string representation of the SHA256 hash as byte array
58+ // to a hex string representation of the hash to use the common way of representing SHA256 hashes.
59+ // See https://github.com/envelope-zero/backend/issues/628.
60+ func migrateImportHashString (db * gorm.DB ) (err error ) {
61+ var accounts []Account
62+ err = db .Unscoped ().Where ("import_hash LIKE '[%'" ).Find (& accounts ).Error
63+ if err != nil {
64+ return err
65+ }
66+
67+ for _ , account := range accounts {
68+ // The string looks like this: "[40 52 207 7 118 61 80 107 178 242 5 47 211 161 180 135 104 222 118 28 56 12 33 63 179 78 39 173 206 11 77 3]"
69+ // With trimming and splitting it, we get a slice containing every individual number
70+ bytes := strings .Split (strings .TrimRight (strings .TrimLeft (account .ImportHash , "[" ), "]" ), " " )
71+
72+ // Assemble the slice back to a string. We pad with zeroes so that every byte takes two characters
73+ var b strings.Builder
74+ for _ , part := range bytes {
75+ // Need to convert to int first so that it's interpreted correctly
76+ charAsInt , _ := strconv .Atoi (part )
77+ b .WriteString (fmt .Sprintf ("%02x" , byte (charAsInt )))
78+ }
79+
80+ // Save the record back to the DB
81+ account .ImportHash = b .String ()
82+ db .Unscoped ().Save (& account )
83+ }
84+
85+ var transactions []Transaction
86+ err = db .Unscoped ().Where ("import_hash LIKE '[%'" ).Find (& transactions ).Error
87+ if err != nil {
88+ return err
89+ }
90+
91+ for _ , transaction := range transactions {
92+ // The string looks like this: "[40 52 207 7 118 61 80 107 178 242 5 47 211 161 180 135 104 222 118 28 56 12 33 63 179 78 39 173 206 11 77 3]"
93+ // With trimming and splitting it, we get a slice containing every individual number
94+ bytes := strings .Split (strings .TrimRight (strings .TrimLeft (transaction .ImportHash , "[" ), "]" ), " " )
95+
96+ // Assemble the slice back to a string. We pad with zeroes so that every byte takes two characters
97+ var b strings.Builder
98+ for _ , part := range bytes {
99+ // Need to convert to int first so that it's interpreted correctly
100+ charAsInt , _ := strconv .Atoi (part )
101+ b .WriteString (fmt .Sprintf ("%02x" , byte (charAsInt )))
102+ }
103+
104+ // Save the record back to the DB
105+ transaction .ImportHash = b .String ()
106+ db .Unscoped ().Save (& transaction )
107+ }
108+
109+ return
110+ }
0 commit comments