Skip to content

Repositories

Derevtsov Konstantin edited this page Jul 10, 2020 · 6 revisions

The repository provides an abstraction on a specific database. Besides that, to provide a persistence ignorance principle, this abstraction must be designed like any other container that using in programming languages. Let's look at an example with standard GO container - slice:

// create user
user := &User{age: 27}
// create container for users - slice
userSlice := make([]*User)
// put user into container
userSlice = append(userSlice, user)
// get user from container
user = userSlice[0]
// update user
user.age = 28

D3 provide same interface, but for database:

// create user
user := &User{age: 27}
// create container for users repository
userRepository, err := d3orm.MakeRepository((*User)(nil))
// put user into container
userRepository.Persists(ctx, user)
// get user from container
user, err = userRepository.FindOne(userRepository.Select().AndWhere("id", "=", 1))
// update user
user.age = 28
// and finnally: synchronize changes with database
orm.Session(ctx).Flush()

Creating repository

For creating entity repository use Orm.MakeRepository method:

userRepository, err := d3orm.MakeRepository((*User)(nil))
if err != nil {
   return err
}

Fetching entities

For fetch entities from database use repository.FindOne or FindAll methods. FindOne return first entity from the result, FindAll return *Collection of entities. For define selection use instance of query.Query, you can create it by repository.Select method.

query := userRepository.Select().AndWhere("age", ">", 18)

adultUser, err := userRepository.FindOne(ctx, query)
if errors.Is(err, orm.ErrEntityNotFound) {
    fmt.Println("adult user not found")
}

adultUsers, err := userRepository.FindAll(ctx, query)
fmt.Printf("found %d users", adultUsers.Count())

Saving new entities and deleting

If you create a new entity and want to save it the database use repository.Persists method. For delete existing entity - use repository.Delete method. Note that all changes will apply after session.Flush is calling.

user := &User{age: 27}
userRepository.Persists(ctx, user)

// flush generate insert query
orm.Session(ctx).Flush()

userRepository.Delete(ctx, user)

// flush generate delete query
orm.Session(ctx).Flush()

user2 := &User{age: 28}
userRepository.Persists(ctx, user2)
userRepository.Delete(ctx, user2)

// no new query generated
orm.Session(ctx).Flush()
Clone this wiki locally