# Crea el proyecto en Go


## Inicializa el proyecto

Comienza creando un proyecto en Go.

```console
$ mkdir testcontainers-go-demo
$ cd testcontainers-go-demo
$ go mod init github.com/testcontainers/testcontainers-go-demo
```

Esta guía utiliza el controlador de PostgreSQL [jackc/pgx](https://github.com/jackc/pgx) para interactuar con la base de datos Postgres y el [módulo de Postgres de testcontainers-go](https://golang.testcontainers.org/modules/postgres/) para levantar una instancia de Docker de Postgres para las pruebas. También utiliza [testify](https://github.com/stretchr/testify) para ejecutar múltiples pruebas como una suite y para escribir aserciones.

Instala estas dependencias:

```console
$ go get github.com/jackc/pgx/v5
$ go get github.com/testcontainers/testcontainers-go
$ go get github.com/testcontainers/testcontainers-go/modules/postgres
$ go get github.com/stretchr/testify
```

## Crea la estructura Customer

Crea un archivo `types.go` en el paquete `customer` y define la estructura `Customer` para modelar los detalles del cliente:

```go
package customer

type Customer struct {
	Id    int
	Name  string
	Email string
}
```

## Crea el Repositorio

A continuación, crea `customer/repo.go`, define la estructura `Repository` y agrega métodos para crear un cliente y obtener un cliente por correo electrónico:

```go
package customer

import (
	"context"
	"fmt"
	"os"

	"github.com/jackc/pgx/v5"
)

type Repository struct {
	conn *pgx.Conn
}

func NewRepository(ctx context.Context, connStr string) (*Repository, error) {
	conn, err := pgx.Connect(ctx, connStr)
	if err != nil {
		_, _ = fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
		return nil, err
	}
	return &Repository{
		conn: conn,
	}, nil
}

func (r Repository) CreateCustomer(ctx context.Context, customer Customer) (Customer, error) {
	err := r.conn.QueryRow(ctx,
		"INSERT INTO customers (name, email) VALUES ($1, $2) RETURNING id",
		customer.Name, customer.Email).Scan(&customer.Id)
	return customer, err
}

func (r Repository) GetCustomerByEmail(ctx context.Context, email string) (Customer, error) {
	var customer Customer
	query := "SELECT id, name, email FROM customers WHERE email = $1"
	err := r.conn.QueryRow(ctx, query, email).
		Scan(&customer.Id, &customer.Name, &customer.Email)
	if err != nil {
		return Customer{}, err
	}
	return customer, nil
}
```

Esto es lo que hace el código:

- `Repository` contiene un `*pgx.Conn` para realizar operaciones en la base de datos.
- `NewRepository(connStr)` toma una cadena de conexión a la base de datos e inicializa un `Repository`.
- `CreateCustomer()` y `GetCustomerByEmail()` son métodos en el receptor de `Repository` que insertan y consultan registros de clientes.

