| Index: service/datastore/serialize.go
|
| diff --git a/service/datastore/serialize.go b/service/datastore/serialize.go
|
| index 30480231f7ad6de2060767b3f4a96c590f7321a2..e9117ababcf2e4fea3a4506f010144181715763b 100644
|
| --- a/service/datastore/serialize.go
|
| +++ b/service/datastore/serialize.go
|
| @@ -15,6 +15,10 @@ import (
|
| "github.com/luci/luci-go/common/cmpbin"
|
| )
|
|
|
| +// MaxIndexColumns is the maximum number of sort orders you may have on a
|
| +// single composite index. 64 was chosen as a likely-astronomical number.
|
| +const MaxIndexColumns = 64
|
| +
|
| // WritePropertyMapDeterministic allows tests to make WritePropertyMap
|
| // deterministic.
|
| var WritePropertyMapDeterministic = false
|
| @@ -365,6 +369,90 @@ func (pm PropertyMap) Read(buf Buffer, context KeyContext, appid, namespace stri
|
| return
|
| }
|
|
|
| +func (c *IndexColumn) Write(buf Buffer) (err error) {
|
| + defer recoverTo(&err)
|
| +
|
| + if c.Direction == ASCENDING {
|
| + panicIf(buf.WriteByte(0))
|
| + } else {
|
| + panicIf(buf.WriteByte(1))
|
| + }
|
| + _, err = cmpbin.WriteString(buf, c.Property)
|
| + return
|
| +}
|
| +
|
| +func (c *IndexColumn) Read(buf Buffer) (err error) {
|
| + defer recoverTo(&err)
|
| +
|
| + dir, err := buf.ReadByte()
|
| + panicIf(err)
|
| +
|
| + switch dir {
|
| + case 0:
|
| + c.Direction = ASCENDING
|
| + default:
|
| + c.Direction = DESCENDING
|
| + }
|
| + c.Property, _, err = cmpbin.ReadString(buf)
|
| + return err
|
| +}
|
| +
|
| +func (i *IndexDefinition) Write(buf Buffer) (err error) {
|
| + defer recoverTo(&err)
|
| +
|
| + if i.Builtin() {
|
| + panicIf(buf.WriteByte(0))
|
| + } else {
|
| + panicIf(buf.WriteByte(1))
|
| + }
|
| + _, err = cmpbin.WriteString(buf, i.Kind)
|
| + panicIf(err)
|
| + if !i.Ancestor {
|
| + panicIf(buf.WriteByte(0))
|
| + } else {
|
| + panicIf(buf.WriteByte(1))
|
| + }
|
| + _, err = cmpbin.WriteUint(buf, uint64(len(i.SortBy)))
|
| + panicIf(err)
|
| + for _, sb := range i.SortBy {
|
| + panicIf(sb.Write(buf))
|
| + }
|
| + return
|
| +}
|
| +
|
| +func (i *IndexDefinition) Read(buf Buffer) (err error) {
|
| + defer recoverTo(&err)
|
| +
|
| + // discard builtin/complex byte
|
| + _, err = buf.ReadByte()
|
| + panicIf(err)
|
| +
|
| + i.Kind, _, err = cmpbin.ReadString(buf)
|
| + panicIf(err)
|
| +
|
| + anc, err := buf.ReadByte()
|
| + panicIf(err)
|
| +
|
| + i.Ancestor = anc == 1
|
| +
|
| + numSorts, _, err := cmpbin.ReadUint(buf)
|
| + panicIf(err)
|
| +
|
| + if numSorts > MaxIndexColumns {
|
| + return fmt.Errorf("datastore: Got over %d sort orders: %d",
|
| + MaxIndexColumns, numSorts)
|
| + }
|
| +
|
| + if numSorts > 0 {
|
| + i.SortBy = make([]IndexColumn, numSorts)
|
| + for idx := range i.SortBy {
|
| + panicIf(i.SortBy[idx].Read(buf))
|
| + }
|
| + }
|
| +
|
| + return
|
| +}
|
| +
|
| type parseError error
|
|
|
| func panicIf(err error) {
|
|
|