@@ -7,11 +7,13 @@ package models
7
7
import (
8
8
"context"
9
9
"errors"
10
+ "fmt"
10
11
11
12
"code.gitea.io/gitea/models/db"
12
13
repo_model "code.gitea.io/gitea/models/repo"
13
14
user_model "code.gitea.io/gitea/models/user"
14
15
"code.gitea.io/gitea/modules/lfs"
16
+ "code.gitea.io/gitea/modules/log"
15
17
"code.gitea.io/gitea/modules/timeutil"
16
18
17
19
"xorm.io/builder"
@@ -145,6 +147,11 @@ func LFSObjectAccessible(user *user_model.User, oid string) (bool, error) {
145
147
return count > 0 , err
146
148
}
147
149
150
+ // LFSObjectIsAssociated checks if a provided Oid is associated
151
+ func LFSObjectIsAssociated (oid string ) (bool , error ) {
152
+ return db .GetEngine (db .DefaultContext ).Exist (& LFSMetaObject {Pointer : lfs.Pointer {Oid : oid }})
153
+ }
154
+
148
155
// LFSAutoAssociate auto associates accessible LFSMetaObjects
149
156
func LFSAutoAssociate (metas []* LFSMetaObject , user * user_model.User , repoID int64 ) error {
150
157
ctx , committer , err := db .TxContext ()
@@ -162,23 +169,39 @@ func LFSAutoAssociate(metas []*LFSMetaObject, user *user_model.User, repoID int6
162
169
oidMap [meta .Oid ] = meta
163
170
}
164
171
165
- cond := builder .NewCond ()
166
172
if ! user .IsAdmin {
167
- cond = builder .In ("`lfs_meta_object`.repository_id" ,
168
- builder .Select ("`repository`.id" ).From ("repository" ).Where (accessibleRepositoryCondition (user )))
169
- }
170
- newMetas := make ([]* LFSMetaObject , 0 , len (metas ))
171
- if err := sess .Cols ("oid" ).Where (cond ).In ("oid" , oids ... ).GroupBy ("oid" ).Find (& newMetas ); err != nil {
172
- return err
173
- }
174
- for i := range newMetas {
175
- newMetas [i ].Size = oidMap [newMetas [i ].Oid ].Size
176
- newMetas [i ].RepositoryID = repoID
177
- }
178
- if err := db .Insert (ctx , newMetas ); err != nil {
179
- return err
173
+ newMetas := make ([]* LFSMetaObject , 0 , len (metas ))
174
+ cond := builder .In (
175
+ "`lfs_meta_object`.repository_id" ,
176
+ builder .Select ("`repository`.id" ).From ("repository" ).Where (accessibleRepositoryCondition (user )),
177
+ )
178
+ err = sess .Cols ("oid" ).Where (cond ).In ("oid" , oids ... ).GroupBy ("oid" ).Find (& newMetas )
179
+ if err != nil {
180
+ return err
181
+ }
182
+ if len (newMetas ) != len (oidMap ) {
183
+ return fmt .Errorf ("unable collect all LFS objects from database, expected %d, actually %d" , len (oidMap ), len (newMetas ))
184
+ }
185
+ for i := range newMetas {
186
+ newMetas [i ].Size = oidMap [newMetas [i ].Oid ].Size
187
+ newMetas [i ].RepositoryID = repoID
188
+ }
189
+ if err = db .Insert (ctx , newMetas ); err != nil {
190
+ return err
191
+ }
192
+ } else {
193
+ // admin can associate any LFS object to any repository, and we do not care about errors (eg: duplicated unique key),
194
+ // even if error occurs, it won't hurt users and won't make things worse
195
+ for i := range metas {
196
+ _ , err = sess .Insert (& LFSMetaObject {
197
+ Pointer : lfs.Pointer {Oid : metas [i ].Oid , Size : metas [i ].Size },
198
+ RepositoryID : repoID ,
199
+ })
200
+ if err != nil {
201
+ log .Warn ("failed to insert LFS meta object into database, err=%v" , err )
202
+ }
203
+ }
180
204
}
181
-
182
205
return committer .Commit ()
183
206
}
184
207
0 commit comments