@@ -12,13 +12,17 @@ import (
12
12
"slices"
13
13
"strings"
14
14
15
+ "code.gitea.io/gitea/models/db"
16
+
15
17
"gopkg.in/yaml.v3"
16
18
"xorm.io/xorm"
17
19
"xorm.io/xorm/schemas"
18
20
)
19
21
20
- type fixtureItem struct {
21
- tableName string
22
+ type FixtureItem struct {
23
+ fileFullPath string
24
+ tableName string
25
+
22
26
tableNameQuoted string
23
27
sqlInserts []string
24
28
sqlInsertArgs [][]any
@@ -27,10 +31,11 @@ type fixtureItem struct {
27
31
}
28
32
29
33
type fixturesLoaderInternal struct {
34
+ xormEngine * xorm.Engine
35
+ xormTableNames map [string ]bool
30
36
db * sql.DB
31
37
dbType schemas.DBType
32
- files []string
33
- fixtures map [string ]* fixtureItem
38
+ fixtures map [string ]* FixtureItem
34
39
quoteObject func (string ) string
35
40
paramPlaceholder func (idx int ) string
36
41
}
@@ -59,29 +64,27 @@ func (f *fixturesLoaderInternal) preprocessFixtureRow(row []map[string]any) (err
59
64
return nil
60
65
}
61
66
62
- func (f * fixturesLoaderInternal ) prepareFixtureItem (file string ) (_ * fixtureItem , err error ) {
63
- fixture := & fixtureItem {}
64
- fixture .tableName , _ , _ = strings .Cut (filepath .Base (file ), "." )
67
+ func (f * fixturesLoaderInternal ) prepareFixtureItem (fixture * FixtureItem ) (err error ) {
65
68
fixture .tableNameQuoted = f .quoteObject (fixture .tableName )
66
69
67
70
if f .dbType == schemas .MSSQL {
68
71
fixture .mssqlHasIdentityColumn , err = f .mssqlTableHasIdentityColumn (f .db , fixture .tableName )
69
72
if err != nil {
70
- return nil , err
73
+ return err
71
74
}
72
75
}
73
76
74
- data , err := os .ReadFile (file )
77
+ data , err := os .ReadFile (fixture . fileFullPath )
75
78
if err != nil {
76
- return nil , fmt .Errorf ("failed to read file %q: %w" , file , err )
79
+ return fmt .Errorf ("failed to read file %q: %w" , fixture . fileFullPath , err )
77
80
}
78
81
79
82
var rows []map [string ]any
80
83
if err = yaml .Unmarshal (data , & rows ); err != nil {
81
- return nil , fmt .Errorf ("failed to unmarshal yaml data from %q: %w" , file , err )
84
+ return fmt .Errorf ("failed to unmarshal yaml data from %q: %w" , fixture . fileFullPath , err )
82
85
}
83
86
if err = f .preprocessFixtureRow (rows ); err != nil {
84
- return nil , fmt .Errorf ("failed to preprocess fixture rows from %q: %w" , file , err )
87
+ return fmt .Errorf ("failed to preprocess fixture rows from %q: %w" , fixture . fileFullPath , err )
85
88
}
86
89
87
90
var sqlBuf []byte
@@ -107,16 +110,14 @@ func (f *fixturesLoaderInternal) prepareFixtureItem(file string) (_ *fixtureItem
107
110
sqlBuf = sqlBuf [:0 ]
108
111
sqlArguments = sqlArguments [:0 ]
109
112
}
110
- return fixture , nil
113
+ return nil
111
114
}
112
115
113
- func (f * fixturesLoaderInternal ) loadFixtures (tx * sql.Tx , file string ) (err error ) {
114
- fixture := f .fixtures [file ]
115
- if fixture == nil {
116
- if fixture , err = f .prepareFixtureItem (file ); err != nil {
116
+ func (f * fixturesLoaderInternal ) loadFixtures (tx * sql.Tx , fixture * FixtureItem ) (err error ) {
117
+ if fixture .tableNameQuoted == "" {
118
+ if err = f .prepareFixtureItem (fixture ); err != nil {
117
119
return err
118
120
}
119
- f .fixtures [file ] = fixture
120
121
}
121
122
122
123
_ , err = tx .Exec (fmt .Sprintf ("DELETE FROM %s" , fixture .tableNameQuoted )) // sqlite3 doesn't support truncate
@@ -147,15 +148,26 @@ func (f *fixturesLoaderInternal) Load() error {
147
148
}
148
149
defer func () { _ = tx .Rollback () }()
149
150
150
- for _ , file := range f .files {
151
- if err := f .loadFixtures (tx , file ); err != nil {
152
- return fmt .Errorf ("failed to load fixtures from %s: %w" , file , err )
151
+ for _ , fixture := range f .fixtures {
152
+ if ! f .xormTableNames [fixture .tableName ] {
153
+ continue
154
+ }
155
+ if err := f .loadFixtures (tx , fixture ); err != nil {
156
+ return fmt .Errorf ("failed to load fixtures from %s: %w" , fixture .fileFullPath , err )
153
157
}
154
158
}
155
- return tx .Commit ()
159
+ if err = tx .Commit (); err != nil {
160
+ return err
161
+ }
162
+ for xormTableName := range f .xormTableNames {
163
+ if f .fixtures [xormTableName ] == nil {
164
+ _ , _ = f .xormEngine .Exec ("DELETE FROM `" + xormTableName + "`" )
165
+ }
166
+ }
167
+ return nil
156
168
}
157
169
158
- func FixturesFileFullPaths (dir string , files []string ) ([] string , error ) {
170
+ func FixturesFileFullPaths (dir string , files []string ) (map [ string ] * FixtureItem , error ) {
159
171
if files != nil && len (files ) == 0 {
160
172
return nil , nil // load nothing
161
173
}
@@ -169,20 +181,25 @@ func FixturesFileFullPaths(dir string, files []string) ([]string, error) {
169
181
files = append (files , e .Name ())
170
182
}
171
183
}
172
- for i , file := range files {
173
- if ! filepath .IsAbs (file ) {
174
- files [i ] = filepath .Join (dir , file )
184
+ fixtureItems := map [string ]* FixtureItem {}
185
+ for _ , file := range files {
186
+ fileFillPath := file
187
+ if ! filepath .IsAbs (fileFillPath ) {
188
+ fileFillPath = filepath .Join (dir , file )
175
189
}
190
+ tableName , _ , _ := strings .Cut (filepath .Base (file ), "." )
191
+ fixtureItems [tableName ] = & FixtureItem {fileFullPath : fileFillPath , tableName : tableName }
176
192
}
177
- return files , nil
193
+ return fixtureItems , nil
178
194
}
179
195
180
196
func NewFixturesLoader (x * xorm.Engine , opts FixturesOptions ) (FixturesLoader , error ) {
181
- files , err := FixturesFileFullPaths (opts .Dir , opts .Files )
197
+ fixtureItems , err := FixturesFileFullPaths (opts .Dir , opts .Files )
182
198
if err != nil {
183
199
return nil , fmt .Errorf ("failed to get fixtures files: %w" , err )
184
200
}
185
- f := & fixturesLoaderInternal {db : x .DB ().DB , dbType : x .Dialect ().URI ().DBType , files : files , fixtures : map [string ]* fixtureItem {}}
201
+
202
+ f := & fixturesLoaderInternal {xormEngine : x , db : x .DB ().DB , dbType : x .Dialect ().URI ().DBType , fixtures : fixtureItems }
186
203
switch f .dbType {
187
204
case schemas .SQLITE :
188
205
f .quoteObject = func (s string ) string { return fmt .Sprintf (`"%s"` , s ) }
@@ -197,5 +214,12 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er
197
214
f .quoteObject = func (s string ) string { return fmt .Sprintf ("[%s]" , s ) }
198
215
f .paramPlaceholder = func (idx int ) string { return "?" }
199
216
}
217
+
218
+ xormBeans , _ := db .NamesToBean ()
219
+ f .xormTableNames = map [string ]bool {}
220
+ for _ , bean := range xormBeans {
221
+ f .xormTableNames [db .TableName (bean )] = true
222
+ }
223
+
200
224
return f , nil
201
225
}
0 commit comments