func (st *BuildStruct) emit(g *genbase.Generator) error { g.Printf("// %[1]sQueryBuilder build query for %[1]s.\n", st.Name()) // generate FooQueryBuilder struct from Foo struct g.Printf("type %sQueryBuilder struct {\n", st.Name()) g.Printf("q *datastore.Query\n") g.Printf("plugin qbgutils.Plugin\n") for _, field := range st.Fields { if field.Tag.Ignore { continue } g.Printf("%[1]s *%[2]sQueryProperty\n", field.Tag.PropertyNameAlter, st.Name()) } g.Printf("}\n\n") // generate property info g.Printf(` // %[1]sQueryProperty has property information for %[1]sQueryBuilder. type %[1]sQueryProperty struct { bldr *%[1]sQueryBuilder name string } `, st.Name()) // generate new query builder factory function g.Printf("// New%[1]sQueryBuilder create new %[1]sQueryBuilder.\n", st.Name()) g.Printf("func New%[1]sQueryBuilder() *%[1]sQueryBuilder {\n", st.Name()) g.Printf("return New%[1]sQueryBuilderWithKind(\"%[2]s\")\n", st.Name(), st.Kind()) g.Printf("}\n\n") g.Printf("// New%[1]sQueryBuilderWithKind create new %[1]sQueryBuilder with specific kind.\n", st.Name()) g.Printf("func New%[1]sQueryBuilderWithKind(kind string) *%[1]sQueryBuilder {\n", st.Name()) g.Printf("q := datastore.NewQuery(kind)\n") g.Printf("bldr := &%[1]sQueryBuilder{q:q}\n", st.Name()) for _, field := range st.Fields { if field.Tag.Ignore { continue } name := field.Tag.Name if field.Tag.ID { name = "__key__" } g.Printf(`bldr.%[2]s= &%[1]sQueryProperty{ bldr : bldr, name: "%[3]s", } `, st.Name(), field.Tag.PropertyNameAlter, name) } g.Printf(` if plugger, ok := interface{}(bldr).(qbgutils.Plugger); ok { bldr.plugin = plugger.Plugin() bldr.plugin.Init("%[1]s") } `, st.Name()) g.Printf("return bldr\n") g.Printf("}\n\n") // generate methods g.Printf(` // Ancestor sets parent key to ancestor query. func (bldr *%[1]sQueryBuilder) Ancestor(parentKey *datastore.Key) *%[1]sQueryBuilder { bldr.q = bldr.q.Ancestor(parentKey) if bldr.plugin != nil { bldr.plugin.Ancestor(parentKey) } return bldr } // KeysOnly sets keys only option to query. func (bldr *%[1]sQueryBuilder) KeysOnly() *%[1]sQueryBuilder { bldr.q = bldr.q.KeysOnly() if bldr.plugin != nil { bldr.plugin.KeysOnly() } return bldr } // Start setup to query. func (bldr *%[1]sQueryBuilder) Start(cur datastore.Cursor) *%[1]sQueryBuilder { bldr.q = bldr.q.Start(cur) if bldr.plugin != nil { bldr.plugin.Start(cur) } return bldr } // Offset setupto query. func (bldr *%[1]sQueryBuilder) Offset(offset int) *%[1]sQueryBuilder { bldr.q = bldr.q.Offset(offset) if bldr.plugin != nil { bldr.plugin.Offset(offset) } return bldr } // Limit setup to query. func (bldr *%[1]sQueryBuilder) Limit(limit int) *%[1]sQueryBuilder { bldr.q = bldr.q.Limit(limit) if bldr.plugin != nil { bldr.plugin.Limit(limit) } return bldr } // Query returns *datastore.Query. func (bldr *%[1]sQueryBuilder) Query() *datastore.Query { return bldr.q } // Filter with op & value. func (p *%[1]sQueryProperty) Filter(op string, value interface{}) *%[1]sQueryBuilder { switch op { case "<=": p.LessThanOrEqual(value) case ">=": p.GreaterThanOrEqual(value) case "<": p.LessThan(value) case ">": p.GreaterThan(value) case "=": p.Equal(value) default: p.bldr.q = p.bldr.q.Filter(p.name + " " + op, value) // error raised by native query } if p.bldr.plugin != nil { p.bldr.plugin.Filter(p.name, op, value) } return p.bldr } // LessThanOrEqual filter with value. func (p *%[1]sQueryProperty) LessThanOrEqual(value interface{}) *%[1]sQueryBuilder { p.bldr.q = p.bldr.q.Filter(p.name + " <=", value) if p.bldr.plugin != nil { p.bldr.plugin.Filter(p.name,"<=", value) } return p.bldr } // GreaterThanOrEqual filter with value. func (p *%[1]sQueryProperty) GreaterThanOrEqual(value interface{}) *%[1]sQueryBuilder { p.bldr.q = p.bldr.q.Filter(p.name + " >=", value) if p.bldr.plugin != nil { p.bldr.plugin.Filter(p.name,">=", value) } return p.bldr } // LessThan filter with value. func (p *%[1]sQueryProperty) LessThan(value interface{}) *%[1]sQueryBuilder { p.bldr.q = p.bldr.q.Filter(p.name + " <", value) if p.bldr.plugin != nil { p.bldr.plugin.Filter(p.name,"<", value) } return p.bldr } // GreaterThan filter with value. func (p *%[1]sQueryProperty) GreaterThan(value interface{}) *%[1]sQueryBuilder { p.bldr.q = p.bldr.q.Filter(p.name + " >", value) if p.bldr.plugin != nil { p.bldr.plugin.Filter(p.name,">", value) } return p.bldr } // Equal filter with value. func (p *%[1]sQueryProperty) Equal(value interface{}) *%[1]sQueryBuilder { p.bldr.q = p.bldr.q.Filter(p.name + " =", value) if p.bldr.plugin != nil { p.bldr.plugin.Filter(p.name,"=", value) } return p.bldr } // Asc order. func (p *%[1]sQueryProperty) Asc() *%[1]sQueryBuilder { p.bldr.q = p.bldr.q.Order(p.name) if p.bldr.plugin != nil { p.bldr.plugin.Asc(p.name) } return p.bldr } // Desc order. func (p *%[1]sQueryProperty) Desc() *%[1]sQueryBuilder { p.bldr.q = p.bldr.q.Order("-" + p.name) if p.bldr.plugin != nil { p.bldr.plugin.Desc(p.name) } return p.bldr } `, st.Name(), "%s") g.Printf("\n\n") return nil }
func (st *BuildStruct) emit(g *genbase.Generator) error { g.Printf("// %[1]sSearch best match Search API wrapper for %[1]s.\n", st.Name()) // generate FooJson struct from Foo struct g.Printf("type %sSearch struct {\n", st.Name()) g.Printf("src *%s\n\n", st.Name()) for _, field := range st.Fields { if field.Tag.Ignore { continue } if field.Tag.ID { g.Printf("%[1]s string\n", field.Name) } else if field.Tag.Ngram { g.Printf("%[1]s string\n", field.Name, st.Name()) g.Printf("%[1]sUnigram string\n", field.Name, st.Name()) g.Printf("%[1]sBigram string\n", field.Name, st.Name()) } else if field.Tag.String { g.Printf("%[1]s string\n", field.Name, st.Name()) } else if field.Tag.JSON { g.Printf("%[1]s string\n", field.Name, st.Name()) } else if field.fieldInfo.IsNumber() { g.Printf("%[1]s float64\n", field.Name, st.Name()) } else if field.fieldInfo.IsBool() { g.Printf("%[1]s float64 // 1(true) or 0(false)\n", field.Name, st.Name()) } else if field.Tag.UnixTime { g.Printf("%[1]s time.Time\n", field.Name, st.Name()) g.Printf("%[1]sUnixTime float64\n", field.Name, st.Name()) } else if field.fieldInfo.IsTime() { g.Printf("%[1]s time.Time\n", field.Name, st.Name()) } else if field.fieldInfo.IsString() { g.Printf("%[1]s string\n", field.Name, st.Name()) } else { return fmt.Errorf("%s: unknown field type in %s", field.Name, st.Name()) } } g.Printf("}\n\n") // implement DocumentMetadata rank := st.Rank() if rank != nil { g.Printf(` // Load by search.LoadStruct. func (s *%[1]sSearch) Load(fields []search.Field, metadata *search.DocumentMetadata) error { return search.LoadStruct(s, fields) } // Save with search.DocumentMetadata#Rank. func (s *%[1]sSearch) Save() ([]search.Field, *search.DocumentMetadata, error) { fields, err := search.SaveStruct(s) if err != nil { return nil, nil, err } // https://cloud.google.com/appengine/docs/go/search/reference#DocumentMetadata // 0 origin value can not be correctly sorted. // Typically, the data is assumed to be 0's origin, 1 added every time. metadata := &search.DocumentMetadata{Rank: int(s.%[2]s) + 1} return fields, metadata, nil } `, st.Name(), rank.Name) } // implement Searchfy method g.Printf(` // Searchfy converts *%[1]s to *%[1]sSearch. func (src *%[1]s) Searchfy() (*%[1]sSearch, error) { if src == nil { return nil, nil } dest := &%[1]sSearch{} dest.src = src `, st.Name()) if st.HasJSON() { g.Printf("var err error\n") g.Printf("var b []byte\n") } else if st.HasNgram() { g.Printf("var err error\n") } for _, field := range st.Fields { if field.Tag.Ignore { continue } if field.Tag.ID || field.Tag.String { if field.fieldInfo.IsInt64() { g.Printf("dest.%[1]s = strconv.FormatInt(src.%[1]s, 10)\n", field.Name) } else if field.fieldInfo.IsInt() { g.Printf("dest.%[1]s = strconv.Itoa(src.%[1]s)\n", field.Name) } else if field.fieldInfo.IsString() { g.Printf("dest.%[1]s = src.%[1]s\n", field.Name) } else { // TODO support float32, float64 return fmt.Errorf("%s: id field should be int64, int, or string", field.Name) } } else if field.Tag.Ngram { if field.fieldInfo.IsString() { g.Printf(` dest.%[1]s = src.%[1]s dest.%[1]sUnigram, err = smgutils.UnigramForSearch(src.%[1]s) if err != nil { return nil, err } dest.%[1]sBigram, err = smgutils.BigramForSearch(src.%[1]s) if err != nil { return nil, err } `, field.Name) } else { return fmt.Errorf("%s: ngram field should be string", field.Name) } } else if field.Tag.JSON { g.Printf(` b, err = json.Marshal(src.%[1]s) if err != nil { return nil, err } if str := string(b); str != "" && str != "\"\"" { dest.%[1]s = str } `, field.Name) } else if field.Tag.UnixTime { if field.fieldInfo.IsTime() { g.Printf(` dest.%[1]sUnixTime = float64(smgutils.Unix(src.%[1]s)) dest.%[1]s = src.%[1]s `, field.Name) } else { return fmt.Errorf("%s: unixtime field should be time.Time", field.Name) } } else { // TODO implement invalid type detection if field.fieldInfo.IsInt64() || field.fieldInfo.IsInt() || field.fieldInfo.IsFloat32() { g.Printf("dest.%[1]s = float64(src.%[1]s)\n", field.Name) } else if field.fieldInfo.IsBool() { g.Printf(`if src.%[1]s { dest.%[1]s = 1 } else { dest.%[1]s = 0 } `, field.Name) } else if field.fieldInfo.IsString() || field.fieldInfo.IsFloat64() || field.fieldInfo.IsTime() { g.Printf("dest.%[1]s = src.%[1]s\n", field.Name) } else { return fmt.Errorf("%s: unknown field type in %s", field.Name, st.Name()) } } } g.Printf("return dest, nil\n}\n\n") // implement New*Search method g.Printf(` // New%[1]sSearch create new *%[1]sSearchBuilder. func New%[1]sSearch() *%[1]sSearchBuilder { op := &smgutils.Op{} b := &%[1]sSearchBuilder{ rootOp: op, currentOp: op, opts: &search.SearchOptions{ Sort: &search.SortOptions {}, }, } `, st.Name()) for _, field := range st.Fields { if field.Tag.ID || field.Tag.Ignore { continue } else if field.Tag.Ngram { g.Printf("b.%[1]s = &%[2]sSearchNgramStringPropertyInfo{%[2]sSearchStringPropertyInfo{\"%[1]s\", b}}\n", field.Name, st.Name()) } else if field.fieldInfo.IsString() || field.Tag.JSON || field.Tag.String { g.Printf("b.%[1]s = &%[2]sSearchStringPropertyInfo{\"%[1]s\", b}\n", field.Name, st.Name()) } else if field.fieldInfo.IsNumber() || field.fieldInfo.IsBool() { // special support to bool g.Printf("b.%[1]s = &%[2]sSearchNumberPropertyInfo{\"%[1]s\", b}\n", field.Name, st.Name()) } else if field.Tag.UnixTime { g.Printf("b.%[1]s = &%[2]sSearchUnixTimePropertyInfo{\"%[1]s\", b}\n", field.Name, st.Name()) } else if field.fieldInfo.IsTime() { g.Printf("b.%[1]s = &%[2]sSearchTimePropertyInfo{\"%[1]s\", b}\n", field.Name, st.Name()) } else { return fmt.Errorf("%s: unknown field type in %s", field.Name, st.Name()) } } g.Printf(` return b } `) // implement *SearchBuilder struct g.Printf(` var _ smgutils.SearchBuilder = &%[1]sSearchBuilder{} // %[1]sSearchBuilder builds Search API query. type %[1]sSearchBuilder struct { rootOp *smgutils.Op currentOp *smgutils.Op // for grouping opts *search.SearchOptions query string index *search.Index `, st.Name()) for _, field := range st.Fields { if field.Tag.ID || field.Tag.Ignore { continue } else if field.Tag.Ngram { g.Printf("%[1]s *%[2]sSearchNgramStringPropertyInfo\n", field.Name, st.Name()) } else if field.fieldInfo.IsString() || field.Tag.JSON || field.Tag.String { g.Printf("%[1]s *%[2]sSearchStringPropertyInfo\n", field.Name, st.Name()) } else if field.fieldInfo.IsNumber() || field.fieldInfo.IsBool() { // TODO special support to bool g.Printf("%[1]s *%[2]sSearchNumberPropertyInfo\n", field.Name, st.Name()) } else if field.Tag.UnixTime { g.Printf("%[1]s *%[2]sSearchUnixTimePropertyInfo\n", field.Name, st.Name()) } else if field.fieldInfo.IsTime() { g.Printf("%[1]s *%[2]sSearchTimePropertyInfo\n", field.Name, st.Name()) } else { return fmt.Errorf("%s: unknown field type in %s", field.Name, st.Name()) } } g.Printf("}\n\n") // implement SearchBuilder methods and others g.Printf(` // IndexName returns name of target index. func (b *%[1]sSearchBuilder) IndexName() string { return "%[1]s" } // QueryString returns query string. func (b *%[1]sSearchBuilder) QueryString() (string, error) { buffer := &bytes.Buffer{} err := b.rootOp.Query(buffer) if err != nil { return "", err } return buffer.String(), nil } // SearchOptions returns search options. func (b *%[1]sSearchBuilder) SearchOptions() *search.SearchOptions { return b.opts } // And append new operant to query. func (b *%[1]sSearchBuilder) And() *%[1]sSearchBuilder { b.currentOp.Children = append(b.currentOp.Children, &smgutils.Op{Type: smgutils.And}) return b } // Or append new operant to query. func (b *%[1]sSearchBuilder) Or() *%[1]sSearchBuilder { b.currentOp.Children = append(b.currentOp.Children, &smgutils.Op{Type: smgutils.Or}) return b } // Group append new operant to query. func (b *%[1]sSearchBuilder) Group(p func()) *%[1]sSearchBuilder { b.StartGroup() p() b.EndGroup() return b } // StartGroup append new operant to query. func (b *%[1]sSearchBuilder) StartGroup() *%[1]sSearchBuilder { op := &smgutils.Op{Type: smgutils.Group, Parent: b.currentOp} b.currentOp.Children = append(b.currentOp.Children, op) b.currentOp = op return b } // EndGroup append new operant to query. func (b *%[1]sSearchBuilder) EndGroup() *%[1]sSearchBuilder { b.currentOp = b.currentOp.Parent return b } // Put document to Index. func (b *%[1]sSearchBuilder) Put(c context.Context, src *%[1]s) (string, error) { doc, err := src.Searchfy() if err != nil { return "", err } return b.PutDocument(c, doc) } // PutDocument to Index. func (b *%[1]sSearchBuilder) PutDocument(c context.Context, src *%[1]sSearch) (string, error) { index, err := search.Open(b.IndexName()) if err != nil { return "", err } docID := "" if v, ok := interface{}(src).(smgutils.DocIDer); ok { // TODO can I shorten this cond expression? docID, err = v.DocID(c) if err != nil { return "", err } `, st.Name(), "%") if st.HasID() { g.Printf("src.ID = docID") } g.Printf(` } log.Debugf(c, "id: %[2]s#v, payload: %[2]s#v", docID, src) docID, err = index.Put(c, docID, src) if err != nil { return "", err } `, st.Name(), "%") if st.HasID() { g.Printf("src.ID = docID") } g.Printf(` return docID, nil } // Delete document from Index. func (b *%[1]sSearchBuilder) Delete(c context.Context, src *%[1]s) error { doc, err := src.Searchfy() if err != nil { return err } return b.DeleteDocument(c, doc) } // DeleteDocument from Index. func (b *%[1]sSearchBuilder) DeleteDocument(c context.Context, src *%[1]sSearch) error { if v, ok := interface{}(src).(smgutils.DocIDer); ok { // TODO can I shorten this cond expression? docID, err := v.DocID(c) if err != nil { return err } return b.DeleteByDocID(c, docID) } return errors.New("src is not implemented DocIDer interface") } // DeleteByDocID from Index. func (b *%[1]sSearchBuilder) DeleteByDocID(c context.Context, docID string) error { index, err := search.Open(b.IndexName()) if err != nil { return err } return index.Delete(c, docID) } // Opts returns *%[1]sSearchOptions. func (b *%[1]sSearchBuilder) Opts() *%[1]sSearchOptions { return &%[1]sSearchOptions{b: b} } // Search returns *%[1]sSearchIterator, It is result from Index. func (b *%[1]sSearchBuilder) Search(c context.Context) (*%[1]sSearchIterator, error) { index, err := search.Open(b.IndexName()) if err != nil { return nil, err } b.index = index query, err := b.QueryString() if err != nil { return nil, err } b.query = query log.Debugf(c, "query: '%[2]ss', opts: %[2]s#v", b.query, b.opts) iter := b.index.Search(c, b.query, b.opts) return &%[1]sSearchIterator{b, iter}, nil } // %[1]sSearchOptions construct *search.SearchOptions. type %[1]sSearchOptions struct { b *%[1]sSearchBuilder } // Limit setup opts. func (b *%[1]sSearchOptions) Limit(value int) *%[1]sSearchOptions { b.b.opts.Limit = value return b } // IDsOnly setup opts. func (b *%[1]sSearchOptions) IDsOnly() *%[1]sSearchOptions { b.b.opts.IDsOnly = true return b } // Cursor setup opts. func (b *%[1]sSearchOptions) Cursor(cursor search.Cursor) *%[1]sSearchOptions { b.b.opts.Cursor = cursor return b } // Offset setup opts. func (b *%[1]sSearchOptions) Offset(value int) *%[1]sSearchOptions { b.b.opts.Offset = value return b } // %[1]sSearchIterator can access to search result. type %[1]sSearchIterator struct { b *%[1]sSearchBuilder iter *search.Iterator } // Next returns next document from iter. func (b *%[1]sSearchIterator) Next(c context.Context) (string, *%[1]sSearch, error) { var s *%[1]sSearch if b.b.opts == nil || b.b.opts.IDsOnly != true { s = &%[1]sSearch{} } docID, err := b.iter.Next(s) if err != nil { return "", nil, err } `, st.Name(), "%") if st.HasID() { g.Printf("if s != nil {\n") g.Printf("s.ID = docID\n") g.Printf("}\n") } g.Printf(` return docID, s, err } // Cursor returns cursor of search. func (b *%[1]sSearchIterator) Cursor() search.Cursor { return b.iter.Cursor() } // %[1]sSearchStringPropertyInfo hold property info. type %[1]sSearchStringPropertyInfo struct { Name string b *%[1]sSearchBuilder } // Match add query operand. func (p *%[1]sSearchStringPropertyInfo) Match(value string) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Match, Value: value}) return p.b } // Asc add query operand. func (p *%[1]sSearchStringPropertyInfo) Asc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name, Reverse: true, }) return p.b } // Desc add query operand. func (p *%[1]sSearchStringPropertyInfo) Desc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name, Reverse: false, }) return p.b } // %[1]sSearchNgramStringPropertyInfo hold property info. type %[1]sSearchNgramStringPropertyInfo struct { %[1]sSearchStringPropertyInfo } // NgramMatch add query operand. func (p *%[1]sSearchNgramStringPropertyInfo) NgramMatch(value string) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.NgramMatch, Value: value}) return p.b } // %[1]sSearchNumberPropertyInfo hold property info. type %[1]sSearchNumberPropertyInfo struct { Name string b *%[1]sSearchBuilder } // IntGreaterThanOrEqual add query operand. func (p *%[1]sSearchNumberPropertyInfo) IntGreaterThanOrEqual(value int) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.GtEq, Value: value}) return p.b } // IntGreaterThan add query operand. func (p *%[1]sSearchNumberPropertyInfo) IntGreaterThan(value int) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Gt, Value: value}) return p.b } // IntLessThanOrEqual add query operand. func (p *%[1]sSearchNumberPropertyInfo) IntLessThanOrEqual(value int) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.LtEq, Value: value}) return p.b } // IntLessThan add query operand. func (p *%[1]sSearchNumberPropertyInfo) IntLessThan(value int) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Lt, Value: value}) return p.b } // IntEqual add query operand. func (p *%[1]sSearchNumberPropertyInfo) IntEqual(value int) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Eq, Value: value}) return p.b } // Int64GreaterThanOrEqual add query operand. func (p *%[1]sSearchNumberPropertyInfo) Int64GreaterThanOrEqual(value int64) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.GtEq, Value: value}) return p.b } // Int64GreaterThan add query operand. func (p *%[1]sSearchNumberPropertyInfo) Int64GreaterThan(value int64) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Gt, Value: value}) return p.b } // Int64LessThanOrEqual add query operand. func (p *%[1]sSearchNumberPropertyInfo) Int64LessThanOrEqual(value int64) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.LtEq, Value: value}) return p.b } // Int64LessThan add query operand. func (p *%[1]sSearchNumberPropertyInfo) Int64LessThan(value int64) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Lt, Value: value}) return p.b } // Int64Equal add query operand. func (p *%[1]sSearchNumberPropertyInfo) Int64Equal(value int64) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Eq, Value: value}) return p.b } // Asc add query operand. func (p *%[1]sSearchNumberPropertyInfo) Asc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name, Reverse: true, }) return p.b } // Desc add query operand. func (p *%[1]sSearchNumberPropertyInfo) Desc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name, Reverse: false, }) return p.b } // %[1]sSearchBoolPropertyInfo hold property info. type %[1]sSearchBoolPropertyInfo struct { Name string b *%[1]sSearchBuilder } // Equal add query operand. func (p *%[1]sSearchNumberPropertyInfo) Equal(value bool) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Eq, Value: value}) return p.b } // %[1]sSearchTimePropertyInfo hold property info. type %[1]sSearchTimePropertyInfo struct { Name string b *%[1]sSearchBuilder } // query spec for time.Time. // https://cloud.google.com/appengine/docs/go/search/query_strings#Go_Queries_on_date_fields // It using date, not datetime. // GreaterThanOrEqual add query operand. func (p *%[1]sSearchTimePropertyInfo) GreaterThanOrEqual(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.GtEq, Value: value.UTC()}) return p.b } // GreaterThan add query operand. func (p *%[1]sSearchTimePropertyInfo) GreaterThan(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Gt, Value: value.UTC()}) return p.b } // LessThanOrEqual add query operand. func (p *%[1]sSearchTimePropertyInfo) LessThanOrEqual(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.LtEq, Value: value.UTC()}) return p.b } // LessThan add query operand. func (p *%[1]sSearchTimePropertyInfo) LessThan(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Lt, Value: value.UTC()}) return p.b } // Equal add query operand. func (p *%[1]sSearchTimePropertyInfo) Equal(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Eq, Value: value.UTC()}) return p.b } // Asc add query operand. func (p *%[1]sSearchTimePropertyInfo) Asc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name, Reverse: true, }) return p.b } // Desc add query operand. func (p *%[1]sSearchTimePropertyInfo) Desc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name, Reverse: false, }) return p.b } // %[1]sSearchUnixTimePropertyInfo hold property info. type %[1]sSearchUnixTimePropertyInfo struct { Name string b *%[1]sSearchBuilder } // GreaterThanOrEqual add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) GreaterThanOrEqual(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.GtEq, Value: value.UTC()}) return p.b } // GreaterThan add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) GreaterThan(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Gt, Value: value.UTC()}) return p.b } // LessThanOrEqual add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) LessThanOrEqual(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.LtEq, Value: value.UTC()}) return p.b } // LessThan add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) LessThan(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Lt, Value: value.UTC()}) return p.b } // Equal add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) Equal(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name, Type: smgutils.Eq, Value: value.UTC()}) return p.b } // Asc add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) Asc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name, Reverse: true, }) return p.b } // Desc add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) Desc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name, Reverse: false, }) return p.b } // UnixTimeGreaterThanOrEqual add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) UnixTimeGreaterThanOrEqual(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name + "UnixTime", Type: smgutils.GtEq, Value: smgutils.Unix(value)}) return p.b } // UnixTimeGreaterThan add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) UnixTimeGreaterThan(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name + "UnixTime", Type: smgutils.Gt, Value: smgutils.Unix(value)}) return p.b } // UnixTimeLessThanOrEqual add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) UnixTimeLessThanOrEqual(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name + "UnixTime", Type: smgutils.LtEq, Value: smgutils.Unix(value)}) return p.b } // UnixTimeLessThan add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) UnixTimeLessThan(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name + "UnixTime", Type: smgutils.Lt, Value: smgutils.Unix(value)}) return p.b } // UnixTimeEqual add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) UnixTimeEqual(value time.Time) *%[1]sSearchBuilder { p.b.currentOp.Children = append(p.b.currentOp.Children, &smgutils.Op{FieldName: p.Name + "UnixTime", Type: smgutils.Eq, Value: smgutils.Unix(value)}) return p.b } // UnixTimeAsc add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) UnixTimeAsc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name + "UnixTime", Reverse: true, }) return p.b } // UnixTimeDesc add query operand. func (p *%[1]sSearchUnixTimePropertyInfo) UnixTimeDesc() *%[1]sSearchBuilder { if p.b.opts == nil { p.b.opts = &search.SearchOptions{} } if p.b.opts.Sort == nil { p.b.opts.Sort = &search.SortOptions{} } p.b.opts.Sort.Expressions = append(p.b.opts.Sort.Expressions, search.SortExpression{ Expr: p.Name + "UnixTime", Reverse: false, }) return p.b } `, st.Name(), "%") g.Printf("\n\n") return nil }