Created
January 15, 2024 08:44
-
-
Save ptflp/bb3cf825f6c701d02a1b93c58c65b734 to your computer and use it in GitHub Desktop.
task3.1.1.4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package dao | |
import ( | |
"context" | |
"database/sql" | |
"fmt" | |
"golang-course/test/dao/tabler" | |
"reflect" | |
"strings" | |
sq "github.com/Masterminds/squirrel" | |
"github.com/jmoiron/sqlx" | |
) | |
//go:generate mockgen -source=./sql_adapter.go -destination=../../mock/adapter_mock.go -package=mock | |
type IfaceDAO interface { | |
BuildSelect(tableName string, condition Condition, fields ...string) (string, []interface{}, error) | |
Create(ctx context.Context, entity tabler.Tabler, opts ...interface{}) error | |
List(ctx context.Context, dest interface{}, table tabler.Tabler, condition Condition, opts ...interface{}) error | |
Update(ctx context.Context, entity tabler.Tabler, condition Condition, opts ...interface{}) error | |
} | |
type Condition struct { | |
Equal map[string]interface{} | |
NotEqual map[string]interface{} | |
Order []*Order | |
LimitOffset *LimitOffset | |
ForUpdate bool | |
Upsert bool | |
} | |
type Order struct { | |
Field string | |
Asc bool | |
} | |
type LimitOffset struct { | |
Offset int64 | |
Limit int64 | |
} | |
type DAO struct { | |
db *sqlx.DB | |
sqlBuilder sq.StatementBuilderType | |
} | |
func NewDAO(db *sqlx.DB) IfaceDAO { | |
builder := sq.StatementBuilder.PlaceholderFormat(sq.Dollar) | |
return &DAO{db: db, sqlBuilder: builder} | |
} | |
func (d *DAO) BuildSelect(tableName string, condition Condition, fields ...string) (string, []interface{}, error) { | |
} | |
func filterByTag(tag string, tvalue string) func(fields *[]reflect.StructField) { | |
return tabler.FilterByTags(map[string]func(value string) bool{ | |
tag: func(value string) bool { | |
return strings.Contains(value, tvalue) | |
}, | |
}) | |
} | |
func (d *DAO) Create(ctx context.Context, entity tabler.Tabler, opts ...interface{}) error { | |
} | |
func (d *DAO) List(ctx context.Context, dest interface{}, table tabler.Tabler, condition Condition, opts ...interface{}) error { | |
} | |
func (d *DAO) Update(ctx context.Context, entity tabler.Tabler, condition Condition, opts ...interface{}) error { | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"database/sql" | |
"github.com/brianvoe/gofakeit/v6" | |
"github.com/jmoiron/sqlx" | |
_ "github.com/mattn/go-sqlite3" | |
"golang-course/test/dao/dao" | |
"golang-course/test/dao/migrator" | |
) | |
type User struct { | |
ID int `db:"id" db_type:"SERIAL PRIMARY KEY"` | |
FirstName string `db:"first_name" db_type:"VARCHAR(100)"` | |
LastName string `db:"last_name" db_type:"VARCHAR(100)"` | |
Username string `db:"username" db_type:"VARCHAR(100)"` | |
Email string `db:"email" db_type:"VARCHAR(100)"` | |
Address string `db:"address" db_type:"VARCHAR(100)"` | |
Status int `db:"status" db_type:"INT"` | |
DeletedAt string `db:"deleted_at" db_type:"VARCHAR(100)"` | |
} | |
func (u User) TableName() string { | |
return "users" | |
} | |
func main() { | |
db, err := sql.Open("sqlite3", "mydao.db") | |
if err != nil { | |
panic(err) | |
} | |
dbx := sqlx.NewDb(db, "sqlite3") | |
d := dao.NewDAO(dbx) | |
var generator migrator.SQLiteGenerator | |
m := migrator.NewMigrator(db, &generator) | |
err = m.Migrate(&User{}) | |
if err != nil { | |
panic(err) | |
} | |
for i := 0; i < 100; i++ { | |
user := GenerateFakeUser() | |
err = d.Create(context.Background(), &user) | |
} | |
users := make([]User, 1) | |
err = d.List(context.Background(), &users, &users[0], dao.Condition{ | |
LimitOffset: &dao.LimitOffset{ | |
Offset: 0, | |
Limit: 3, | |
}, | |
Equal: map[string]interface{}{ | |
"first_name": "Vilma", | |
}, | |
}) | |
if err != nil { | |
panic(err) | |
} | |
for _, user := range users { | |
println(user.FirstName) | |
} | |
} | |
func GenerateFakeUser() User { | |
return User{ | |
ID: gofakeit.Number(1000, 9999), | |
FirstName: gofakeit.FirstName(), | |
LastName: gofakeit.LastName(), | |
Email: gofakeit.Email(), | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package migrator | |
import ( | |
"database/sql" | |
"golang-course/test/dao/tabler" | |
"golang.org/x/sync/errgroup" | |
) | |
type Migratorer interface { | |
Migrate(tables ...func(tabler tabler.Tabler)) error | |
} | |
type Migrator struct { | |
db *sql.DB | |
sqlGenerator SQLGenerator | |
} | |
func NewMigrator(db *sql.DB, sqlGenerator SQLGenerator) *Migrator { | |
return &Migrator{ | |
db: db, | |
sqlGenerator: sqlGenerator, | |
} | |
} | |
func (m *Migrator) Migrate(tables ...tabler.Tabler) error { | |
var errGroup errgroup.Group | |
for _, table := range tables { | |
createSQL := m.sqlGenerator.CreateTableSQL(table) | |
errGroup.Go(func() error { | |
_, err := m.db.Exec(createSQL) | |
return err | |
}) | |
} | |
return errGroup.Wait() | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package migrator | |
import ( | |
"fmt" | |
"golang-course/test/dao/tabler" | |
"reflect" | |
"strings" | |
) | |
type SQLGenerator interface { | |
CreateTableSQL(table tabler.Tabler) string | |
} | |
type SQLiteGenerator struct{} | |
func (sg *SQLiteGenerator) CreateTableSQL(table tabler.Tabler) string { | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tabler | |
import ( | |
"reflect" | |
) | |
type Tabler interface { | |
TableName() string | |
} | |
type StructInfo struct { | |
Fields []string | |
Pointers []interface{} | |
} | |
func GetStructInfo(u interface{}, args ...func(*[]reflect.StructField)) StructInfo { | |
val := reflect.ValueOf(u).Elem() | |
var structFields []reflect.StructField | |
for i := 0; i < val.NumField(); i++ { | |
structFields = append(structFields, val.Type().Field(i)) | |
} | |
for i := range args { | |
if args[i] == nil { | |
continue | |
} | |
args[i](&structFields) | |
} | |
var res StructInfo | |
for _, field := range structFields { | |
valueField := val.FieldByName(field.Name) | |
res.Pointers = append(res.Pointers, valueField.Addr().Interface()) | |
res.Fields = append(res.Fields, field.Tag.Get("db")) | |
} | |
return res | |
} | |
func FilterByFields(fields ...int) func(fields *[]reflect.StructField) { | |
return func(fs *[]reflect.StructField) { | |
} | |
} | |
func FilterByTags(tags map[string]func(value string) bool) func(fields *[]reflect.StructField) { | |
return func(fields *[]reflect.StructField) { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment