github.com/go-generalize/volcago@v1.7.0/generator/testfiles/auto/lock_meta2_gen.go (about) 1 // Code generated by volcago. DO NOT EDIT. 2 // generated version: (devel) 3 package model 4 5 import ( 6 "context" 7 "time" 8 9 "cloud.google.com/go/firestore" 10 "golang.org/x/xerrors" 11 "google.golang.org/api/iterator" 12 "google.golang.org/grpc/codes" 13 "google.golang.org/grpc/status" 14 ) 15 16 //go:generate mockgen -source $GOFILE -destination mock/mock_lock_meta2_gen/mock_lock_meta2_gen.go 17 18 // LockMeta2Repository - Repository of LockMeta2 19 type LockMeta2Repository interface { 20 // Single 21 Get(ctx context.Context, id string, opts ...GetOption) (*LockMeta2, error) 22 GetWithDoc(ctx context.Context, doc *firestore.DocumentRef, opts ...GetOption) (*LockMeta2, error) 23 Insert(ctx context.Context, subject *LockMeta2) (_ string, err error) 24 Update(ctx context.Context, subject *LockMeta2) (err error) 25 StrictUpdate(ctx context.Context, id string, param *LockMeta2UpdateParam, opts ...firestore.Precondition) error 26 Delete(ctx context.Context, subject *LockMeta2, opts ...DeleteOption) (err error) 27 DeleteByID(ctx context.Context, id string, opts ...DeleteOption) (err error) 28 // Multiple 29 GetMulti(ctx context.Context, ids []string, opts ...GetOption) ([]*LockMeta2, error) 30 InsertMulti(ctx context.Context, subjects []*LockMeta2) (_ []string, er error) 31 UpdateMulti(ctx context.Context, subjects []*LockMeta2) (er error) 32 DeleteMulti(ctx context.Context, subjects []*LockMeta2, opts ...DeleteOption) (er error) 33 DeleteMultiByIDs(ctx context.Context, ids []string, opts ...DeleteOption) (er error) 34 // Single(Transaction) 35 GetWithTx(tx *firestore.Transaction, id string, opts ...GetOption) (*LockMeta2, error) 36 GetWithDocWithTx(tx *firestore.Transaction, doc *firestore.DocumentRef, opts ...GetOption) (*LockMeta2, error) 37 InsertWithTx(ctx context.Context, tx *firestore.Transaction, subject *LockMeta2) (_ string, err error) 38 UpdateWithTx(ctx context.Context, tx *firestore.Transaction, subject *LockMeta2) (err error) 39 StrictUpdateWithTx(tx *firestore.Transaction, id string, param *LockMeta2UpdateParam, opts ...firestore.Precondition) error 40 DeleteWithTx(ctx context.Context, tx *firestore.Transaction, subject *LockMeta2, opts ...DeleteOption) (err error) 41 DeleteByIDWithTx(ctx context.Context, tx *firestore.Transaction, id string, opts ...DeleteOption) (err error) 42 // Multiple(Transaction) 43 GetMultiWithTx(tx *firestore.Transaction, ids []string, opts ...GetOption) ([]*LockMeta2, error) 44 InsertMultiWithTx(ctx context.Context, tx *firestore.Transaction, subjects []*LockMeta2) (_ []string, er error) 45 UpdateMultiWithTx(ctx context.Context, tx *firestore.Transaction, subjects []*LockMeta2) (er error) 46 DeleteMultiWithTx(ctx context.Context, tx *firestore.Transaction, subjects []*LockMeta2, opts ...DeleteOption) (er error) 47 DeleteMultiByIDsWithTx(ctx context.Context, tx *firestore.Transaction, ids []string, opts ...DeleteOption) (er error) 48 // Search 49 Search(ctx context.Context, param *LockMeta2SearchParam, q *firestore.Query) ([]*LockMeta2, error) 50 SearchWithTx(tx *firestore.Transaction, param *LockMeta2SearchParam, q *firestore.Query) ([]*LockMeta2, error) 51 SearchByParam(ctx context.Context, param *LockMeta2SearchParam) ([]*LockMeta2, *PagingResult, error) 52 SearchByParamWithTx(tx *firestore.Transaction, param *LockMeta2SearchParam) ([]*LockMeta2, *PagingResult, error) 53 // misc 54 GetCollection() *firestore.CollectionRef 55 GetCollectionName() string 56 GetDocRef(id string) *firestore.DocumentRef 57 RunInTransaction() func(ctx context.Context, f func(context.Context, *firestore.Transaction) error, opts ...firestore.TransactionOption) (err error) 58 } 59 60 // LockMeta2RepositoryMiddleware - middleware of LockMeta2Repository 61 type LockMeta2RepositoryMiddleware interface { 62 BeforeInsert(ctx context.Context, subject *LockMeta2) (bool, error) 63 BeforeUpdate(ctx context.Context, old, subject *LockMeta2) (bool, error) 64 BeforeDelete(ctx context.Context, subject *LockMeta2, opts ...DeleteOption) (bool, error) 65 BeforeDeleteByID(ctx context.Context, ids []string, opts ...DeleteOption) (bool, error) 66 } 67 68 type lockMeta2Repository struct { 69 collectionName string 70 firestoreClient *firestore.Client 71 middleware []LockMeta2RepositoryMiddleware 72 uniqueRepository *uniqueRepository 73 } 74 75 // NewLockMeta2Repository - constructor 76 func NewLockMeta2Repository(firestoreClient *firestore.Client, middleware ...LockMeta2RepositoryMiddleware) LockMeta2Repository { 77 return &lockMeta2Repository{ 78 collectionName: "LockMeta2", 79 firestoreClient: firestoreClient, 80 middleware: middleware, 81 uniqueRepository: newUniqueRepository(firestoreClient, "LockMeta2"), 82 } 83 } 84 85 func (repo *lockMeta2Repository) setMeta(subject *LockMeta2, isInsert bool) { 86 now := time.Now() 87 88 if isInsert { 89 subject.CreatedAt = now 90 } 91 subject.UpdatedAt = now 92 subject.Version++ 93 } 94 95 func (repo *lockMeta2Repository) setMetaWithStrictUpdate(param *LockMeta2UpdateParam) { 96 param.UpdatedAt = firestore.ServerTimestamp 97 param.Version = firestore.Increment(1) 98 } 99 100 func (repo *lockMeta2Repository) beforeInsert(ctx context.Context, subject *LockMeta2) error { 101 if subject.Version != 0 { 102 return xerrors.Errorf("insert data must be Version == 0 %+v: %w", subject, ErrVersionConflict) 103 } 104 if subject.DeletedAt != nil { 105 return xerrors.Errorf("insert data must be DeletedAt == nil: %+v", subject) 106 } 107 repo.setMeta(subject, true) 108 repo.uniqueRepository.setMiddleware(ctx) 109 err := repo.uniqueRepository.CheckUnique(ctx, nil, subject) 110 if err != nil { 111 return xerrors.Errorf("unique.middleware error: %w", err) 112 } 113 114 for _, m := range repo.middleware { 115 c, err := m.BeforeInsert(ctx, subject) 116 if err != nil { 117 return xerrors.Errorf("beforeInsert.middleware error: %w", err) 118 } 119 if !c { 120 continue 121 } 122 } 123 124 return nil 125 } 126 127 func (repo *lockMeta2Repository) beforeUpdate(ctx context.Context, old, subject *LockMeta2) error { 128 if ctx.Value(transactionInProgressKey{}) != nil && old == nil { 129 var err error 130 doc := repo.GetDocRef(subject.ID) 131 old, err = repo.get(context.Background(), doc) 132 if err != nil { 133 if status.Code(err) == codes.NotFound { 134 return ErrNotFound 135 } 136 return xerrors.Errorf("error in Get method: %w", err) 137 } 138 } 139 if old.Version > subject.Version { 140 return xerrors.Errorf( 141 "The data in the database is newer: (db version: %d, target version: %d) %+v: %w", 142 old.Version, subject.Version, subject, ErrVersionConflict, 143 ) 144 } 145 if subject.DeletedAt != nil { 146 return xerrors.Errorf("update data must be DeletedAt == nil: %+v", subject) 147 } 148 repo.setMeta(subject, false) 149 repo.uniqueRepository.setMiddleware(ctx) 150 err := repo.uniqueRepository.CheckUnique(ctx, old, subject) 151 if err != nil { 152 return xerrors.Errorf("unique.middleware error: %w", err) 153 } 154 155 for _, m := range repo.middleware { 156 c, err := m.BeforeUpdate(ctx, old, subject) 157 if err != nil { 158 return xerrors.Errorf("beforeUpdate.middleware error: %w", err) 159 } 160 if !c { 161 continue 162 } 163 } 164 165 return nil 166 } 167 168 func (repo *lockMeta2Repository) beforeDelete(ctx context.Context, subject *LockMeta2, opts ...DeleteOption) error { 169 repo.setMeta(subject, false) 170 repo.uniqueRepository.setMiddleware(ctx) 171 err := repo.uniqueRepository.DeleteUnique(ctx, subject) 172 if err != nil { 173 return xerrors.Errorf("unique.middleware error: %w", err) 174 } 175 176 for _, m := range repo.middleware { 177 c, err := m.BeforeDelete(ctx, subject, opts...) 178 if err != nil { 179 return xerrors.Errorf("beforeDelete.middleware error: %w", err) 180 } 181 if !c { 182 continue 183 } 184 } 185 186 return nil 187 } 188 189 // GetCollection - *firestore.CollectionRef getter 190 func (repo *lockMeta2Repository) GetCollection() *firestore.CollectionRef { 191 return repo.firestoreClient.Collection(repo.collectionName) 192 } 193 194 // GetCollectionName - CollectionName getter 195 func (repo *lockMeta2Repository) GetCollectionName() string { 196 return repo.collectionName 197 } 198 199 // GetDocRef - *firestore.DocumentRef getter 200 func (repo *lockMeta2Repository) GetDocRef(id string) *firestore.DocumentRef { 201 return repo.GetCollection().Doc(id) 202 } 203 204 // RunInTransaction - (*firestore.Client).RunTransaction getter 205 func (repo *lockMeta2Repository) RunInTransaction() func(ctx context.Context, f func(context.Context, *firestore.Transaction) error, opts ...firestore.TransactionOption) (err error) { 206 return repo.firestoreClient.RunTransaction 207 } 208 209 // LockMeta2SearchParam - params for search 210 type LockMeta2SearchParam struct { 211 ID *QueryChainer 212 Text *QueryChainer 213 Flag *QueryChainer 214 CreatedAt *QueryChainer 215 CreatedBy *QueryChainer 216 UpdatedAt *QueryChainer 217 UpdatedBy *QueryChainer 218 DeletedAt *QueryChainer 219 DeletedBy *QueryChainer 220 Version *QueryChainer 221 222 IncludeSoftDeleted bool 223 CursorKey string 224 CursorLimit int 225 } 226 227 // LockMeta2UpdateParam - params for strict updates 228 type LockMeta2UpdateParam struct { 229 Text interface{} 230 Flag interface{} 231 CreatedAt interface{} 232 CreatedBy interface{} 233 UpdatedAt interface{} 234 UpdatedBy interface{} 235 DeletedAt interface{} 236 DeletedBy interface{} 237 Version interface{} 238 } 239 240 // Search - search documents 241 // The third argument is firestore.Query, basically you can pass nil 242 func (repo *lockMeta2Repository) Search(ctx context.Context, param *LockMeta2SearchParam, q *firestore.Query) ([]*LockMeta2, error) { 243 return repo.search(ctx, param, q) 244 } 245 246 // SearchByParam - search documents by search param 247 func (repo *lockMeta2Repository) SearchByParam(ctx context.Context, param *LockMeta2SearchParam) ([]*LockMeta2, *PagingResult, error) { 248 return repo.searchByParam(ctx, param) 249 } 250 251 // Get - get `LockMeta2` by `LockMeta2.ID` 252 func (repo *lockMeta2Repository) Get(ctx context.Context, id string, opts ...GetOption) (*LockMeta2, error) { 253 doc := repo.GetDocRef(id) 254 return repo.get(ctx, doc, opts...) 255 } 256 257 // GetWithDoc - get `LockMeta2` by *firestore.DocumentRef 258 func (repo *lockMeta2Repository) GetWithDoc(ctx context.Context, doc *firestore.DocumentRef, opts ...GetOption) (*LockMeta2, error) { 259 return repo.get(ctx, doc, opts...) 260 } 261 262 // Insert - insert of `LockMeta2` 263 func (repo *lockMeta2Repository) Insert(ctx context.Context, subject *LockMeta2) (_ string, err error) { 264 if err := repo.beforeInsert(ctx, subject); err != nil { 265 return "", xerrors.Errorf("before insert error: %w", err) 266 } 267 268 return repo.insert(ctx, subject) 269 } 270 271 // Update - update of `LockMeta2` 272 func (repo *lockMeta2Repository) Update(ctx context.Context, subject *LockMeta2) (err error) { 273 doc := repo.GetDocRef(subject.ID) 274 275 old, err := repo.get(ctx, doc) 276 if err != nil { 277 if status.Code(err) == codes.NotFound { 278 return ErrNotFound 279 } 280 return xerrors.Errorf("error in Get method: %w", err) 281 } 282 283 if err := repo.beforeUpdate(ctx, old, subject); err != nil { 284 return xerrors.Errorf("before update error: %w", err) 285 } 286 287 return repo.update(ctx, subject) 288 } 289 290 // StrictUpdate - strict update of `LockMeta2` 291 func (repo *lockMeta2Repository) StrictUpdate(ctx context.Context, id string, param *LockMeta2UpdateParam, opts ...firestore.Precondition) error { 292 return repo.strictUpdate(ctx, id, param, opts...) 293 } 294 295 // Delete - delete of `LockMeta2` 296 func (repo *lockMeta2Repository) Delete(ctx context.Context, subject *LockMeta2, opts ...DeleteOption) (err error) { 297 if err := repo.beforeDelete(ctx, subject, opts...); err != nil { 298 return xerrors.Errorf("before delete error: %w", err) 299 } 300 301 if len(opts) > 0 && opts[0].Mode == DeleteModeSoft { 302 t := time.Now() 303 subject.DeletedAt = &t 304 if err := repo.update(ctx, subject); err != nil { 305 return xerrors.Errorf("error in update method: %w", err) 306 } 307 return nil 308 } 309 310 return repo.deleteByID(ctx, subject.ID) 311 } 312 313 // DeleteByID - delete `LockMeta2` by `LockMeta2.ID` 314 func (repo *lockMeta2Repository) DeleteByID(ctx context.Context, id string, opts ...DeleteOption) (err error) { 315 subject, err := repo.Get(ctx, id) 316 if err != nil { 317 return xerrors.Errorf("error in Get method: %w", err) 318 } 319 320 if err := repo.beforeDelete(ctx, subject, opts...); err != nil { 321 return xerrors.Errorf("before delete error: %w", err) 322 } 323 324 if len(opts) > 0 && opts[0].Mode == DeleteModeSoft { 325 t := time.Now() 326 subject.DeletedAt = &t 327 if err := repo.update(ctx, subject); err != nil { 328 return xerrors.Errorf("error in update method: %w", err) 329 } 330 return nil 331 } 332 333 return repo.Delete(ctx, subject, opts...) 334 } 335 336 // GetMulti - get `LockMeta2` in bulk by array of `LockMeta2.ID` 337 func (repo *lockMeta2Repository) GetMulti(ctx context.Context, ids []string, opts ...GetOption) ([]*LockMeta2, error) { 338 return repo.getMulti(ctx, ids, opts...) 339 } 340 341 // InsertMulti - bulk insert of `LockMeta2` 342 func (repo *lockMeta2Repository) InsertMulti(ctx context.Context, subjects []*LockMeta2) (_ []string, er error) { 343 344 ids := make([]string, 0, len(subjects)) 345 batches := make([]*firestore.WriteBatch, 0) 346 batch := repo.firestoreClient.Batch() 347 collect := repo.GetCollection() 348 349 for i, subject := range subjects { 350 var ref *firestore.DocumentRef 351 if subject.ID == "" { 352 ref = collect.NewDoc() 353 subject.ID = ref.ID 354 } else { 355 ref = collect.Doc(subject.ID) 356 if s, err := ref.Get(ctx); err == nil { 357 return nil, xerrors.Errorf("already exists [%v]: %#v", subject.ID, s) 358 } 359 } 360 361 if err := repo.beforeInsert(ctx, subject); err != nil { 362 return nil, xerrors.Errorf("before insert error(%d) [%v]: %w", i, subject.ID, err) 363 } 364 365 batch.Set(ref, subject) 366 ids = append(ids, ref.ID) 367 i++ 368 if (i%500) == 0 && len(subjects) != i { 369 batches = append(batches, batch) 370 batch = repo.firestoreClient.Batch() 371 } 372 } 373 batches = append(batches, batch) 374 375 for _, b := range batches { 376 if _, err := b.Commit(ctx); err != nil { 377 return nil, xerrors.Errorf("error in Commit method: %w", err) 378 } 379 } 380 381 return ids, nil 382 } 383 384 // UpdateMulti - bulk update of `LockMeta2` 385 func (repo *lockMeta2Repository) UpdateMulti(ctx context.Context, subjects []*LockMeta2) (er error) { 386 387 batches := make([]*firestore.WriteBatch, 0) 388 batch := repo.firestoreClient.Batch() 389 collect := repo.GetCollection() 390 391 for i, subject := range subjects { 392 ref := collect.Doc(subject.ID) 393 snapShot, err := ref.Get(ctx) 394 if err != nil { 395 if status.Code(err) == codes.NotFound { 396 return xerrors.Errorf("not found [%v]: %w", subject.ID, err) 397 } 398 return xerrors.Errorf("error in Get method [%v]: %w", subject.ID, err) 399 } 400 401 old := new(LockMeta2) 402 if err = snapShot.DataTo(&old); err != nil { 403 return xerrors.Errorf("error in DataTo method: %w", err) 404 } 405 406 if err := repo.beforeUpdate(ctx, old, subject); err != nil { 407 return xerrors.Errorf("before update error(%d) [%v]: %w", i, subject.ID, err) 408 } 409 410 batch.Set(ref, subject) 411 i++ 412 if (i%500) == 0 && len(subjects) != i { 413 batches = append(batches, batch) 414 batch = repo.firestoreClient.Batch() 415 } 416 } 417 batches = append(batches, batch) 418 419 for _, b := range batches { 420 if _, err := b.Commit(ctx); err != nil { 421 return xerrors.Errorf("error in Commit method: %w", err) 422 } 423 } 424 425 return nil 426 } 427 428 // DeleteMulti - bulk delete of `LockMeta2` 429 func (repo *lockMeta2Repository) DeleteMulti(ctx context.Context, subjects []*LockMeta2, opts ...DeleteOption) (er error) { 430 431 batches := make([]*firestore.WriteBatch, 0) 432 batch := repo.firestoreClient.Batch() 433 collect := repo.GetCollection() 434 435 for i, subject := range subjects { 436 ref := collect.Doc(subject.ID) 437 if _, err := ref.Get(ctx); err != nil { 438 if status.Code(err) == codes.NotFound { 439 return xerrors.Errorf("not found [%v]: %w", subject.ID, err) 440 } 441 return xerrors.Errorf("error in Get method [%v]: %w", subject.ID, err) 442 } 443 444 if err := repo.beforeDelete(ctx, subject, opts...); err != nil { 445 return xerrors.Errorf("before delete error(%d) [%v]: %w", i, subject.ID, err) 446 } 447 448 if len(opts) > 0 && opts[0].Mode == DeleteModeSoft { 449 t := time.Now() 450 subject.DeletedAt = &t 451 batch.Set(ref, subject) 452 } else { 453 batch.Delete(ref) 454 } 455 456 i++ 457 if (i%500) == 0 && len(subjects) != i { 458 batches = append(batches, batch) 459 batch = repo.firestoreClient.Batch() 460 } 461 } 462 batches = append(batches, batch) 463 464 for _, b := range batches { 465 if _, err := b.Commit(ctx); err != nil { 466 return xerrors.Errorf("error in Commit method: %w", err) 467 } 468 } 469 470 return nil 471 } 472 473 // DeleteMultiByIDs - delete `LockMeta2` in bulk by array of `LockMeta2.ID` 474 func (repo *lockMeta2Repository) DeleteMultiByIDs(ctx context.Context, ids []string, opts ...DeleteOption) (er error) { 475 subjects := make([]*LockMeta2, len(ids)) 476 477 opt := GetOption{} 478 if len(opts) > 0 { 479 opt.IncludeSoftDeleted = opts[0].Mode == DeleteModeHard 480 } 481 for i, id := range ids { 482 subject, err := repo.Get(ctx, id, opt) 483 if err != nil { 484 return xerrors.Errorf("error in Get method: %w", err) 485 } 486 subjects[i] = subject 487 } 488 489 return repo.DeleteMulti(ctx, subjects, opts...) 490 } 491 492 // SearchWithTx - search documents in transaction 493 func (repo *lockMeta2Repository) SearchWithTx(tx *firestore.Transaction, param *LockMeta2SearchParam, q *firestore.Query) ([]*LockMeta2, error) { 494 return repo.search(tx, param, q) 495 } 496 497 // SearchByParamWithTx - search documents by search param in transaction 498 func (repo *lockMeta2Repository) SearchByParamWithTx(tx *firestore.Transaction, param *LockMeta2SearchParam) ([]*LockMeta2, *PagingResult, error) { 499 return repo.searchByParam(tx, param) 500 } 501 502 // GetWithTx - get `LockMeta2` by `LockMeta2.ID` in transaction 503 func (repo *lockMeta2Repository) GetWithTx(tx *firestore.Transaction, id string, opts ...GetOption) (*LockMeta2, error) { 504 doc := repo.GetDocRef(id) 505 return repo.get(tx, doc, opts...) 506 } 507 508 // GetWithDocWithTx - get `LockMeta2` by *firestore.DocumentRef in transaction 509 func (repo *lockMeta2Repository) GetWithDocWithTx(tx *firestore.Transaction, doc *firestore.DocumentRef, opts ...GetOption) (*LockMeta2, error) { 510 return repo.get(tx, doc, opts...) 511 } 512 513 // InsertWithTx - insert of `LockMeta2` in transaction 514 func (repo *lockMeta2Repository) InsertWithTx(ctx context.Context, tx *firestore.Transaction, subject *LockMeta2) (_ string, err error) { 515 if err := repo.beforeInsert(context.WithValue(ctx, transactionInProgressKey{}, tx), subject); err != nil { 516 return "", xerrors.Errorf("before insert error: %w", err) 517 } 518 519 return repo.insert(tx, subject) 520 } 521 522 // UpdateWithTx - update of `LockMeta2` in transaction 523 func (repo *lockMeta2Repository) UpdateWithTx(ctx context.Context, tx *firestore.Transaction, subject *LockMeta2) (err error) { 524 if err := repo.beforeUpdate(context.WithValue(ctx, transactionInProgressKey{}, tx), nil, subject); err != nil { 525 return xerrors.Errorf("before update error: %w", err) 526 } 527 528 return repo.update(tx, subject) 529 } 530 531 // StrictUpdateWithTx - strict update of `LockMeta2` in transaction 532 func (repo *lockMeta2Repository) StrictUpdateWithTx(tx *firestore.Transaction, id string, param *LockMeta2UpdateParam, opts ...firestore.Precondition) error { 533 return repo.strictUpdate(tx, id, param, opts...) 534 } 535 536 // DeleteWithTx - delete of `LockMeta2` in transaction 537 func (repo *lockMeta2Repository) DeleteWithTx(ctx context.Context, tx *firestore.Transaction, subject *LockMeta2, opts ...DeleteOption) (err error) { 538 if err := repo.beforeDelete(context.WithValue(ctx, transactionInProgressKey{}, tx), subject, opts...); err != nil { 539 return xerrors.Errorf("before delete error: %w", err) 540 } 541 542 if len(opts) > 0 && opts[0].Mode == DeleteModeSoft { 543 t := time.Now() 544 subject.DeletedAt = &t 545 if err := repo.update(tx, subject); err != nil { 546 return xerrors.Errorf("error in update method: %w", err) 547 } 548 return nil 549 } 550 551 return repo.deleteByID(tx, subject.ID) 552 } 553 554 // DeleteByIDWithTx - delete `LockMeta2` by `LockMeta2.ID` in transaction 555 func (repo *lockMeta2Repository) DeleteByIDWithTx(ctx context.Context, tx *firestore.Transaction, id string, opts ...DeleteOption) (err error) { 556 subject, err := repo.Get(context.Background(), id) 557 if err != nil { 558 return xerrors.Errorf("error in Get method: %w", err) 559 } 560 561 if len(opts) > 0 && opts[0].Mode == DeleteModeSoft { 562 t := time.Now() 563 subject.DeletedAt = &t 564 if err := repo.update(tx, subject); err != nil { 565 return xerrors.Errorf("error in update method: %w", err) 566 } 567 return nil 568 } 569 570 if err := repo.beforeDelete(context.WithValue(ctx, transactionInProgressKey{}, tx), subject, opts...); err != nil { 571 return xerrors.Errorf("before delete error: %w", err) 572 } 573 574 return repo.deleteByID(tx, id) 575 } 576 577 // GetMultiWithTx - get `LockMeta2` in bulk by array of `LockMeta2.ID` in transaction 578 func (repo *lockMeta2Repository) GetMultiWithTx(tx *firestore.Transaction, ids []string, opts ...GetOption) ([]*LockMeta2, error) { 579 return repo.getMulti(tx, ids, opts...) 580 } 581 582 // InsertMultiWithTx - bulk insert of `LockMeta2` in transaction 583 func (repo *lockMeta2Repository) InsertMultiWithTx(ctx context.Context, tx *firestore.Transaction, subjects []*LockMeta2) (_ []string, er error) { 584 585 ids := make([]string, len(subjects)) 586 587 for i := range subjects { 588 if err := repo.beforeInsert(ctx, subjects[i]); err != nil { 589 return nil, xerrors.Errorf("before insert error(%d) [%v]: %w", i, subjects[i].ID, err) 590 } 591 592 id, err := repo.insert(tx, subjects[i]) 593 if err != nil { 594 return nil, xerrors.Errorf("error in insert method(%d) [%v]: %w", i, subjects[i].ID, err) 595 } 596 ids[i] = id 597 } 598 599 return ids, nil 600 } 601 602 // UpdateMultiWithTx - bulk update of `LockMeta2` in transaction 603 func (repo *lockMeta2Repository) UpdateMultiWithTx(ctx context.Context, tx *firestore.Transaction, subjects []*LockMeta2) (er error) { 604 ctx = context.WithValue(ctx, transactionInProgressKey{}, tx) 605 606 for i := range subjects { 607 if err := repo.beforeUpdate(ctx, nil, subjects[i]); err != nil { 608 return xerrors.Errorf("before update error(%d) [%v]: %w", i, subjects[i].ID, err) 609 } 610 } 611 612 for i := range subjects { 613 if err := repo.update(tx, subjects[i]); err != nil { 614 return xerrors.Errorf("error in update method(%d) [%v]: %w", i, subjects[i].ID, err) 615 } 616 } 617 618 return nil 619 } 620 621 // DeleteMultiWithTx - bulk delete of `LockMeta2` in transaction 622 func (repo *lockMeta2Repository) DeleteMultiWithTx(ctx context.Context, tx *firestore.Transaction, subjects []*LockMeta2, opts ...DeleteOption) (er error) { 623 624 t := time.Now() 625 var isHardDeleteMode bool 626 if len(opts) > 0 { 627 isHardDeleteMode = opts[0].Mode == DeleteModeHard 628 } 629 opt := GetOption{ 630 IncludeSoftDeleted: isHardDeleteMode, 631 } 632 for i := range subjects { 633 dr := repo.GetDocRef(subjects[i].ID) 634 if _, err := repo.get(context.Background(), dr, opt); err != nil { 635 if status.Code(err) == codes.NotFound { 636 return xerrors.Errorf("not found(%d) [%v]", i, subjects[i].ID) 637 } 638 return xerrors.Errorf("error in get method(%d) [%v]: %w", i, subjects[i].ID, err) 639 } 640 641 if err := repo.beforeDelete(context.WithValue(ctx, transactionInProgressKey{}, tx), subjects[i], opts...); err != nil { 642 return xerrors.Errorf("before delete error(%d) [%v]: %w", i, subjects[i].ID, err) 643 } 644 645 if !isHardDeleteMode { 646 subjects[i].DeletedAt = &t 647 if err := repo.update(tx, subjects[i]); err != nil { 648 return xerrors.Errorf("error in update method(%d) [%v]: %w", i, subjects[i].ID, err) 649 } 650 } 651 } 652 653 if len(opts) > 0 && opts[0].Mode == DeleteModeSoft { 654 return nil 655 } 656 657 for i := range subjects { 658 if err := repo.deleteByID(tx, subjects[i].ID); err != nil { 659 return xerrors.Errorf("error in delete method(%d) [%v]: %w", i, subjects[i].ID, err) 660 } 661 } 662 663 return nil 664 } 665 666 // DeleteMultiByIDWithTx - delete `LockMeta2` in bulk by array of `LockMeta2.ID` in transaction 667 func (repo *lockMeta2Repository) DeleteMultiByIDsWithTx(ctx context.Context, tx *firestore.Transaction, ids []string, opts ...DeleteOption) (er error) { 668 669 t := time.Now() 670 for i := range ids { 671 dr := repo.GetDocRef(ids[i]) 672 subject, err := repo.get(context.Background(), dr) 673 if err != nil { 674 if status.Code(err) == codes.NotFound { 675 return xerrors.Errorf("not found(%d) [%v]", i, ids[i]) 676 } 677 return xerrors.Errorf("error in get method(%d) [%v]: %w", i, ids[i], err) 678 } 679 680 if err := repo.beforeDelete(context.WithValue(ctx, transactionInProgressKey{}, tx), subject, opts...); err != nil { 681 return xerrors.Errorf("before delete error(%d) [%v]: %w", i, subject.ID, err) 682 } 683 684 if len(opts) > 0 && opts[0].Mode == DeleteModeSoft { 685 subject.DeletedAt = &t 686 if err := repo.update(tx, subject); err != nil { 687 return xerrors.Errorf("error in update method(%d) [%v]: %w", i, ids[i], err) 688 } 689 } 690 } 691 692 if len(opts) > 0 && opts[0].Mode == DeleteModeSoft { 693 return nil 694 } 695 696 for i := range ids { 697 if err := repo.deleteByID(tx, ids[i]); err != nil { 698 return xerrors.Errorf("error in delete method(%d) [%v]: %w", i, ids[i], err) 699 } 700 } 701 702 return nil 703 } 704 705 func (repo *lockMeta2Repository) get(v interface{}, doc *firestore.DocumentRef, opts ...GetOption) (*LockMeta2, error) { 706 var ( 707 snapShot *firestore.DocumentSnapshot 708 err error 709 ) 710 711 switch x := v.(type) { 712 case *firestore.Transaction: 713 snapShot, err = x.Get(doc) 714 case context.Context: 715 snapShot, err = doc.Get(x) 716 default: 717 return nil, xerrors.Errorf("invalid type: %v", x) 718 } 719 720 if err != nil { 721 if status.Code(err) == codes.NotFound { 722 return nil, ErrNotFound 723 } 724 return nil, xerrors.Errorf("error in Get method: %w", err) 725 } 726 727 subject := new(LockMeta2) 728 if err := snapShot.DataTo(&subject); err != nil { 729 return nil, xerrors.Errorf("error in DataTo method: %w", err) 730 } 731 732 if len(opts) == 0 || !opts[0].IncludeSoftDeleted { 733 if subject.DeletedAt != nil { 734 return nil, ErrAlreadyDeleted 735 } 736 } 737 subject.ID = snapShot.Ref.ID 738 739 return subject, nil 740 } 741 742 func (repo *lockMeta2Repository) getMulti(v interface{}, ids []string, opts ...GetOption) ([]*LockMeta2, error) { 743 var ( 744 snapShots []*firestore.DocumentSnapshot 745 err error 746 collect = repo.GetCollection() 747 drs = make([]*firestore.DocumentRef, len(ids)) 748 ) 749 750 for i, id := range ids { 751 ref := collect.Doc(id) 752 drs[i] = ref 753 } 754 755 switch x := v.(type) { 756 case *firestore.Transaction: 757 snapShots, err = x.GetAll(drs) 758 case context.Context: 759 snapShots, err = repo.firestoreClient.GetAll(x, drs) 760 default: 761 return nil, xerrors.Errorf("invalid type: %v", v) 762 } 763 764 if err != nil { 765 return nil, xerrors.Errorf("error in GetAll method: %w", err) 766 } 767 768 subjects := make([]*LockMeta2, 0, len(ids)) 769 mErr := NewMultiErrors() 770 for i, snapShot := range snapShots { 771 if !snapShot.Exists() { 772 mErr = append(mErr, NewMultiError(i, ErrNotFound)) 773 continue 774 } 775 776 subject := new(LockMeta2) 777 if err = snapShot.DataTo(&subject); err != nil { 778 return nil, xerrors.Errorf("error in DataTo method: %w", err) 779 } 780 781 if len(opts) == 0 || !opts[0].IncludeSoftDeleted { 782 if subject.DeletedAt != nil { 783 mErr = append(mErr, NewMultiError(i, ErrLogicallyDeletedData)) 784 continue 785 } 786 } 787 subject.ID = snapShot.Ref.ID 788 subjects = append(subjects, subject) 789 } 790 791 if len(mErr) == 0 { 792 return subjects, nil 793 } 794 795 return subjects, mErr 796 } 797 798 func (repo *lockMeta2Repository) insert(v interface{}, subject *LockMeta2) (string, error) { 799 var ( 800 dr = repo.GetCollection().NewDoc() 801 err error 802 ) 803 804 switch x := v.(type) { 805 case *firestore.Transaction: 806 err = x.Create(dr, subject) 807 case context.Context: 808 _, err = dr.Create(x, subject) 809 default: 810 return "", xerrors.Errorf("invalid type: %v", v) 811 } 812 813 if err != nil { 814 if status.Code(err) == codes.AlreadyExists { 815 return "", xerrors.Errorf("error in Create method: err=%+v: %w", err, ErrAlreadyExists) 816 } 817 return "", xerrors.Errorf("error in Create method: %w", err) 818 } 819 820 subject.ID = dr.ID 821 822 return dr.ID, nil 823 } 824 825 func (repo *lockMeta2Repository) update(v interface{}, subject *LockMeta2) error { 826 var ( 827 dr = repo.GetDocRef(subject.ID) 828 err error 829 ) 830 831 switch x := v.(type) { 832 case *firestore.Transaction: 833 err = x.Set(dr, subject) 834 case context.Context: 835 _, err = dr.Set(x, subject) 836 default: 837 return xerrors.Errorf("invalid type: %v", v) 838 } 839 840 if err != nil { 841 return xerrors.Errorf("error in Set method: %w", err) 842 } 843 844 return nil 845 } 846 847 func (repo *lockMeta2Repository) strictUpdate(v interface{}, id string, param *LockMeta2UpdateParam, opts ...firestore.Precondition) error { 848 var ( 849 dr = repo.GetDocRef(id) 850 err error 851 ) 852 853 repo.setMetaWithStrictUpdate(param) 854 855 updates := updater(LockMeta2{}, param) 856 857 switch x := v.(type) { 858 case *firestore.Transaction: 859 err = x.Update(dr, updates, opts...) 860 case context.Context: 861 _, err = dr.Update(x, updates, opts...) 862 default: 863 return xerrors.Errorf("invalid type: %v", v) 864 } 865 866 if err != nil { 867 return xerrors.Errorf("error in Update method: %w", err) 868 } 869 870 return nil 871 } 872 873 func (repo *lockMeta2Repository) deleteByID(v interface{}, id string) error { 874 dr := repo.GetDocRef(id) 875 var err error 876 877 switch x := v.(type) { 878 case *firestore.Transaction: 879 err = x.Delete(dr, firestore.Exists) 880 case context.Context: 881 _, err = dr.Delete(x, firestore.Exists) 882 default: 883 return xerrors.Errorf("invalid type: %v", v) 884 } 885 886 if err != nil { 887 return xerrors.Errorf("error in Delete method: %w", err) 888 } 889 890 return nil 891 } 892 893 func (repo *lockMeta2Repository) runQuery(v interface{}, query firestore.Query) ([]*LockMeta2, error) { 894 var iter *firestore.DocumentIterator 895 896 switch x := v.(type) { 897 case *firestore.Transaction: 898 iter = x.Documents(query) 899 case context.Context: 900 iter = query.Documents(x) 901 default: 902 return nil, xerrors.Errorf("invalid type: %v", v) 903 } 904 905 defer iter.Stop() 906 907 subjects := make([]*LockMeta2, 0) 908 909 for { 910 doc, err := iter.Next() 911 if err == iterator.Done { 912 break 913 } 914 if err != nil { 915 return nil, xerrors.Errorf("error in Next method: %w", err) 916 } 917 918 subject := new(LockMeta2) 919 920 if err = doc.DataTo(&subject); err != nil { 921 return nil, xerrors.Errorf("error in DataTo method: %w", err) 922 } 923 924 subject.ID = doc.Ref.ID 925 subjects = append(subjects, subject) 926 } 927 928 return subjects, nil 929 } 930 931 // BUG(54m): there may be potential bugs 932 func (repo *lockMeta2Repository) searchByParam(v interface{}, param *LockMeta2SearchParam) ([]*LockMeta2, *PagingResult, error) { 933 query := func() firestore.Query { 934 return repo.GetCollection().Query 935 }() 936 if param.ID != nil { 937 for _, chain := range param.ID.QueryGroup { 938 var value interface{} 939 switch val := chain.Value.(type) { 940 case string: 941 value = repo.GetDocRef(val) 942 case []string: 943 docRefs := make([]*firestore.DocumentRef, len(val)) 944 for i := range val { 945 docRefs[i] = repo.GetDocRef(val[i]) 946 } 947 value = docRefs 948 default: 949 return nil, nil, xerrors.Errorf("document id can only be of type `string` and `[]string`. value: %#v", chain.Value) 950 } 951 query = query.Where(firestore.DocumentID, chain.Operator, value) 952 } 953 if direction := param.ID.OrderByDirection; direction > 0 { 954 query = query.OrderBy(firestore.DocumentID, direction) 955 query = param.ID.BuildCursorQuery(query) 956 } 957 } 958 if param.Text != nil { 959 for _, chain := range param.Text.QueryGroup { 960 query = query.Where("text", chain.Operator, chain.Value) 961 } 962 if direction := param.Text.OrderByDirection; direction > 0 { 963 query = query.OrderBy("text", direction) 964 query = param.Text.BuildCursorQuery(query) 965 } 966 } 967 if param.Flag != nil { 968 for _, chain := range param.Flag.QueryGroup { 969 items, ok := chain.Value.(map[string]float64) 970 if !ok { 971 continue 972 } 973 for key, value := range items { 974 query = query.WherePath(firestore.FieldPath{"flag", key}, chain.Operator, value) 975 } 976 } 977 } 978 if param.CreatedAt != nil { 979 for _, chain := range param.CreatedAt.QueryGroup { 980 query = query.Where("CreatedAt", chain.Operator, chain.Value) 981 } 982 if direction := param.CreatedAt.OrderByDirection; direction > 0 { 983 query = query.OrderBy("CreatedAt", direction) 984 query = param.CreatedAt.BuildCursorQuery(query) 985 } 986 } 987 if param.CreatedBy != nil { 988 for _, chain := range param.CreatedBy.QueryGroup { 989 query = query.Where("CreatedBy", chain.Operator, chain.Value) 990 } 991 if direction := param.CreatedBy.OrderByDirection; direction > 0 { 992 query = query.OrderBy("CreatedBy", direction) 993 query = param.CreatedBy.BuildCursorQuery(query) 994 } 995 } 996 if param.UpdatedAt != nil { 997 for _, chain := range param.UpdatedAt.QueryGroup { 998 query = query.Where("UpdatedAt", chain.Operator, chain.Value) 999 } 1000 if direction := param.UpdatedAt.OrderByDirection; direction > 0 { 1001 query = query.OrderBy("UpdatedAt", direction) 1002 query = param.UpdatedAt.BuildCursorQuery(query) 1003 } 1004 } 1005 if param.UpdatedBy != nil { 1006 for _, chain := range param.UpdatedBy.QueryGroup { 1007 query = query.Where("UpdatedBy", chain.Operator, chain.Value) 1008 } 1009 if direction := param.UpdatedBy.OrderByDirection; direction > 0 { 1010 query = query.OrderBy("UpdatedBy", direction) 1011 query = param.UpdatedBy.BuildCursorQuery(query) 1012 } 1013 } 1014 if param.DeletedAt != nil { 1015 for _, chain := range param.DeletedAt.QueryGroup { 1016 query = query.Where("DeletedAt", chain.Operator, chain.Value) 1017 } 1018 if direction := param.DeletedAt.OrderByDirection; direction > 0 { 1019 query = query.OrderBy("DeletedAt", direction) 1020 query = param.DeletedAt.BuildCursorQuery(query) 1021 } 1022 } 1023 if param.DeletedBy != nil { 1024 for _, chain := range param.DeletedBy.QueryGroup { 1025 query = query.Where("DeletedBy", chain.Operator, chain.Value) 1026 } 1027 if direction := param.DeletedBy.OrderByDirection; direction > 0 { 1028 query = query.OrderBy("DeletedBy", direction) 1029 query = param.DeletedBy.BuildCursorQuery(query) 1030 } 1031 } 1032 if param.Version != nil { 1033 for _, chain := range param.Version.QueryGroup { 1034 query = query.Where("Version", chain.Operator, chain.Value) 1035 } 1036 if direction := param.Version.OrderByDirection; direction > 0 { 1037 query = query.OrderBy("Version", direction) 1038 query = param.Version.BuildCursorQuery(query) 1039 } 1040 } 1041 if !param.IncludeSoftDeleted { 1042 query = query.Where("DeletedAt", OpTypeEqual, nil) 1043 } 1044 1045 limit := param.CursorLimit + 1 1046 1047 if param.CursorKey != "" { 1048 var ( 1049 ds *firestore.DocumentSnapshot 1050 err error 1051 ) 1052 switch x := v.(type) { 1053 case *firestore.Transaction: 1054 ds, err = x.Get(repo.GetDocRef(param.CursorKey)) 1055 case context.Context: 1056 ds, err = repo.GetDocRef(param.CursorKey).Get(x) 1057 default: 1058 return nil, nil, xerrors.Errorf("invalid x type: %v", v) 1059 } 1060 if err != nil { 1061 if status.Code(err) == codes.NotFound { 1062 return nil, nil, ErrNotFound 1063 } 1064 return nil, nil, xerrors.Errorf("error in Get method: %w", err) 1065 } 1066 query = query.StartAt(ds) 1067 } 1068 1069 if limit > 1 { 1070 query = query.Limit(limit) 1071 } 1072 1073 subjects, err := repo.runQuery(v, query) 1074 if err != nil { 1075 return nil, nil, xerrors.Errorf("error in runQuery method: %w", err) 1076 } 1077 1078 pagingResult := &PagingResult{ 1079 Length: len(subjects), 1080 } 1081 if limit > 1 && limit == pagingResult.Length { 1082 next := pagingResult.Length - 1 1083 pagingResult.NextCursorKey = subjects[next].ID 1084 subjects = subjects[:next] 1085 pagingResult.Length-- 1086 } 1087 1088 return subjects, pagingResult, nil 1089 } 1090 1091 func (repo *lockMeta2Repository) search(v interface{}, param *LockMeta2SearchParam, q *firestore.Query) ([]*LockMeta2, error) { 1092 if (param == nil && q == nil) || (param != nil && q != nil) { 1093 return nil, xerrors.New("either one should be nil") 1094 } 1095 1096 query := func() firestore.Query { 1097 if q != nil { 1098 return *q 1099 } 1100 return repo.GetCollection().Query 1101 }() 1102 1103 if q == nil { 1104 subjects, _, err := repo.searchByParam(v, param) 1105 if err != nil { 1106 return nil, xerrors.Errorf("error in searchByParam method: %w", err) 1107 } 1108 1109 return subjects, nil 1110 } 1111 1112 return repo.runQuery(v, query) 1113 }