Skip to content

Commit

Permalink
Feat/support custom type (#16)
Browse files Browse the repository at this point in the history
* feat: add GenCustomType

* feat: support custom type

* test: test custom type

* refactor: helpers structure

* refactor: renaming

---------

Co-authored-by: Eyo Chen <[email protected]>
  • Loading branch information
eyo-chen and Eyo Chen authored Aug 4, 2024
1 parent edc99bf commit b063078
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 127 deletions.
8 changes: 7 additions & 1 deletion db/db.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package db

import "context"
import (
"context"
"reflect"
)

// Database is responsible for inserting data into the database
type Database interface {
Expand All @@ -9,6 +12,9 @@ type Database interface {

// insertList inserts a list of data into the database
InsertList(context.Context, InserListParams) ([]interface{}, error)

// GenCustomType generates a non-zero value for custom types
GenCustomType(reflect.Type) (interface{}, bool)
}

// InsertParams is a struct that holds the parameters for the Insert method
Expand Down
29 changes: 29 additions & 0 deletions db/gormf/gormf.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package gormf

import (
"context"
"reflect"
"time"

"github.com/eyo-chen/gofacto/db"
"gorm.io/datatypes"
"gorm.io/gorm"
)

Expand Down Expand Up @@ -38,3 +41,29 @@ func (c *config) InsertList(ctx context.Context, params db.InserListParams) ([]i

return params.Values, nil
}

func (c *config) GenCustomType(t reflect.Type) (interface{}, bool) {
// Check if the type is a pointer
if t.Kind() == reflect.Ptr {
v, ok := c.GenCustomType(t.Elem())
if !ok {
return nil, false
}

ptr := reflect.New(reflect.TypeOf(v))
ptr.Elem().Set(reflect.ValueOf(v))
return ptr.Interface(), true
}

// Handle specific types
switch t.String() {
case jsonType:
return datatypes.JSON([]byte(`{"test": "test"}`)), true
case dateType:
return datatypes.Date(time.Now()), true
case timeType:
return datatypes.NewTime(1, 2, 3, 0), true
default:
return nil, false
}
}
32 changes: 19 additions & 13 deletions db/gormf/gormf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"
"time"

"gorm.io/datatypes"
"gorm.io/driver/mysql"
"gorm.io/gorm"

Expand Down Expand Up @@ -36,22 +37,27 @@ type Author struct {
WebsiteURL *string
FanCount *int64
ProfilePicture []byte
BornTime datatypes.Time
BornTime1 *datatypes.Time
}

type Book struct {
ID int64
AuthorID int64 `gofacto:"Author,authors"`
Title string
ISBN *string
PublicationDate *time.Time
Genre *string
Price *float64
PageCount *int32
Description *string
InStock bool
CoverImage []byte
CreatedAt time.Time
UpdatedAt time.Time
ID int64
AuthorID int64 `gofacto:"Author,authors"`
Title string
ISBN *string
PublicationDate datatypes.Date
PublicationDate1 *datatypes.Date
Genre *string
Price *float64
PageCount *int32
Description *string
InStock bool
CoverImage []byte
Data datatypes.JSON
Data1 *datatypes.JSON
CreatedAt time.Time
UpdatedAt time.Time
}

type testingSuite struct {
Expand Down
9 changes: 7 additions & 2 deletions db/gormf/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ CREATE TABLE IF NOT EXISTS authors (
email VARCHAR(100) UNIQUE,
biography TEXT,
is_active BOOLEAN DEFAULT TRUE,
rating DECIMAL(3,2),
rating DECIMAL(4,2),
books_written INT UNSIGNED,
last_publication_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
website_url VARCHAR(255),
fan_count BIGINT UNSIGNED,
profile_picture BLOB
profile_picture BLOB,
born_time TIME,
born_time1 TIME
);

CREATE TABLE IF NOT EXISTS books (
Expand All @@ -21,12 +23,15 @@ CREATE TABLE IF NOT EXISTS books (
title VARCHAR(255) NOT NULL,
isbn CHAR(13) UNIQUE,
publication_date DATE,
publication_date1 DATE,
genre ENUM('Fiction', 'Non-Fiction', 'Science', 'History', 'Biography', 'Other'),
price DECIMAL(10,2),
page_count SMALLINT UNSIGNED,
description TEXT,
in_stock BOOLEAN DEFAULT TRUE,
cover_image MEDIUMBLOB,
data JSON,
data1 JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (author_id) REFERENCES authors(id) ON DELETE SET NULL
Expand Down
12 changes: 12 additions & 0 deletions db/gormf/type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package gormf

var (
// json is the string representation of datatypes.JSON
jsonType = "datatypes.JSON"

// date is the string representation of datatypes.Date
dateType = "datatypes.Date"

// time is the string representation of datatypes.Time
timeType = "datatypes.Time"
)
4 changes: 4 additions & 0 deletions db/mongof/mongof.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ func (c *config) InsertList(ctx context.Context, params db.InserListParams) ([]i
return params.Values, nil
}

func (c *config) GenCustomType(t reflect.Type) (interface{}, bool) {
return nil, false
}

// setIDField sets the ID field of the value to the given ID
func setIDField(val interface{}, id primitive.ObjectID) {
v := reflect.ValueOf(val).Elem().FieldByName("ID")
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ require (
golang.org/x/text v0.16.0 // indirect
golang.org/x/tools v0.23.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gorm.io/datatypes v1.2.1 // indirect
gorm.io/driver/mysql v1.5.7 // indirect
gorm.io/gorm v1.25.11 // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/datatypes v1.2.1 h1:r+g0bk4LPCW2v4+Ls7aeNgGme7JYdNDQ2VtvlNUfBh0=
gorm.io/datatypes v1.2.1/go.mod h1:hYK6OTb/1x+m96PgoZZq10UXJ6RvEBb9kRDQ2yyhzGs=
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
Expand Down
14 changes: 7 additions & 7 deletions gofacto.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (f *Factory[T]) Build(ctx context.Context) *builder[T] {
}

if f.isSetZeroValue {
setNonZeroValues(f.index, &v, f.ignoreFields)
f.setNonZeroValues(&v)
}

f.index++
Expand Down Expand Up @@ -181,7 +181,7 @@ func (f *Factory[T]) BuildList(ctx context.Context, n int) *builderList[T] {
}

if f.isSetZeroValue {
setNonZeroValues(f.index, &v, f.ignoreFields)
f.setNonZeroValues(&v)
}

list[i] = &v
Expand Down Expand Up @@ -458,7 +458,7 @@ func (b *builder[T]) WithOne(v interface{}, ignoreFields ...string) *builder[T]
b.f.tagToInfo = t
}

if err := setAssValue(v, b.f.tagToInfo, b.f.index, "WithOne", ignoreFields); err != nil {
if err := b.f.setAssValue(v); err != nil {
b.errors = append(b.errors, err)
return b
}
Expand All @@ -485,7 +485,7 @@ func (b *builderList[T]) WithOne(v interface{}, ignoreFields ...string) *builder
b.f.tagToInfo = t
}

if err := setAssValue(v, b.f.tagToInfo, b.f.index, "WithOne", ignoreFields); err != nil {
if err := b.f.setAssValue(v); err != nil {
b.errors = append(b.errors, err)
return b
}
Expand Down Expand Up @@ -514,7 +514,7 @@ func (b *builderList[T]) WithMany(values []interface{}, ignoreFields ...string)

var curValName string
for _, v := range values {
if err := setAssValue(v, b.f.tagToInfo, b.f.index, "WithMany", ignoreFields); err != nil {
if err := b.f.setAssValue(v); err != nil {
b.errors = append(b.errors, err)
return b
}
Expand All @@ -539,7 +539,7 @@ func (b *builderList[T]) WithMany(values []interface{}, ignoreFields ...string)
// setAss sets and inserts the associations
func (b *builder[T]) setAss() error {
// insert the associations
if err := insertAss(b.ctx, b.f.db, b.f.associations, b.f.tagToInfo); err != nil {
if err := b.f.insertAss(b.ctx); err != nil {
return err
}

Expand All @@ -563,7 +563,7 @@ func (b *builder[T]) setAss() error {
// setAss sets and inserts the associations
func (b *builderList[T]) setAss() error {
// insert the associations
if err := insertAss(b.ctx, b.f.db, b.f.associations, b.f.tagToInfo); err != nil {
if err := b.f.insertAss(b.ctx); err != nil {
return err
}

Expand Down
Loading

0 comments on commit b063078

Please sign in to comment.