Skip to content

Commit

Permalink
implement customizable primary key types
Browse files Browse the repository at this point in the history
  • Loading branch information
Miguel Molina committed Feb 16, 2017
1 parent 63d2ae8 commit 77b51c3
Show file tree
Hide file tree
Showing 29 changed files with 780 additions and 288 deletions.
7 changes: 4 additions & 3 deletions batcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (r *batchQueryRunner) processBatch(rows *sql.Rows) ([]Record, error) {

var ids = make([]interface{}, len(records))
for i, r := range records {
ids[i] = r.GetID()
ids[i] = r.GetID().Raw()
}

for _, rel := range r.oneToManyRels {
Expand All @@ -129,7 +129,7 @@ func (r *batchQueryRunner) processBatch(rows *sql.Rows) ([]Record, error) {
}

for _, r := range records {
err := r.SetRelationship(rel.Field, indexedResults[r.GetID()])
err := r.SetRelationship(rel.Field, indexedResults[r.GetID().Raw()])
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -184,7 +184,8 @@ func (r *batchQueryRunner) getRecordRelationships(ids []interface{}, rel Relatio

rec.setPersisted()
rec.setWritable(true)
indexedResults[val] = append(indexedResults[val], rec)
id := val.(Identifier).Raw()
indexedResults[id] = append(indexedResults[id], rec)
}

if err := relRs.Close(); err != nil {
Expand Down
31 changes: 22 additions & 9 deletions common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ func openTestDB() (*sql.DB, error) {

func setupTables(t *testing.T, db *sql.DB) {
_, err := db.Exec(`CREATE TABLE model (
id uuid PRIMARY KEY,
id serial PRIMARY KEY,
name varchar(255) not null,
email varchar(255) not null,
age int not null
)`)
require.NoError(t, err)

_, err = db.Exec(`CREATE TABLE rel (
id uuid PRIMARY KEY,
model_id uuid,
id serial PRIMARY KEY,
model_id integer,
foo text
)`)
require.NoError(t, err)
Expand All @@ -52,6 +52,7 @@ func teardownTables(t *testing.T, db *sql.DB) {

type model struct {
Model
ID int64 `pk:"autoincr"`
Name string
Email string
Age int
Expand Down Expand Up @@ -129,22 +130,32 @@ func (m *model) SetRelationship(field string, record interface{}) error {
return fmt.Errorf("kallax: no relationship found for field %s", field)
}

func (m *model) GetID() Identifier {
return (*NumericID)(&m.ID)
}

type rel struct {
Model
ModelID ID
Foo string
ID int64 `pk:"autoincr"`
Foo string
}

func newRel(id Identifier, foo string) *rel {
rel := &rel{NewModel(), 0, foo}
rel.AddVirtualColumn("model_id", id)
return rel
}

func newRel(id ID, foo string) *rel {
return &rel{NewModel(), id, foo}
func (r *rel) GetID() Identifier {
return (*NumericID)(&r.ID)
}

func (m *rel) Value(col string) (interface{}, error) {
switch col {
case "id":
return m.ID, nil
case "model_id":
return m.ModelID, nil
return m.VirtualColumn(col), nil
case "foo":
return m.Foo, nil
}
Expand All @@ -156,7 +167,7 @@ func (m *rel) ColumnAddress(col string) (interface{}, error) {
case "id":
return &m.ID, nil
case "model_id":
return &m.ModelID, nil
return VirtualColumn(col, m, new(NumericID)), nil
case "foo":
return &m.Foo, nil
}
Expand All @@ -183,6 +194,7 @@ var ModelSchema = NewBaseSchema(
func() Record {
return new(model)
},
true,
f("id"),
f("name"),
f("email"),
Expand All @@ -197,6 +209,7 @@ var RelSchema = NewBaseSchema(
func() Record {
return new(rel)
},
true,
f("id"),
f("model_id"),
f("foo"),
Expand Down
40 changes: 23 additions & 17 deletions generator/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,13 @@ func (p *Processor) parseSourceFiles(filenames []string) (*types.Package, error)
}

func (p *Processor) processPackage() (*Package, error) {
pkg := &Package{pkg: p.Package, Name: p.Package.Name()}
pkg := NewPackage(p.Package)
var ctors []*types.Func

fmt.Println("Package: ", pkg.Name)

s := p.Package.Scope()
var models []*Model
for _, name := range s.Names() {
obj := s.Lookup(name)
switch t := obj.Type().(type) {
Expand All @@ -124,36 +125,39 @@ func (p *Processor) processPackage() (*Package, error) {
}
case *types.Named:
if str, ok := t.Underlying().(*types.Struct); ok {
if m := p.processModel(name, str, t); m != nil {
fmt.Printf("Found: %s\n", m)
if m, err := p.processModel(name, str, t); err != nil {
return nil, err
} else if m != nil {
fmt.Printf("Model: %s\n", m)
if err := m.Validate(); err != nil {
return nil, err
}

pkg.Models = append(pkg.Models, m)
models = append(models, m)
m.Node = t
m.Package = p.Package
}
}
}
}

pkg.SetModels(models)
for _, ctor := range ctors {
p.tryMatchConstructor(pkg.Models, ctor)
p.tryMatchConstructor(pkg, ctor)
}

return pkg, nil
}

func (p *Processor) tryMatchConstructor(models []*Model, fun *types.Func) {
for _, m := range models {
if fun.Name() != fmt.Sprintf("new%s", m.Name) {
continue
}
func (p *Processor) tryMatchConstructor(pkg *Package, fun *types.Func) {
if !strings.HasPrefix(fun.Name(), "new") {
return
}

if m := pkg.FindModel(fun.Name()[3:]); m != nil {
sig := fun.Type().(*types.Signature)
if sig.Recv() != nil {
continue
return
}

res := sig.Results()
Expand All @@ -165,23 +169,25 @@ func (p *Processor) tryMatchConstructor(models []*Model, fun *types.Func) {
}
}
}
return
}
}

func (p *Processor) processModel(name string, s *types.Struct, t *types.Named) *Model {
func (p *Processor) processModel(name string, s *types.Struct, t *types.Named) (*Model, error) {
m := NewModel(name)
m.Events = p.findEvents(t)

var base int
var fields []*Field
if base, fields = p.processFields(s, nil, true); base == -1 {
return nil
return nil, nil
}

if err := m.SetFields(fields); err != nil {
return nil, err
}

m.SetFields(fields)
p.processBaseField(m, m.Fields[base])
return m
p.processBaseField(m, fields[base])
return m, nil
}

var allEvents = Events{
Expand Down
31 changes: 23 additions & 8 deletions generator/processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ func (s *ProcessorSuite) TestInlineStruct() {
type Bar struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Foo string
R *Foo ` + "`kallax:\",inline\"`" + `
}
`

pkg := s.processFixture(fixtureSrc)
s.True(findModel(pkg, "Bar").Fields[2].Inline())
s.True(findModel(pkg, "Bar").Fields[3].Inline())
}

func (s *ProcessorSuite) TestTags() {
Expand All @@ -44,12 +45,13 @@ func (s *ProcessorSuite) TestTags() {
type Foo struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Int int "foo"
}
`

pkg := s.processFixture(fixtureSrc)
s.Equal(reflect.StructTag("foo"), findModel(pkg, "Foo").Fields[1].Tag)
s.Equal(reflect.StructTag("foo"), findModel(pkg, "Foo").Fields[2].Tag)
}

func (s *ProcessorSuite) TestRecursiveModel() {
Expand All @@ -60,6 +62,7 @@ func (s *ProcessorSuite) TestRecursiveModel() {
type Recur struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Foo string
R *Recur
}
Expand All @@ -80,6 +83,7 @@ func (s *ProcessorSuite) TestDeepRecursiveStruct() {
type Recur struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Foo string
Rec *Other
}
Expand All @@ -93,11 +97,11 @@ func (s *ProcessorSuite) TestDeepRecursiveStruct() {
m := findModel(pkg, "Recur")

s.Equal(
m.Fields[2].Fields[0].Fields[2].Node,
m.Fields[2].Node,
m.Fields[3].Fields[0].Fields[3].Node,
m.Fields[3].Node,
"indirect type recursivity not handled correctly.",
)
s.Len(pkg.Models[0].Fields[2].Fields[0].Fields[2].Fields, 0)
s.Len(pkg.Models[0].Fields[3].Fields[0].Fields[3].Fields, 0)
}

func (s *ProcessorSuite) TestIsEventPresent() {
Expand All @@ -108,6 +112,7 @@ func (s *ProcessorSuite) TestIsEventPresent() {
type Foo struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Foo string
}
Expand Down Expand Up @@ -152,6 +157,7 @@ func (s *ProcessorSuite) TestProcessField() {
type Related struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Foo string
}
Expand All @@ -170,6 +176,7 @@ func (s *ProcessorSuite) TestProcessField() {
type Foo struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Basic string
AliasBasic BasicAlias
BasicPtr *string
Expand Down Expand Up @@ -241,6 +248,7 @@ func (s *ProcessorSuite) TestCtor() {
type Foo struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Foo string
}
Expand All @@ -264,6 +272,7 @@ func (s *ProcessorSuite) TestSQLTypeIsInterface() {
type Foo struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Foo Bar
}
Expand All @@ -289,18 +298,20 @@ func (s *ProcessorSuite) TestIsSQLType() {
import "github.com/src-d/go-kallax"
type Foo struct {
type SQLTypeFixture struct {
kallax.Model
ID kallax.ULID ` + "`pk:\"\"`" + `
Foo string
}
`

p := s.processorFixture(fixtureSrc)
pkg, err := p.processPackage()
s.Nil(err)
m := findModel(pkg, "Foo")
m := findModel(pkg, "SQLTypeFixture")

s.True(isSQLType(p.Package, types.NewPointer(m.Fields[0].Fields[0].Node.Type())))
s.True(isSQLType(p.Package, types.NewPointer(m.ID.Node.Type())))
// model is index 1 because ID is always index 0
s.False(isSQLType(p.Package, types.NewPointer(m.Fields[1].Node.Type())))
}

Expand Down Expand Up @@ -341,6 +352,7 @@ func (s *ProcessorSuite) TestIsModel() {
type Bar struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Bar string
}
Expand All @@ -350,6 +362,7 @@ func (s *ProcessorSuite) TestIsModel() {
type Foo struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Foo string
Ptr *Bar
NoPtr Bar
Expand Down Expand Up @@ -381,6 +394,7 @@ func (s *ProcessorSuite) TestIsEmbedded() {
type Bar struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
Bar string
}
Expand All @@ -390,6 +404,7 @@ func (s *ProcessorSuite) TestIsEmbedded() {
type Foo struct {
kallax.Model
ID int64 ` + "`pk:\"autoincr\"`" + `
A Bar
B *Bar
Bar
Expand Down
Loading

0 comments on commit 77b51c3

Please sign in to comment.