Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autogenerated FindBy #92

Merged
merged 2 commits into from Feb 20, 2017
Merged

Autogenerated FindBy #92

merged 2 commits into from Feb 20, 2017

Conversation

dpordomingo
Copy link
Contributor

@dpordomingo dpordomingo commented Feb 13, 2017

solves #39

Functionality

Kallax will auto-generate the FindBy of each Model property if it satisfies one of the following;

A property will cause an auto-generated FindBy if:

  • its type is a "Valid" one:
    • a) "Basic", one of the following: string, byte, bool, float(s), int(s) or uint(s) (see)
    • b) "Special" (see)
      • one of the "kallaxKnownTypes" (SQL already knows how to handle it) (see)
      • a "SQLType" (implements sql.Scanner and driver.Valuer, see)
  • its type is a "collection" of "Valid" types

Type aliases will be valid if one of its underlying types is a "Valid" one.

Generated FindBy

The auto-generated FindBy for a given property named "PropertyName" will be as it follows:

  • model.ID -> FindByID(v ...kallax.ID)
    the query will success if the model.ID is one of the passed kallax.ID
  • "Basic" and "Special" properties
    • string and boolean properties -> FindByPopertyName(v validType),
      the query will success if the model property is equal to the passed kallax.ID
    • comparable properties -> FindByPopertyName(cond kallax.ScalarCond, v validType),
      the query will success if the model property satisfies the passed kallax.ScalarCond
  • "Collection" properties -> FindByPopertyName(v ...singleValidType)
    the query will success if the model collection property contains one of the passed values

@dpordomingo
Copy link
Contributor Author

affected by #93

Copy link
Contributor

@erizocosmico erizocosmico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry for the amount of requested changes, most of them are small stuff, naming of things and requesting tests

)

const (
tplFindByInclude = "\n\n// FindBy adds a new filter to the query that will require that\n" +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use the ` for multiline strings instead of concatenated strings, it would be easier to read imho

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

much better

@@ -106,7 +106,7 @@ var reservedKeywords = map[string]struct{}{

// special types that are not analyzed because SQL already knows
// how to handle them
var specialTypes = map[string]string{
var kallaxKnownTypes = map[string]string{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the rename of this?

return s
}

func isEqualizable(f *Field) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some docs for these 3 functions would be nice for context

// string, byte, bool, float(s), int(s) or uint(s)
func isBasicType(pkg *types.Package, typ types.Type) bool {
s := typ.String()
return s == "string" || s == "bool" || s == "byte" || s == "float64" || s == "float32" ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about converting this to a switch, which would be cleaner?

switch s {
case "string", "bool", "byte", "float64", ...:
    return true
}
return false

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tricky... but ok :)

return cleanName(typ, true)
}

func cleanName(typ types.Type, requireShortName bool) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs tests

// validType returns the short name of the type that can be used to search for
// the passed Field, in an autogenerated 'FindBy';
// if the Field is not valid for an autogenerated 'FindBy' it will return an error
func validType(f *Field) (string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about naming this findableTypeName?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should have tests


// GenFindBy generates FindByPropertyName for all model properties that are
// valid types or collection of valid types.
func (td *TemplateData) GenFindBy(model *Model) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should have tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea ;)

return ok || isSQLType(pkg, typ)
}

func kallaxKnownTypeName(typ types.Type) (string, bool) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the name of kallaxKnownTypes changes, this should change too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did't changed :)


// isSpecialType returns true if the passed type is one of the kallaxKnownTypes
// or a types.SQLType
func isSpecialType(pkg *types.Package, typ types.Type) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if kallaxKnownTypes changes, this should change too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did't changed :)


func (s *QuerySuite) TestGeneration() {
q := NewQueryFixtureQuery()
s.hasFindByMethod(q, "ID")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about a trable-driven tests?

var cases = []struct{
    name string
    generated bool
}{
    {"ID", true},
    // ...
}

for _, c := range cases {
    if c.generated {
        s.hasFindByMethod(q, c.name)
    } else {
        s.hasNotFindByMethod(q, c.name)
    }
}

that way it's easier to add more cases and there is less repeated code

Copy link
Contributor

@erizocosmico erizocosmico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when tests are implemented lgtm

if special, ok := specialTypeShortName(typ); ok {
return special
}

return cleanName(typ, true)
}

//TODO: review existent implementation generator.types::typeString
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after //

@erizocosmico
Copy link
Contributor

Btw, a lot of tests are failing

@dpordomingo
Copy link
Contributor Author

@erizocosmico many thanks for your recommendations!!!
I applied most of your suggested changes but:

  • moving findby.go into template.go in order to make it easier the sequential review of the PR,
  • adding tests, that will be done from now on, since we agree in the api and global behavior,
  • using generator.typeString instead of generator.cleanName, after the tests (of the previous step) has been done, to ensure that this changes breaks nothing.

@dpordomingo
Copy link
Contributor Author

affected by #96

@codecov-io
Copy link

codecov-io commented Feb 15, 2017

Codecov Report

Merging #92 into master will increase coverage by 0.41%.
The diff coverage is 92.39%.

@@            Coverage Diff             @@
##           master      #92      +/-   ##
==========================================
+ Coverage    80.1%   80.51%   +0.41%     
==========================================
  Files          15       15              
  Lines        2568     2659      +91     
==========================================
+ Hits         2057     2141      +84     
- Misses        348      354       +6     
- Partials      163      164       +1
Impacted Files Coverage Δ
generator/types.go 86.56% <ø> (ø)
operators.go 92.85% <ø> (ø)
generator/processor.go 88.93% <100%> (+0.08%)
generator/template.go 90.56% <92.13%> (+0.56%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 309f22e...14519e0. Read the comment docs.

@erizocosmico
Copy link
Contributor

Is this ready for review again? @dpordomingo

@dpordomingo
Copy link
Contributor Author

I forgot pushing it;
58877ad Use generator.types::typeString as suggested by @erizocosmico
a11cfb2 Add test for autogenerated FindBy

Pending, and will be done after your validation, in order to make it easier the sequential review of the PR :

  • moving findby.go into template.go in order to make it easier the sequential review of the PR,
  • squash and rebase after your validation

@erizocosmico
Copy link
Contributor

@dpordomingo so is it ready for review, right?

@dpordomingo
Copy link
Contributor Author

Yes, it is :)

})

s.NotPanics(func() {
//s.True(store.MustFindOne(NewQueryFixtureQuery().FindByBoolean(false)).Eq(queryFixtures[1]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leftovers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope,
Those tests are already broken tests, affected by #96

I updated it in my rebased branch, and it looks this way:
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, ok, then lgtm

@Serabe
Copy link
Contributor

Serabe commented Feb 20, 2017

@dpordomingo tests are failing. Are they supposed to fail yet?

@dpordomingo
Copy link
Contributor Author

@erizocosmico @Serabe Tests now passes, it was needed to use the go-parse-utils importer 58a187c

Copy link
Contributor

@Serabe Serabe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disregard the test thing.

case isEqualizable(f):
writeTplCode(buf, parent, f, tplFindByEquality)
case isSortable(f):
writeTplCode(buf, parent, f, tplFindByCondition)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This path is not tested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants