@@ -12,13 +12,17 @@ import (
1212 "slices"
1313 "strings"
1414
15+ "code.gitea.io/gitea/models/db"
16+
1517 "gopkg.in/yaml.v3"
1618 "xorm.io/xorm"
1719 "xorm.io/xorm/schemas"
1820)
1921
20- type fixtureItem struct {
21- tableName string
22+ type FixtureItem struct {
23+ fileFullPath string
24+ tableName string
25+
2226 tableNameQuoted string
2327 sqlInserts []string
2428 sqlInsertArgs [][]any
@@ -27,10 +31,11 @@ type fixtureItem struct {
2731}
2832
2933type fixturesLoaderInternal struct {
34+ xormEngine * xorm.Engine
35+ xormTableNames map [string ]bool
3036 db * sql.DB
3137 dbType schemas.DBType
32- files []string
33- fixtures map [string ]* fixtureItem
38+ fixtures map [string ]* FixtureItem
3439 quoteObject func (string ) string
3540 paramPlaceholder func (idx int ) string
3641}
@@ -59,29 +64,27 @@ func (f *fixturesLoaderInternal) preprocessFixtureRow(row []map[string]any) (err
5964 return nil
6065}
6166
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 ) {
6568 fixture .tableNameQuoted = f .quoteObject (fixture .tableName )
6669
6770 if f .dbType == schemas .MSSQL {
6871 fixture .mssqlHasIdentityColumn , err = f .mssqlTableHasIdentityColumn (f .db , fixture .tableName )
6972 if err != nil {
70- return nil , err
73+ return err
7174 }
7275 }
7376
74- data , err := os .ReadFile (file )
77+ data , err := os .ReadFile (fixture . fileFullPath )
7578 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 )
7780 }
7881
7982 var rows []map [string ]any
8083 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 )
8285 }
8386 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 )
8588 }
8689
8790 var sqlBuf []byte
@@ -107,16 +110,14 @@ func (f *fixturesLoaderInternal) prepareFixtureItem(file string) (_ *fixtureItem
107110 sqlBuf = sqlBuf [:0 ]
108111 sqlArguments = sqlArguments [:0 ]
109112 }
110- return fixture , nil
113+ return nil
111114}
112115
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 {
117119 return err
118120 }
119- f .fixtures [file ] = fixture
120121 }
121122
122123 _ , err = tx .Exec (fmt .Sprintf ("DELETE FROM %s" , fixture .tableNameQuoted )) // sqlite3 doesn't support truncate
@@ -147,15 +148,26 @@ func (f *fixturesLoaderInternal) Load() error {
147148 }
148149 defer func () { _ = tx .Rollback () }()
149150
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 )
153157 }
154158 }
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
156168}
157169
158- func FixturesFileFullPaths (dir string , files []string ) ([] string , error ) {
170+ func FixturesFileFullPaths (dir string , files []string ) (map [ string ] * FixtureItem , error ) {
159171 if files != nil && len (files ) == 0 {
160172 return nil , nil // load nothing
161173 }
@@ -169,20 +181,25 @@ func FixturesFileFullPaths(dir string, files []string) ([]string, error) {
169181 files = append (files , e .Name ())
170182 }
171183 }
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 )
175189 }
190+ tableName , _ , _ := strings .Cut (filepath .Base (file ), "." )
191+ fixtureItems [tableName ] = & FixtureItem {fileFullPath : fileFillPath , tableName : tableName }
176192 }
177- return files , nil
193+ return fixtureItems , nil
178194}
179195
180196func NewFixturesLoader (x * xorm.Engine , opts FixturesOptions ) (FixturesLoader , error ) {
181- files , err := FixturesFileFullPaths (opts .Dir , opts .Files )
197+ fixtureItems , err := FixturesFileFullPaths (opts .Dir , opts .Files )
182198 if err != nil {
183199 return nil , fmt .Errorf ("failed to get fixtures files: %w" , err )
184200 }
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 }
186203 switch f .dbType {
187204 case schemas .SQLITE :
188205 f .quoteObject = func (s string ) string { return fmt .Sprintf (`"%s"` , s ) }
@@ -197,5 +214,12 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er
197214 f .quoteObject = func (s string ) string { return fmt .Sprintf ("[%s]" , s ) }
198215 f .paramPlaceholder = func (idx int ) string { return "?" }
199216 }
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+
200224 return f , nil
201225}
0 commit comments