#!/usr/bin/perl
$|=1;$N=shift||100;$M=int(3.3*$N)
;$t[0]=2;$s[0]=2;sub z{$a=$r=00};
for( $k=1
;$k<$M ;$k++){$a=$r=0; };for(
$k=01; $k<$M;$k++){&z; for($i
=$N;$i >=0;$i--){$a=$t [$i]*(
$k)+$r ;$t[$i]=int($a% 10);${
r}=int ($a/10);}$K=($k <<1)+1
;&{z}; map{$a=$t[$_]+( 10)*((
$r));; ${t}[$_]=int($a /($K))
;${r}= int(($a)%($K))} (0..$N
);if(( $r>=(int(($K)/2 )))){;
;;${t} [$N]++}while($t [$N]>9
){${t} [$N]-=10;;$t[$N -1]++}
&z(); for($i=$N;$i>=0 ;$i--){
$a= ($t[$i]+$s[$i]+ $r);${s}
[$i]=int($a%10);$r=int($a/10)}if(
$k>$x+3){${x}=$k;;print"$s[$y++]"
;};}for($y..${N}){print"$s[$_]";}
if !something.OK() { // flipped
return errors.New("something not ok")
}
err := something.Do()
if err != nil { // flipped
return err
}
doWork()
log.Println("finished")
return nil
if something.OK() {
err := something.Do()
if err == nil {
doWork()
log.Println("finished")
return nil
} else {
return err
}
} else {
return errors.New("something not ok")
}
err := doSomething()
if err != nil {
return err
}
err := doSomething()
if err != nil {
log.Error("[functionName] Can't do something: "+ err.Error())
return err
}
Make it as simple as possible but not simpler -- Albert Einstein
go.mod go.sum config/ db/ project-tables.sql models/ init.go alias.go links.go alias/ repository.go repository/ gorm_alias.go gorm_alias_test.go pg_alias.go pg_alias_test.go usecase.go usecase/ alias_usecase.go alias_usecase_test.go link/ repository.go repository/ gorm_link.go gorm_link_test.go pg_link.go pg_link_test.go usecase.go usecase/ link_usecase.go link_usecase_test.go
package models
import "time"
// Alias structure holds the information about email aliases
type Alias struct {
ID int64 `json:"id"`
IDAccount int64 `json:"id_account"`
Email string `json:"email"`
DstEmail string `json:"dst_email"`
Class string `json:"class"`
Permanent bool `json:"permanent"`
DateCreation time.Time `json:"date_creation"`
Active bool `json:"active"`
DateEnd time.Time `json:"date_end"`
}
...
// Init initializes a connection to the database and returns a database handle and an error
func Init(l *logrus.Logger) (*gorm.DB, error) {
log = l
err := godotenv.Load(".env")
if err != nil {
log.Infof("INFO: unable to load .env file: %s", err)
return nil, err
}
db, err := gorm.Open("postgres", getConnectString())
// db, err := gorm.Open("sqlite3", "/tmp/project.db")
if err != nil {
return nil, err
}
log.Infof("Successfully connected to 'database' %s on host %s as user '%s'", name, host, user)
return db, err
}
...
package alias
import (
"mailcape/models"
)
// Repository represent the alias repository contract
type Repository interface {
GetAll() ([]*models.Alias, error)
GetByID(id int64) (*models.Alias, error)
GetByEmail(title string) (*models.Alias, error)
Update(a *models.Alias) error
Store(a *models.Alias) error
Delete(id int64) error
}
package models
package repository
import (
"mailcape/alias"
"mailcape/models"
"github.com/jinzhu/gorm"
)
type gormAliasRepository struct {
db *gorm.DB
}
// NewGormAliasRepository will create an object that represent the alias.Repository interface
func NewGormAliasRepository(db *gorm.DB) alias.Repository {
return &gormAliasRepository{db}
}
func (repo *gormAliasRepository) Delete(id int64) error {
alias := new(models.Alias)
alias.ID = id
if err := repo.db.First(&alias).Error; err != nil {
return err
}
if err := repo.db.Delete(alias).Error; err != nil {
return err
}
return nil
}
func (repo *gormAliasRepository) GetAll() ([]*models.Alias, error) {
var aliases []*models.Alias
if err := repo.db.Find(&aliases).Error; err != nil {
return nil, err
}
return aliases, nil
}
...
package alias
import (
"mailcape/models"
)
// Usecase for alias
type Usecase interface {
Delete(id int64) error
GetAll() ([]*models.Alias, error)
GetByID(int64) (*models.Alias, error)
GetByEmail(string) (*models.Alias, error)
Store(*models.Alias) error
Update(*models.Alias) error
Special(*models.Alias) error
}
package usecase
import (
"mailcape/alias"
"mailcape/models"
)
type aliasUsecase struct {
repo alias.Repository
}
// NewAliasUsecase returns a service to manipulate Alias
func NewAliasUsecase(r alias.Repository) alias.Usecase {
return &aliasUsecase{repo: r}
}
func (a *aliasUsecase) Delete(id int64) error {
return a.repo.Delete(id)
}
func (a *aliasUsecase) Special(id int64) error {
// Do whatever you wan using alias repository here
return nil
}
import (
aliasRepoF "mailcape/alias/repository"
aliasServiceF "mailcape/alias/usecase"
goalRepoF "mailcape/goal/repository"
goalServiceF "mailcape/goal/usecase"
objectiveRepoF "mailcape/objective/repository"
objectiveServiceF "mailcape/objective/usecase"
projectRepoF "mailcape/project/repository"
projectServiceF "mailcape/project/usecase"
"github.com/jinzhu/gorm"
"github.com/sirupsen/logrus"
)
// In my program/API
func Init(d *gorm.DB, l *logrus.Logger) {
db = d
log = l
aliasRepo := aliasRepoF.NewGormAliasRepository(db)
aliasService = aliasServiceF.NewAliasUsecase(aliasRepo)
goalRepo := goalRepoF.NewGormGoalRepository(db)
goalService = goalServiceF.NewGoalUsecase(goalRepo)
objectiveRepo := objectiveRepoF.NewGormObjectiveRepository(db)
objectiveService = objectiveServiceF.NewObjectiveUsecase(objectiveRepo)
projectRepo := projectRepoF.NewGormProjectRepository(db)
projectService = projectServiceF.NewProjectUsecase(projectRepo)
}
FROM golang:1.11 as builder # build stage
WORKDIR /api # setup the working directory
COPY go.* /api/ # install dependencies
RUN go mod download # in a specific layer (cache optimisation)
ADD . . # add source code
RUN CGO_ENABLED=0 GOOS=linux go build -a -o server ./cmd/daemon/main.go
# build the source
FROM alpine:3.7 # use a minimal alpine image
# FROM gcr.io/distroless/base # In prod use distroless
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
WORKDIR /root # set working directory
COPY --from=builder /api/server . # copy the binary from builder
EXPOSE 8080 # expose the port
CMD ["./server"] # run the binary
Questions ?