gofactory

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 15, 2021 License: LGPL-3.0 Imports: 8 Imported by: 1

README

gogo-factory

gogo-factory is a fixtures replacement with a clear definition syntax, which inspired by factory-go and factory_bot.

Install

Install go-factory library
go get -u github.com/vx416/gogo-factory
Install factory generator
go get -u github.com/vx416/gogo-factory/cmd/factorygen
usage
factorygen -i=input_directory -s=User,Product -o=output_directory -p

Getting Started

Defining Factories

This section introduce how to define a basic fixture factory. This Employee struct is sample struct for this section.

type Gender int8

const (
  Male Gender = iota+1
  Female
)

type Employee struct {
  ID          int64
  Name        string  
  Gender      Gender  
  Age         *int32  
  Phone       string  
  Salary      float64
  CreatedAt   time.Time
  UpdatedAt   sql.NullTime
}
Provide initial object

The first argument of factory construction is initial object. The built object from factory is always a pointer.

var EmployeeFactory = factory.New(
  &Employee{},
)

employee := EmployeeFactory.MustBuild().(*Employee)

The initial object can be used to setup initial fields.

var EmployeeFactory = factory.New(
  &Employee{Name: "david"},
)

employee := EmployeeFactory.MustBuild().(*Employee)
Assign value to field

The rest of arguments of factory construction is slice of Attributer which is used to assign value to object's field, there are some helper functions to construct different types of Attributer. The Attributer construction require three arguments, fieldName, genFunc, and colName.

  • fieldName: Assigned field's name

  • genFunc: Value generated function

  • colName: Column name in database

types of Attributes: Int, String, Uint, Time, Bytes, Bool Inteface


var (
  id = 0
  idGenFunc = func() int {
    id++
    return id
  }
)


var EmployeeFactory = factory.New(
  &Employee{},
  attr.Int("ID", idGenFunc, "id"),
  attr.Str("Name", func() string { return "test_user" }), // you can omit the colName argument, so that this field will not be considered as column
)

employee := EmployeeFactory.MustBuild().(*Employee)

Customizing each genFunc is annoying, therefore, gogo-factory provide built-in genFunc to generate value with different context:

generate random value
var EmployeeFactory = factory.New(
  &Employee{},
  attr.Int("ID", genutil.RandInt(1, 100)), // generate random int value between 1 to 100
  attr.Str("Name", genutil.RandName(3)), // generate name with gender flag (1:male, 2:female, 3:random)
  attr.Float("Salary", genutil.RandFloatSet(6.8, 5.2, 100.5, 10.5)), // generate random float value from given float set
  attr.Time("CreatedAt", genutil.RandTime(time.Now().Add(-10*24*time.Hour), time.Now())), // generate random time value between now()-10days to now()
)

employee := EmployeeFactory.MustBuild().(*Employee)
generate sequential value
var EmployeeFactory = factory.New(
  &Employee{},
  attr.Int("ID", genutil.SeqInt(1, 1)), // generate sequential int value start by 1 and delta 1
  attr.Str("Name", genutil.SeqStrSet({"david", "vic", "shelly")), // generate string value from given slice sequentially
  attr.Float("Salary", genutil.SeqFloat(6.8, 0.5)), // generate sequential float value start by 6.8 and delta 0.5
  attr.Time("CreatedAt", genutil.SeqTime(time.Now(), 30*time.Second)), // generate sequential time value start by now() and delta 30sec
)

employee := EmployeeFactory.MustBuild().(*Employee)
other generated functions
var EmployeeFactory = factory.New(
  &Employee{},
  attr.Int("ID", genutil.SeqInt(1, 1)),
  attr.Str("Name", genutil.FixInt("vic")), // generate fixed value
  attr.Float("Salary", genutil.SeqFloat(6.8, 0.5)),
  attr.Time("CreatedAt", genutil.Now()), // generate current time
  attr.Time("UpdatedAt", genutil.Now()), // support Scanner interface
  attr.Int("Age", genutil.SeqInt(18, 3)), // support pointer value
)

employee := EmployeeFactory.MustBuild().(*Employee)
Customize value with other fields

In some context, a value of fields which combined by other field(e.g ID) can debugger easier. The Attributer interface provide the Process method to process field.

var EmployeeFactory = factory.New(
  &Employee{},
  attr.Int("ID", genutil.SeqInt(1, 1)),
  attr.Str("Name", genutil.FixInt("vic")).Process(func(a attr.Attributer) error{
    e := a.GetObject().(*Employee)
    name := a.GetVal().(string)
    return a.SetVal(fmt.Sprintf("%s-%d", name, e.ID))
  }),
)

employee := EmployeeFactory.MustBuild().(*Employee)
Building Objects
Build one or many objects

gogo-factory can allow user to build one or many objects in one time, moreover, you can use Insert method to build a object meanwhile insert this object into database.

factory.Opt().SetDB(db, "sqlite3") // setup global sql.DB instance and database type

var EmployeeFactory = factory.New(
  &Employee{},
  attr.Int("ID", genutil.SeqInt(1, 1)),
  attr.Str("Name", genutil.SeqStrSet({"david", "vic", "shelly")),
  attr.Float("Salary", genutil.SeqFloat(6.8, 0.5)),
  attr.Time("CreatedAt", genutil.SeqTime(time.Now(), 30*time.Second)),
).Table("employees") // setup table name

// build a object
employeeData, err := EmployeeFactory.Build()
if err == nil{
  employee := employeeData.(*Employee)
}
employee := EmployeeFactory.MustBuild().(*Employee) // panic if error not nil

// build many objects
employeesData, err := EmployeeFactory.BuildN(10)
if err == nil{
  employees := employeeData.([]*Employee)
}
employees := EmployeeFactory.MustBuildN(10).([]*Employee) // panic if error not nil


// build and insert object
employee := EmployeeFactory.MustInsert().(*Employee) // panic if error not nil
employees := EmployeeFactory.MustInsertN(10).([]*Employee) // panic if error not nil
Setup building context

When you invoke factory's method, factory will return cloned factory object which wont affect old factory building context.

omit some attributes
// old factory object
employeeFactory := factory.New(
  &Employee{},
  attr.Int("ID", genutil.SeqInt(1, 1)),
  attr.Int("Gender", genutil.RandIntSet(1, 2)),
  attr.Time("UpdatedAt", genutil.RandTime(minTime, maxTime)),
)

// got cloned factory object
newFactory := employeeFactory.Omit("Gender")
e1 := employeeFactory.MustBuild().(*Employee)
e2 := newFactory.MustBuild().(*Employee)
assert.Equal(t, e1.ID, int64(1))
assert.NotZero(t, e1.Gender)

assert.Equal(t, e2.ID, int64(2))
assert.Zero(t, e2.Gender)
overwrite or append attributes
// old factory object
employeeFactory := factory.New(
  &Employee{},
  attr.Int("ID", genutil.SeqInt(1, 1)),
  attr.Int("Gender", genutil.RandIntSet(1, 2)),
)

// got cloned factory object
newFactory := employeeFactory.Attrs(
  attr.Int("Gender", genutil.FixInt(3)),
  attr.Int("Age", genutil.SeqInt(20, 5)),
)

e1 := employeeFactory.MustBuild().(*Employee)
assert.Equal(t, e1.ID, int64(1))
assert.Nil(t, e1.Age)
assert.Less(t, int(e1.Gender), 3)

e2 := newFactory.MustBuild().(*Employee)
assert.Equal(t, e2.ID, int64(2))
assert.NotNil(t, e2.Age)
assert.Equal(t, e2.Gender, Gender(3))
Factory Associations

gogo-factory support association between factories. You can combine objects and insert data across tables one time by building the factory's association.

Here are sample structs:

// domain <- 1:n -> specialty <- n:1- > employee <- m:m -> project
type Employee struct {
  ID                int64        `db:"id" gorm:"column:id"`
  Name              string       `db:"name" gorm:"column:name"`
  Gender            Gender       `db:"gender" gorm:"column:gender"`
  Age               *int32       `db:"age" gorm:"column:age"`
  Phone             string       `db:"phone" gorm:"column:phone"`
  Salary            float64      `db:"salary" gorm:"column:salary"`
  Specialty         *Specialty   `gorm:"-"`
  SecondSpecialties []*Specialty `gorm:"-"`
  Projects          []*Project   `gorm:"-"`
  CreatedAt         time.Time    `db:"created_at" gorm:"column:created_at"`
  UpdatedAt         sql.NullTime `db:"updated_at" gorm:"column:updated_at"`
}

type Project struct {
  ID        int64       `db:"id" gorm:"column:id"`
  Name      string      `db:"name" gorm:"column:name"`
  Employees []*Employee `gorm:"-"`
  Tasks     []*Task     `gorm:"-"`
  Deadline  time.Time   `db:"deadline" gorm:"column:deadline"`
}

type Task struct {
  ID        int64     `db:"id" gorm:"column:id"`
  Name      string    `db:"name" gorm:"column:name"`
  ProjectID int64     `db:"project_id" gorm:"column:project_id"`
  Deadline  time.Time `db:"deadline" gorm:"column:deadline"`
}

type Specialty struct {
  ID       int64         `db:"id" gorm:"column:id"`
  Name     string        `db:"name" gorm:"column:name"`
  OwnerID  sql.NullInt64 `db:"owner_id" gorm:"column:owner_id"`
  Domain   *Domain
  DomainID sql.NullInt64 `db:"domain_id" gorm:"column:domain_id"`
}

type Domain struct {
  ID   int64  `db:"id" gorm:"column:id"`
  Name string `db:"name" gorm:"column:name"`
}
BelongsTo association

To build association, we need to convert Factory object to Association object. This Association object is used to store association context information:

  • ReferField: the field referred by the foreign key
    • In the example, the specialties table has a foreign key (domain_id), which refers to the ID field of Domain struct.
  • ForeignKey: the name of foreign key in the table
    • In the example, the foreign key is domain_id in specialties table.
  • ForeignField: the field which represents the foreign key will be assigned by the ReferField
    • note: the ForeignField can be empty
var DomainFactory = factory.New(
  &Domain{},
  attr.Int("ID", genutil.SeqInt(1, 1), "id"),
  attr.Str("Name", genutil.RandAlph(10), "name"),
).Table("domains")

type SpecialtyExt struct {
  *factory.Factory
}

func (f *SpecialtyExt) BelongsToDomain(domainFactory *factory.Factory) *SpecialtyExt {
  domainAss := domainFactory.ToAssociation().ReferField("ID").ForeignKey("domain_id").ForeignField("DomainID")
  return &SpecialtyExt{f.BelongsTo("Domain", domainAss)} // use belongs to method will cloned a new factory
}

var SpecialtyFactory = &SpecialtyExt{
  factory.New(
    &Specialty{},
    attr.Int("ID", genutil.SeqInt(1, 1), "id"),
    attr.Str("Name", genutil.RandStrSet("design", "programming", "analysis", "management"), "name"),
  ).Table("specialties"),
}

spec := SpecialtyFactory.BelongsToDomain(DomainFactory).MustInsert().(*Specialty)
suite.Assert().NotZero(spec.ID)
suite.Assert().NotNil(spec.Domain)
suite.Assert().NotZero(spec.Domain.ID)
suite.Equal(spec.DomainID.Int64, spec.Domain.ID)
suite.Assert().NotEmpty(spec.Domain.Name)

specs := SpecialtyFactory.BelongsToDomain(DomainFactory).MustInsertN(5).([]*Specialty)
suite.Len(specs, 5)
-- MustInsert
INSERT INTO domains (id, name) VALUES (?, ?) [1 IPDZicTGXD]
INSERT INTO specialties (id, name, domain_id) VALUES (?, ?, ?) [1 analysis 1]
-- MustInsertN(5)
INSERT INTO domains (id, name) VALUES (?, ?) [2 oTMyziTclv]
INSERT INTO specialties (domain_id, id, name) VALUES (?, ?, ?) [2 2 programming]
INSERT INTO domains (id, name) VALUES (?, ?) [3 ATUrWrnfdY]
INSERT INTO specialties (name, domain_id, id) VALUES (?, ?, ?) [design 3 3]
INSERT INTO domains (name, id) VALUES (?, ?) [gOMxfdPSTz 4]
INSERT INTO specialties (domain_id, name, id) VALUES (?, ?, ?) [4 management 4]
INSERT INTO domains (id, name) VALUES (?, ?) [5 NsmgDRwbvP]
INSERT INTO specialties (name, id, domain_id) VALUES (?, ?, ?) [management 5 5]
INSERT INTO domains (id, name) VALUES (?, ?) [6 cdevwdAyKd]
INSERT INTO specialties (name, id, domain_id) VALUES (?, ?, ?) [analysis 6 6]
HasOne or HasMany association

HasOne or HasMany association information context:

  • ReferField: In the example, the employees table is the referred table whose referred column is id and field is ID.
  • ForeignKey: In the example, the specialties table has foreign key owner_id which refer to employees id.
  • ForeignField: In the example, the Specialty struct has OwnerID field which corresponds to foreign key (owner_id).
type EmployeeExt struct {
  *factory.Factory
}

func (f *EmployeeExt) HasOneSpecialty(spec *SpecialtyExt) *EmployeeExt {
  specAss := spec.ToAssociation().ReferField("ID").ForeignField("OwnerID").ForeignKey("owner_id")
  return &EmployeeExt{f.HasOne("Specialty", specAss)}
}

func (f *EmployeeExt) HasManySecondSpecialties(spec *SpecialtyExt, num int32) *EmployeeExt {
  specAss := spec.ToAssociation().ReferField("ID").ForeignField("OwnerID").ForeignKey("owner_id")
  return &EmployeeExt{f.HasMany("SecondSpecialties", specAss, num)}
}

var EmployeeFactory = &EmployeeExt{
  factory.New(
    &Employee{},
    attr.Int("ID", genutil.SeqInt(1, 1), "id"),
    attr.Str("Name", genutil.RandName(3), "name"),
    attr.Int("Gender", genutil.RandInt(1, 2), "gender"),
    attr.Int("Age", genutil.RandInt(18, 60), "age"),
    attr.Float("Salary", genutil.RandFloat(6.5, 12.8), "salary"),
    attr.Str("Phone", genutil.RandAlph(10), "phone"),
    attr.Time("CreatedAt", genutil.Now(), "created_at"),
  ).Table("employees"),
}

employee := EmployeeFactory.HasOneSpecialty(SpecialtyFactory).
  HasManySecondSpecialties(SpecialtyFactory, 5).MustInsert().(*Employee)
suite.Assert().NotZero(employee.ID)
suite.Assert().NotNil(employee.Specialty)
suite.Assert().Len(employee.SecondSpecialties, 5)
INSERT INTO employees (age, salary, phone, created_at, id, name, gender) VALUES (?, ?, ?, ?, ?, ?, ?) [32 11.275899307789922 psuhTzivdX 2020-11-15 14:20:40.076026 +0800 CST m=+0.079557615 1 Joshua, Robinson 1]
INSERT INTO specialties (owner_id, id, name) VALUES (?, ?, ?) [{8 true} 1 programming]
INSERT INTO specialties (id, name, owner_id) VALUES (?, ?, ?) [2 design {8 true}]
INSERT INTO specialties (id, name, owner_id) VALUES (?, ?, ?) [3 analysis {8 true}]
INSERT INTO specialties (owner_id, id, name) VALUES (?, ?, ?) [{8 true} 4 management]
INSERT INTO specialties (id, name, owner_id) VALUES (?, ?, ?) [5 programming {8 true}]
INSERT INTO specialties (owner_id, id, name) VALUES (?, ?, ?) [{8 true} 6 design]

The factory association can be connected, for example, Employee has many Specialty, and Specialty belongs to Domain.

specAndDomainFactory := SpecialtyFactory.BelongsToDomain(DomainFactory)
employee := EmployeeFactory.HasOneSpecialty(specAndDomainFactory).
  HasManySecondSpecialties(specAndDomainFactory, 5).MustInsert().(*Employee)
suite.Assert().NotZero(employee.ID)
suite.Assert().NotNil(employee.Specialty)
suite.Assert().NotNil(employee.Specialty.Domain)
INSERT INTO employees (name, gender, age, salary, phone, created_at, id) VALUES (?, ?, ?, ?, ?, ?, ?) [Joshua, Jackson 1 36 12.649925079901706 kyAOLjsSxk 2020-11-15 14:25:33.125297 +0800 CST m=+0.017510176 1]
INSERT INTO domains (id, name) VALUES (?, ?) [1 dNPiJWShix]
INSERT INTO specialties (owner_id, domain_id, id, name) VALUES (?, ?, ?, ?) [{1 true} 1 1 analysis]
INSERT INTO domains (name, id) VALUES (?, ?) [RWkktbtcwx 2]
INSERT INTO specialties (name, owner_id, domain_id, id) VALUES (?, ?, ?, ?) [programming {1 true} 2 2]
INSERT INTO domains (name, id) VALUES (?, ?) [rKfZiSNxLW 3]
INSERT INTO specialties (id, name, owner_id, domain_id) VALUES (?, ?, ?, ?) [3 analysis {1 true} 3]
INSERT INTO domains (name, id) VALUES (?, ?) [VQKSqGNrKA 4]
INSERT INTO specialties (id, name, owner_id, domain_id) VALUES (?, ?, ?, ?) [4 programming {1 true} 4]
INSERT INTO domains (name, id) VALUES (?, ?) [LnwDycoyXo 5]
INSERT INTO specialties (domain_id, id, name, owner_id) VALUES (?, ?, ?, ?) [5 5 programming {1 true}]
INSERT INTO domains (name, id) VALUES (?, ?) [DTHQGwCLXz 6]
INSERT INTO specialties (owner_id, id, name, domain_id) VALUES (?, ?, ?, ?) [{1 true} 6 analysis 6]
ManyToMany association

ManyToMany association is more complex, so it need more information:

  • JoinTable: The join table represent a table which link two tables. You can use Attributer to set column value (e.g id) for join table.
    • In the example, the join table is employees_projects which has employee_id and project_id as foreign keys.
  • ReferField: The field of current struct has value of foreign key in the join table.
    • In the example, the current struct Employee has ID field which corresponds to employee_id in join table.
  • ReferColumn: The column name of join table which corresponds to ReferField.
    • In the example, the ReferColumn will be employee_id.
  • ForeignField: The field of associated struct has value of foreign key in the join table.
    • In the example, the associated struct Project has ID field which corresponds to project_id in join table.
  • ForeignKey: The column name of join table which corresponds to ForeignField.
    • In the example, the ReferColumn will be project_id.
  • AssociatedField: The field of associated struct Project whose element is current struct Employee.
    • In the example, the AssociatedField will be Employees.
    • note: AssociatedField should be slice.
type EmployeeExt struct {
  *factory.Factory
}

func (f *EmployeeExt) HasManyProjects(prj *ProjectExt, num int32) *EmployeeExt {
  prjAss := prj.ToAssociation().ReferField("ID").ReferColumn("employee_id").
    ForeignField("ID").ForeignKey("project_id").AssociatedField("Employees").
    JoinTable("employees_projects", attr.Int("ID", genutil.SeqInt(1, 1), "id"))
  return &EmployeeExt{f.ManyToMany("Projects", prjAss, num)}
}


type ProjectExt struct {
  *factory.Factory
}

var ProjectFactory = &ProjectExt{
  factory.New(
    &Project{},
    attr.Int("ID", genutil.SeqInt(1, 1), "id")
    attr.Str("Name", genutil.RandUUID(), "name"),
    attr.Time("Deadline", genutil.SeqTime(time.Now(), 100*time.Hour), "deadline"),
  ).Table("projects"),
}


employee := EmployeeFactory.HasManyProjects(ProjectFactory, 2).MustInsert().(*Employee)
suite.Assert().NotZero(employee.ID)
suite.Assert().Len(employee.Projects, 2)
suite.Assert().Len(employee.Projects[0].Employees, 1)
suite.Assert().Len(employee.Projects[1].Employees, 1)
suite.Assert().Equal(employee.Projects[1].Employees[0].ID, employee.ID)
INSERT INTO employees (created_at, id, name, gender, age, salary, phone) VALUES (?, ?, ?, ?, ?, ?, ?) [2020-11-15 14:59:22.99355 +0800 CST m=+0.015319184 1 Zoey, Thomas 1 36 10.318368751716168 dUHjJKjLoV]
INSERT INTO projects (name, deadline, id) VALUES (?, ?, ?) [bb19d463-dabf-4afe-88e2-296d44a5f09f 2020-11-15 14:59:22.981192 +0800 CST m=+0.002961345 1]
INSERT INTO projects (id, name, deadline) VALUES (?, ?, ?) [2 a4dafce3-8e4b-4f34-a56c-2d30c79fcfb4 2020-11-19 18:59:22.981192 +0800 CST m=+360000.002961345]
INSERT INTO employees_projects (employee_id, project_id, id) VALUES (?, ?, ?) [1 1 1]
INSERT INTO employees_projects (employee_id, project_id, id) VALUES (?, ?, ?) [1 2 2]

Connect all association together.


type ProjectExt struct {
  *factory.Factory
}

func (f *ProjectExt) HasManyTasks(taskFactory *factory.Factory, num int32) *ProjectExt {
  taskAss := taskFactory.ToAssociation().ReferField("ID").ForeignKey("project_id").ForeignField("ProjectID")
  return &ProjectExt{f.HasMany("Tasks", taskAss, num)}
}

var TaskFactory = factory.New(
  &Task{},
  attr.Int("ID", genutil.SeqInt(1, 1), "id")
  attr.Str("Name", genutil.RandUUID(), "name"),
  attr.Time("Deadline", genutil.SeqTime(time.Now(), 100*time.Hour), "deadline"),
).Table("tasks")

spec := SpecialtyFactory.BelongsToDomain(DomainFactory)
proj := ProjectFactory.HasManyTasks(TaskFactory, 10)
employee := EmployeeFactory.HasOneSpecialty(spec).HasManySecondSpecialties(spec, 3).
  HasManyProjects(proj, 2).MustInsert().(*Employee)
suite.Assert().NotZero(employee.ID)
suite.Assert().Len(employee.Projects, 2)
suite.Assert().Equal(employee.Projects[1].Employees[0].ID, employee.ID)
suite.Assert().NotNil(employee.Specialty)
suite.Assert().NotNil(employee.Specialty.Domain)
suite.Assert().Len(employee.Projects[0].Tasks, 10)
INSERT INTO employees (name, gender, age, salary, phone, created_at, id) VALUES (?, ?, ?, ?, ?, ?, ?) [Isabella, Williams 2 54 12.323119013120419 VrfhHyrTAL 2020-11-15 15:35:45.777974 +0800 CST m=+0.014762944 1]
INSERT INTO domains (id, name) VALUES (?, ?) [1 aLvKjKUdXY]
INSERT INTO specialties (id, name, owner_id, domain_id) VALUES (?, ?, ?, ?) [1 design {1 true} 1]
INSERT INTO domains (id, name) VALUES (?, ?) [2 fCLOddJBBF]
INSERT INTO specialties (id, name, owner_id, domain_id) VALUES (?, ?, ?, ?) [2 design {1 true} 2]
INSERT INTO domains (id, name) VALUES (?, ?) [3 riivdoxaxJ]
INSERT INTO specialties (id, name, owner_id, domain_id) VALUES (?, ?, ?, ?) [3 programming {1 true} 3]
INSERT INTO domains (id, name) VALUES (?, ?) [4 QChCzKWQvs]
INSERT INTO specialties (id, name, owner_id, domain_id) VALUES (?, ?, ?, ?) [4 programming {1 true} 4]
INSERT INTO projects (deadline, id, name) VALUES (?, ?, ?) [2020-11-15 15:35:45.766096 +0800 CST m=+0.002885016 1 2f4a8e39-66d1-4cd4-a0cb-96d892a822a5]
INSERT INTO tasks (name, deadline, id, project_id) VALUES (?, ?, ?, ?) [cfa26a28-0e3d-48c0-9e6f-582d2abbb9be 2020-11-15 15:35:45.766097 +0800 CST m=+0.002886438 1 1]
INSERT INTO tasks (id, project_id, name, deadline) VALUES (?, ?, ?, ?) [2 1 c8b323c4-f66d-4071-be73-0409d04eeccd 2020-11-19 19:35:45.766097 +0800 CST m=+360000.002886438]
INSERT INTO tasks (project_id, name, deadline, id) VALUES (?, ?, ?, ?) [1 9446c004-f5c0-43f9-a8d0-5864cc86b357 2020-11-23 23:35:45.766097 +0800 CST m=+720000.002886438 3]
INSERT INTO tasks (name, deadline, id, project_id) VALUES (?, ?, ?, ?) [2b57a035-548f-4269-9cd9-001f2f523bbf 2020-11-28 03:35:45.766097 +0800 CST m=+1080000.002886438 4 1]
INSERT INTO tasks (deadline, id, project_id, name) VALUES (?, ?, ?, ?) [2020-12-02 07:35:45.766097 +0800 CST m=+1440000.002886438 5 1 4ee7b87e-430c-488b-b991-0918b1c59b12]
INSERT INTO tasks (project_id, name, deadline, id) VALUES (?, ?, ?, ?) [1 6f9b8921-1d0b-407b-85c9-08a6ce3a192a 2020-12-06 11:35:45.766097 +0800 CST m=+1800000.002886438 6]
INSERT INTO tasks (deadline, id, project_id, name) VALUES (?, ?, ?, ?) [2020-12-10 15:35:45.766097 +0800 CST m=+2160000.002886438 7 1 803f1d9e-66f5-4dfe-96d5-6bb385ef457c]
INSERT INTO tasks (name, deadline, id, project_id) VALUES (?, ?, ?, ?) [0b380cc1-513f-4c5e-b627-62d88b463ab5 2020-12-14 19:35:45.766097 +0800 CST m=+2520000.002886438 8 1]
INSERT INTO tasks (deadline, id, project_id, name) VALUES (?, ?, ?, ?) [2020-12-18 23:35:45.766097 +0800 CST m=+2880000.002886438 9 1 d9700d31-7c98-49d8-a0e9-1643d0b10fcc]
INSERT INTO tasks (project_id, name, deadline, id) VALUES (?, ?, ?, ?) [1 7f09ca4c-9bbd-4188-85d4-17db84097bbd 2020-12-23 03:35:45.766097 +0800 CST m=+3240000.002886438 10]
INSERT INTO projects (deadline, id, name) VALUES (?, ?, ?) [2020-11-19 19:35:45.766096 +0800 CST m=+360000.002885016 2 c014be25-9026-4d57-99e2-4d0d97245efa]
INSERT INTO tasks (id, project_id, name, deadline) VALUES (?, ?, ?, ?) [11 2 c578d2fc-03c2-48f7-b08b-e96fe09531a3 2020-12-27 07:35:45.766097 +0800 CST m=+3600000.002886438]
INSERT INTO tasks (id, project_id, name, deadline) VALUES (?, ?, ?, ?) [12 2 3eeafd4d-931e-4b59-bc9b-6e7cfd610bd9 2020-12-31 11:35:45.766097 +0800 CST m=+3960000.002886438]
INSERT INTO tasks (id, project_id, name, deadline) VALUES (?, ?, ?, ?) [13 2 74470827-2cda-4c30-a963-9a1d0bb4e253 2021-01-04 15:35:45.766097 +0800 CST m=+4320000.002886438]
INSERT INTO tasks (deadline, id, project_id, name) VALUES (?, ?, ?, ?) [2021-01-08 19:35:45.766097 +0800 CST m=+4680000.002886438 14 2 3e42ed58-1eee-4da4-a092-97c038c3a871]
INSERT INTO tasks (name, deadline, id, project_id) VALUES (?, ?, ?, ?) [4157556e-2fa6-448c-86ef-6ffe29789ddf 2021-01-12 23:35:45.766097 +0800 CST m=+5040000.002886438 15 2]
INSERT INTO tasks (id, project_id, name, deadline) VALUES (?, ?, ?, ?) [16 2 7d4e68ba-2037-41c1-a9b1-2f113aa701c3 2021-01-17 03:35:45.766097 +0800 CST m=+5400000.002886438]
INSERT INTO tasks (id, project_id, name, deadline) VALUES (?, ?, ?, ?) [17 2 034e05f9-b394-460f-a467-7ce9374b41e5 2021-01-21 07:35:45.766097 +0800 CST m=+5760000.002886438]
INSERT INTO tasks (project_id, name, deadline, id) VALUES (?, ?, ?, ?) [2 3675914a-09b5-423c-b575-77b109ee14ba 2021-01-25 11:35:45.766097 +0800 CST m=+6120000.002886438 18]
INSERT INTO tasks (deadline, id, project_id, name) VALUES (?, ?, ?, ?) [2021-01-29 15:35:45.766097 +0800 CST m=+6480000.002886438 19 2 2dc6f22e-8a79-4172-881a-ebf30eaf51a0]
INSERT INTO tasks (deadline, id, project_id, name) VALUES (?, ?, ?, ?) [2021-02-02 19:35:45.766097 +0800 CST m=+6840000.002886438 20 2 35eb35d7-0e23-4871-962a-dce0280388ae]
INSERT INTO employees_projects (employee_id, project_id, id) VALUES (?, ?, ?) [1 1 1]
INSERT INTO employees_projects (employee_id, project_id, id) VALUES (?, ?, ?) [1 2 2]

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DBTagProcess

func DBTagProcess(tagGetter TagGetter) string

DBTagProcess db tag process

func GormTagProcess

func GormTagProcess(tagGetter TagGetter) string

GormTagProcess gorm tag process

Types

type Association

type Association struct {
	// contains filtered or unexported fields
}

func (*Association) AssociatedField

func (as *Association) AssociatedField(asField string) *Association

func (*Association) FieldName

func (as *Association) FieldName(fieldName string) *Association

func (*Association) ForeignField

func (as *Association) ForeignField(foreignField string) *Association

func (*Association) ForeignKey

func (as *Association) ForeignKey(foreignKey string) *Association

func (*Association) JoinTable

func (as *Association) JoinTable(joinTableName string, attrs ...attr.Attributer) *Association

func (*Association) Num

func (as *Association) Num(num int32) *Association

func (*Association) ReferColumn

func (as *Association) ReferColumn(referCol string) *Association

func (*Association) ReferField

func (as *Association) ReferField(referField string) *Association

type AssociationType

type AssociationType int8
const (
	BelongsTo AssociationType = iota + 1
	HasMany
	HasOne
	ManyToMany
)

type Associations

type Associations struct {
	// contains filtered or unexported fields
}

func NewAssociations

func NewAssociations() *Associations

type Factory

type Factory struct {
	// contains filtered or unexported fields
}

func New

func New(obj interface{}, attrs ...attr.Attributer) *Factory

New construct a factory object

func (*Factory) Attrs

func (f *Factory) Attrs(attrs ...attr.Attributer) *Factory

Attrs replace object Attributer and return the new factory

func (*Factory) BelongsTo

func (f *Factory) BelongsTo(fieldName string, ass *Association) *Factory

func (*Factory) Build

func (f *Factory) Build() (interface{}, error)

func (*Factory) BuildN

func (f *Factory) BuildN(n int) (interface{}, error)

func (*Factory) ClearOmit

func (f *Factory) ClearOmit() *Factory

func (*Factory) Clone

func (f *Factory) Clone() *Factory

Clone clone a factory object

func (*Factory) HasMany

func (f *Factory) HasMany(fieldName string, ass *Association, num int32) *Factory

func (*Factory) HasOne

func (f *Factory) HasOne(fieldName string, ass *Association) *Factory

func (*Factory) Insert

func (f *Factory) Insert() (interface{}, error)

func (*Factory) InsertFunc

func (f *Factory) InsertFunc(fn dbutil.InsertFunc) *Factory

func (*Factory) InsertN

func (f *Factory) InsertN(n int) (interface{}, error)

func (*Factory) ManyToMany

func (f *Factory) ManyToMany(fieldName string, ass *Association, num int32) *Factory

func (*Factory) MustBuild

func (f *Factory) MustBuild() interface{}

func (*Factory) MustBuildN

func (f *Factory) MustBuildN(n int) interface{}

func (*Factory) MustInsert

func (f *Factory) MustInsert() interface{}

func (*Factory) MustInsertN

func (f *Factory) MustInsertN(n int) interface{}

func (*Factory) Omit

func (f *Factory) Omit(fields ...string) *Factory

func (*Factory) Only

func (f *Factory) Only(fields ...string) *Factory

func (*Factory) Table

func (f *Factory) Table(tableName string) *Factory

func (*Factory) ToAssociation

func (f *Factory) ToAssociation() *Association

type InsertJobsQueue

type InsertJobsQueue struct {
	// contains filtered or unexported fields
}

func NewInsertJobQueue

func NewInsertJobQueue() *InsertJobsQueue

func (*InsertJobsQueue) Dequeue

func (queue *InsertJobsQueue) Dequeue() *dbutil.InsertJob

func (*InsertJobsQueue) Enqueue

func (queue *InsertJobsQueue) Enqueue(job *dbutil.InsertJob)

type Node

type Node struct {
	// contains filtered or unexported fields
}

type ObjectSetter

type ObjectSetter []attr.Attributer

ObjectSetter object setter

func (ObjectSetter) SetupObject

func (setter ObjectSetter) SetupObject(val reflect.Value, omits map[string]bool, only map[string]bool) error

SetupObject setup object with Attributers

type Options

type Options struct {
	DB         *sql.DB
	Driver     string
	InsertFunc dbutil.InsertFunc
	TagProcess TagProcess
}

Options global option for factory context

func Opt

func Opt() *Options

Opt get global options

func (*Options) SetDB

func (opt *Options) SetDB(db *sql.DB, driver string) *Options

SetDB setup db instance

func (*Options) SetInsertFunc

func (opt *Options) SetInsertFunc(fn dbutil.InsertFunc) *Options

SetInsertFunc setup global insert function

func (*Options) SetTagProcess

func (opt *Options) SetTagProcess(tp TagProcess) *Options

SetTagProcess setup tag process

type Queue

type Queue struct {
	// contains filtered or unexported fields
}

func (*Queue) Dequeue

func (queue *Queue) Dequeue() *Node

func (*Queue) Enqueue

func (queue *Queue) Enqueue(node *Node)

func (*Queue) Head

func (queue *Queue) Head() *Node

func (*Queue) Scan

func (queue *Queue) Scan() func() *Node

func (*Queue) String

func (queue *Queue) String() string

func (*Queue) Tail

func (queue *Queue) Tail() *Node

type TagGetter

type TagGetter interface {
	Get(tagName string) (tagString string)
}

TagGetter tag getter

type TagProcess

type TagProcess func(tagGetter TagGetter) string

Directories

Path Synopsis
cmd
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL